diff --git a/Downstream/Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f401xc.h b/Downstream/Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f401xc.h new file mode 100644 index 0000000..2dd2c67 --- /dev/null +++ b/Downstream/Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f401xc.h @@ -0,0 +1,4773 @@ +/** + ****************************************************************************** + * @file stm32f401xc.h + * @author MCD Application Team + * @version V2.3.2 + * @date 26-June-2015 + * @brief CMSIS STM32F401xCxx Device Peripheral Access Layer Header File. + * + * This file contains: + * - Data structures and the address mapping for all peripherals + * - Peripheral's registers declarations and bits definition + * - Macros to access peripheral’s registers hardware + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f401xc + * @{ + */ + +#ifndef __STM32F401xC_H +#define __STM32F401xC_H + +#ifdef __cplusplus + extern "C" { +#endif /* __cplusplus */ + + +/** @addtogroup Configuration_section_for_CMSIS + * @{ + */ + +/** + * @brief Configuration of the Cortex-M4 Processor and Core Peripherals + */ +#define __CM4_REV 0x0001 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 1 /*!< STM32F4XX provides an MPU */ +#define __NVIC_PRIO_BITS 4 /*!< STM32F4XX uses 4 Bits for the Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1 /*!< FPU present */ + +/** + * @} + */ + +/** @addtogroup Peripheral_interrupt_number_definition + * @{ + */ + +/** + * @brief STM32F4XX Interrupt Number Definition, according to the selected device + * in @ref Library_configuration_section + */ +typedef enum +{ +/****** Cortex-M4 Processor Exceptions Numbers ****************************************************************/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M4 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M4 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M4 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M4 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M4 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M4 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M4 System Tick Interrupt */ +/****** STM32 specific Interrupt Numbers **********************************************************************/ + WWDG_IRQn = 0, /*!< Window WatchDog Interrupt */ + PVD_IRQn = 1, /*!< PVD through EXTI Line detection Interrupt */ + TAMP_STAMP_IRQn = 2, /*!< Tamper and TimeStamp interrupts through the EXTI line */ + RTC_WKUP_IRQn = 3, /*!< RTC Wakeup interrupt through the EXTI line */ + FLASH_IRQn = 4, /*!< FLASH global Interrupt */ + RCC_IRQn = 5, /*!< RCC global Interrupt */ + EXTI0_IRQn = 6, /*!< EXTI Line0 Interrupt */ + EXTI1_IRQn = 7, /*!< EXTI Line1 Interrupt */ + EXTI2_IRQn = 8, /*!< EXTI Line2 Interrupt */ + EXTI3_IRQn = 9, /*!< EXTI Line3 Interrupt */ + EXTI4_IRQn = 10, /*!< EXTI Line4 Interrupt */ + DMA1_Stream0_IRQn = 11, /*!< DMA1 Stream 0 global Interrupt */ + DMA1_Stream1_IRQn = 12, /*!< DMA1 Stream 1 global Interrupt */ + DMA1_Stream2_IRQn = 13, /*!< DMA1 Stream 2 global Interrupt */ + DMA1_Stream3_IRQn = 14, /*!< DMA1 Stream 3 global Interrupt */ + DMA1_Stream4_IRQn = 15, /*!< DMA1 Stream 4 global Interrupt */ + DMA1_Stream5_IRQn = 16, /*!< DMA1 Stream 5 global Interrupt */ + DMA1_Stream6_IRQn = 17, /*!< DMA1 Stream 6 global Interrupt */ + ADC_IRQn = 18, /*!< ADC1, ADC2 and ADC3 global Interrupts */ + EXTI9_5_IRQn = 23, /*!< External Line[9:5] Interrupts */ + TIM1_BRK_TIM9_IRQn = 24, /*!< TIM1 Break interrupt and TIM9 global interrupt */ + TIM1_UP_TIM10_IRQn = 25, /*!< TIM1 Update Interrupt and TIM10 global interrupt */ + TIM1_TRG_COM_TIM11_IRQn = 26, /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */ + TIM1_CC_IRQn = 27, /*!< TIM1 Capture Compare Interrupt */ + TIM2_IRQn = 28, /*!< TIM2 global Interrupt */ + TIM3_IRQn = 29, /*!< TIM3 global Interrupt */ + TIM4_IRQn = 30, /*!< TIM4 global Interrupt */ + I2C1_EV_IRQn = 31, /*!< I2C1 Event Interrupt */ + I2C1_ER_IRQn = 32, /*!< I2C1 Error Interrupt */ + I2C2_EV_IRQn = 33, /*!< I2C2 Event Interrupt */ + I2C2_ER_IRQn = 34, /*!< I2C2 Error Interrupt */ + SPI1_IRQn = 35, /*!< SPI1 global Interrupt */ + SPI2_IRQn = 36, /*!< SPI2 global Interrupt */ + USART1_IRQn = 37, /*!< USART1 global Interrupt */ + USART2_IRQn = 38, /*!< USART2 global Interrupt */ + EXTI15_10_IRQn = 40, /*!< External Line[15:10] Interrupts */ + RTC_Alarm_IRQn = 41, /*!< RTC Alarm (A and B) through EXTI Line Interrupt */ + OTG_FS_WKUP_IRQn = 42, /*!< USB OTG FS Wakeup through EXTI line interrupt */ + DMA1_Stream7_IRQn = 47, /*!< DMA1 Stream7 Interrupt */ + SDIO_IRQn = 49, /*!< SDIO global Interrupt */ + TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ + SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ + DMA2_Stream0_IRQn = 56, /*!< DMA2 Stream 0 global Interrupt */ + DMA2_Stream1_IRQn = 57, /*!< DMA2 Stream 1 global Interrupt */ + DMA2_Stream2_IRQn = 58, /*!< DMA2 Stream 2 global Interrupt */ + DMA2_Stream3_IRQn = 59, /*!< DMA2 Stream 3 global Interrupt */ + DMA2_Stream4_IRQn = 60, /*!< DMA2 Stream 4 global Interrupt */ + OTG_FS_IRQn = 67, /*!< USB OTG FS global Interrupt */ + DMA2_Stream5_IRQn = 68, /*!< DMA2 Stream 5 global interrupt */ + DMA2_Stream6_IRQn = 69, /*!< DMA2 Stream 6 global interrupt */ + DMA2_Stream7_IRQn = 70, /*!< DMA2 Stream 7 global interrupt */ + USART6_IRQn = 71, /*!< USART6 global interrupt */ + I2C3_EV_IRQn = 72, /*!< I2C3 event interrupt */ + I2C3_ER_IRQn = 73, /*!< I2C3 error interrupt */ + FPU_IRQn = 81, /*!< FPU global interrupt */ + SPI4_IRQn = 84 /*!< SPI4 global Interrupt */ +} IRQn_Type; + +/** + * @} + */ + +#include "core_cm4.h" /* Cortex-M4 processor and core peripherals */ +#include "system_stm32f4xx.h" +#include + +/** @addtogroup Peripheral_registers_structures + * @{ + */ + +/** + * @brief Analog to Digital Converter + */ + +typedef struct +{ + __IO uint32_t SR; /*!< ADC status register, Address offset: 0x00 */ + __IO uint32_t CR1; /*!< ADC control register 1, Address offset: 0x04 */ + __IO uint32_t CR2; /*!< ADC control register 2, Address offset: 0x08 */ + __IO uint32_t SMPR1; /*!< ADC sample time register 1, Address offset: 0x0C */ + __IO uint32_t SMPR2; /*!< ADC sample time register 2, Address offset: 0x10 */ + __IO uint32_t JOFR1; /*!< ADC injected channel data offset register 1, Address offset: 0x14 */ + __IO uint32_t JOFR2; /*!< ADC injected channel data offset register 2, Address offset: 0x18 */ + __IO uint32_t JOFR3; /*!< ADC injected channel data offset register 3, Address offset: 0x1C */ + __IO uint32_t JOFR4; /*!< ADC injected channel data offset register 4, Address offset: 0x20 */ + __IO uint32_t HTR; /*!< ADC watchdog higher threshold register, Address offset: 0x24 */ + __IO uint32_t LTR; /*!< ADC watchdog lower threshold register, Address offset: 0x28 */ + __IO uint32_t SQR1; /*!< ADC regular sequence register 1, Address offset: 0x2C */ + __IO uint32_t SQR2; /*!< ADC regular sequence register 2, Address offset: 0x30 */ + __IO uint32_t SQR3; /*!< ADC regular sequence register 3, Address offset: 0x34 */ + __IO uint32_t JSQR; /*!< ADC injected sequence register, Address offset: 0x38*/ + __IO uint32_t JDR1; /*!< ADC injected data register 1, Address offset: 0x3C */ + __IO uint32_t JDR2; /*!< ADC injected data register 2, Address offset: 0x40 */ + __IO uint32_t JDR3; /*!< ADC injected data register 3, Address offset: 0x44 */ + __IO uint32_t JDR4; /*!< ADC injected data register 4, Address offset: 0x48 */ + __IO uint32_t DR; /*!< ADC regular data register, Address offset: 0x4C */ +} ADC_TypeDef; + +typedef struct +{ + __IO uint32_t CSR; /*!< ADC Common status register, Address offset: ADC1 base address + 0x300 */ + __IO uint32_t CCR; /*!< ADC common control register, Address offset: ADC1 base address + 0x304 */ + __IO uint32_t CDR; /*!< ADC common regular data register for dual + AND triple modes, Address offset: ADC1 base address + 0x308 */ +} ADC_Common_TypeDef; + +/** + * @brief CRC calculation unit + */ + +typedef struct +{ + __IO uint32_t DR; /*!< CRC Data register, Address offset: 0x00 */ + __IO uint8_t IDR; /*!< CRC Independent data register, Address offset: 0x04 */ + uint8_t RESERVED0; /*!< Reserved, 0x05 */ + uint16_t RESERVED1; /*!< Reserved, 0x06 */ + __IO uint32_t CR; /*!< CRC Control register, Address offset: 0x08 */ +} CRC_TypeDef; + +/** + * @brief Debug MCU + */ + +typedef struct +{ + __IO uint32_t IDCODE; /*!< MCU device ID code, Address offset: 0x00 */ + __IO uint32_t CR; /*!< Debug MCU configuration register, Address offset: 0x04 */ + __IO uint32_t APB1FZ; /*!< Debug MCU APB1 freeze register, Address offset: 0x08 */ + __IO uint32_t APB2FZ; /*!< Debug MCU APB2 freeze register, Address offset: 0x0C */ +}DBGMCU_TypeDef; + + +/** + * @brief DMA Controller + */ + +typedef struct +{ + __IO uint32_t CR; /*!< DMA stream x configuration register */ + __IO uint32_t NDTR; /*!< DMA stream x number of data register */ + __IO uint32_t PAR; /*!< DMA stream x peripheral address register */ + __IO uint32_t M0AR; /*!< DMA stream x memory 0 address register */ + __IO uint32_t M1AR; /*!< DMA stream x memory 1 address register */ + __IO uint32_t FCR; /*!< DMA stream x FIFO control register */ +} DMA_Stream_TypeDef; + +typedef struct +{ + __IO uint32_t LISR; /*!< DMA low interrupt status register, Address offset: 0x00 */ + __IO uint32_t HISR; /*!< DMA high interrupt status register, Address offset: 0x04 */ + __IO uint32_t LIFCR; /*!< DMA low interrupt flag clear register, Address offset: 0x08 */ + __IO uint32_t HIFCR; /*!< DMA high interrupt flag clear register, Address offset: 0x0C */ +} DMA_TypeDef; + + +/** + * @brief External Interrupt/Event Controller + */ + +typedef struct +{ + __IO uint32_t IMR; /*!< EXTI Interrupt mask register, Address offset: 0x00 */ + __IO uint32_t EMR; /*!< EXTI Event mask register, Address offset: 0x04 */ + __IO uint32_t RTSR; /*!< EXTI Rising trigger selection register, Address offset: 0x08 */ + __IO uint32_t FTSR; /*!< EXTI Falling trigger selection register, Address offset: 0x0C */ + __IO uint32_t SWIER; /*!< EXTI Software interrupt event register, Address offset: 0x10 */ + __IO uint32_t PR; /*!< EXTI Pending register, Address offset: 0x14 */ +} EXTI_TypeDef; + +/** + * @brief FLASH Registers + */ + +typedef struct +{ + __IO uint32_t ACR; /*!< FLASH access control register, Address offset: 0x00 */ + __IO uint32_t KEYR; /*!< FLASH key register, Address offset: 0x04 */ + __IO uint32_t OPTKEYR; /*!< FLASH option key register, Address offset: 0x08 */ + __IO uint32_t SR; /*!< FLASH status register, Address offset: 0x0C */ + __IO uint32_t CR; /*!< FLASH control register, Address offset: 0x10 */ + __IO uint32_t OPTCR; /*!< FLASH option control register , Address offset: 0x14 */ + __IO uint32_t OPTCR1; /*!< FLASH option control register 1, Address offset: 0x18 */ +} FLASH_TypeDef; + +/** + * @brief General Purpose I/O + */ + +typedef struct +{ + __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ + __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ + __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ + __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ + __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ + __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ + __IO uint32_t BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x18 */ + __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ + __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ +} GPIO_TypeDef; + +/** + * @brief System configuration controller + */ + +typedef struct +{ + __IO uint32_t MEMRMP; /*!< SYSCFG memory remap register, Address offset: 0x00 */ + __IO uint32_t PMC; /*!< SYSCFG peripheral mode configuration register, Address offset: 0x04 */ + __IO uint32_t EXTICR[4]; /*!< SYSCFG external interrupt configuration registers, Address offset: 0x08-0x14 */ + uint32_t RESERVED[2]; /*!< Reserved, 0x18-0x1C */ + __IO uint32_t CMPCR; /*!< SYSCFG Compensation cell control register, Address offset: 0x20 */ +} SYSCFG_TypeDef; + +/** + * @brief Inter-integrated Circuit Interface + */ + +typedef struct +{ + __IO uint32_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */ + __IO uint32_t OAR1; /*!< I2C Own address register 1, Address offset: 0x08 */ + __IO uint32_t OAR2; /*!< I2C Own address register 2, Address offset: 0x0C */ + __IO uint32_t DR; /*!< I2C Data register, Address offset: 0x10 */ + __IO uint32_t SR1; /*!< I2C Status register 1, Address offset: 0x14 */ + __IO uint32_t SR2; /*!< I2C Status register 2, Address offset: 0x18 */ + __IO uint32_t CCR; /*!< I2C Clock control register, Address offset: 0x1C */ + __IO uint32_t TRISE; /*!< I2C TRISE register, Address offset: 0x20 */ + __IO uint32_t FLTR; /*!< I2C FLTR register, Address offset: 0x24 */ +} I2C_TypeDef; + +/** + * @brief Independent WATCHDOG + */ + +typedef struct +{ + __IO uint32_t KR; /*!< IWDG Key register, Address offset: 0x00 */ + __IO uint32_t PR; /*!< IWDG Prescaler register, Address offset: 0x04 */ + __IO uint32_t RLR; /*!< IWDG Reload register, Address offset: 0x08 */ + __IO uint32_t SR; /*!< IWDG Status register, Address offset: 0x0C */ +} IWDG_TypeDef; + +/** + * @brief Power Control + */ + +typedef struct +{ + __IO uint32_t CR; /*!< PWR power control register, Address offset: 0x00 */ + __IO uint32_t CSR; /*!< PWR power control/status register, Address offset: 0x04 */ +} PWR_TypeDef; + +/** + * @brief Reset and Clock Control + */ + +typedef struct +{ + __IO uint32_t CR; /*!< RCC clock control register, Address offset: 0x00 */ + __IO uint32_t PLLCFGR; /*!< RCC PLL configuration register, Address offset: 0x04 */ + __IO uint32_t CFGR; /*!< RCC clock configuration register, Address offset: 0x08 */ + __IO uint32_t CIR; /*!< RCC clock interrupt register, Address offset: 0x0C */ + __IO uint32_t AHB1RSTR; /*!< RCC AHB1 peripheral reset register, Address offset: 0x10 */ + __IO uint32_t AHB2RSTR; /*!< RCC AHB2 peripheral reset register, Address offset: 0x14 */ + __IO uint32_t AHB3RSTR; /*!< RCC AHB3 peripheral reset register, Address offset: 0x18 */ + uint32_t RESERVED0; /*!< Reserved, 0x1C */ + __IO uint32_t APB1RSTR; /*!< RCC APB1 peripheral reset register, Address offset: 0x20 */ + __IO uint32_t APB2RSTR; /*!< RCC APB2 peripheral reset register, Address offset: 0x24 */ + uint32_t RESERVED1[2]; /*!< Reserved, 0x28-0x2C */ + __IO uint32_t AHB1ENR; /*!< RCC AHB1 peripheral clock register, Address offset: 0x30 */ + __IO uint32_t AHB2ENR; /*!< RCC AHB2 peripheral clock register, Address offset: 0x34 */ + __IO uint32_t AHB3ENR; /*!< RCC AHB3 peripheral clock register, Address offset: 0x38 */ + uint32_t RESERVED2; /*!< Reserved, 0x3C */ + __IO uint32_t APB1ENR; /*!< RCC APB1 peripheral clock enable register, Address offset: 0x40 */ + __IO uint32_t APB2ENR; /*!< RCC APB2 peripheral clock enable register, Address offset: 0x44 */ + uint32_t RESERVED3[2]; /*!< Reserved, 0x48-0x4C */ + __IO uint32_t AHB1LPENR; /*!< RCC AHB1 peripheral clock enable in low power mode register, Address offset: 0x50 */ + __IO uint32_t AHB2LPENR; /*!< RCC AHB2 peripheral clock enable in low power mode register, Address offset: 0x54 */ + __IO uint32_t AHB3LPENR; /*!< RCC AHB3 peripheral clock enable in low power mode register, Address offset: 0x58 */ + uint32_t RESERVED4; /*!< Reserved, 0x5C */ + __IO uint32_t APB1LPENR; /*!< RCC APB1 peripheral clock enable in low power mode register, Address offset: 0x60 */ + __IO uint32_t APB2LPENR; /*!< RCC APB2 peripheral clock enable in low power mode register, Address offset: 0x64 */ + uint32_t RESERVED5[2]; /*!< Reserved, 0x68-0x6C */ + __IO uint32_t BDCR; /*!< RCC Backup domain control register, Address offset: 0x70 */ + __IO uint32_t CSR; /*!< RCC clock control & status register, Address offset: 0x74 */ + uint32_t RESERVED6[2]; /*!< Reserved, 0x78-0x7C */ + __IO uint32_t SSCGR; /*!< RCC spread spectrum clock generation register, Address offset: 0x80 */ + __IO uint32_t PLLI2SCFGR; /*!< RCC PLLI2S configuration register, Address offset: 0x84 */ + +} RCC_TypeDef; + +/** + * @brief Real-Time Clock + */ + +typedef struct +{ + __IO uint32_t TR; /*!< RTC time register, Address offset: 0x00 */ + __IO uint32_t DR; /*!< RTC date register, Address offset: 0x04 */ + __IO uint32_t CR; /*!< RTC control register, Address offset: 0x08 */ + __IO uint32_t ISR; /*!< RTC initialization and status register, Address offset: 0x0C */ + __IO uint32_t PRER; /*!< RTC prescaler register, Address offset: 0x10 */ + __IO uint32_t WUTR; /*!< RTC wakeup timer register, Address offset: 0x14 */ + __IO uint32_t CALIBR; /*!< RTC calibration register, Address offset: 0x18 */ + __IO uint32_t ALRMAR; /*!< RTC alarm A register, Address offset: 0x1C */ + __IO uint32_t ALRMBR; /*!< RTC alarm B register, Address offset: 0x20 */ + __IO uint32_t WPR; /*!< RTC write protection register, Address offset: 0x24 */ + __IO uint32_t SSR; /*!< RTC sub second register, Address offset: 0x28 */ + __IO uint32_t SHIFTR; /*!< RTC shift control register, Address offset: 0x2C */ + __IO uint32_t TSTR; /*!< RTC time stamp time register, Address offset: 0x30 */ + __IO uint32_t TSDR; /*!< RTC time stamp date register, Address offset: 0x34 */ + __IO uint32_t TSSSR; /*!< RTC time-stamp sub second register, Address offset: 0x38 */ + __IO uint32_t CALR; /*!< RTC calibration register, Address offset: 0x3C */ + __IO uint32_t TAFCR; /*!< RTC tamper and alternate function configuration register, Address offset: 0x40 */ + __IO uint32_t ALRMASSR;/*!< RTC alarm A sub second register, Address offset: 0x44 */ + __IO uint32_t ALRMBSSR;/*!< RTC alarm B sub second register, Address offset: 0x48 */ + uint32_t RESERVED7; /*!< Reserved, 0x4C */ + __IO uint32_t BKP0R; /*!< RTC backup register 1, Address offset: 0x50 */ + __IO uint32_t BKP1R; /*!< RTC backup register 1, Address offset: 0x54 */ + __IO uint32_t BKP2R; /*!< RTC backup register 2, Address offset: 0x58 */ + __IO uint32_t BKP3R; /*!< RTC backup register 3, Address offset: 0x5C */ + __IO uint32_t BKP4R; /*!< RTC backup register 4, Address offset: 0x60 */ + __IO uint32_t BKP5R; /*!< RTC backup register 5, Address offset: 0x64 */ + __IO uint32_t BKP6R; /*!< RTC backup register 6, Address offset: 0x68 */ + __IO uint32_t BKP7R; /*!< RTC backup register 7, Address offset: 0x6C */ + __IO uint32_t BKP8R; /*!< RTC backup register 8, Address offset: 0x70 */ + __IO uint32_t BKP9R; /*!< RTC backup register 9, Address offset: 0x74 */ + __IO uint32_t BKP10R; /*!< RTC backup register 10, Address offset: 0x78 */ + __IO uint32_t BKP11R; /*!< RTC backup register 11, Address offset: 0x7C */ + __IO uint32_t BKP12R; /*!< RTC backup register 12, Address offset: 0x80 */ + __IO uint32_t BKP13R; /*!< RTC backup register 13, Address offset: 0x84 */ + __IO uint32_t BKP14R; /*!< RTC backup register 14, Address offset: 0x88 */ + __IO uint32_t BKP15R; /*!< RTC backup register 15, Address offset: 0x8C */ + __IO uint32_t BKP16R; /*!< RTC backup register 16, Address offset: 0x90 */ + __IO uint32_t BKP17R; /*!< RTC backup register 17, Address offset: 0x94 */ + __IO uint32_t BKP18R; /*!< RTC backup register 18, Address offset: 0x98 */ + __IO uint32_t BKP19R; /*!< RTC backup register 19, Address offset: 0x9C */ +} RTC_TypeDef; + + +/** + * @brief SD host Interface + */ + +typedef struct +{ + __IO uint32_t POWER; /*!< SDIO power control register, Address offset: 0x00 */ + __IO uint32_t CLKCR; /*!< SDI clock control register, Address offset: 0x04 */ + __IO uint32_t ARG; /*!< SDIO argument register, Address offset: 0x08 */ + __IO uint32_t CMD; /*!< SDIO command register, Address offset: 0x0C */ + __I uint32_t RESPCMD; /*!< SDIO command response register, Address offset: 0x10 */ + __I uint32_t RESP1; /*!< SDIO response 1 register, Address offset: 0x14 */ + __I uint32_t RESP2; /*!< SDIO response 2 register, Address offset: 0x18 */ + __I uint32_t RESP3; /*!< SDIO response 3 register, Address offset: 0x1C */ + __I uint32_t RESP4; /*!< SDIO response 4 register, Address offset: 0x20 */ + __IO uint32_t DTIMER; /*!< SDIO data timer register, Address offset: 0x24 */ + __IO uint32_t DLEN; /*!< SDIO data length register, Address offset: 0x28 */ + __IO uint32_t DCTRL; /*!< SDIO data control register, Address offset: 0x2C */ + __I uint32_t DCOUNT; /*!< SDIO data counter register, Address offset: 0x30 */ + __I uint32_t STA; /*!< SDIO status register, Address offset: 0x34 */ + __IO uint32_t ICR; /*!< SDIO interrupt clear register, Address offset: 0x38 */ + __IO uint32_t MASK; /*!< SDIO mask register, Address offset: 0x3C */ + uint32_t RESERVED0[2]; /*!< Reserved, 0x40-0x44 */ + __I uint32_t FIFOCNT; /*!< SDIO FIFO counter register, Address offset: 0x48 */ + uint32_t RESERVED1[13]; /*!< Reserved, 0x4C-0x7C */ + __IO uint32_t FIFO; /*!< SDIO data FIFO register, Address offset: 0x80 */ +} SDIO_TypeDef; + +/** + * @brief Serial Peripheral Interface + */ + +typedef struct +{ + __IO uint32_t CR1; /*!< SPI control register 1 (not used in I2S mode), Address offset: 0x00 */ + __IO uint32_t CR2; /*!< SPI control register 2, Address offset: 0x04 */ + __IO uint32_t SR; /*!< SPI status register, Address offset: 0x08 */ + __IO uint32_t DR; /*!< SPI data register, Address offset: 0x0C */ + __IO uint32_t CRCPR; /*!< SPI CRC polynomial register (not used in I2S mode), Address offset: 0x10 */ + __IO uint32_t RXCRCR; /*!< SPI RX CRC register (not used in I2S mode), Address offset: 0x14 */ + __IO uint32_t TXCRCR; /*!< SPI TX CRC register (not used in I2S mode), Address offset: 0x18 */ + __IO uint32_t I2SCFGR; /*!< SPI_I2S configuration register, Address offset: 0x1C */ + __IO uint32_t I2SPR; /*!< SPI_I2S prescaler register, Address offset: 0x20 */ +} SPI_TypeDef; + +/** + * @brief TIM + */ + +typedef struct +{ + __IO uint32_t CR1; /*!< TIM control register 1, Address offset: 0x00 */ + __IO uint32_t CR2; /*!< TIM control register 2, Address offset: 0x04 */ + __IO uint32_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */ + __IO uint32_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */ + __IO uint32_t SR; /*!< TIM status register, Address offset: 0x10 */ + __IO uint32_t EGR; /*!< TIM event generation register, Address offset: 0x14 */ + __IO uint32_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */ + __IO uint32_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */ + __IO uint32_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */ + __IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */ + __IO uint32_t PSC; /*!< TIM prescaler, Address offset: 0x28 */ + __IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */ + __IO uint32_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */ + __IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */ + __IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */ + __IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */ + __IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */ + __IO uint32_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */ + __IO uint32_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */ + __IO uint32_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */ + __IO uint32_t OR; /*!< TIM option register, Address offset: 0x50 */ +} TIM_TypeDef; + +/** + * @brief Universal Synchronous Asynchronous Receiver Transmitter + */ + +typedef struct +{ + __IO uint32_t SR; /*!< USART Status register, Address offset: 0x00 */ + __IO uint32_t DR; /*!< USART Data register, Address offset: 0x04 */ + __IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */ + __IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x0C */ + __IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x10 */ + __IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x14 */ + __IO uint32_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */ +} USART_TypeDef; + +/** + * @brief Window WATCHDOG + */ + +typedef struct +{ + __IO uint32_t CR; /*!< WWDG Control register, Address offset: 0x00 */ + __IO uint32_t CFR; /*!< WWDG Configuration register, Address offset: 0x04 */ + __IO uint32_t SR; /*!< WWDG Status register, Address offset: 0x08 */ +} WWDG_TypeDef; + +/** + * @brief __USB_OTG_Core_register + */ +typedef struct +{ + __IO uint32_t GOTGCTL; /*!< USB_OTG Control and Status Register Address offset : 0x00 */ + __IO uint32_t GOTGINT; /*!< USB_OTG Interrupt Register Address offset : 0x04 */ + __IO uint32_t GAHBCFG; /*!< Core AHB Configuration Register Address offset : 0x08 */ + __IO uint32_t GUSBCFG; /*!< Core USB Configuration Register Address offset : 0x0C */ + __IO uint32_t GRSTCTL; /*!< Core Reset Register Address offset : 0x10 */ + __IO uint32_t GINTSTS; /*!< Core Interrupt Register Address offset : 0x14 */ + __IO uint32_t GINTMSK; /*!< Core Interrupt Mask Register Address offset : 0x18 */ + __IO uint32_t GRXSTSR; /*!< Receive Sts Q Read Register Address offset : 0x1C */ + __IO uint32_t GRXSTSP; /*!< Receive Sts Q Read & POP Register Address offset : 0x20 */ + __IO uint32_t GRXFSIZ; /* Receive FIFO Size Register Address offset : 0x24 */ + __IO uint32_t DIEPTXF0_HNPTXFSIZ; /*!< EP0 / Non Periodic Tx FIFO Size Register Address offset : 0x28 */ + __IO uint32_t HNPTXSTS; /*!< Non Periodic Tx FIFO/Queue Sts reg Address offset : 0x2C */ + uint32_t Reserved30[2]; /* Reserved Address offset : 0x30 */ + __IO uint32_t GCCFG; /*!< General Purpose IO Register Address offset : 0x38 */ + __IO uint32_t CID; /*!< User ID Register Address offset : 0x3C */ + uint32_t Reserved40[48]; /*!< Reserved Address offset : 0x40-0xFF */ + __IO uint32_t HPTXFSIZ; /*!< Host Periodic Tx FIFO Size Reg Address offset : 0x100 */ + __IO uint32_t DIEPTXF[0x0F]; /*!< dev Periodic Transmit FIFO */ +} +USB_OTG_GlobalTypeDef; + + + +/** + * @brief __device_Registers + */ +typedef struct +{ + __IO uint32_t DCFG; /*!< dev Configuration Register Address offset : 0x800 */ + __IO uint32_t DCTL; /*!< dev Control Register Address offset : 0x804 */ + __IO uint32_t DSTS; /*!< dev Status Register (RO) Address offset : 0x808 */ + uint32_t Reserved0C; /*!< Reserved Address offset : 0x80C */ + __IO uint32_t DIEPMSK; /* !< dev IN Endpoint Mask Address offset : 0x810 */ + __IO uint32_t DOEPMSK; /*!< dev OUT Endpoint Mask Address offset : 0x814 */ + __IO uint32_t DAINT; /*!< dev All Endpoints Itr Reg Address offset : 0x818 */ + __IO uint32_t DAINTMSK; /*!< dev All Endpoints Itr Mask Address offset : 0x81C */ + uint32_t Reserved20; /*!< Reserved Address offset : 0x820 */ + uint32_t Reserved9; /*!< Reserved Address offset : 0x824 */ + __IO uint32_t DVBUSDIS; /*!< dev VBUS discharge Register Address offset : 0x828 */ + __IO uint32_t DVBUSPULSE; /*!< dev VBUS Pulse Register Address offset : 0x82C */ + __IO uint32_t DTHRCTL; /*!< dev thr Address offset : 0x830 */ + __IO uint32_t DIEPEMPMSK; /*!< dev empty msk Address offset : 0x834 */ + __IO uint32_t DEACHINT; /*!< dedicated EP interrupt Address offset : 0x838 */ + __IO uint32_t DEACHMSK; /*!< dedicated EP msk Address offset : 0x83C */ + uint32_t Reserved40; /*!< dedicated EP mask Address offset : 0x840 */ + __IO uint32_t DINEP1MSK; /*!< dedicated EP mask Address offset : 0x844 */ + uint32_t Reserved44[15]; /*!< Reserved Address offset : 0x844-0x87C */ + __IO uint32_t DOUTEP1MSK; /*!< dedicated EP msk Address offset : 0x884 */ +} +USB_OTG_DeviceTypeDef; + + +/** + * @brief __IN_Endpoint-Specific_Register + */ +typedef struct +{ + __IO uint32_t DIEPCTL; /* dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h */ + uint32_t Reserved04; /* Reserved 900h + (ep_num * 20h) + 04h */ + __IO uint32_t DIEPINT; /* dev IN Endpoint Itr Reg 900h + (ep_num * 20h) + 08h */ + uint32_t Reserved0C; /* Reserved 900h + (ep_num * 20h) + 0Ch */ + __IO uint32_t DIEPTSIZ; /* IN Endpoint Txfer Size 900h + (ep_num * 20h) + 10h */ + __IO uint32_t DIEPDMA; /* IN Endpoint DMA Address Reg 900h + (ep_num * 20h) + 14h */ + __IO uint32_t DTXFSTS; /*IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h */ + uint32_t Reserved18; /* Reserved 900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch */ +} +USB_OTG_INEndpointTypeDef; + + +/** + * @brief __OUT_Endpoint-Specific_Registers + */ +typedef struct +{ + __IO uint32_t DOEPCTL; /* dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h*/ + uint32_t Reserved04; /* Reserved B00h + (ep_num * 20h) + 04h*/ + __IO uint32_t DOEPINT; /* dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h*/ + uint32_t Reserved0C; /* Reserved B00h + (ep_num * 20h) + 0Ch*/ + __IO uint32_t DOEPTSIZ; /* dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h*/ + __IO uint32_t DOEPDMA; /* dev OUT Endpoint DMA Address B00h + (ep_num * 20h) + 14h*/ + uint32_t Reserved18[2]; /* Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch*/ +} +USB_OTG_OUTEndpointTypeDef; + + +/** + * @brief __Host_Mode_Register_Structures + */ +typedef struct +{ + __IO uint32_t HCFG; /* Host Configuration Register 400h*/ + __IO uint32_t HFIR; /* Host Frame Interval Register 404h*/ + __IO uint32_t HFNUM; /* Host Frame Nbr/Frame Remaining 408h*/ + uint32_t Reserved40C; /* Reserved 40Ch*/ + __IO uint32_t HPTXSTS; /* Host Periodic Tx FIFO/ Queue Status 410h*/ + __IO uint32_t HAINT; /* Host All Channels Interrupt Register 414h*/ + __IO uint32_t HAINTMSK; /* Host All Channels Interrupt Mask 418h*/ +} +USB_OTG_HostTypeDef; + + +/** + * @brief __Host_Channel_Specific_Registers + */ +typedef struct +{ + __IO uint32_t HCCHAR; + __IO uint32_t HCSPLT; + __IO uint32_t HCINT; + __IO uint32_t HCINTMSK; + __IO uint32_t HCTSIZ; + __IO uint32_t HCDMA; + uint32_t Reserved[2]; +} +USB_OTG_HostChannelTypeDef; + + +/** + * @brief Peripheral_memory_map + */ +#define FLASH_BASE ((uint32_t)0x08000000) /*!< FLASH(up to 1 MB) base address in the alias region */ +#define CCMDATARAM_BASE ((uint32_t)0x10000000) /*!< CCM(core coupled memory) data RAM(64 KB) base address in the alias region */ +#define SRAM1_BASE ((uint32_t)0x20000000) /*!< SRAM1(112 KB) base address in the alias region */ +#define SRAM2_BASE ((uint32_t)0x2001C000) /*!< SRAM2(16 KB) base address in the alias region */ +#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */ +#define BKPSRAM_BASE ((uint32_t)0x40024000) /*!< Backup SRAM(4 KB) base address in the alias region */ +#define SRAM1_BB_BASE ((uint32_t)0x22000000) /*!< SRAM1(112 KB) base address in the bit-band region */ +#define SRAM2_BB_BASE ((uint32_t)0x22380000) /*!< SRAM2(16 KB) base address in the bit-band region */ +#define PERIPH_BB_BASE ((uint32_t)0x42000000) /*!< Peripheral base address in the bit-band region */ +#define BKPSRAM_BB_BASE ((uint32_t)0x42480000) /*!< Backup SRAM(4 KB) base address in the bit-band region */ +#define FLASH_END ((uint32_t)0x0803FFFF) /*!< FLASH end address */ + +/* Legacy defines */ +#define SRAM_BASE SRAM1_BASE +#define SRAM_BB_BASE SRAM1_BB_BASE + + +/*!< Peripheral memory map */ +#define APB1PERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000) +#define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000) +#define AHB2PERIPH_BASE (PERIPH_BASE + 0x10000000) + +/*!< APB1 peripherals */ +#define TIM2_BASE (APB1PERIPH_BASE + 0x0000) +#define TIM3_BASE (APB1PERIPH_BASE + 0x0400) +#define TIM4_BASE (APB1PERIPH_BASE + 0x0800) +#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00) +#define RTC_BASE (APB1PERIPH_BASE + 0x2800) +#define WWDG_BASE (APB1PERIPH_BASE + 0x2C00) +#define IWDG_BASE (APB1PERIPH_BASE + 0x3000) +#define I2S2ext_BASE (APB1PERIPH_BASE + 0x3400) +#define SPI2_BASE (APB1PERIPH_BASE + 0x3800) +#define SPI3_BASE (APB1PERIPH_BASE + 0x3C00) +#define I2S3ext_BASE (APB1PERIPH_BASE + 0x4000) +#define USART2_BASE (APB1PERIPH_BASE + 0x4400) +#define I2C1_BASE (APB1PERIPH_BASE + 0x5400) +#define I2C2_BASE (APB1PERIPH_BASE + 0x5800) +#define I2C3_BASE (APB1PERIPH_BASE + 0x5C00) +#define PWR_BASE (APB1PERIPH_BASE + 0x7000) + +/*!< APB2 peripherals */ +#define TIM1_BASE (APB2PERIPH_BASE + 0x0000) +#define USART1_BASE (APB2PERIPH_BASE + 0x1000) +#define USART6_BASE (APB2PERIPH_BASE + 0x1400) +#define ADC1_BASE (APB2PERIPH_BASE + 0x2000) +#define ADC_BASE (APB2PERIPH_BASE + 0x2300) +#define SDIO_BASE (APB2PERIPH_BASE + 0x2C00) +#define SPI1_BASE (APB2PERIPH_BASE + 0x3000) +#define SPI4_BASE (APB2PERIPH_BASE + 0x3400) +#define SYSCFG_BASE (APB2PERIPH_BASE + 0x3800) +#define EXTI_BASE (APB2PERIPH_BASE + 0x3C00) +#define TIM9_BASE (APB2PERIPH_BASE + 0x4000) +#define TIM10_BASE (APB2PERIPH_BASE + 0x4400) +#define TIM11_BASE (APB2PERIPH_BASE + 0x4800) + +/*!< AHB1 peripherals */ +#define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000) +#define GPIOB_BASE (AHB1PERIPH_BASE + 0x0400) +#define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800) +#define GPIOD_BASE (AHB1PERIPH_BASE + 0x0C00) +#define GPIOE_BASE (AHB1PERIPH_BASE + 0x1000) +#define GPIOH_BASE (AHB1PERIPH_BASE + 0x1C00) +#define CRC_BASE (AHB1PERIPH_BASE + 0x3000) +#define RCC_BASE (AHB1PERIPH_BASE + 0x3800) +#define FLASH_R_BASE (AHB1PERIPH_BASE + 0x3C00) +#define DMA1_BASE (AHB1PERIPH_BASE + 0x6000) +#define DMA1_Stream0_BASE (DMA1_BASE + 0x010) +#define DMA1_Stream1_BASE (DMA1_BASE + 0x028) +#define DMA1_Stream2_BASE (DMA1_BASE + 0x040) +#define DMA1_Stream3_BASE (DMA1_BASE + 0x058) +#define DMA1_Stream4_BASE (DMA1_BASE + 0x070) +#define DMA1_Stream5_BASE (DMA1_BASE + 0x088) +#define DMA1_Stream6_BASE (DMA1_BASE + 0x0A0) +#define DMA1_Stream7_BASE (DMA1_BASE + 0x0B8) +#define DMA2_BASE (AHB1PERIPH_BASE + 0x6400) +#define DMA2_Stream0_BASE (DMA2_BASE + 0x010) +#define DMA2_Stream1_BASE (DMA2_BASE + 0x028) +#define DMA2_Stream2_BASE (DMA2_BASE + 0x040) +#define DMA2_Stream3_BASE (DMA2_BASE + 0x058) +#define DMA2_Stream4_BASE (DMA2_BASE + 0x070) +#define DMA2_Stream5_BASE (DMA2_BASE + 0x088) +#define DMA2_Stream6_BASE (DMA2_BASE + 0x0A0) +#define DMA2_Stream7_BASE (DMA2_BASE + 0x0B8) + +/* Debug MCU registers base address */ +#define DBGMCU_BASE ((uint32_t )0xE0042000) + +/*!< USB registers base address */ +#define USB_OTG_FS_PERIPH_BASE ((uint32_t )0x50000000) + +#define USB_OTG_GLOBAL_BASE ((uint32_t )0x000) +#define USB_OTG_DEVICE_BASE ((uint32_t )0x800) +#define USB_OTG_IN_ENDPOINT_BASE ((uint32_t )0x900) +#define USB_OTG_OUT_ENDPOINT_BASE ((uint32_t )0xB00) +#define USB_OTG_EP_REG_SIZE ((uint32_t )0x20) +#define USB_OTG_HOST_BASE ((uint32_t )0x400) +#define USB_OTG_HOST_PORT_BASE ((uint32_t )0x440) +#define USB_OTG_HOST_CHANNEL_BASE ((uint32_t )0x500) +#define USB_OTG_HOST_CHANNEL_SIZE ((uint32_t )0x20) +#define USB_OTG_PCGCCTL_BASE ((uint32_t )0xE00) +#define USB_OTG_FIFO_BASE ((uint32_t )0x1000) +#define USB_OTG_FIFO_SIZE ((uint32_t )0x1000) + +/** + * @} + */ + +/** @addtogroup Peripheral_declaration + * @{ + */ +#define TIM2 ((TIM_TypeDef *) TIM2_BASE) +#define TIM3 ((TIM_TypeDef *) TIM3_BASE) +#define TIM4 ((TIM_TypeDef *) TIM4_BASE) +#define TIM5 ((TIM_TypeDef *) TIM5_BASE) +#define RTC ((RTC_TypeDef *) RTC_BASE) +#define WWDG ((WWDG_TypeDef *) WWDG_BASE) +#define IWDG ((IWDG_TypeDef *) IWDG_BASE) +#define I2S2ext ((SPI_TypeDef *) I2S2ext_BASE) +#define SPI2 ((SPI_TypeDef *) SPI2_BASE) +#define SPI3 ((SPI_TypeDef *) SPI3_BASE) +#define I2S3ext ((SPI_TypeDef *) I2S3ext_BASE) +#define USART2 ((USART_TypeDef *) USART2_BASE) +#define I2C1 ((I2C_TypeDef *) I2C1_BASE) +#define I2C2 ((I2C_TypeDef *) I2C2_BASE) +#define I2C3 ((I2C_TypeDef *) I2C3_BASE) +#define PWR ((PWR_TypeDef *) PWR_BASE) +#define TIM1 ((TIM_TypeDef *) TIM1_BASE) +#define USART1 ((USART_TypeDef *) USART1_BASE) +#define USART6 ((USART_TypeDef *) USART6_BASE) +#define ADC ((ADC_Common_TypeDef *) ADC_BASE) +#define ADC1 ((ADC_TypeDef *) ADC1_BASE) +#define SDIO ((SDIO_TypeDef *) SDIO_BASE) +#define SPI1 ((SPI_TypeDef *) SPI1_BASE) +#define SPI4 ((SPI_TypeDef *) SPI4_BASE) +#define SYSCFG ((SYSCFG_TypeDef *) SYSCFG_BASE) +#define EXTI ((EXTI_TypeDef *) EXTI_BASE) +#define TIM9 ((TIM_TypeDef *) TIM9_BASE) +#define TIM10 ((TIM_TypeDef *) TIM10_BASE) +#define TIM11 ((TIM_TypeDef *) TIM11_BASE) +#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) +#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) +#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) +#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) +#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) +#define GPIOH ((GPIO_TypeDef *) GPIOH_BASE) +#define CRC ((CRC_TypeDef *) CRC_BASE) +#define RCC ((RCC_TypeDef *) RCC_BASE) +#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE) +#define DMA1 ((DMA_TypeDef *) DMA1_BASE) +#define DMA1_Stream0 ((DMA_Stream_TypeDef *) DMA1_Stream0_BASE) +#define DMA1_Stream1 ((DMA_Stream_TypeDef *) DMA1_Stream1_BASE) +#define DMA1_Stream2 ((DMA_Stream_TypeDef *) DMA1_Stream2_BASE) +#define DMA1_Stream3 ((DMA_Stream_TypeDef *) DMA1_Stream3_BASE) +#define DMA1_Stream4 ((DMA_Stream_TypeDef *) DMA1_Stream4_BASE) +#define DMA1_Stream5 ((DMA_Stream_TypeDef *) DMA1_Stream5_BASE) +#define DMA1_Stream6 ((DMA_Stream_TypeDef *) DMA1_Stream6_BASE) +#define DMA1_Stream7 ((DMA_Stream_TypeDef *) DMA1_Stream7_BASE) +#define DMA2 ((DMA_TypeDef *) DMA2_BASE) +#define DMA2_Stream0 ((DMA_Stream_TypeDef *) DMA2_Stream0_BASE) +#define DMA2_Stream1 ((DMA_Stream_TypeDef *) DMA2_Stream1_BASE) +#define DMA2_Stream2 ((DMA_Stream_TypeDef *) DMA2_Stream2_BASE) +#define DMA2_Stream3 ((DMA_Stream_TypeDef *) DMA2_Stream3_BASE) +#define DMA2_Stream4 ((DMA_Stream_TypeDef *) DMA2_Stream4_BASE) +#define DMA2_Stream5 ((DMA_Stream_TypeDef *) DMA2_Stream5_BASE) +#define DMA2_Stream6 ((DMA_Stream_TypeDef *) DMA2_Stream6_BASE) +#define DMA2_Stream7 ((DMA_Stream_TypeDef *) DMA2_Stream7_BASE) + +#define DBGMCU ((DBGMCU_TypeDef *) DBGMCU_BASE) + +#define USB_OTG_FS ((USB_OTG_GlobalTypeDef *) USB_OTG_FS_PERIPH_BASE) + +/** + * @} + */ + +/** @addtogroup Exported_constants + * @{ + */ + + /** @addtogroup Peripheral_Registers_Bits_Definition + * @{ + */ + +/******************************************************************************/ +/* Peripheral Registers_Bits_Definition */ +/******************************************************************************/ + +/******************************************************************************/ +/* */ +/* Analog to Digital Converter */ +/* */ +/******************************************************************************/ +/******************** Bit definition for ADC_SR register ********************/ +#define ADC_SR_AWD ((uint32_t)0x00000001) /*!
© COPYRIGHT(c) 2015 STMicroelectronics
+ * + * 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. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f4xx + * @{ + */ + +#ifndef __STM32F4xx_H +#define __STM32F4xx_H + +#ifdef __cplusplus + extern "C" { +#endif /* __cplusplus */ + +/** @addtogroup Library_configuration_section + * @{ + */ + +/** + * @brief STM32 Family + */ +#if !defined (STM32F4) +#define STM32F4 +#endif /* STM32F4 */ + +/* Uncomment the line below according to the target STM32 device used in your + application + */ +#if !defined (STM32F405xx) && !defined (STM32F415xx) && !defined (STM32F407xx) && !defined (STM32F417xx) && \ + !defined (STM32F427xx) && !defined (STM32F437xx) && !defined (STM32F429xx) && !defined (STM32F439xx) && \ + !defined (STM32F401xC) && !defined (STM32F401xE) && !defined (STM32F411xE) && !defined (STM32F446xx) + /* #define STM32F405xx */ /*!< STM32F405RG, STM32F405VG and STM32F405ZG Devices */ + /* #define STM32F415xx */ /*!< STM32F415RG, STM32F415VG and STM32F415ZG Devices */ + /* #define STM32F407xx */ /*!< STM32F407VG, STM32F407VE, STM32F407ZG, STM32F407ZE, STM32F407IG and STM32F407IE Devices */ + /* #define STM32F417xx */ /*!< STM32F417VG, STM32F417VE, STM32F417ZG, STM32F417ZE, STM32F417IG and STM32F417IE Devices */ + /* #define STM32F427xx */ /*!< STM32F427VG, STM32F427VI, STM32F427ZG, STM32F427ZI, STM32F427IG and STM32F427II Devices */ + /* #define STM32F437xx */ /*!< STM32F437VG, STM32F437VI, STM32F437ZG, STM32F437ZI, STM32F437IG and STM32F437II Devices */ + /* #define STM32F429xx */ /*!< STM32F429VG, STM32F429VI, STM32F429ZG, STM32F429ZI, STM32F429BG, STM32F429BI, STM32F429NG, + STM32F439NI, STM32F429IG and STM32F429II Devices */ + /* #define STM32F439xx */ /*!< STM32F439VG, STM32F439VI, STM32F439ZG, STM32F439ZI, STM32F439BG, STM32F439BI, STM32F439NG, + STM32F439NI, STM32F439IG and STM32F439II Devices */ + /* #define STM32F401xC */ /*!< STM32F401CB, STM32F401CC, STM32F401RB, STM32F401RC, STM32F401VB and STM32F401VC Devices */ + /* #define STM32F401xE */ /*!< STM32F401CD, STM32F401RD, STM32F401VD, STM32F401CE, STM32F401RE and STM32F401VE Devices */ + /* #define STM32F411xE */ /*!< STM32F411CD, STM32F411RD, STM32F411VD, STM32F411CE, STM32F411RE and STM32F411VE Devices */ + /* #define STM32F446xx */ /*!< STM32F446MC, STM32F446ME, STM32F446RC, STM32F446RE, STM32F446VC, STM32F446VE, STM32F446ZC, + and STM32F446ZE Devices */ +#endif + +/* Tip: To avoid modifying this file each time you need to switch between these + devices, you can define the device in your toolchain compiler preprocessor. + */ +#if !defined (USE_HAL_DRIVER) +/** + * @brief Comment the line below if you will not use the peripherals drivers. + In this case, these drivers will not be included and the application code will + be based on direct access to peripherals registers + */ + /*#define USE_HAL_DRIVER */ +#endif /* USE_HAL_DRIVER */ + +/** + * @brief CMSIS Device version number V2.3.2 + */ +#define __STM32F4xx_CMSIS_DEVICE_VERSION_MAIN (0x02) /*!< [31:24] main version */ +#define __STM32F4xx_CMSIS_DEVICE_VERSION_SUB1 (0x03) /*!< [23:16] sub1 version */ +#define __STM32F4xx_CMSIS_DEVICE_VERSION_SUB2 (0x02) /*!< [15:8] sub2 version */ +#define __STM32F4xx_CMSIS_DEVICE_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __STM32F4xx_CMSIS_DEVICE_VERSION ((__STM32F4xx_CMSIS_DEVICE_VERSION_MAIN << 24)\ + |(__STM32F4xx_CMSIS_DEVICE_VERSION_SUB1 << 16)\ + |(__STM32F4xx_CMSIS_DEVICE_VERSION_SUB2 << 8 )\ + |(__STM32F4xx_CMSIS_DEVICE_VERSION)) + +/** + * @} + */ + +/** @addtogroup Device_Included + * @{ + */ + +#if defined(STM32F405xx) + #include "stm32f405xx.h" +#elif defined(STM32F415xx) + #include "stm32f415xx.h" +#elif defined(STM32F407xx) + #include "stm32f407xx.h" +#elif defined(STM32F417xx) + #include "stm32f417xx.h" +#elif defined(STM32F427xx) + #include "stm32f427xx.h" +#elif defined(STM32F437xx) + #include "stm32f437xx.h" +#elif defined(STM32F429xx) + #include "stm32f429xx.h" +#elif defined(STM32F439xx) + #include "stm32f439xx.h" +#elif defined(STM32F401xC) + #include "stm32f401xc.h" +#elif defined(STM32F401xE) + #include "stm32f401xe.h" +#elif defined(STM32F411xE) + #include "stm32f411xe.h" +#elif defined(STM32F446xx) + #include "stm32f446xx.h" +#else + #error "Please select first the target STM32F4xx device used in your application (in stm32f4xx.h file)" +#endif + +/** + * @} + */ + +/** @addtogroup Exported_types + * @{ + */ +typedef enum +{ + RESET = 0, + SET = !RESET +} FlagStatus, ITStatus; + +typedef enum +{ + DISABLE = 0, + ENABLE = !DISABLE +} FunctionalState; +#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) + +typedef enum +{ + ERROR = 0, + SUCCESS = !ERROR +} ErrorStatus; + +/** + * @} + */ + + +/** @addtogroup Exported_macro + * @{ + */ +#define SET_BIT(REG, BIT) ((REG) |= (BIT)) + +#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT)) + +#define READ_BIT(REG, BIT) ((REG) & (BIT)) + +#define CLEAR_REG(REG) ((REG) = (0x0)) + +#define WRITE_REG(REG, VAL) ((REG) = (VAL)) + +#define READ_REG(REG) ((REG)) + +#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK))) + +#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL))) + + +/** + * @} + */ + +#if defined (USE_HAL_DRIVER) + #include "stm32f4xx_hal.h" +#endif /* USE_HAL_DRIVER */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __STM32F4xx_H */ +/** + * @} + */ + +/** + * @} + */ + + + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h b/Downstream/Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h new file mode 100644 index 0000000..67aac51 --- /dev/null +++ b/Downstream/Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h @@ -0,0 +1,122 @@ +/** + ****************************************************************************** + * @file system_stm32f4xx.h + * @author MCD Application Team + * @version V2.3.2 + * @date 26-June-2015 + * @brief CMSIS Cortex-M4 Device System Source File for STM32F4xx devices. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f4xx_system + * @{ + */ + +/** + * @brief Define to prevent recursive inclusion + */ +#ifndef __SYSTEM_STM32F4XX_H +#define __SYSTEM_STM32F4XX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** @addtogroup STM32F4xx_System_Includes + * @{ + */ + +/** + * @} + */ + + +/** @addtogroup STM32F4xx_System_Exported_types + * @{ + */ + /* This variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetSysClockFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Exported_Constants + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Exported_Functions + * @{ + */ + +extern void SystemInit(void); +extern void SystemCoreClockUpdate(void); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__SYSTEM_STM32F4XX_H */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc/startup_stm32f401xc.S b/Downstream/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc/startup_stm32f401xc.S new file mode 100644 index 0000000..a911209 --- /dev/null +++ b/Downstream/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc/startup_stm32f401xc.S @@ -0,0 +1,453 @@ +/** + ****************************************************************************** + * @file startup_stm32f401xc.s + * @author MCD Application Team + * @version V2.2.0 + * @date 15-December-2014 + * @brief STM32F405xx Devices vector table for Atollic TrueSTUDIO toolchain. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M4 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2014 STMicroelectronics

+ * + * 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. + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m4 + .fpu softvfp + .thumb + +.global __Vectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word __etext +/* start address for the .data section. defined in linker script */ +.word __data_start__ +/* end address for the .data section. defined in linker script */ +.word __data_end__ +/* start address for the .bss section. defined in linker script */ +.word __bss_start__ +/* end address for the .bss section. defined in linker script */ +.word __bss_end__ +/* stack used for SystemInit_ExtMemCtl; always internal RAM used */ + +/** + * @brief This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + * @param None + * @retval : None +*/ + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr sp, =__StackTop /* set stack pointer */ + +/* Copy the data segment initializers from flash to SRAM */ + movs r1, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r3, =__etext + ldr r3, [r3, r1] + str r3, [r0, r1] + adds r1, r1, #4 + +LoopCopyDataInit: + ldr r0, =__data_start__ + ldr r3, =__data_end__ + adds r2, r0, r1 + cmp r2, r3 + bcc CopyDataInit + ldr r2, =__bss_start__ + b LoopFillZerobss +/* Zero fill the bss segment. */ +FillZerobss: + movs r3, #0 + str r3, [r2], #4 + +LoopFillZerobss: + ldr r3, = __bss_end__ + cmp r2, r3 + bcc FillZerobss + +/* Call the clock system intitialization function.*/ + bl SystemInit +/* Call static constructors */ + //bl __libc_init_array +/* Call the application's entry point.*/ + bl main + bx lr +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * @param None + * @retval None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex M3. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +*******************************************************************************/ + .section .vectors,"a",%progbits + .type __Vectors, %object + .size __Vectors, .-__Vectors + + + +__Vectors: + .word __StackTop + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + + /* External Interrupts */ + .word WWDG_IRQHandler /* Window WatchDog */ + .word PVD_IRQHandler /* PVD through EXTI Line detection */ + .word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */ + .word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */ + .word FLASH_IRQHandler /* FLASH */ + .word RCC_IRQHandler /* RCC */ + .word EXTI0_IRQHandler /* EXTI Line0 */ + .word EXTI1_IRQHandler /* EXTI Line1 */ + .word EXTI2_IRQHandler /* EXTI Line2 */ + .word EXTI3_IRQHandler /* EXTI Line3 */ + .word EXTI4_IRQHandler /* EXTI Line4 */ + .word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */ + .word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */ + .word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */ + .word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */ + .word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */ + .word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */ + .word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */ + .word ADC_IRQHandler /* ADC1 */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word EXTI9_5_IRQHandler /* External Line[9:5]s */ + .word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */ + .word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */ + .word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */ + .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */ + .word TIM2_IRQHandler /* TIM2 */ + .word TIM3_IRQHandler /* TIM3 */ + .word TIM4_IRQHandler /* TIM4 */ + .word I2C1_EV_IRQHandler /* I2C1 Event */ + .word I2C1_ER_IRQHandler /* I2C1 Error */ + .word I2C2_EV_IRQHandler /* I2C2 Event */ + .word I2C2_ER_IRQHandler /* I2C2 Error */ + .word SPI1_IRQHandler /* SPI1 */ + .word SPI2_IRQHandler /* SPI2 */ + .word USART1_IRQHandler /* USART1 */ + .word USART2_IRQHandler /* USART2 */ + .word 0 /* Reserved */ + .word EXTI15_10_IRQHandler /* External Line[15:10]s */ + .word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */ + .word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */ + .word 0 /* Reserved */ + .word SDIO_IRQHandler /* SDIO */ + .word TIM5_IRQHandler /* TIM5 */ + .word SPI3_IRQHandler /* SPI3 */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */ + .word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */ + .word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */ + .word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */ + .word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word OTG_FS_IRQHandler /* USB OTG FS */ + .word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */ + .word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */ + .word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */ + .word USART6_IRQHandler /* USART6 */ + .word I2C3_EV_IRQHandler /* I2C3 event */ + .word I2C3_ER_IRQHandler /* I2C3 error */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word FPU_IRQHandler /* FPU */ + .word 0 /* Reserved */ + .word 0 /* Reserved */ + .word SPI4_IRQHandler /* SPI4 */ + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_IRQHandler + .thumb_set PVD_IRQHandler,Default_Handler + + .weak TAMP_STAMP_IRQHandler + .thumb_set TAMP_STAMP_IRQHandler,Default_Handler + + .weak RTC_WKUP_IRQHandler + .thumb_set RTC_WKUP_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak DMA1_Stream0_IRQHandler + .thumb_set DMA1_Stream0_IRQHandler,Default_Handler + + .weak DMA1_Stream1_IRQHandler + .thumb_set DMA1_Stream1_IRQHandler,Default_Handler + + .weak DMA1_Stream2_IRQHandler + .thumb_set DMA1_Stream2_IRQHandler,Default_Handler + + .weak DMA1_Stream3_IRQHandler + .thumb_set DMA1_Stream3_IRQHandler,Default_Handler + + .weak DMA1_Stream4_IRQHandler + .thumb_set DMA1_Stream4_IRQHandler,Default_Handler + + .weak DMA1_Stream5_IRQHandler + .thumb_set DMA1_Stream5_IRQHandler,Default_Handler + + .weak DMA1_Stream6_IRQHandler + .thumb_set DMA1_Stream6_IRQHandler,Default_Handler + + .weak ADC_IRQHandler + .thumb_set ADC_IRQHandler,Default_Handler + + .weak EXTI9_5_IRQHandler + .thumb_set EXTI9_5_IRQHandler,Default_Handler + + .weak TIM1_BRK_TIM9_IRQHandler + .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler + + .weak TIM1_UP_TIM10_IRQHandler + .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler + + .weak TIM1_TRG_COM_TIM11_IRQHandler + .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak TIM3_IRQHandler + .thumb_set TIM3_IRQHandler,Default_Handler + + .weak TIM4_IRQHandler + .thumb_set TIM4_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C2_EV_IRQHandler + .thumb_set I2C2_EV_IRQHandler,Default_Handler + + .weak I2C2_ER_IRQHandler + .thumb_set I2C2_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak USART2_IRQHandler + .thumb_set USART2_IRQHandler,Default_Handler + + .weak EXTI15_10_IRQHandler + .thumb_set EXTI15_10_IRQHandler,Default_Handler + + .weak RTC_Alarm_IRQHandler + .thumb_set RTC_Alarm_IRQHandler,Default_Handler + + .weak OTG_FS_WKUP_IRQHandler + .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler + + .weak DMA1_Stream7_IRQHandler + .thumb_set DMA1_Stream7_IRQHandler,Default_Handler + + .weak SDIO_IRQHandler + .thumb_set SDIO_IRQHandler,Default_Handler + + .weak TIM5_IRQHandler + .thumb_set TIM5_IRQHandler,Default_Handler + + .weak SPI3_IRQHandler + .thumb_set SPI3_IRQHandler,Default_Handler + + .weak DMA2_Stream0_IRQHandler + .thumb_set DMA2_Stream0_IRQHandler,Default_Handler + + .weak DMA2_Stream1_IRQHandler + .thumb_set DMA2_Stream1_IRQHandler,Default_Handler + + .weak DMA2_Stream2_IRQHandler + .thumb_set DMA2_Stream2_IRQHandler,Default_Handler + + .weak DMA2_Stream3_IRQHandler + .thumb_set DMA2_Stream3_IRQHandler,Default_Handler + + .weak DMA2_Stream4_IRQHandler + .thumb_set DMA2_Stream4_IRQHandler,Default_Handler + + .weak OTG_FS_IRQHandler + .thumb_set OTG_FS_IRQHandler,Default_Handler + + .weak DMA2_Stream5_IRQHandler + .thumb_set DMA2_Stream5_IRQHandler,Default_Handler + + .weak DMA2_Stream6_IRQHandler + .thumb_set DMA2_Stream6_IRQHandler,Default_Handler + + .weak DMA2_Stream7_IRQHandler + .thumb_set DMA2_Stream7_IRQHandler,Default_Handler + + .weak USART6_IRQHandler + .thumb_set USART6_IRQHandler,Default_Handler + + .weak I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak SPI4_IRQHandler + .thumb_set SPI4_IRQHandler,Default_Handler + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + diff --git a/Downstream/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c b/Downstream/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c new file mode 100644 index 0000000..b10cf74 --- /dev/null +++ b/Downstream/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c @@ -0,0 +1,587 @@ +/** + ****************************************************************************** + * @file system_stm32f4xx.c + * @author MCD Application Team + * @version V2.3.2 + * @date 26-June-2015 + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File. + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32f4xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2015 STMicroelectronics

+ * + * 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. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f4xx_system + * @{ + */ + +/** @addtogroup STM32F4xx_System_Private_Includes + * @{ + */ + + +#include "stm32f4xx.h" + +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Defines + * @{ + */ + +/************************* Miscellaneous Configuration ************************/ +/*!< Uncomment the following line if you need to use external SRAM or SDRAM as data memory */ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) +/* #define DATA_IN_ExtSRAM */ +#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F446xx) +/* #define DATA_IN_ExtSDRAM */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ + +#if defined(DATA_IN_ExtSRAM) && defined(DATA_IN_ExtSDRAM) + #error "Please select DATA_IN_ExtSRAM or DATA_IN_ExtSDRAM " +#endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */ + +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +/******************************************************************************/ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Variables + * @{ + */ + /* This variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ + uint32_t SystemCoreClock = 16000000; +const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes + * @{ + */ + +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) + static void SystemInit_ExtMemCtl(void); +#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system + * Initialize the FPU setting, vector table location and External memory + * configuration. + * @param None + * @retval None + */ +void SystemInit(void) +{ + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ + #endif + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set HSION bit */ + RCC->CR |= (uint32_t)0x00000001; + + /* Reset CFGR register */ + RCC->CFGR = 0x00000000; + + /* Reset HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFFF; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x24003010; + + /* Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /* Disable all interrupts */ + RCC->CIR = 0x00000000; + +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) + SystemInit_ExtMemCtl(); +#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ + + /* Configure the Vector Table location add offset address ------------------*/ +#ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ +#endif +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (its value + * depends on the application requirements), user has to ensure that HSE_VALUE + * is same as the real frequency of the crystal used. Otherwise, this function + * may have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + case 0x04: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + case 0x08: /* PLL used as system clock source */ + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N + SYSCLK = PLL_VCO / PLL_P + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + + if (pllsource != 0) + { + /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + else + { + /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + + pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; + SystemCoreClock = pllvco/pllp; + break; + default: + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK frequency --------------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK frequency */ + SystemCoreClock >>= tmp; +} + +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) +/** + * @brief Setup the external memory controller. + * Called in startup_stm32f4xx.s before jump to main. + * This function configures the external memories (SRAM/SDRAM) + * This SRAM/SDRAM will be used as program data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ + __IO uint32_t tmp = 0x00; +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) +#if defined (DATA_IN_ExtSDRAM) + register uint32_t tmpreg = 0, timeout = 0xFFFF; + register uint32_t index; + +#if defined(STM32F446xx) + /* Enable GPIOA, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG interface + clock */ + RCC->AHB1ENR |= 0x0000007D; +#else + /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface + clock */ + RCC->AHB1ENR |= 0x000001F8; +#endif /* STM32F446xx */ + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN); + +#if defined(STM32F446xx) + /* Connect PAx pins to FMC Alternate function */ + GPIOA->AFR[0] |= 0xC0000000; + GPIOA->AFR[1] |= 0x00000000; + /* Configure PDx pins in Alternate function mode */ + GPIOA->MODER |= 0x00008000; + /* Configure PDx pins speed to 50 MHz */ + GPIOA->OSPEEDR |= 0x00008000; + /* Configure PDx pins Output type to push-pull */ + GPIOA->OTYPER |= 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOA->PUPDR |= 0x00000000; + + /* Connect PCx pins to FMC Alternate function */ + GPIOC->AFR[0] |= 0x00CC0000; + GPIOC->AFR[1] |= 0x00000000; + /* Configure PDx pins in Alternate function mode */ + GPIOC->MODER |= 0x00000A00; + /* Configure PDx pins speed to 50 MHz */ + GPIOC->OSPEEDR |= 0x00000A00; + /* Configure PDx pins Output type to push-pull */ + GPIOC->OTYPER |= 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOC->PUPDR |= 0x00000000; +#endif /* STM32F446xx */ + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x000000CC; + GPIOD->AFR[1] = 0xCC000CCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xA02A000A; + /* Configure PDx pins speed to 50 MHz */ + GPIOD->OSPEEDR = 0xA02A000A; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00000CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA800A; + /* Configure PEx pins speed to 50 MHz */ + GPIOE->OSPEEDR = 0xAAAA800A; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0xCCCCCCCC; + GPIOF->AFR[1] = 0xCCCCCCCC; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA800AAA; + /* Configure PFx pins speed to 50 MHz */ + GPIOF->OSPEEDR = 0xAA800AAA; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0xCCCCCCCC; + GPIOG->AFR[1] = 0xCCCCCCCC; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0xAAAAAAAA; + /* Configure PGx pins speed to 50 MHz */ + GPIOG->OSPEEDR = 0xAAAAAAAA; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + /* Connect PHx pins to FMC Alternate function */ + GPIOH->AFR[0] = 0x00C0CC00; + GPIOH->AFR[1] = 0xCCCCCCCC; + /* Configure PHx pins in Alternate function mode */ + GPIOH->MODER = 0xAAAA08A0; + /* Configure PHx pins speed to 50 MHz */ + GPIOH->OSPEEDR = 0xAAAA08A0; + /* Configure PHx pins Output type to push-pull */ + GPIOH->OTYPER = 0x00000000; + /* No pull-up, pull-down for PHx pins */ + GPIOH->PUPDR = 0x00000000; + + /* Connect PIx pins to FMC Alternate function */ + GPIOI->AFR[0] = 0xCCCCCCCC; + GPIOI->AFR[1] = 0x00000CC0; + /* Configure PIx pins in Alternate function mode */ + GPIOI->MODER = 0x0028AAAA; + /* Configure PIx pins speed to 50 MHz */ + GPIOI->OSPEEDR = 0x0028AAAA; + /* Configure PIx pins Output type to push-pull */ + GPIOI->OTYPER = 0x00000000; + /* No pull-up, pull-down for PIx pins */ + GPIOI->PUPDR = 0x00000000; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +/*-- FMC Configuration -------------------------------------------------------*/ + /* Enable the FMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + + /* Configure and enable SDRAM bank1 */ +#if defined(STM32F446xx) + FMC_Bank5_6->SDCR[0] = 0x00001954; +#else + FMC_Bank5_6->SDCR[0] = 0x000019E4; +#endif /* STM32F446xx */ + FMC_Bank5_6->SDTR[0] = 0x01115351; + + /* SDRAM initialization sequence */ + /* Clock enable command */ + FMC_Bank5_6->SDCMR = 0x00000011; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Delay */ + for (index = 0; index<1000; index++); + + /* PALL command */ + FMC_Bank5_6->SDCMR = 0x00000012; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Auto refresh command */ +#if defined(STM32F446xx) + FMC_Bank5_6->SDCMR = 0x000000F3; +#else + FMC_Bank5_6->SDCMR = 0x00000073; +#endif /* STM32F446xx */ + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* MRD register program */ +#if defined(STM32F446xx) + FMC_Bank5_6->SDCMR = 0x00044014; +#else + FMC_Bank5_6->SDCMR = 0x00046014; +#endif /* STM32F446xx */ + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + + /* Set refresh count */ + tmpreg = FMC_Bank5_6->SDRTR; +#if defined(STM32F446xx) + FMC_Bank5_6->SDRTR = (tmpreg | (0x0000050C<<1)); +#else + FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1)); +#endif /* STM32F446xx */ + + /* Disable write protection */ + tmpreg = FMC_Bank5_6->SDCR[0]; + FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF); +#endif /* DATA_IN_ExtSDRAM */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + +#if defined(DATA_IN_ExtSRAM) +/*-- GPIOs Configuration -----------------------------------------------------*/ + /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ + RCC->AHB1ENR |= 0x00000078; + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN); + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x00CCC0CC; + GPIOD->AFR[1] = 0xCCCCCCCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xAAAA0A8A; + /* Configure PDx pins speed to 100 MHz */ + GPIOD->OSPEEDR = 0xFFFF0FCF; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00CC0CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA828A; + /* Configure PEx pins speed to 100 MHz */ + GPIOE->OSPEEDR = 0xFFFFC3CF; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0x00CCCCCC; + GPIOF->AFR[1] = 0xCCCC0000; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA000AAA; + /* Configure PFx pins speed to 100 MHz */ + GPIOF->OSPEEDR = 0xFF000FFF; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0x00CCCCCC; + GPIOG->AFR[1] = 0x000000C0; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0x00085AAA; + /* Configure PGx pins speed to 100 MHz */ + GPIOG->OSPEEDR = 0x000CAFFF; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + +/*-- FMC/FSMC Configuration --------------------------------------------------*/ + /* Enable the FMC/FSMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001011; + FMC_Bank1->BTCR[3] = 0x00000201; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN); + /* Configure and enable Bank1_SRAM2 */ + FSMC_Bank1->BTCR[2] = 0x00001011; + FSMC_Bank1->BTCR[3] = 0x00000201; + FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF; +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */ + +#endif /* DATA_IN_ExtSRAM */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + (void)(tmp); +} +#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/CMSIS/Include/arm_common_tables.h b/Downstream/Drivers/CMSIS/Include/arm_common_tables.h new file mode 100644 index 0000000..76aadca --- /dev/null +++ b/Downstream/Drivers/CMSIS/Include/arm_common_tables.h @@ -0,0 +1,136 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2014 ARM Limited. All rights reserved. +* +* $Date: 31. July 2014 +* $Revision: V1.4.4 +* +* Project: CMSIS DSP Library +* Title: arm_common_tables.h +* +* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions +* +* Target Processor: Cortex-M4/Cortex-M3 +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - 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. +* - Neither the name of ARM LIMITED 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 OWNER 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. +* -------------------------------------------------------------------- */ + +#ifndef _ARM_COMMON_TABLES_H +#define _ARM_COMMON_TABLES_H + +#include "arm_math.h" + +extern const uint16_t armBitRevTable[1024]; +extern const q15_t armRecipTableQ15[64]; +extern const q31_t armRecipTableQ31[64]; +//extern const q31_t realCoefAQ31[1024]; +//extern const q31_t realCoefBQ31[1024]; +extern const float32_t twiddleCoef_16[32]; +extern const float32_t twiddleCoef_32[64]; +extern const float32_t twiddleCoef_64[128]; +extern const float32_t twiddleCoef_128[256]; +extern const float32_t twiddleCoef_256[512]; +extern const float32_t twiddleCoef_512[1024]; +extern const float32_t twiddleCoef_1024[2048]; +extern const float32_t twiddleCoef_2048[4096]; +extern const float32_t twiddleCoef_4096[8192]; +#define twiddleCoef twiddleCoef_4096 +extern const q31_t twiddleCoef_16_q31[24]; +extern const q31_t twiddleCoef_32_q31[48]; +extern const q31_t twiddleCoef_64_q31[96]; +extern const q31_t twiddleCoef_128_q31[192]; +extern const q31_t twiddleCoef_256_q31[384]; +extern const q31_t twiddleCoef_512_q31[768]; +extern const q31_t twiddleCoef_1024_q31[1536]; +extern const q31_t twiddleCoef_2048_q31[3072]; +extern const q31_t twiddleCoef_4096_q31[6144]; +extern const q15_t twiddleCoef_16_q15[24]; +extern const q15_t twiddleCoef_32_q15[48]; +extern const q15_t twiddleCoef_64_q15[96]; +extern const q15_t twiddleCoef_128_q15[192]; +extern const q15_t twiddleCoef_256_q15[384]; +extern const q15_t twiddleCoef_512_q15[768]; +extern const q15_t twiddleCoef_1024_q15[1536]; +extern const q15_t twiddleCoef_2048_q15[3072]; +extern const q15_t twiddleCoef_4096_q15[6144]; +extern const float32_t twiddleCoef_rfft_32[32]; +extern const float32_t twiddleCoef_rfft_64[64]; +extern const float32_t twiddleCoef_rfft_128[128]; +extern const float32_t twiddleCoef_rfft_256[256]; +extern const float32_t twiddleCoef_rfft_512[512]; +extern const float32_t twiddleCoef_rfft_1024[1024]; +extern const float32_t twiddleCoef_rfft_2048[2048]; +extern const float32_t twiddleCoef_rfft_4096[4096]; + + +/* floating-point bit reversal tables */ +#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20 ) +#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48 ) +#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56 ) +#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 ) +#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 ) +#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 ) +#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800) +#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808) +#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH]; + +/* fixed-point bit reversal tables */ +#define ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12 ) +#define ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24 ) +#define ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56 ) +#define ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 ) +#define ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 ) +#define ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 ) +#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 ) +#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) +#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; + +/* Tables for Fast Math Sine and Cosine */ +extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; +extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; +extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; + +#endif /* ARM_COMMON_TABLES_H */ diff --git a/Downstream/Drivers/CMSIS/Include/arm_const_structs.h b/Downstream/Drivers/CMSIS/Include/arm_const_structs.h new file mode 100644 index 0000000..217f1d5 --- /dev/null +++ b/Downstream/Drivers/CMSIS/Include/arm_const_structs.h @@ -0,0 +1,79 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2014 ARM Limited. All rights reserved. +* +* $Date: 31. July 2014 +* $Revision: V1.4.4 +* +* Project: CMSIS DSP Library +* Title: arm_const_structs.h +* +* Description: This file has constant structs that are initialized for +* user convenience. For example, some can be given as +* arguments to the arm_cfft_f32() function. +* +* Target Processor: Cortex-M4/Cortex-M3 +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - 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. +* - Neither the name of ARM LIMITED 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 OWNER 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. +* -------------------------------------------------------------------- */ + +#ifndef _ARM_CONST_STRUCTS_H +#define _ARM_CONST_STRUCTS_H + +#include "arm_math.h" +#include "arm_common_tables.h" + + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096; + + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096; + + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096; + +#endif diff --git a/Downstream/Drivers/CMSIS/Include/arm_math.h b/Downstream/Drivers/CMSIS/Include/arm_math.h new file mode 100644 index 0000000..f06a071 --- /dev/null +++ b/Downstream/Drivers/CMSIS/Include/arm_math.h @@ -0,0 +1,7538 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2014 ARM Limited. All rights reserved. +* +* $Date: 12. March 2014 +* $Revision: V1.4.4 +* +* Project: CMSIS DSP Library +* Title: arm_math.h +* +* Description: Public header file for CMSIS DSP Library +* +* Target Processor: Cortex-M7/Cortex-M4/Cortex-M3/Cortex-M0 +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - 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. +* - Neither the name of ARM LIMITED 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 OWNER 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. + * -------------------------------------------------------------------- */ + +/** + \mainpage CMSIS DSP Software Library + * + * Introduction + * ------------ + * + * This user manual describes the CMSIS DSP software library, + * a suite of common signal processing functions for use on Cortex-M processor based devices. + * + * The library is divided into a number of functions each covering a specific category: + * - Basic math functions + * - Fast math functions + * - Complex math functions + * - Filters + * - Matrix functions + * - Transforms + * - Motor control functions + * - Statistical functions + * - Support functions + * - Interpolation functions + * + * The library has separate functions for operating on 8-bit integers, 16-bit integers, + * 32-bit integer and 32-bit floating-point values. + * + * Using the Library + * ------------ + * + * The library installer contains prebuilt versions of the libraries in the Lib folder. + * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4) + * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4) + * - arm_cortexM4l_math.lib (Little endian on Cortex-M4) + * - arm_cortexM4b_math.lib (Big endian on Cortex-M4) + * - arm_cortexM3l_math.lib (Little endian on Cortex-M3) + * - arm_cortexM3b_math.lib (Big endian on Cortex-M3) + * - arm_cortexM0l_math.lib (Little endian on Cortex-M0) + * - arm_cortexM0b_math.lib (Big endian on Cortex-M3) + * + * The library functions are declared in the public file arm_math.h which is placed in the Include folder. + * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single + * public header file arm_math.h for Cortex-M4/M3/M0 with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. + * Define the appropriate pre processor MACRO ARM_MATH_CM4 or ARM_MATH_CM3 or + * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application. + * + * Examples + * -------- + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * Toolchain Support + * ------------ + * + * The library has been developed and tested with MDK-ARM version 4.60. + * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. + * + * Building the Library + * ------------ + * + * The library installer contains a project file to re build libraries on MDK-ARM Tool chain in the CMSIS\\DSP_Lib\\Source\\ARM folder. + * - arm_cortexM_math.uvproj + * + * + * The libraries can be built by opening the arm_cortexM_math.uvproj project in MDK-ARM, selecting a specific target, and defining the optional pre processor MACROs detailed above. + * + * Pre-processor Macros + * ------------ + * + * Each library project have differant pre-processor macros. + * + * - UNALIGNED_SUPPORT_DISABLE: + * + * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access + * + * - ARM_MATH_BIG_ENDIAN: + * + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. + * + * - ARM_MATH_MATRIX_CHECK: + * + * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices + * + * - ARM_MATH_ROUNDING: + * + * Define macro ARM_MATH_ROUNDING for rounding on support functions + * + * - ARM_MATH_CMx: + * + * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target + * and ARM_MATH_CM0 for building library on cortex-M0 target, ARM_MATH_CM0PLUS for building library on cortex-M0+ target. + * + * - __FPU_PRESENT: + * + * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries + * + *
+ * CMSIS-DSP in ARM::CMSIS Pack + * ----------------------------- + * + * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: + * |File/Folder |Content | + * |------------------------------|------------------------------------------------------------------------| + * |\b CMSIS\\Documentation\\DSP | This documentation | + * |\b CMSIS\\DSP_Lib | Software license agreement (license.txt) | + * |\b CMSIS\\DSP_Lib\\Examples | Example projects demonstrating the usage of the library functions | + * |\b CMSIS\\DSP_Lib\\Source | Source files for rebuilding the library | + * + *
+ * Revision History of CMSIS-DSP + * ------------ + * Please refer to \ref ChangeLog_pg. + * + * Copyright Notice + * ------------ + * + * Copyright (C) 2010-2014 ARM Limited. All rights reserved. + */ + + +/** + * @defgroup groupMath Basic Math Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CMSIS math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + *
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * 
+ * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size numRows X numCols + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + *
+ *     pData[i*numCols + j]
+ * 
+ * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to the function arm_mat_init_f32(), arm_mat_init_q31() + * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ * 
+ * where nRows specifies the number of rows, nColumns + * specifies the number of columns, and pData points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + *
+ *     ARM_MATH_SIZE_MISMATCH
+ * 
+ * Otherwise the functions return + *
+ *     ARM_MATH_SUCCESS
+ * 
+ * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + *
+ *     ARM_MATH_MATRIX_CHECK
+ * 
+ * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return ARM_MATH_SUCCESS. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + +/** + * @defgroup groupExamples Examples + */ +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ + +#if defined(ARM_MATH_CM7) + #include "core_cm7.h" +#elif defined (ARM_MATH_CM4) + #include "core_cm4.h" +#elif defined (ARM_MATH_CM3) + #include "core_cm3.h" +#elif defined (ARM_MATH_CM0) + #include "core_cm0.h" +#define ARM_MATH_CM0_FAMILY + #elif defined (ARM_MATH_CM0PLUS) +#include "core_cm0plus.h" + #define ARM_MATH_CM0_FAMILY +#else + #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS or ARM_MATH_CM0" +#endif + +#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ +#include "string.h" +#include "math.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 (0x100) +#define DELTA_Q15 0x5 +#define INDEX_MASK 0x0000003F +#ifndef PI +#define PI 3.14159265358979f +#endif + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define FAST_MATH_TABLE_SIZE 512 +#define FAST_MATH_Q31_SHIFT (32 - 10) +#define FAST_MATH_Q15_SHIFT (16 - 10) +#define CONTROLLER_Q31_SHIFT (32 - 9) +#define TABLE_SIZE 256 +#define TABLE_SPACING_Q31 0x400000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + /** + * @brief Macro for Unaligned Support + */ +#ifndef UNALIGNED_SUPPORT_DISABLE + #define ALIGN4 +#else + #if defined (__GNUC__) + #define ALIGN4 __attribute__((aligned(4))) + #else + #define ALIGN4 __align(4) + #endif +#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + ARM_MATH_SUCCESS = 0, /**< No error */ + ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ + ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ + ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } arm_status; + + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + /** + * @brief definition to read/write two 16 bit values. + */ +#if defined __CC_ARM +#define __SIMD32_TYPE int32_t __packed +#define CMSIS_UNUSED __attribute__((unused)) +#elif defined __ICCARM__ +#define CMSIS_UNUSED +#define __SIMD32_TYPE int32_t __packed +#elif defined __GNUC__ +#define __SIMD32_TYPE int32_t +#define CMSIS_UNUSED __attribute__((unused)) +#elif defined __CSMC__ /* Cosmic */ +#define CMSIS_UNUSED +#define __SIMD32_TYPE int32_t +#else +#error Unknown compiler +#endif + +#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) +#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr)) + +#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr)) + +#define __SIMD64(addr) (*(int64_t **) & (addr)) + +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) + /** + * @brief definition to pack two 16 bit values. + */ +#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) +#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) + +#endif + + + /** + * @brief definition to pack four 8 bit values. + */ +#ifndef ARM_MATH_BIG_ENDIAN + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) +#else + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) + +#endif + + + /** + * @brief Clips Q63 to Q31 values. + */ + static __INLINE q31_t clip_q63_to_q31( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; + } + + /** + * @brief Clips Q63 to Q15 values. + */ + static __INLINE q15_t clip_q63_to_q15( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); + } + + /** + * @brief Clips Q31 to Q7 values. + */ + static __INLINE q7_t clip_q31_to_q7( + q31_t x) + { + return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? + ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; + } + + /** + * @brief Clips Q31 to Q15 values. + */ + static __INLINE q15_t clip_q31_to_q15( + q31_t x) + { + return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? + ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; + } + + /** + * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. + */ + + static __INLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y))); + } + + +#if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM ) +#define __CLZ __clz +#endif + +#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) ||(defined (__GNUC__)) || defined (__TASKING__) ) + + static __INLINE uint32_t __CLZ( + q31_t data); + + + static __INLINE uint32_t __CLZ( + q31_t data) + { + uint32_t count = 0; + uint32_t mask = 0x80000000; + + while((data & mask) == 0) + { + count += 1u; + mask = mask >> 1u; + } + + return (count); + + } + +#endif + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. + */ + + static __INLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + q31_t * pRecipTable) + { + + uint32_t out, tempVal; + uint32_t index, i; + uint32_t signBits; + + if(in > 0) + { + signBits = __CLZ(in) - 1; + } + else + { + signBits = __CLZ(-in) - 1; + } + + /* Convert input sample to 1.31 format */ + in = in << signBits; + + /* calculation of index for initial approximated Val */ + index = (uint32_t) (in >> 24u); + index = (index & INDEX_MASK); + + /* 1.31 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0u; i < 2u; i++) + { + tempVal = (q31_t) (((q63_t) in * out) >> 31u); + tempVal = 0x7FFFFFFF - tempVal; + /* 1.31 with exp 1 */ + //out = (q31_t) (((q63_t) out * tempVal) >> 30u); + out = (q31_t) clip_q63_to_q31(((q63_t) out * tempVal) >> 30u); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1u); + + } + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. + */ + static __INLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + q15_t * pRecipTable) + { + + uint32_t out = 0, tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if(in > 0) + { + signBits = __CLZ(in) - 17; + } + else + { + signBits = __CLZ(-in) - 17; + } + + /* Convert input sample to 1.15 format */ + in = in << signBits; + + /* calculation of index for initial approximated Val */ + index = in >> 8; + index = (index & INDEX_MASK); + + /* 1.15 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0; i < 2; i++) + { + tempVal = (q15_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFF - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((q31_t) out * tempVal) >> 14); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1); + + } + + + /* + * @brief C custom defined intrinisic function for only M0 processors + */ +#if defined(ARM_MATH_CM0_FAMILY) + + static __INLINE q31_t __SSAT( + q31_t x, + uint32_t y) + { + int32_t posMax, negMin; + uint32_t i; + + posMax = 1; + for (i = 0; i < (y - 1); i++) + { + posMax = posMax * 2; + } + + if(x > 0) + { + posMax = (posMax - 1); + + if(x > posMax) + { + x = posMax; + } + } + else + { + negMin = -posMax; + + if(x < negMin) + { + x = negMin; + } + } + return (x); + + + } + +#endif /* end of ARM_MATH_CM0_FAMILY */ + + + + /* + * @brief C custom defined intrinsic function for M3 and M0 processors + */ +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) + + /* + * @brief C custom defined QADD8 for M3 and M0 processors + */ + static __INLINE q31_t __QADD8( + q31_t x, + q31_t y) + { + + q31_t sum; + q7_t r, s, t, u; + + r = (q7_t) x; + s = (q7_t) y; + + r = __SSAT((q31_t) (r + s), 8); + s = __SSAT(((q31_t) (((x << 16) >> 24) + ((y << 16) >> 24))), 8); + t = __SSAT(((q31_t) (((x << 8) >> 24) + ((y << 8) >> 24))), 8); + u = __SSAT(((q31_t) ((x >> 24) + (y >> 24))), 8); + + sum = + (((q31_t) u << 24) & 0xFF000000) | (((q31_t) t << 16) & 0x00FF0000) | + (((q31_t) s << 8) & 0x0000FF00) | (r & 0x000000FF); + + return sum; + + } + + /* + * @brief C custom defined QSUB8 for M3 and M0 processors + */ + static __INLINE q31_t __QSUB8( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s, t, u; + + r = (q7_t) x; + s = (q7_t) y; + + r = __SSAT((r - s), 8); + s = __SSAT(((q31_t) (((x << 16) >> 24) - ((y << 16) >> 24))), 8) << 8; + t = __SSAT(((q31_t) (((x << 8) >> 24) - ((y << 8) >> 24))), 8) << 16; + u = __SSAT(((q31_t) ((x >> 24) - (y >> 24))), 8) << 24; + + sum = + (u & 0xFF000000) | (t & 0x00FF0000) | (s & 0x0000FF00) | (r & + 0x000000FF); + + return sum; + } + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + static __INLINE q31_t __QADD16( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (q15_t) x; + s = (q15_t) y; + + r = __SSAT(r + s, 16); + s = __SSAT(((q31_t) ((x >> 16) + (y >> 16))), 16) << 16; + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + + } + + /* + * @brief C custom defined SHADD16 for M3 and M0 processors + */ + static __INLINE q31_t __SHADD16( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (q15_t) x; + s = (q15_t) y; + + r = ((r >> 1) + (s >> 1)); + s = ((q31_t) ((x >> 17) + (y >> 17))) << 16; + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + + } + + /* + * @brief C custom defined QSUB16 for M3 and M0 processors + */ + static __INLINE q31_t __QSUB16( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (q15_t) x; + s = (q15_t) y; + + r = __SSAT(r - s, 16); + s = __SSAT(((q31_t) ((x >> 16) - (y >> 16))), 16) << 16; + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + } + + /* + * @brief C custom defined SHSUB16 for M3 and M0 processors + */ + static __INLINE q31_t __SHSUB16( + q31_t x, + q31_t y) + { + + q31_t diff; + q31_t r, s; + + r = (q15_t) x; + s = (q15_t) y; + + r = ((r >> 1) - (s >> 1)); + s = (((x >> 17) - (y >> 17)) << 16); + + diff = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return diff; + } + + /* + * @brief C custom defined QASX for M3 and M0 processors + */ + static __INLINE q31_t __QASX( + q31_t x, + q31_t y) + { + + q31_t sum = 0; + + sum = + ((sum + + clip_q31_to_q15((q31_t) ((q15_t) (x >> 16) + (q15_t) y))) << 16) + + clip_q31_to_q15((q31_t) ((q15_t) x - (q15_t) (y >> 16))); + + return sum; + } + + /* + * @brief C custom defined SHASX for M3 and M0 processors + */ + static __INLINE q31_t __SHASX( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (q15_t) x; + s = (q15_t) y; + + r = ((r >> 1) - (y >> 17)); + s = (((x >> 17) + (s >> 1)) << 16); + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + } + + + /* + * @brief C custom defined QSAX for M3 and M0 processors + */ + static __INLINE q31_t __QSAX( + q31_t x, + q31_t y) + { + + q31_t sum = 0; + + sum = + ((sum + + clip_q31_to_q15((q31_t) ((q15_t) (x >> 16) - (q15_t) y))) << 16) + + clip_q31_to_q15((q31_t) ((q15_t) x + (q15_t) (y >> 16))); + + return sum; + } + + /* + * @brief C custom defined SHSAX for M3 and M0 processors + */ + static __INLINE q31_t __SHSAX( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (q15_t) x; + s = (q15_t) y; + + r = ((r >> 1) + (y >> 17)); + s = (((x >> 17) - (s >> 1)) << 16); + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + } + + /* + * @brief C custom defined SMUSDX for M3 and M0 processors + */ + static __INLINE q31_t __SMUSDX( + q31_t x, + q31_t y) + { + + return ((q31_t) (((q15_t) x * (q15_t) (y >> 16)) - + ((q15_t) (x >> 16) * (q15_t) y))); + } + + /* + * @brief C custom defined SMUADX for M3 and M0 processors + */ + static __INLINE q31_t __SMUADX( + q31_t x, + q31_t y) + { + + return ((q31_t) (((q15_t) x * (q15_t) (y >> 16)) + + ((q15_t) (x >> 16) * (q15_t) y))); + } + + /* + * @brief C custom defined QADD for M3 and M0 processors + */ + static __INLINE q31_t __QADD( + q31_t x, + q31_t y) + { + return clip_q63_to_q31((q63_t) x + y); + } + + /* + * @brief C custom defined QSUB for M3 and M0 processors + */ + static __INLINE q31_t __QSUB( + q31_t x, + q31_t y) + { + return clip_q63_to_q31((q63_t) x - y); + } + + /* + * @brief C custom defined SMLAD for M3 and M0 processors + */ + static __INLINE q31_t __SMLAD( + q31_t x, + q31_t y, + q31_t sum) + { + + return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + + ((q15_t) x * (q15_t) y)); + } + + /* + * @brief C custom defined SMLADX for M3 and M0 processors + */ + static __INLINE q31_t __SMLADX( + q31_t x, + q31_t y, + q31_t sum) + { + + return (sum + ((q15_t) (x >> 16) * (q15_t) (y)) + + ((q15_t) x * (q15_t) (y >> 16))); + } + + /* + * @brief C custom defined SMLSDX for M3 and M0 processors + */ + static __INLINE q31_t __SMLSDX( + q31_t x, + q31_t y, + q31_t sum) + { + + return (sum - ((q15_t) (x >> 16) * (q15_t) (y)) + + ((q15_t) x * (q15_t) (y >> 16))); + } + + /* + * @brief C custom defined SMLALD for M3 and M0 processors + */ + static __INLINE q63_t __SMLALD( + q31_t x, + q31_t y, + q63_t sum) + { + + return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + + ((q15_t) x * (q15_t) y)); + } + + /* + * @brief C custom defined SMLALDX for M3 and M0 processors + */ + static __INLINE q63_t __SMLALDX( + q31_t x, + q31_t y, + q63_t sum) + { + + return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + + ((q15_t) x * (q15_t) (y >> 16)); + } + + /* + * @brief C custom defined SMUAD for M3 and M0 processors + */ + static __INLINE q31_t __SMUAD( + q31_t x, + q31_t y) + { + + return (((x >> 16) * (y >> 16)) + + (((x << 16) >> 16) * ((y << 16) >> 16))); + } + + /* + * @brief C custom defined SMUSD for M3 and M0 processors + */ + static __INLINE q31_t __SMUSD( + q31_t x, + q31_t y) + { + + return (-((x >> 16) * (y >> 16)) + + (((x << 16) >> 16) * ((y << 16) >> 16))); + } + + + /* + * @brief C custom defined SXTB16 for M3 and M0 processors + */ + static __INLINE q31_t __SXTB16( + q31_t x) + { + + return ((((x << 24) >> 24) & 0x0000FFFF) | + (((x << 8) >> 8) & 0xFFFF0000)); + } + + +#endif /* defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ + + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_f32; + + + /** + * @brief Processing function for the Q7 FIR filter. + * @param[in] *S points to an instance of the Q7 FIR filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_q7( + const arm_fir_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 FIR filter. + * @param[in,out] *S points to an instance of the Q7 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of samples that are processed. + * @return none + */ + void arm_fir_init_q7( + arm_fir_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR filter. + * @param[in] *S points to an instance of the Q15 FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q15 FIR filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_fast_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q15 FIR filter. + * @param[in,out] *S points to an instance of the Q15 FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if + * numTaps is not a supported value. + */ + + arm_status arm_fir_init_q15( + arm_fir_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR filter. + * @param[in] *S points to an instance of the Q31 FIR filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q31 FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_fast_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 FIR filter. + * @param[in,out] *S points to an instance of the Q31 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return none. + */ + void arm_fir_init_q31( + arm_fir_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the floating-point FIR filter. + * @param[in] *S points to an instance of the floating-point FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_f32( + const arm_fir_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point FIR filter. + * @param[in,out] *S points to an instance of the floating-point FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return none. + */ + void arm_fir_init_f32( + arm_fir_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + + } arm_biquad_casd_df1_inst_q15; + + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + + } arm_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + + + } arm_biquad_casd_df1_inst_f32; + + + + /** + * @brief Processing function for the Q15 Biquad cascade filter. + * @param[in] *S points to an instance of the Q15 Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q15 Biquad cascade filter. + * @param[in,out] *S points to an instance of the Q15 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + * @return none + */ + + void arm_biquad_cascade_df1_init_q15( + arm_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + + /** + * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q15 Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_fast_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 Biquad cascade filter + * @param[in] *S points to an instance of the Q31 Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q31 Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_fast_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 Biquad cascade filter. + * @param[in,out] *S points to an instance of the Q31 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + * @return none + */ + + void arm_biquad_cascade_df1_init_q31( + arm_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + /** + * @brief Processing function for the floating-point Biquad cascade filter. + * @param[in] *S points to an instance of the floating-point Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_f32( + const arm_biquad_casd_df1_inst_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point Biquad cascade filter. + * @param[in,out] *S points to an instance of the floating-point Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @return none + */ + + void arm_biquad_cascade_df1_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f32; + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float64_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f64; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + + } arm_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + + } arm_matrix_instance_q31; + + + + /** + * @brief Floating-point matrix addition. + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_add_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix addition. + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_add_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix addition. + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_add_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point, complex, matrix multiplication. + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_cmplx_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15, complex, matrix multiplication. + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_cmplx_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pScratch); + + /** + * @brief Q31, complex, matrix multiplication. + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_cmplx_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix transpose. + * @param[in] *pSrc points to the input matrix + * @param[out] *pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix transpose. + * @param[in] *pSrc points to the input matrix + * @param[out] *pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix transpose. + * @param[in] *pSrc points to the input matrix + * @param[out] *pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix multiplication + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix multiplication + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @param[in] *pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + /** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @param[in] *pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_mult_fast_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + /** + * @brief Q31 matrix multiplication + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix subtraction + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix subtraction + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix subtraction + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix scaling. + * @param[in] *pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] *pDst points to the output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix scaling. + * @param[in] *pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix scaling. + * @param[in] *pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix initialization. + * @param[in,out] *S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] *pData points to the matrix data array. + * @return none + */ + + void arm_mat_init_q31( + arm_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + + /** + * @brief Q15 matrix initialization. + * @param[in,out] *S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] *pData points to the matrix data array. + * @return none + */ + + void arm_mat_init_q15( + arm_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + + /** + * @brief Floating-point matrix initialization. + * @param[in,out] *S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] *pData points to the matrix data array. + * @return none + */ + + void arm_mat_init_f32( + arm_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + + + /** + * @brief Instance structure for the Q15 PID Control. + */ + typedef struct + { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ +#ifdef ARM_MATH_CM0_FAMILY + q15_t A1; + q15_t A2; +#else + q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ +#endif + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q15; + + /** + * @brief Instance structure for the Q31 PID Control. + */ + typedef struct + { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ + + } arm_pid_instance_q31; + + /** + * @brief Instance structure for the floating-point PID Control. + */ + typedef struct + { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ + } arm_pid_instance_f32; + + + + /** + * @brief Initialization function for the floating-point PID Control. + * @param[in,out] *S points to an instance of the PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + * @return none. + */ + void arm_pid_init_f32( + arm_pid_instance_f32 * S, + int32_t resetStateFlag); + + /** + * @brief Reset function for the floating-point PID Control. + * @param[in,out] *S is an instance of the floating-point PID Control structure + * @return none + */ + void arm_pid_reset_f32( + arm_pid_instance_f32 * S); + + + /** + * @brief Initialization function for the Q31 PID Control. + * @param[in,out] *S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + * @return none. + */ + void arm_pid_init_q31( + arm_pid_instance_q31 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q31 PID Control. + * @param[in,out] *S points to an instance of the Q31 PID Control structure + * @return none + */ + + void arm_pid_reset_q31( + arm_pid_instance_q31 * S); + + /** + * @brief Initialization function for the Q15 PID Control. + * @param[in,out] *S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + * @return none. + */ + void arm_pid_init_q15( + arm_pid_instance_q15 * S, + int32_t resetStateFlag); + + /** + * @brief Reset function for the Q15 PID Control. + * @param[in,out] *S points to an instance of the q15 PID Control structure + * @return none + */ + void arm_pid_reset_q15( + arm_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } arm_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q7; + + + /** + * @brief Q7 vector multiplication. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Q15 vector multiplication. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Q31 vector multiplication. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_mult_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Floating-point vector multiplication. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_mult_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + + + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q15( + arm_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q15( + const arm_cfft_radix2_instance_q15 * S, + q15_t * pSrc); + + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q31; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q31( + arm_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q31( + const arm_cfft_radix2_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q31; + +/* Deprecated */ + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix2_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_f32( + arm_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_f32( + const arm_cfft_radix2_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix4_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q15; + +void arm_cfft_q15( + const arm_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q31; + +void arm_cfft_q31( + const arm_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_f32; + + void arm_cfft_f32( + const arm_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q15; + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q31; + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_f32; + + arm_status arm_rfft_init_f32( + arm_rfft_instance_f32 * S, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + +typedef struct + { + arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f32 ; + +arm_status arm_rfft_fast_init_f32 ( + arm_rfft_fast_instance_f32 * S, + uint16_t fftLen); + +void arm_rfft_fast_f32( + arm_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + float32_t *pTwiddle; /**< points to the twiddle factor table. */ + float32_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_f32; + + /** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] *S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] *S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] *S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. + */ + + arm_status arm_dct4_init_f32( + arm_dct4_instance_f32 * S, + arm_rfft_instance_f32 * S_RFFT, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + /** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] *S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] *pState points to state buffer. + * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. + * @return none. + */ + + void arm_dct4_f32( + const arm_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + q31_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q31; + + /** + * @brief Initialization function for the Q31 DCT4/IDCT4. + * @param[in,out] *S points to an instance of Q31 DCT4/IDCT4 structure. + * @param[in] *S_RFFT points to an instance of Q31 RFFT/RIFFT structure + * @param[in] *S_CFFT points to an instance of Q31 CFFT/CIFFT structure + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + + arm_status arm_dct4_init_q31( + arm_dct4_instance_q31 * S, + arm_rfft_instance_q31 * S_RFFT, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + /** + * @brief Processing function for the Q31 DCT4/IDCT4. + * @param[in] *S points to an instance of the Q31 DCT4 structure. + * @param[in] *pState points to state buffer. + * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. + * @return none. + */ + + void arm_dct4_q31( + const arm_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + q15_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q15; + + /** + * @brief Initialization function for the Q15 DCT4/IDCT4. + * @param[in,out] *S points to an instance of Q15 DCT4/IDCT4 structure. + * @param[in] *S_RFFT points to an instance of Q15 RFFT/RIFFT structure. + * @param[in] *S_CFFT points to an instance of Q15 CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + + arm_status arm_dct4_init_q15( + arm_dct4_instance_q15 * S, + arm_rfft_instance_q15 * S_RFFT, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + /** + * @brief Processing function for the Q15 DCT4/IDCT4. + * @param[in] *S points to an instance of the Q15 DCT4 structure. + * @param[in] *pState points to state buffer. + * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. + * @return none. + */ + + void arm_dct4_q15( + const arm_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + /** + * @brief Floating-point vector addition. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_add_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Q7 vector addition. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_add_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Q15 vector addition. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_add_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Q31 vector addition. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_add_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Floating-point vector subtraction. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_sub_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Q7 vector subtraction. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_sub_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Q15 vector subtraction. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_sub_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Q31 vector subtraction. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_sub_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Multiplies a floating-point vector by a scalar. + * @param[in] *pSrc points to the input vector + * @param[in] scale scale factor to be applied + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_scale_f32( + float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Multiplies a Q7 vector by a scalar. + * @param[in] *pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_scale_q7( + q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Multiplies a Q15 vector by a scalar. + * @param[in] *pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_scale_q15( + q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Multiplies a Q31 vector by a scalar. + * @param[in] *pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_scale_q31( + q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Q7 vector absolute value. + * @param[in] *pSrc points to the input buffer + * @param[out] *pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_abs_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Floating-point vector absolute value. + * @param[in] *pSrc points to the input buffer + * @param[out] *pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_abs_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Q15 vector absolute value. + * @param[in] *pSrc points to the input buffer + * @param[out] *pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_abs_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Q31 vector absolute value. + * @param[in] *pSrc points to the input buffer + * @param[out] *pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_abs_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Dot product of floating-point vectors. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] *result output result returned here + * @return none. + */ + + void arm_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + /** + * @brief Dot product of Q7 vectors. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] *result output result returned here + * @return none. + */ + + void arm_dot_prod_q7( + q7_t * pSrcA, + q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + /** + * @brief Dot product of Q15 vectors. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] *result output result returned here + * @return none. + */ + + void arm_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + /** + * @brief Dot product of Q31 vectors. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] *result output result returned here + * @return none. + */ + + void arm_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + /** + * @brief Shifts the elements of a Q7 vector a specified number of bits. + * @param[in] *pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_shift_q7( + q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Shifts the elements of a Q15 vector a specified number of bits. + * @param[in] *pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_shift_q15( + q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Shifts the elements of a Q31 vector a specified number of bits. + * @param[in] *pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_shift_q31( + q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Adds a constant offset to a floating-point vector. + * @param[in] *pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_offset_f32( + float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Adds a constant offset to a Q7 vector. + * @param[in] *pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_offset_q7( + q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Adds a constant offset to a Q15 vector. + * @param[in] *pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_offset_q15( + q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Adds a constant offset to a Q31 vector. + * @param[in] *pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_offset_q31( + q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Negates the elements of a floating-point vector. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_negate_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Negates the elements of a Q7 vector. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_negate_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Negates the elements of a Q15 vector. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_negate_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Negates the elements of a Q31 vector. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_negate_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + /** + * @brief Copies the elements of a floating-point vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_copy_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Copies the elements of a Q7 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_copy_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Copies the elements of a Q15 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_copy_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Copies the elements of a Q31 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_copy_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + /** + * @brief Fills a constant value into a floating-point vector. + * @param[in] value input value to be filled + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Fills a constant value into a Q7 vector. + * @param[in] value input value to be filled + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Fills a constant value into a Q15 vector. + * @param[in] value input value to be filled + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Fills a constant value into a Q31 vector. + * @param[in] value input value to be filled + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + +/** + * @brief Convolution of floating-point sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Convolution of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] *pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] *pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return none. + */ + + + void arm_conv_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] *pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] *pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return none. + */ + + void arm_conv_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + + /** + * @brief Convolution of Q31 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + /** + * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return none. + */ + + void arm_conv_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Partial convolution of floating-point sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] * pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] * pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] * pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] * pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q31 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q7 sequences + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + + } arm_fir_decimate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR decimator. + */ + + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + + } arm_fir_decimate_instance_f32; + + + + /** + * @brief Processing function for the floating-point FIR decimator. + * @param[in] *S points to an instance of the floating-point FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_f32( + const arm_fir_decimate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR decimator. + * @param[in,out] *S points to an instance of the floating-point FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + + arm_status arm_fir_decimate_init_f32( + arm_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q15 FIR decimator. + * @param[in] *S points to an instance of the Q15 FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q15 FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + + /** + * @brief Initialization function for the Q15 FIR decimator. + * @param[in,out] *S points to an instance of the Q15 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + + arm_status arm_fir_decimate_init_q15( + arm_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator. + * @param[in] *S points to an instance of the Q31 FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_q31( + const arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q31 FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_fast_q31( + arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR decimator. + * @param[in,out] *S points to an instance of the Q31 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + + arm_status arm_fir_decimate_init_q31( + arm_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + } arm_fir_interpolate_instance_f32; + + + /** + * @brief Processing function for the Q15 FIR interpolator. + * @param[in] *S points to an instance of the Q15 FIR interpolator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_interpolate_q15( + const arm_fir_interpolate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR interpolator. + * @param[in,out] *S points to an instance of the Q15 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficient buffer. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + + arm_status arm_fir_interpolate_init_q15( + arm_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR interpolator. + * @param[in] *S points to an instance of the Q15 FIR interpolator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_interpolate_q31( + const arm_fir_interpolate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 FIR interpolator. + * @param[in,out] *S points to an instance of the Q31 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficient buffer. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + + arm_status arm_fir_interpolate_init_q31( + arm_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR interpolator. + * @param[in] *S points to an instance of the floating-point FIR interpolator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_interpolate_f32( + const arm_fir_interpolate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point FIR interpolator. + * @param[in,out] *S points to an instance of the floating-point FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficient buffer. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + + arm_status arm_fir_interpolate_init_f32( + arm_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + /** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ + + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ + + } arm_biquad_cas_df1_32x64_ins_q31; + + + /** + * @param[in] *S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cas_df1_32x64_q31( + const arm_biquad_cas_df1_32x64_ins_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @param[in,out] *S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format + * @return none + */ + + void arm_biquad_cas_df1_32x64_init_q31( + arm_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f32; + + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_stereo_df2T_instance_f32; + + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f64; + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] *S points to an instance of the filter data structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels + * @param[in] *S points to an instance of the filter data structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_stereo_df2T_f32( + const arm_biquad_cascade_stereo_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] *S points to an instance of the filter data structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df2T_f64( + const arm_biquad_cascade_df2T_instance_f64 * S, + float64_t * pSrc, + float64_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] *S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @return none + */ + + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] *S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @return none + */ + + void arm_biquad_cascade_stereo_df2T_init_f32( + arm_biquad_cascade_stereo_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] *S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @return none + */ + + void arm_biquad_cascade_df2T_init_f64( + arm_biquad_cascade_df2T_instance_f64 * S, + uint8_t numStages, + float64_t * pCoeffs, + float64_t * pState); + + + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_f32; + + /** + * @brief Initialization function for the Q15 FIR lattice filter. + * @param[in] *S points to an instance of the Q15 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] *pState points to the state buffer. The array is of length numStages. + * @return none. + */ + + void arm_fir_lattice_init_q15( + arm_fir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pCoeffs, + q15_t * pState); + + + /** + * @brief Processing function for the Q15 FIR lattice filter. + * @param[in] *S points to an instance of the Q15 FIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_lattice_q15( + const arm_fir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 FIR lattice filter. + * @param[in] *S points to an instance of the Q31 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] *pState points to the state buffer. The array is of length numStages. + * @return none. + */ + + void arm_fir_lattice_init_q31( + arm_fir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pCoeffs, + q31_t * pState); + + + /** + * @brief Processing function for the Q31 FIR lattice filter. + * @param[in] *S points to an instance of the Q31 FIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_fir_lattice_q31( + const arm_fir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + +/** + * @brief Initialization function for the floating-point FIR lattice filter. + * @param[in] *S points to an instance of the floating-point FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] *pState points to the state buffer. The array is of length numStages. + * @return none. + */ + + void arm_fir_lattice_init_f32( + arm_fir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + /** + * @brief Processing function for the floating-point FIR lattice filter. + * @param[in] *S points to an instance of the floating-point FIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_fir_lattice_f32( + const arm_fir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_f32; + + /** + * @brief Processing function for the floating-point IIR lattice filter. + * @param[in] *S points to an instance of the floating-point IIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_f32( + const arm_iir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point IIR lattice filter. + * @param[in] *S points to an instance of the floating-point IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize-1. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_init_f32( + arm_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 IIR lattice filter. + * @param[in] *S points to an instance of the Q31 IIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_q31( + const arm_iir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 IIR lattice filter. + * @param[in] *S points to an instance of the Q31 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_init_q31( + arm_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 IIR lattice filter. + * @param[in] *S points to an instance of the Q15 IIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_q15( + const arm_iir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 IIR lattice filter. + * @param[in] *S points to an instance of the fixed-point Q15 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] *pkCoeffs points to reflection coefficient buffer. The array is of length numStages. + * @param[in] *pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. + * @param[in] *pState points to state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process per call. + * @return none. + */ + + void arm_iir_lattice_init_q15( + arm_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ + } arm_lms_instance_f32; + + /** + * @brief Processing function for floating-point LMS filter. + * @param[in] *S points to an instance of the floating-point LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_f32( + const arm_lms_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + /** + * @brief Initialization function for floating-point LMS filter. + * @param[in] *S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to the coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_init_f32( + arm_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q15; + + + /** + * @brief Initialization function for the Q15 LMS filter. + * @param[in] *S points to an instance of the Q15 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to the coefficient buffer. + * @param[in] *pState points to the state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + * @return none. + */ + + void arm_lms_init_q15( + arm_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + /** + * @brief Processing function for Q15 LMS filter. + * @param[in] *S points to an instance of the Q15 LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_q15( + const arm_lms_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + + } arm_lms_instance_q31; + + /** + * @brief Processing function for Q31 LMS filter. + * @param[in] *S points to an instance of the Q15 LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_q31( + const arm_lms_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + /** + * @brief Initialization function for Q31 LMS filter. + * @param[in] *S points to an instance of the Q31 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + * @return none. + */ + + void arm_lms_init_q31( + arm_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_f32; + + /** + * @brief Processing function for floating-point normalized LMS filter. + * @param[in] *S points to an instance of the floating-point normalized LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_norm_f32( + arm_lms_norm_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + /** + * @brief Initialization function for floating-point normalized LMS filter. + * @param[in] *S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_norm_init_f32( + arm_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q31; + + /** + * @brief Processing function for Q31 normalized LMS filter. + * @param[in] *S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_norm_q31( + arm_lms_norm_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + /** + * @brief Initialization function for Q31 normalized LMS filter. + * @param[in] *S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + * @return none. + */ + + void arm_lms_norm_init_q31( + arm_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q15; + + /** + * @brief Processing function for Q15 normalized LMS filter. + * @param[in] *S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_norm_q15( + arm_lms_norm_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q15 normalized LMS filter. + * @param[in] *S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + * @return none. + */ + + void arm_lms_norm_init_q15( + arm_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + /** + * @brief Correlation of floating-point sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Correlation of Q15 sequences + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] *pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @return none. + */ + void arm_correlate_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] *pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @return none. + */ + + void arm_correlate_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + /** + * @brief Correlation of Q31 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + /** + * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return none. + */ + + void arm_correlate_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q7; + + /** + * @brief Processing function for the floating-point sparse FIR filter. + * @param[in] *S points to an instance of the floating-point sparse FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] *pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_sparse_f32( + arm_fir_sparse_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point sparse FIR filter. + * @param[in,out] *S points to an instance of the floating-point sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] *pCoeffs points to the array of filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] *pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + * @return none + */ + + void arm_fir_sparse_init_f32( + arm_fir_sparse_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 sparse FIR filter. + * @param[in] *S points to an instance of the Q31 sparse FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] *pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_sparse_q31( + arm_fir_sparse_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 sparse FIR filter. + * @param[in,out] *S points to an instance of the Q31 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] *pCoeffs points to the array of filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] *pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + * @return none + */ + + void arm_fir_sparse_init_q31( + arm_fir_sparse_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + /** + * @brief Processing function for the Q15 sparse FIR filter. + * @param[in] *S points to an instance of the Q15 sparse FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] *pScratchIn points to a temporary buffer of size blockSize. + * @param[in] *pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_sparse_q15( + arm_fir_sparse_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 sparse FIR filter. + * @param[in,out] *S points to an instance of the Q15 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] *pCoeffs points to the array of filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] *pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + * @return none + */ + + void arm_fir_sparse_init_q15( + arm_fir_sparse_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + /** + * @brief Processing function for the Q7 sparse FIR filter. + * @param[in] *S points to an instance of the Q7 sparse FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] *pScratchIn points to a temporary buffer of size blockSize. + * @param[in] *pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_sparse_q7( + arm_fir_sparse_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q7 sparse FIR filter. + * @param[in,out] *S points to an instance of the Q7 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] *pCoeffs points to the array of filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] *pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + * @return none + */ + + void arm_fir_sparse_init_q7( + arm_fir_sparse_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /* + * @brief Floating-point sin_cos function. + * @param[in] theta input value in degrees + * @param[out] *pSinVal points to the processed sine output. + * @param[out] *pCosVal points to the processed cos output. + * @return none. + */ + + void arm_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCcosVal); + + /* + * @brief Q31 sin_cos function. + * @param[in] theta scaled input value in degrees + * @param[out] *pSinVal points to the processed sine output. + * @param[out] *pCosVal points to the processed cosine output. + * @return none. + */ + + void arm_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + + /** + * @brief Floating-point complex conjugate. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_conj_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex conjugate. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_conj_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + /** + * @brief Q15 complex conjugate. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_conj_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + + /** + * @brief Floating-point complex magnitude squared + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_squared_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex magnitude squared + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_squared_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + /** + * @brief Q15 complex magnitude squared + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_squared_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * S points to an instance of the PID control data structure. in + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + *
+   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+   *    A0 = Kp + Ki + Kd
+   *    A1 = (-Kp ) - (2 * Kd )
+   *    A2 = Kd  
+ * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup PID + * @{ + */ + + /** + * @brief Process function for the floating-point PID Control. + * @param[in,out] *S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + */ + + + static __INLINE float32_t arm_pid_f32( + arm_pid_instance_f32 * S, + float32_t in) + { + float32_t out; + + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @brief Process function for the Q31 PID Control. + * @param[in,out] *S points to an instance of the Q31 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 64-bit accumulator. + * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + * Thus, if the accumulator result overflows it wraps around rather than clip. + * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ + + static __INLINE q31_t arm_pid_q31( + arm_pid_instance_q31 * S, + q31_t in) + { + q63_t acc; + q31_t out; + + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31u); + + /* out += y[n-1] */ + out += S->state[2]; + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @brief Process function for the Q15 PID Control. + * @param[in,out] *S points to an instance of the Q15 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using a 64-bit internal accumulator. + * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + * Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ + + static __INLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + +#ifndef ARM_MATH_CM0_FAMILY + __SIMD32_TYPE *vstate; + + /* Implementation of PID controller */ + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD(S->A0, in); + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + vstate = __SIMD32_CONST(S->state); + acc = __SMLALD(S->A1, (q31_t) *vstate, acc); + +#else + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; + +#endif + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT((acc >> 15), 16)); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @} end of PID group + */ + + + /** + * @brief Floating-point matrix inverse. + * @param[in] *src points to the instance of the input floating-point matrix structure. + * @param[out] *dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + + arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * src, + arm_matrix_instance_f32 * dst); + + + /** + * @brief Floating-point matrix inverse. + * @param[in] *src points to the instance of the input floating-point matrix structure. + * @param[out] *dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + + arm_status arm_mat_inverse_f64( + const arm_matrix_instance_f64 * src, + arm_matrix_instance_f64 * dst); + + + + /** + * @ingroup groupController + */ + + + /** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents + * in the two-phase orthogonal stator axis Ialpha and Ibeta. + * When Ialpha is superposed with Ia as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta + * can be calculated using only Ia and Ib. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where Ia and Ib are the instantaneous stator phases and + * pIalpha and pIbeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup clarke + * @{ + */ + + /** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta + * @return none. + */ + + static __INLINE void arm_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) + { + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = + ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); + + } + + /** + * @brief Clarke transform for Q31 version + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + + static __INLINE void arm_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); + } + + /** + * @} end of clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q31 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_q7_to_q31( + q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where pIa and pIb are the instantaneous stator phases and + * Ialpha and Ibeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_clarke + * @{ + */ + + /** + * @brief Floating-point Inverse Clarke transform + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] *pIa points to output three-phase coordinate a + * @param[out] *pIb points to output three-phase coordinate b + * @return none. + */ + + + static __INLINE void arm_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) + { + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5 * Ialpha + (float32_t) 0.8660254039 *Ibeta; + + } + + /** + * @brief Inverse Clarke transform for Q31 version + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] *pIa points to output three-phase coordinate a + * @param[out] *pIb points to output three-phase coordinate b + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the subtraction, hence there is no risk of overflow. + */ + + static __INLINE void arm_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); + + } + + /** + * @} end of inv_clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q15 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_q7_to_q15( + q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where Ialpha and Ibeta are the stator vector components, + * pId and pIq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup park + * @{ + */ + + /** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] *pId points to output rotor reference frame d + * @param[out] *pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none. + * + * The function implements the forward Park transform. + * + */ + + static __INLINE void arm_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; + + } + + /** + * @brief Park transform for Q31 version + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] *pId points to output rotor reference frame d + * @param[out] *pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ + + + static __INLINE void arm_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); + + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); + } + + /** + * @} end of park group + */ + + /** + * @brief Converts the elements of the Q7 vector to floating-point vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q7_to_float( + q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where pIalpha and pIbeta are the stator vector components, + * Id and Iq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_park + * @{ + */ + + /** + * @brief Floating-point Inverse Park transform + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none. + */ + + static __INLINE void arm_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; + + } + + + /** + * @brief Inverse Park transform for Q31 version + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + + + static __INLINE void arm_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); + + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); + + } + + /** + * @} end of Inverse park group + */ + + + /** + * @brief Converts the elements of the Q31 vector to floating-point vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q31_to_float( + q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + *
+   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+   *       where x0, x1 are nearest values of input x
+   *             y0, y1 are nearest values to output y
+   * 
+ * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * S points to an instance of the Linear Interpolate function data structure. + * x is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ + + /** + * @addtogroup LinearInterpolate + * @{ + */ + + /** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] *S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ + + static __INLINE float32_t arm_linear_interp_f32( + arm_linear_interp_instance_f32 * S, + float32_t x) + { + + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + + /* Calculation of index */ + i = (int32_t) ((x - S->x1) / xSpacing); + + if(i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if((uint32_t)i >= S->nValues) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + + } + + /* returns output value */ + return (y); + } + + /** + * + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] *pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + + + static __INLINE q31_t arm_linear_interp_q31( + q31_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & 0xFFF00000) >> 20); + + if(index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1u]; + + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); + + /* Convert y to 1.31 format */ + return (y << 1u); + + } + + } + + /** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] *pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + + + static __INLINE q15_t arm_linear_interp_q15( + q15_t * pYData, + q31_t x, + uint32_t nValues) + { + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & 0xFFF00000) >> 20u); + + if(index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1u]; + + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); + + /* convert y to 1.15 format */ + return (y >> 20); + } + + + } + + /** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] *pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ + + + static __INLINE q7_t arm_linear_interp_q7( + q7_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + uint32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + if (x < 0) + { + return (pYData[0]); + } + index = (x >> 20) & 0xfff; + + + if(index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else + { + + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1u]; + + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + + /* convert y to 1.7(q7) format */ + return (y >> 20u); + + } + + } + /** + * @} end of LinearInterpolate group + */ + + /** + * @brief Fast approximation to the trigonometric sine function for floating-point data. + * @param[in] x input value in radians. + * @return sin(x). + */ + + float32_t arm_sin_f32( + float32_t x); + + /** + * @brief Fast approximation to the trigonometric sine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + + q31_t arm_sin_q31( + q31_t x); + + /** + * @brief Fast approximation to the trigonometric sine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + + q15_t arm_sin_q15( + q15_t x); + + /** + * @brief Fast approximation to the trigonometric cosine function for floating-point data. + * @param[in] x input value in radians. + * @return cos(x). + */ + + float32_t arm_cos_f32( + float32_t x); + + /** + * @brief Fast approximation to the trigonometric cosine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + + q31_t arm_cos_q31( + q31_t x); + + /** + * @brief Fast approximation to the trigonometric cosine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + + q15_t arm_cos_q15( + q15_t x); + + + /** + * @ingroup groupFastMath + */ + + + /** + * @defgroup SQRT Square Root + * + * Computes the square root of a number. + * There are separate functions for Q15, Q31, and floating-point data types. + * The square root function is computed using the Newton-Raphson algorithm. + * This is an iterative algorithm of the form: + *
+   *      x1 = x0 - f(x0)/f'(x0)
+   * 
+ * where x1 is the current estimate, + * x0 is the previous estimate, and + * f'(x0) is the derivative of f() evaluated at x0. + * For the square root function, the algorithm reduces to: + *
+   *     x0 = in/2                         [initial guess]
+   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+   * 
+ */ + + + /** + * @addtogroup SQRT + * @{ + */ + + /** + * @brief Floating-point square root function. + * @param[in] in input value. + * @param[out] *pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + + static __INLINE arm_status arm_sqrt_f32( + float32_t in, + float32_t * pOut) + { + if(in > 0) + { + +// #if __FPU_USED +#if (__FPU_USED == 1) && defined ( __CC_ARM ) + *pOut = __sqrtf(in); +#else + *pOut = sqrtf(in); +#endif + + return (ARM_MATH_SUCCESS); + } + else + { + *pOut = 0.0f; + return (ARM_MATH_ARGUMENT_ERROR); + } + + } + + + /** + * @brief Q31 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF. + * @param[out] *pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q31( + q31_t in, + q31_t * pOut); + + /** + * @brief Q15 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF. + * @param[out] *pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q15( + q15_t in, + q15_t * pOut); + + /** + * @} end of SQRT group + */ + + + + + + + /** + * @brief floating-point Circular write function. + */ + + static __INLINE void arm_circularWrite_f32( + int32_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const int32_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + static __INLINE void arm_circularRead_f32( + int32_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + int32_t * dst, + int32_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (int32_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + /** + * @brief Q15 Circular write function. + */ + + static __INLINE void arm_circularWrite_q15( + q15_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q15_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = wOffset; + } + + + + /** + * @brief Q15 Circular Read function. + */ + static __INLINE void arm_circularRead_q15( + q15_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q15_t * dst, + q15_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (q15_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update wOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q7 Circular write function. + */ + + static __INLINE void arm_circularWrite_q7( + q7_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q7_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = wOffset; + } + + + + /** + * @brief Q7 Circular Read function. + */ + static __INLINE void arm_circularRead_q7( + q7_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q7_t * dst, + q7_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (q7_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Sum of the squares of the elements of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_power_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + /** + * @brief Sum of the squares of the elements of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_power_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Sum of the squares of the elements of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_power_q15( + q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + /** + * @brief Sum of the squares of the elements of a Q7 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_power_q7( + q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Mean value of a Q7 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_mean_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + /** + * @brief Mean value of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + void arm_mean_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + /** + * @brief Mean value of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + void arm_mean_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Mean value of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + void arm_mean_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Variance of the elements of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_var_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Variance of the elements of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_var_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Variance of the elements of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_var_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + /** + * @brief Root Mean Square of the elements of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_rms_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Root Mean Square of the elements of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_rms_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Root Mean Square of the elements of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_rms_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + /** + * @brief Standard deviation of the elements of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_std_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Standard deviation of the elements of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_std_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Standard deviation of the elements of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_std_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + /** + * @brief Floating-point complex magnitude + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex magnitude + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + /** + * @brief Q15 complex magnitude + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + /** + * @brief Q15 complex dot product + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] *realResult real part of the result returned here + * @param[out] *imagResult imaginary part of the result returned here + * @return none. + */ + + void arm_cmplx_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + /** + * @brief Q31 complex dot product + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] *realResult real part of the result returned here + * @param[out] *imagResult imaginary part of the result returned here + * @return none. + */ + + void arm_cmplx_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + /** + * @brief Floating-point complex dot product + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] *realResult real part of the result returned here + * @param[out] *imagResult imaginary part of the result returned here + * @return none. + */ + + void arm_cmplx_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + /** + * @brief Q15 complex-by-real multiplication + * @param[in] *pSrcCmplx points to the complex input vector + * @param[in] *pSrcReal points to the real input vector + * @param[out] *pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + * @return none. + */ + + void arm_cmplx_mult_real_q15( + q15_t * pSrcCmplx, + q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + /** + * @brief Q31 complex-by-real multiplication + * @param[in] *pSrcCmplx points to the complex input vector + * @param[in] *pSrcReal points to the real input vector + * @param[out] *pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + * @return none. + */ + + void arm_cmplx_mult_real_q31( + q31_t * pSrcCmplx, + q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + /** + * @brief Floating-point complex-by-real multiplication + * @param[in] *pSrcCmplx points to the complex input vector + * @param[in] *pSrcReal points to the real input vector + * @param[out] *pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + * @return none. + */ + + void arm_cmplx_mult_real_f32( + float32_t * pSrcCmplx, + float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + /** + * @brief Minimum value of a Q7 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *result is output pointer + * @param[in] index is the array index of the minimum value in the input buffer. + * @return none. + */ + + void arm_min_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + /** + * @brief Minimum value of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output pointer + * @param[in] *pIndex is the array index of the minimum value in the input buffer. + * @return none. + */ + + void arm_min_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + /** + * @brief Minimum value of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output pointer + * @param[out] *pIndex is the array index of the minimum value in the input buffer. + * @return none. + */ + void arm_min_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + /** + * @brief Minimum value of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output pointer + * @param[out] *pIndex is the array index of the minimum value in the input buffer. + * @return none. + */ + + void arm_min_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + +/** + * @brief Maximum value of a Q7 vector. + * @param[in] *pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + + void arm_max_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + +/** + * @brief Maximum value of a Q15 vector. + * @param[in] *pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + + void arm_max_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] *pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + + void arm_max_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + +/** + * @brief Maximum value of a floating-point vector. + * @param[in] *pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + + void arm_max_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + /** + * @brief Q15 complex-by-complex multiplication + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_mult_cmplx_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex-by-complex multiplication + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_mult_cmplx_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + /** + * @brief Floating-point complex-by-complex multiplication + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_mult_cmplx_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Converts the elements of the floating-point vector to Q31 vector. + * @param[in] *pSrc points to the floating-point input vector + * @param[out] *pDst points to the Q31 output vector + * @param[in] blockSize length of the input vector + * @return none. + */ + void arm_float_to_q31( + float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Converts the elements of the floating-point vector to Q15 vector. + * @param[in] *pSrc points to the floating-point input vector + * @param[out] *pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + * @return none + */ + void arm_float_to_q15( + float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Converts the elements of the floating-point vector to Q7 vector. + * @param[in] *pSrc points to the floating-point input vector + * @param[out] *pDst points to the Q7 output vector + * @param[in] blockSize length of the input vector + * @return none + */ + void arm_float_to_q7( + float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q15 vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q31_to_q15( + q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Converts the elements of the Q31 vector to Q7 vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q31_to_q7( + q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Converts the elements of the Q15 vector to floating-point vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q15_to_float( + q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q31 vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q15_to_q31( + q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q7 vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q15_to_q7( + q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function f(x, y) is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * Algorithm + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + *
+   *   typedef struct
+   *   {
+   *     uint16_t numRows;
+   *     uint16_t numCols;
+   *     float32_t *pData;
+   * } arm_bilinear_interp_instance_f32;
+   * 
+ * + * \par + * where numRows specifies the number of rows in the table; + * numCols specifies the number of columns in the table; + * and pData points to an array of size numRows*numCols values. + * The data table pTable is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. + * + * \par + * Let (x, y) specify the desired interpolation point. Then define: + *
+   *     XF = floor(x)
+   *     YF = floor(y)
+   * 
+ * \par + * The interpolated output point is computed as: + *
+   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+   * 
+ * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ + + /** + * @addtogroup BilinearInterpolate + * @{ + */ + + /** + * + * @brief Floating-point bilinear interpolation. + * @param[in,out] *S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate. + * @param[in] Y interpolation coordinate. + * @return out interpolated value. + */ + + + static __INLINE float32_t arm_bilinear_interp_f32( + const arm_bilinear_interp_instance_f32 * S, + float32_t X, + float32_t Y) + { + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 + || yIndex > (S->numCols - 1)) + { + return (0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex - 1) + (yIndex - 1) * S->numCols; + + + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex - 1) + (yIndex) * S->numCols; + + + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + + /* return to application */ + return (out); + + } + + /** + * + * @brief Q31 bilinear interpolation. + * @param[in,out] *S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + + static __INLINE q31_t arm_bilinear_interp_q31( + arm_bilinear_interp_instance_q31 * S, + q31_t X, + q31_t Y) + { + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & 0xFFF00000) >> 20u); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & 0xFFF00000) >> 20u); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + nCols * (cI)]; + x2 = pYData[(rI) + nCols * (cI) + 1u]; + + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + nCols * (cI + 1)]; + y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* Convert acc to 1.31(q31) format */ + return (acc << 2u); + + } + + /** + * @brief Q15 bilinear interpolation. + * @param[in,out] *S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + + static __INLINE q15_t arm_bilinear_interp_q15( + arm_bilinear_interp_instance_q15 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & 0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & 0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + nCols * (cI)]; + x2 = pYData[(rI) + nCols * (cI) + 1u]; + + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + nCols * (cI + 1)]; + y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ + out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u); + acc = ((q63_t) out * (0xFFFFF - yfract)); + + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u); + acc += ((q63_t) out * (xfract)); + + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return (acc >> 36); + + } + + /** + * @brief Q7 bilinear interpolation. + * @param[in,out] *S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + + static __INLINE q7_t arm_bilinear_interp_q7( + arm_bilinear_interp_instance_q7 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & 0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & 0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + nCols * (cI)]; + x2 = pYData[(rI) + nCols * (cI) + 1u]; + + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + nCols * (cI + 1)]; + y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); + acc = (((q63_t) out * (0xFFFFF - yfract))); + + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); + + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return (acc >> 40); + + } + + /** + * @} end of BilinearInterpolate group + */ + + +//SMMLAR +#define multAcc_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) + +//SMMLSR +#define multSub_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) + +//SMMULR +#define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) + +//SMMLA +#define multAcc_32x32_keep32(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + +//SMMLS +#define multSub_32x32_keep32(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +//SMMUL +#define mult_32x32_keep32(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) + + +#if defined ( __CC_ARM ) //Keil + +//Enter low optimization region - place directly above function definition + #ifdef ARM_MATH_CM4 + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("push") \ + _Pragma ("O1") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + +//Exit low optimization region - place directly after end of function definition + #ifdef ARM_MATH_CM4 + #define LOW_OPTIMIZATION_EXIT \ + _Pragma ("pop") + #else + #define LOW_OPTIMIZATION_EXIT + #endif + +//Enter low optimization region - place directly above function definition + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + +//Exit low optimization region - place directly after end of function definition + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__ICCARM__) //IAR + +//Enter low optimization region - place directly above function definition + #ifdef ARM_MATH_CM4 + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + +//Exit low optimization region - place directly after end of function definition + #define LOW_OPTIMIZATION_EXIT + +//Enter low optimization region - place directly above function definition + #ifdef ARM_MATH_CM4 + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #endif + +//Exit low optimization region - place directly after end of function definition + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__GNUC__) + + #define LOW_OPTIMIZATION_ENTER __attribute__(( optimize("-O1") )) + + #define LOW_OPTIMIZATION_EXIT + + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__CSMC__) // Cosmic + +#define LOW_OPTIMIZATION_ENTER +#define LOW_OPTIMIZATION_EXIT +#define IAR_ONLY_LOW_OPTIMIZATION_ENTER +#define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#endif + + +#ifdef __cplusplus +} +#endif + + +#endif /* _ARM_MATH_H */ + +/** + * + * End of file. + */ diff --git a/Downstream/Drivers/CMSIS/Include/core_cm4.h b/Downstream/Drivers/CMSIS/Include/core_cm4.h new file mode 100644 index 0000000..cbb7c58 --- /dev/null +++ b/Downstream/Drivers/CMSIS/Include/core_cm4.h @@ -0,0 +1,1802 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V4.00 + * @date 22. August 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - 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. + - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +#ifdef __cplusplus + extern "C" { +#endif + +/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex_M4 + @{ + */ + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (0x04) /*!< [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x04) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ + #define __STATIC_INLINE static inline + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __CSMC__ ) /* Cosmic */ + #if ( __CSMC__ & 0x400) // FPU present for parser + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ +#include /* Compiler specific SIMD Intrinsics */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000 + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0 + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_CALIB_TENMS_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29]; + __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43]; + __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6]; + __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1]; + __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1]; + __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1]; + __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2]; + __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55]; + __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131]; + __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759]; + __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1]; + __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39]; + __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8]; + __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if (__FPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register */ +#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3 /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1 /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0 /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL << FPU_FPCCR_LSPACT_Pos) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register */ +#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register */ +#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24 /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20 /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16 /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12 /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8 /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4 /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0 /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL << FPU_MVFR0_A_SIMD_registers_Pos) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24 /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4 /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0 /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL << FPU_MVFR1_FtZ_mode_Pos) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M4 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#if (__FPU_PRESENT == 1) + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** \brief Set Priority Grouping + + The function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + The function reads the priority grouping field from the NVIC Interrupt Controller. + + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \brief Enable External Interrupt + + The function enables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ +/* NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */ + NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + The function disables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + The function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + + +/** \brief Set Pending Interrupt + + The function sets the pending bit of an external interrupt. + + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + The function clears the pending bit of an external interrupt. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + The function reads the active register in NVIC and returns the active bit. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \brief Set Interrupt Priority + + The function sets the priority of an interrupt. + + \note The priority cannot be set for every core interrupt. + + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + The function reads the priority of an interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented + priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + The function encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + The function decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \brief System Reset + + The function initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + The function initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + + \param [in] ticks Number of ticks between two interrupts. + + \return 0 Function succeeded. + \return 1 Function failed. + + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + //NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** \brief ITM Send Character + + The function transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + + \param [in] ch Character to transmit. + + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + The function inputs a character via the external variable \ref ITM_RxBuffer. + + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) { + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** \brief ITM Check Character + + The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/Downstream/Drivers/CMSIS/Include/core_cmFunc.h b/Downstream/Drivers/CMSIS/Include/core_cmFunc.h new file mode 100644 index 0000000..01089f1 --- /dev/null +++ b/Downstream/Drivers/CMSIS/Include/core_cmFunc.h @@ -0,0 +1,637 @@ +/**************************************************************************//** + * @file core_cmFunc.h + * @brief CMSIS Cortex-M Core Function Access Header File + * @version V4.00 + * @date 28. August 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - 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. + - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#ifndef __CORE_CMFUNC_H +#define __CORE_CMFUNC_H + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + +/* intrinsic void __enable_irq(); */ +/* intrinsic void __disable_irq(); */ + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** \brief Get IPSR Register + + This function returns the content of the IPSR Register. + + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xff); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1); +} + +#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */ + + +#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#endif +} + +#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */ + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief Enable IRQ Interrupts + + This function enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** \brief Disable IRQ Interrupts + + This function disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +/** \brief Get IPSR Register + + This function returns the content of the IPSR Register. + + \return IPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp"); +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp"); +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); + return(result); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory"); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + uint32_t result; + + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + __ASM volatile (""); + return(result); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); + __ASM volatile (""); +#endif +} + +#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */ + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ +#include + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + +#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ +/* Cosmic specific functions */ +#include + +#endif + +/*@} end of CMSIS_Core_RegAccFunctions */ + +#endif /* __CORE_CMFUNC_H */ diff --git a/Downstream/Drivers/CMSIS/Include/core_cmInstr.h b/Downstream/Drivers/CMSIS/Include/core_cmInstr.h new file mode 100644 index 0000000..d14110b --- /dev/null +++ b/Downstream/Drivers/CMSIS/Include/core_cmInstr.h @@ -0,0 +1,880 @@ +/**************************************************************************//** + * @file core_cmInstr.h + * @brief CMSIS Cortex-M Core Instruction Access Header File + * @version V4.00 + * @date 28. August 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - 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. + - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#ifndef __CORE_CMINSTR_H +#define __CORE_CMINSTR_H + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +#define __ISB() __isb(0xF) + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __dsb(0xF) + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __dmb(0xF) + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** \brief Breakpoint + + This function causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __rbit + + +/** \brief LDR Exclusive (8 bit) + + This function executes a exclusive LDR instruction for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) + + +/** \brief LDR Exclusive (16 bit) + + This function executes a exclusive LDR instruction for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) + + +/** \brief LDR Exclusive (32 bit) + + This function executes a exclusive LDR instruction for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) + + +/** \brief STR Exclusive (8 bit) + + This function executes a exclusive STR instruction for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (16 bit) + + This function executes a exclusive STR instruction for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (32 bit) + + This function executes a exclusive STR instruction for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW(value, ptr) __strex(value, ptr) + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +#define __CLREX __clrex + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +/** \brief Rotate Right with Extend (32 bit) + + This function moves each bit of a bitstring right by one bit. The carry input is shifted in at the left end of the bitstring. + + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** \brief LDRT Unprivileged (8 bit) + + This function executes a Unprivileged LDRT instruction for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** \brief LDRT Unprivileged (16 bit) + + This function executes a Unprivileged LDRT instruction for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** \brief LDRT Unprivileged (32 bit) + + This function executes a Unprivileged LDRT instruction for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** \brief STRT Unprivileged (8 bit) + + This function executes a Unprivileged STRT instruction for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** \brief STRT Unprivileged (16 bit) + + This function executes a Unprivileged STRT instruction for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** \brief STRT Unprivileged (32 bit) + + This function executes a Unprivileged STRT instruction for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */ + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constrant "l" + * Otherwise, use general registers, specified by constrant "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void) +{ + __ASM volatile ("nop"); +} + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void) +{ + __ASM volatile ("wfi"); +} + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void) +{ + __ASM volatile ("wfe"); +} + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void) +{ + __ASM volatile ("sev"); +} + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void) +{ + __ASM volatile ("isb"); +} + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void) +{ + __ASM volatile ("dsb"); +} + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void) +{ + __ASM volatile ("dmb"); +} + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (short)__builtin_bswap16(value); +#else + uint32_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32 - op2)); +} + + +/** \brief Breakpoint + + This function causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief LDR Exclusive (8 bit) + + This function executes a exclusive LDR instruction for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** \brief LDR Exclusive (16 bit) + + This function executes a exclusive LDR instruction for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** \brief LDR Exclusive (32 bit) + + This function executes a exclusive LDR instruction for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** \brief STR Exclusive (8 bit) + + This function executes a exclusive STR instruction for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** \brief STR Exclusive (16 bit) + + This function executes a exclusive STR instruction for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** \brief STR Exclusive (32 bit) + + This function executes a exclusive STR instruction for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** \brief Rotate Right with Extend (32 bit) + + This function moves each bit of a bitstring right by one bit. The carry input is shifted in at the left end of the bitstring. + + \param [in] value Value to rotate + \return Rotated value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** \brief LDRT Unprivileged (8 bit) + + This function executes a Unprivileged LDRT instruction for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** \brief LDRT Unprivileged (16 bit) + + This function executes a Unprivileged LDRT instruction for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** \brief LDRT Unprivileged (32 bit) + + This function executes a Unprivileged LDRT instruction for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** \brief STRT Unprivileged (8 bit) + + This function executes a Unprivileged STRT instruction for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); +} + + +/** \brief STRT Unprivileged (16 bit) + + This function executes a Unprivileged STRT instruction for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); +} + + +/** \brief STRT Unprivileged (32 bit) + + This function executes a Unprivileged STRT instruction for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) ); +} + +#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */ + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ +#include + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + + +#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ +/* Cosmic specific functions */ +#include + +#endif + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + +#endif /* __CORE_CMINSTR_H */ diff --git a/Downstream/Drivers/CMSIS/Include/core_cmSimd.h b/Downstream/Drivers/CMSIS/Include/core_cmSimd.h new file mode 100644 index 0000000..ee58eee --- /dev/null +++ b/Downstream/Drivers/CMSIS/Include/core_cmSimd.h @@ -0,0 +1,697 @@ +/**************************************************************************//** + * @file core_cmSimd.h + * @brief CMSIS Cortex-M SIMD Header File + * @version V4.00 + * @date 22. August 2014 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2014 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - 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. + - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifndef __CORE_CMSIMD_H +#define __CORE_CMSIMD_H + +#ifdef __cplusplus + extern "C" { +#endif + + +/******************************************************************************* + * Hardware Abstraction Layer + ******************************************************************************/ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32) ) >> 32)) + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ // Little endian + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else // Big endian + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ // Little endian + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else // Big endian + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ // Little endian + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else // Big endian + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ // Little endian + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else // Big endian + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ +#include + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ +/* not yet supported */ + + +#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ +/* Cosmic specific functions */ +#include + +#endif + +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CMSIMD_H */ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h new file mode 100644 index 0000000..3c1a907 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h @@ -0,0 +1,2510 @@ +/** + ****************************************************************************** + * @file stm32_hal_legacy.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief This file contains aliases definition for the STM32Cube HAL constants + * macros and functions maintained for legacy purpose. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 __STM32_HAL_LEGACY +#define __STM32_HAL_LEGACY + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup HAL_AES_Aliased_Defines HAL CRYP Aliased Defines maintained for legacy purpose + * @{ + */ +#define AES_FLAG_RDERR CRYP_FLAG_RDERR +#define AES_FLAG_WRERR CRYP_FLAG_WRERR +#define AES_CLEARFLAG_CCF CRYP_CLEARFLAG_CCF +#define AES_CLEARFLAG_RDERR CRYP_CLEARFLAG_RDERR +#define AES_CLEARFLAG_WRERR CRYP_CLEARFLAG_WRERR + +/** + * @} + */ + +/** @defgroup HAL_ADC_Aliased_Defines HAL ADC Aliased Defines maintained for legacy purpose + * @{ + */ +#define ADC_RESOLUTION12b ADC_RESOLUTION_12B +#define ADC_RESOLUTION10b ADC_RESOLUTION_10B +#define ADC_RESOLUTION8b ADC_RESOLUTION_8B +#define ADC_RESOLUTION6b ADC_RESOLUTION_6B +#define OVR_DATA_OVERWRITTEN ADC_OVR_DATA_OVERWRITTEN +#define OVR_DATA_PRESERVED ADC_OVR_DATA_PRESERVED +#define EOC_SINGLE_CONV ADC_EOC_SINGLE_CONV +#define EOC_SEQ_CONV ADC_EOC_SEQ_CONV +#define EOC_SINGLE_SEQ_CONV ADC_EOC_SINGLE_SEQ_CONV +#define REGULAR_GROUP ADC_REGULAR_GROUP +#define INJECTED_GROUP ADC_INJECTED_GROUP +#define REGULAR_INJECTED_GROUP ADC_REGULAR_INJECTED_GROUP +#define AWD_EVENT ADC_AWD_EVENT +#define AWD1_EVENT ADC_AWD1_EVENT +#define AWD2_EVENT ADC_AWD2_EVENT +#define AWD3_EVENT ADC_AWD3_EVENT +#define OVR_EVENT ADC_OVR_EVENT +#define JQOVF_EVENT ADC_JQOVF_EVENT +#define ALL_CHANNELS ADC_ALL_CHANNELS +#define REGULAR_CHANNELS ADC_REGULAR_CHANNELS +#define INJECTED_CHANNELS ADC_INJECTED_CHANNELS +#define SYSCFG_FLAG_SENSOR_ADC ADC_FLAG_SENSOR +#define SYSCFG_FLAG_VREF_ADC ADC_FLAG_VREFINT +#define ADC_EXTERNALTRIG0_T6_TRGO ADC_EXTERNALTRIGCONV_T6_TRGO +#define ADC_EXTERNALTRIG1_T21_CC2 ADC_EXTERNALTRIGCONV_T21_CC2 +#define ADC_EXTERNALTRIG2_T2_TRGO ADC_EXTERNALTRIGCONV_T2_TRGO +#define ADC_EXTERNALTRIG3_T2_CC4 ADC_EXTERNALTRIGCONV_T2_CC4 +#define ADC_EXTERNALTRIG4_T22_TRGO ADC_EXTERNALTRIGCONV_T22_TRGO +#define ADC_EXTERNALTRIG7_EXT_IT11 ADC_EXTERNALTRIGCONV_EXT_IT11 +#define ADC_CLOCK_ASYNC ADC_CLOCK_ASYNC_DIV1 +#define ADC_EXTERNALTRIG_EDGE_NONE ADC_EXTERNALTRIGCONVEDGE_NONE +#define ADC_EXTERNALTRIG_EDGE_RISING ADC_EXTERNALTRIGCONVEDGE_RISING +#define ADC_EXTERNALTRIG_EDGE_FALLING ADC_EXTERNALTRIGCONVEDGE_FALLING +#define ADC_EXTERNALTRIG_EDGE_RISINGFALLING ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING +/** + * @} + */ + +/** @defgroup HAL_CEC_Aliased_Defines HAL CEC Aliased Defines maintained for legacy purpose + * @{ + */ + +#define __HAL_CEC_GET_IT __HAL_CEC_GET_FLAG + +/** + * @} + */ + +/** @defgroup HAL_COMP_Aliased_Defines HAL COMP Aliased Defines maintained for legacy purpose + * @{ + */ + +#define COMP_WINDOWMODE_DISABLED COMP_WINDOWMODE_DISABLE +#define COMP_WINDOWMODE_ENABLED COMP_WINDOWMODE_ENABLE +#define COMP_EXTI_LINE_COMP1_EVENT COMP_EXTI_LINE_COMP1 +#define COMP_EXTI_LINE_COMP2_EVENT COMP_EXTI_LINE_COMP2 + +/** + * @} + */ + +/** @defgroup HAL_CRC_Aliased_Defines HAL CRC Aliased Defines maintained for legacy purpose + * @{ + */ + +#define CRC_OUTPUTDATA_INVERSION_DISABLED CRC_OUTPUTDATA_INVERSION_DISABLE +#define CRC_OUTPUTDATA_INVERSION_ENABLED CRC_OUTPUTDATA_INVERSION_ENABLE + +/** + * @} + */ + +/** @defgroup HAL_DAC_Aliased_Defines HAL DAC Aliased Defines maintained for legacy purpose + * @{ + */ + +#define DAC1_CHANNEL_1 DAC_CHANNEL_1 +#define DAC1_CHANNEL_2 DAC_CHANNEL_2 +#define DAC2_CHANNEL_1 DAC_CHANNEL_1 +#define DAC_WAVE_NONE ((uint32_t)0x00000000) +#define DAC_WAVE_NOISE ((uint32_t)DAC_CR_WAVE1_0) +#define DAC_WAVE_TRIANGLE ((uint32_t)DAC_CR_WAVE1_1) +#define DAC_WAVEGENERATION_NONE DAC_WAVE_NONE +#define DAC_WAVEGENERATION_NOISE DAC_WAVE_NOISE +#define DAC_WAVEGENERATION_TRIANGLE DAC_WAVE_TRIANGLE + +/** + * @} + */ + +/** @defgroup HAL_DMA_Aliased_Defines HAL DMA Aliased Defines maintained for legacy purpose + * @{ + */ +#define HAL_REMAPDMA_ADC_DMA_CH2 DMA_REMAP_ADC_DMA_CH2 +#define HAL_REMAPDMA_USART1_TX_DMA_CH4 DMA_REMAP_USART1_TX_DMA_CH4 +#define HAL_REMAPDMA_USART1_RX_DMA_CH5 DMA_REMAP_USART1_RX_DMA_CH5 +#define HAL_REMAPDMA_TIM16_DMA_CH4 DMA_REMAP_TIM16_DMA_CH4 +#define HAL_REMAPDMA_TIM17_DMA_CH2 DMA_REMAP_TIM17_DMA_CH2 +#define HAL_REMAPDMA_USART3_DMA_CH32 DMA_REMAP_USART3_DMA_CH32 +#define HAL_REMAPDMA_TIM16_DMA_CH6 DMA_REMAP_TIM16_DMA_CH6 +#define HAL_REMAPDMA_TIM17_DMA_CH7 DMA_REMAP_TIM17_DMA_CH7 +#define HAL_REMAPDMA_SPI2_DMA_CH67 DMA_REMAP_SPI2_DMA_CH67 +#define HAL_REMAPDMA_USART2_DMA_CH67 DMA_REMAP_USART2_DMA_CH67 +#define HAL_REMAPDMA_USART3_DMA_CH32 DMA_REMAP_USART3_DMA_CH32 +#define HAL_REMAPDMA_I2C1_DMA_CH76 DMA_REMAP_I2C1_DMA_CH76 +#define HAL_REMAPDMA_TIM1_DMA_CH6 DMA_REMAP_TIM1_DMA_CH6 +#define HAL_REMAPDMA_TIM2_DMA_CH7 DMA_REMAP_TIM2_DMA_CH7 +#define HAL_REMAPDMA_TIM3_DMA_CH6 DMA_REMAP_TIM3_DMA_CH6 + +#define IS_HAL_REMAPDMA IS_DMA_REMAP +#define __HAL_REMAPDMA_CHANNEL_ENABLE __HAL_DMA_REMAP_CHANNEL_ENABLE +#define __HAL_REMAPDMA_CHANNEL_DISABLE __HAL_DMA_REMAP_CHANNEL_DISABLE + + + +/** + * @} + */ + +/** @defgroup HAL_FLASH_Aliased_Defines HAL FLASH Aliased Defines maintained for legacy purpose + * @{ + */ + +#define TYPEPROGRAM_BYTE FLASH_TYPEPROGRAM_BYTE +#define TYPEPROGRAM_HALFWORD FLASH_TYPEPROGRAM_HALFWORD +#define TYPEPROGRAM_WORD FLASH_TYPEPROGRAM_WORD +#define TYPEPROGRAM_DOUBLEWORD FLASH_TYPEPROGRAM_DOUBLEWORD +#define TYPEERASE_SECTORS FLASH_TYPEERASE_SECTORS +#define TYPEERASE_PAGES FLASH_TYPEERASE_PAGES +#define TYPEERASE_PAGEERASE FLASH_TYPEERASE_PAGES +#define TYPEERASE_MASSERASE FLASH_TYPEERASE_MASSERASE +#define WRPSTATE_DISABLE OB_WRPSTATE_DISABLE +#define WRPSTATE_ENABLE OB_WRPSTATE_ENABLE +#define HAL_FLASH_TIMEOUT_VALUE FLASH_TIMEOUT_VALUE +#define OBEX_PCROP OPTIONBYTE_PCROP +#define OBEX_BOOTCONFIG OPTIONBYTE_BOOTCONFIG +#define PCROPSTATE_DISABLE OB_PCROP_STATE_DISABLE +#define PCROPSTATE_ENABLE OB_PCROP_STATE_ENABLE +#define TYPEERASEDATA_BYTE FLASH_TYPEERASEDATA_BYTE +#define TYPEERASEDATA_HALFWORD FLASH_TYPEERASEDATA_HALFWORD +#define TYPEERASEDATA_WORD FLASH_TYPEERASEDATA_WORD +#define TYPEPROGRAMDATA_BYTE FLASH_TYPEPROGRAMDATA_BYTE +#define TYPEPROGRAMDATA_HALFWORD FLASH_TYPEPROGRAMDATA_HALFWORD +#define TYPEPROGRAMDATA_WORD FLASH_TYPEPROGRAMDATA_WORD +#define TYPEPROGRAMDATA_FASTBYTE FLASH_TYPEPROGRAMDATA_FASTBYTE +#define TYPEPROGRAMDATA_FASTHALFWORD FLASH_TYPEPROGRAMDATA_FASTHALFWORD +#define TYPEPROGRAMDATA_FASTWORD FLASH_TYPEPROGRAMDATA_FASTWORD +#define PAGESIZE FLASH_PAGE_SIZE +#define TYPEPROGRAM_FASTBYTE FLASH_TYPEPROGRAM_BYTE +#define TYPEPROGRAM_FASTHALFWORD FLASH_TYPEPROGRAM_HALFWORD +#define TYPEPROGRAM_FASTWORD FLASH_TYPEPROGRAM_WORD +#define VOLTAGE_RANGE_1 FLASH_VOLTAGE_RANGE_1 +#define VOLTAGE_RANGE_2 FLASH_VOLTAGE_RANGE_2 +#define VOLTAGE_RANGE_3 FLASH_VOLTAGE_RANGE_3 +#define VOLTAGE_RANGE_4 FLASH_VOLTAGE_RANGE_4 +#define TYPEPROGRAM_FAST FLASH_TYPEPROGRAM_FAST +#define TYPEPROGRAM_FAST_AND_LAST FLASH_TYPEPROGRAM_FAST_AND_LAST +#define WRPAREA_BANK1_AREAA OB_WRPAREA_BANK1_AREAA +#define WRPAREA_BANK1_AREAB OB_WRPAREA_BANK1_AREAB +#define WRPAREA_BANK2_AREAA OB_WRPAREA_BANK2_AREAA +#define WRPAREA_BANK2_AREAB OB_WRPAREA_BANK2_AREAB +#define IWDG_STDBY_FREEZE OB_IWDG_STDBY_FREEZE +#define IWDG_STDBY_ACTIVE OB_IWDG_STDBY_RUN +#define IWDG_STOP_FREEZE OB_IWDG_STOP_FREEZE +#define IWDG_STOP_ACTIVE OB_IWDG_STOP_RUN +#define FLASH_ERROR_NONE HAL_FLASH_ERROR_NONE +#define FLASH_ERROR_RD HAL_FLASH_ERROR_RD +#define FLASH_ERROR_PG HAL_FLASH_ERROR_PROG +#define FLASH_ERROR_PGP HAL_FLASH_ERROR_PGS +#define FLASH_ERROR_WRP HAL_FLASH_ERROR_WRP +#define FLASH_ERROR_OPTV HAL_FLASH_ERROR_OPTV +#define FLASH_ERROR_OPTVUSR HAL_FLASH_ERROR_OPTVUSR +#define FLASH_ERROR_PROG HAL_FLASH_ERROR_PROG +#define FLASH_ERROR_OP HAL_FLASH_ERROR_OPERATION +#define FLASH_ERROR_PGA HAL_FLASH_ERROR_PGA +#define FLASH_ERROR_SIZE HAL_FLASH_ERROR_SIZE +#define FLASH_ERROR_SIZ HAL_FLASH_ERROR_SIZE +#define FLASH_ERROR_PGS HAL_FLASH_ERROR_PGS +#define FLASH_ERROR_MIS HAL_FLASH_ERROR_MIS +#define FLASH_ERROR_FAST HAL_FLASH_ERROR_FAST +#define FLASH_ERROR_FWWERR HAL_FLASH_ERROR_FWWERR +#define FLASH_ERROR_NOTZERO HAL_FLASH_ERROR_NOTZERO +#define FLASH_ERROR_OPERATION HAL_FLASH_ERROR_OPERATION +#define FLASH_ERROR_ERS HAL_FLASH_ERROR_ERS +#define OB_WDG_SW OB_IWDG_SW +#define OB_WDG_HW OB_IWDG_HW + +/** + * @} + */ + +/** @defgroup HAL_SYSCFG_Aliased_Defines HAL SYSCFG Aliased Defines maintained for legacy purpose + * @{ + */ + +#define SYSCFG_FASTMODEPLUS_I2C_PB6 I2C_FASTMODEPLUS_PB6 +#define SYSCFG_FASTMODEPLUS_I2C_PB7 I2C_FASTMODEPLUS_PB7 +#define SYSCFG_FASTMODEPLUS_I2C_PB8 I2C_FASTMODEPLUS_PB8 +#define SYSCFG_FASTMODEPLUS_I2C_PB9 I2C_FASTMODEPLUS_PB9 +#define SYSCFG_FASTMODEPLUS_I2C1 I2C_FASTMODEPLUS_I2C1 +#define SYSCFG_FASTMODEPLUS_I2C2 I2C_FASTMODEPLUS_I2C2 +#define SYSCFG_FASTMODEPLUS_I2C3 I2C_FASTMODEPLUS_I2C3 + +/** + * @} + */ + + +/** @defgroup LL_FMC_Aliased_Defines LL FMC Aliased Defines maintained for compatibility purpose + * @{ + */ +#if defined(STM32L4) || defined(STM32F7) +#define FMC_NAND_PCC_WAIT_FEATURE_DISABLE FMC_NAND_WAIT_FEATURE_DISABLE +#define FMC_NAND_PCC_WAIT_FEATURE_ENABLE FMC_NAND_WAIT_FEATURE_ENABLE +#define FMC_NAND_PCC_MEM_BUS_WIDTH_8 FMC_NAND_MEM_BUS_WIDTH_8 +#define FMC_NAND_PCC_MEM_BUS_WIDTH_16 FMC_NAND_MEM_BUS_WIDTH_16 +#else +#define FMC_NAND_WAIT_FEATURE_DISABLE FMC_NAND_PCC_WAIT_FEATURE_DISABLE +#define FMC_NAND_WAIT_FEATURE_ENABLE FMC_NAND_PCC_WAIT_FEATURE_ENABLE +#define FMC_NAND_MEM_BUS_WIDTH_8 FMC_NAND_PCC_MEM_BUS_WIDTH_8 +#define FMC_NAND_MEM_BUS_WIDTH_16 FMC_NAND_PCC_MEM_BUS_WIDTH_16 +#endif +/** + * @} + */ + +/** @defgroup LL_FSMC_Aliased_Defines LL FSMC Aliased Defines maintained for legacy purpose + * @{ + */ + +#define FSMC_NORSRAM_TYPEDEF FSMC_NORSRAM_TypeDef +#define FSMC_NORSRAM_EXTENDED_TYPEDEF FSMC_NORSRAM_EXTENDED_TypeDef +/** + * @} + */ + +/** @defgroup HAL_GPIO_Aliased_Macros HAL GPIO Aliased Macros maintained for legacy purpose + * @{ + */ +#define GET_GPIO_SOURCE GPIO_GET_INDEX +#define GET_GPIO_INDEX GPIO_GET_INDEX + +#if defined(STM32F4) +#define GPIO_AF12_SDMMC GPIO_AF12_SDIO +#define GPIO_AF12_SDMMC1 GPIO_AF12_SDIO +#endif + +#if defined(STM32F7) +#define GPIO_AF12_SDIO GPIO_AF12_SDMMC1 +#define GPIO_AF12_SDMMC GPIO_AF12_SDMMC1 +#endif + +#if defined(STM32L4) +#define GPIO_AF12_SDIO GPIO_AF12_SDMMC1 +#define GPIO_AF12_SDMMC GPIO_AF12_SDMMC1 +#endif + +#define GPIO_AF0_LPTIM GPIO_AF0_LPTIM1 +#define GPIO_AF1_LPTIM GPIO_AF1_LPTIM1 +#define GPIO_AF2_LPTIM GPIO_AF2_LPTIM1 + +/** + * @} + */ + +/** @defgroup HAL_HRTIM_Aliased_Macros HAL HRTIM Aliased Macros maintained for legacy purpose + * @{ + */ +#define HRTIM_TIMDELAYEDPROTECTION_DISABLED HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DISABLED +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDOUT1_EEV68 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDOUT1_EEV6 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDOUT2_EEV68 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDOUT2_EEV6 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDBOTH_EEV68 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDBOTH_EEV6 +#define HRTIM_TIMDELAYEDPROTECTION_BALANCED_EEV68 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_BALANCED_EEV6 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDOUT1_DEEV79 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDOUT1_DEEV7 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDOUT2_DEEV79 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDOUT2_DEEV7 +#define HRTIM_TIMDELAYEDPROTECTION_DELAYEDBOTH_EEV79 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_DELAYEDBOTH_EEV7 +#define HRTIM_TIMDELAYEDPROTECTION_BALANCED_EEV79 HRTIM_TIMER_A_B_C_DELAYEDPROTECTION_BALANCED_EEV7 +/** + * @} + */ + +/** @defgroup HAL_I2C_Aliased_Defines HAL I2C Aliased Defines maintained for legacy purpose + * @{ + */ +#define I2C_DUALADDRESS_DISABLED I2C_DUALADDRESS_DISABLE +#define I2C_DUALADDRESS_ENABLED I2C_DUALADDRESS_ENABLE +#define I2C_GENERALCALL_DISABLED I2C_GENERALCALL_DISABLE +#define I2C_GENERALCALL_ENABLED I2C_GENERALCALL_ENABLE +#define I2C_NOSTRETCH_DISABLED I2C_NOSTRETCH_DISABLE +#define I2C_NOSTRETCH_ENABLED I2C_NOSTRETCH_ENABLE +#define I2C_ANALOGFILTER_ENABLED I2C_ANALOGFILTER_ENABLE +#define I2C_ANALOGFILTER_DISABLED I2C_ANALOGFILTER_DISABLE +/** + * @} + */ + +/** @defgroup HAL_IRDA_Aliased_Defines HAL IRDA Aliased Defines maintained for legacy purpose + * @{ + */ +#define IRDA_ONE_BIT_SAMPLE_DISABLED IRDA_ONE_BIT_SAMPLE_DISABLE +#define IRDA_ONE_BIT_SAMPLE_ENABLED IRDA_ONE_BIT_SAMPLE_ENABLE + +/** + * @} + */ + +/** @defgroup HAL_IWDG_Aliased_Defines HAL IWDG Aliased Defines maintained for legacy purpose + * @{ + */ +#define KR_KEY_RELOAD IWDG_KEY_RELOAD +#define KR_KEY_ENABLE IWDG_KEY_ENABLE +#define KR_KEY_EWA IWDG_KEY_WRITE_ACCESS_ENABLE +#define KR_KEY_DWA IWDG_KEY_WRITE_ACCESS_DISABLE +/** + * @} + */ + +/** @defgroup HAL_LPTIM_Aliased_Defines HAL LPTIM Aliased Defines maintained for legacy purpose + * @{ + */ + +#define LPTIM_CLOCKSAMPLETIME_DIRECTTRANSISTION LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION +#define LPTIM_CLOCKSAMPLETIME_2TRANSISTIONS LPTIM_CLOCKSAMPLETIME_2TRANSITIONS +#define LPTIM_CLOCKSAMPLETIME_4TRANSISTIONS LPTIM_CLOCKSAMPLETIME_4TRANSITIONS +#define LPTIM_CLOCKSAMPLETIME_8TRANSISTIONS LPTIM_CLOCKSAMPLETIME_8TRANSITIONS + +#define LPTIM_CLOCKPOLARITY_RISINGEDGE LPTIM_CLOCKPOLARITY_RISING +#define LPTIM_CLOCKPOLARITY_FALLINGEDGE LPTIM_CLOCKPOLARITY_FALLING +#define LPTIM_CLOCKPOLARITY_BOTHEDGES LPTIM_CLOCKPOLARITY_RISING_FALLING + +#define LPTIM_TRIGSAMPLETIME_DIRECTTRANSISTION LPTIM_TRIGSAMPLETIME_DIRECTTRANSITION +#define LPTIM_TRIGSAMPLETIME_2TRANSISTIONS LPTIM_TRIGSAMPLETIME_2TRANSITIONS +#define LPTIM_TRIGSAMPLETIME_4TRANSISTIONS LPTIM_TRIGSAMPLETIME_4TRANSITIONS +#define LPTIM_TRIGSAMPLETIME_8TRANSISTIONS LPTIM_TRIGSAMPLETIME_8TRANSITIONS + +/* The following 3 definition have also been present in a temporary version of lptim.h */ +/* They need to be renamed also to the right name, just in case */ +#define LPTIM_TRIGSAMPLETIME_2TRANSITION LPTIM_TRIGSAMPLETIME_2TRANSITIONS +#define LPTIM_TRIGSAMPLETIME_4TRANSITION LPTIM_TRIGSAMPLETIME_4TRANSITIONS +#define LPTIM_TRIGSAMPLETIME_8TRANSITION LPTIM_TRIGSAMPLETIME_8TRANSITIONS + +/** + * @} + */ + +/** @defgroup HAL_NAND_Aliased_Defines HAL NAND Aliased Defines maintained for legacy purpose + * @{ + */ +#define NAND_AddressTypedef NAND_AddressTypeDef + +#define __ARRAY_ADDRESS ARRAY_ADDRESS +#define __ADDR_1st_CYCLE ADDR_1ST_CYCLE +#define __ADDR_2nd_CYCLE ADDR_2ND_CYCLE +#define __ADDR_3rd_CYCLE ADDR_3RD_CYCLE +#define __ADDR_4th_CYCLE ADDR_4TH_CYCLE +/** + * @} + */ + +/** @defgroup HAL_NOR_Aliased_Defines HAL NOR Aliased Defines maintained for legacy purpose + * @{ + */ +#define NOR_StatusTypedef HAL_NOR_StatusTypeDef +#define NOR_SUCCESS HAL_NOR_STATUS_SUCCESS +#define NOR_ONGOING HAL_NOR_STATUS_ONGOING +#define NOR_ERROR HAL_NOR_STATUS_ERROR +#define NOR_TIMEOUT HAL_NOR_STATUS_TIMEOUT + +#define __NOR_WRITE NOR_WRITE +#define __NOR_ADDR_SHIFT NOR_ADDR_SHIFT +/** + * @} + */ + +/** @defgroup HAL_OPAMP_Aliased_Defines HAL OPAMP Aliased Defines maintained for legacy purpose + * @{ + */ + +#define OPAMP_NONINVERTINGINPUT_VP0 OPAMP_NONINVERTINGINPUT_IO0 +#define OPAMP_NONINVERTINGINPUT_VP1 OPAMP_NONINVERTINGINPUT_IO1 +#define OPAMP_NONINVERTINGINPUT_VP2 OPAMP_NONINVERTINGINPUT_IO2 +#define OPAMP_NONINVERTINGINPUT_VP3 OPAMP_NONINVERTINGINPUT_IO3 + +#define OPAMP_SEC_NONINVERTINGINPUT_VP0 OPAMP_SEC_NONINVERTINGINPUT_IO0 +#define OPAMP_SEC_NONINVERTINGINPUT_VP1 OPAMP_SEC_NONINVERTINGINPUT_IO1 +#define OPAMP_SEC_NONINVERTINGINPUT_VP2 OPAMP_SEC_NONINVERTINGINPUT_IO2 +#define OPAMP_SEC_NONINVERTINGINPUT_VP3 OPAMP_SEC_NONINVERTINGINPUT_IO3 + +#define OPAMP_INVERTINGINPUT_VM0 OPAMP_INVERTINGINPUT_IO0 +#define OPAMP_INVERTINGINPUT_VM1 OPAMP_INVERTINGINPUT_IO1 + +#define IOPAMP_INVERTINGINPUT_VM0 OPAMP_INVERTINGINPUT_IO0 +#define IOPAMP_INVERTINGINPUT_VM1 OPAMP_INVERTINGINPUT_IO1 + +#define OPAMP_SEC_INVERTINGINPUT_VM0 OPAMP_SEC_INVERTINGINPUT_IO0 +#define OPAMP_SEC_INVERTINGINPUT_VM1 OPAMP_SEC_INVERTINGINPUT_IO1 + +#define OPAMP_INVERTINGINPUT_VINM OPAMP_SEC_INVERTINGINPUT_IO1 + +#define OPAMP_PGACONNECT_NO OPAMP_PGA_CONNECT_INVERTINGINPUT_NO +#define OPAMP_PGACONNECT_VM0 OPAMP_PGA_CONNECT_INVERTINGINPUT_IO0 +#define OPAMP_PGACONNECT_VM1 OPAMP_PGA_CONNECT_INVERTINGINPUT_IO1 + +/** + * @} + */ + +/** @defgroup HAL_I2S_Aliased_Defines HAL I2S Aliased Defines maintained for legacy purpose + * @{ + */ +#define I2S_STANDARD_PHILLIPS I2S_STANDARD_PHILIPS +/** + * @} + */ + +/** @defgroup HAL_PCCARD_Aliased_Defines HAL PCCARD Aliased Defines maintained for legacy purpose + * @{ + */ + +/* Compact Flash-ATA registers description */ +#define CF_DATA ATA_DATA +#define CF_SECTOR_COUNT ATA_SECTOR_COUNT +#define CF_SECTOR_NUMBER ATA_SECTOR_NUMBER +#define CF_CYLINDER_LOW ATA_CYLINDER_LOW +#define CF_CYLINDER_HIGH ATA_CYLINDER_HIGH +#define CF_CARD_HEAD ATA_CARD_HEAD +#define CF_STATUS_CMD ATA_STATUS_CMD +#define CF_STATUS_CMD_ALTERNATE ATA_STATUS_CMD_ALTERNATE +#define CF_COMMON_DATA_AREA ATA_COMMON_DATA_AREA + +/* Compact Flash-ATA commands */ +#define CF_READ_SECTOR_CMD ATA_READ_SECTOR_CMD +#define CF_WRITE_SECTOR_CMD ATA_WRITE_SECTOR_CMD +#define CF_ERASE_SECTOR_CMD ATA_ERASE_SECTOR_CMD +#define CF_IDENTIFY_CMD ATA_IDENTIFY_CMD + +#define PCCARD_StatusTypedef HAL_PCCARD_StatusTypeDef +#define PCCARD_SUCCESS HAL_PCCARD_STATUS_SUCCESS +#define PCCARD_ONGOING HAL_PCCARD_STATUS_ONGOING +#define PCCARD_ERROR HAL_PCCARD_STATUS_ERROR +#define PCCARD_TIMEOUT HAL_PCCARD_STATUS_TIMEOUT +/** + * @} + */ + +/** @defgroup HAL_RTC_Aliased_Defines HAL RTC Aliased Defines maintained for legacy purpose + * @{ + */ + +#define FORMAT_BIN RTC_FORMAT_BIN +#define FORMAT_BCD RTC_FORMAT_BCD + +#define RTC_ALARMSUBSECONDMASK_None RTC_ALARMSUBSECONDMASK_NONE +#define RTC_TAMPERERASEBACKUP_ENABLED RTC_TAMPER_ERASE_BACKUP_ENABLE +#define RTC_TAMPERERASEBACKUP_DISABLED RTC_TAMPER_ERASE_BACKUP_DISABLE +#define RTC_TAMPERMASK_FLAG_DISABLED RTC_TAMPERMASK_FLAG_DISABLE +#define RTC_TAMPERMASK_FLAG_ENABLED RTC_TAMPERMASK_FLAG_ENABLE + +#define RTC_MASKTAMPERFLAG_DISABLED RTC_TAMPERMASK_FLAG_DISABLE +#define RTC_MASKTAMPERFLAG_ENABLED RTC_TAMPERMASK_FLAG_ENABLE +#define RTC_TAMPERERASEBACKUP_ENABLED RTC_TAMPER_ERASE_BACKUP_ENABLE +#define RTC_TAMPERERASEBACKUP_DISABLED RTC_TAMPER_ERASE_BACKUP_DISABLE +#define RTC_MASKTAMPERFLAG_DISABLED RTC_TAMPERMASK_FLAG_DISABLE +#define RTC_MASKTAMPERFLAG_ENABLED RTC_TAMPERMASK_FLAG_ENABLE +#define RTC_TAMPER1_2_INTERRUPT RTC_ALL_TAMPER_INTERRUPT +#define RTC_TAMPER1_2_3_INTERRUPT RTC_ALL_TAMPER_INTERRUPT + +#define RTC_TIMESTAMPPIN_PC13 RTC_TIMESTAMPPIN_DEFAULT +#define RTC_TIMESTAMPPIN_PA0 RTC_TIMESTAMPPIN_POS1 +#define RTC_TIMESTAMPPIN_PI8 RTC_TIMESTAMPPIN_POS1 +#define RTC_TIMESTAMPPIN_PC1 RTC_TIMESTAMPPIN_POS2 + +#define RTC_OUTPUT_REMAP_PC13 RTC_OUTPUT_REMAP_NONE +#define RTC_OUTPUT_REMAP_PB14 RTC_OUTPUT_REMAP_POS1 +#define RTC_OUTPUT_REMAP_PB2 RTC_OUTPUT_REMAP_POS1 + +#define RTC_TAMPERPIN_PC13 RTC_TAMPERPIN_DEFAULT +#define RTC_TAMPERPIN_PA0 RTC_TAMPERPIN_POS1 +#define RTC_TAMPERPIN_PI8 RTC_TAMPERPIN_POS1 + +/** + * @} + */ + + +/** @defgroup HAL_SMARTCARD_Aliased_Defines HAL SMARTCARD Aliased Defines maintained for legacy purpose + * @{ + */ +#define SMARTCARD_NACK_ENABLED SMARTCARD_NACK_ENABLE +#define SMARTCARD_NACK_DISABLED SMARTCARD_NACK_DISABLE + +#define SMARTCARD_ONEBIT_SAMPLING_DISABLED SMARTCARD_ONE_BIT_SAMPLE_DISABLE +#define SMARTCARD_ONEBIT_SAMPLING_ENABLED SMARTCARD_ONE_BIT_SAMPLE_ENABLE +#define SMARTCARD_ONEBIT_SAMPLING_DISABLE SMARTCARD_ONE_BIT_SAMPLE_DISABLE +#define SMARTCARD_ONEBIT_SAMPLING_ENABLE SMARTCARD_ONE_BIT_SAMPLE_ENABLE + +#define SMARTCARD_TIMEOUT_DISABLED SMARTCARD_TIMEOUT_DISABLE +#define SMARTCARD_TIMEOUT_ENABLED SMARTCARD_TIMEOUT_ENABLE + +#define SMARTCARD_LASTBIT_DISABLED SMARTCARD_LASTBIT_DISABLE +#define SMARTCARD_LASTBIT_ENABLED SMARTCARD_LASTBIT_ENABLE +/** + * @} + */ + + + /** @defgroup HAL_SMBUS_Aliased_Defines HAL SMBUS Aliased Defines maintained for legacy purpose + * @{ + */ +#define SMBUS_DUALADDRESS_DISABLED SMBUS_DUALADDRESS_DISABLE +#define SMBUS_DUALADDRESS_ENABLED SMBUS_DUALADDRESS_ENABLE +#define SMBUS_GENERALCALL_DISABLED SMBUS_GENERALCALL_DISABLE +#define SMBUS_GENERALCALL_ENABLED SMBUS_GENERALCALL_ENABLE +#define SMBUS_NOSTRETCH_DISABLED SMBUS_NOSTRETCH_DISABLE +#define SMBUS_NOSTRETCH_ENABLED SMBUS_NOSTRETCH_ENABLE +#define SMBUS_ANALOGFILTER_ENABLED SMBUS_ANALOGFILTER_ENABLE +#define SMBUS_ANALOGFILTER_DISABLED SMBUS_ANALOGFILTER_DISABLE +#define SMBUS_PEC_DISABLED SMBUS_PEC_DISABLE +#define SMBUS_PEC_ENABLED SMBUS_PEC_ENABLE +#define HAL_SMBUS_STATE_SLAVE_LISTEN HAL_SMBUS_STATE_LISTEN +/** + * @} + */ + + /** @defgroup HAL_SPI_Aliased_Defines HAL SPI Aliased Defines maintained for legacy purpose + * @{ + */ +#define SPI_TIMODE_DISABLED SPI_TIMODE_DISABLE +#define SPI_TIMODE_ENABLED SPI_TIMODE_ENABLE + +#define SPI_CRCCALCULATION_DISABLED SPI_CRCCALCULATION_DISABLE +#define SPI_CRCCALCULATION_ENABLED SPI_CRCCALCULATION_ENABLE + +#define SPI_NSS_PULSE_DISABLED SPI_NSS_PULSE_DISABLE +#define SPI_NSS_PULSE_ENABLED SPI_NSS_PULSE_ENABLE + +/** + * @} + */ + +/** @defgroup HAL_TIM_Aliased_Defines HAL TIM Aliased Defines maintained for legacy purpose + * @{ + */ +#define CCER_CCxE_MASK TIM_CCER_CCxE_MASK +#define CCER_CCxNE_MASK TIM_CCER_CCxNE_MASK + +#define TIM_DMABase_CR1 TIM_DMABASE_CR1 +#define TIM_DMABase_CR2 TIM_DMABASE_CR2 +#define TIM_DMABase_SMCR TIM_DMABASE_SMCR +#define TIM_DMABase_DIER TIM_DMABASE_DIER +#define TIM_DMABase_SR TIM_DMABASE_SR +#define TIM_DMABase_EGR TIM_DMABASE_EGR +#define TIM_DMABase_CCMR1 TIM_DMABASE_CCMR1 +#define TIM_DMABase_CCMR2 TIM_DMABASE_CCMR2 +#define TIM_DMABase_CCER TIM_DMABASE_CCER +#define TIM_DMABase_CNT TIM_DMABASE_CNT +#define TIM_DMABase_PSC TIM_DMABASE_PSC +#define TIM_DMABase_ARR TIM_DMABASE_ARR +#define TIM_DMABase_RCR TIM_DMABASE_RCR +#define TIM_DMABase_CCR1 TIM_DMABASE_CCR1 +#define TIM_DMABase_CCR2 TIM_DMABASE_CCR2 +#define TIM_DMABase_CCR3 TIM_DMABASE_CCR3 +#define TIM_DMABase_CCR4 TIM_DMABASE_CCR4 +#define TIM_DMABase_BDTR TIM_DMABASE_BDTR +#define TIM_DMABase_DCR TIM_DMABASE_DCR +#define TIM_DMABase_DMAR TIM_DMABASE_DMAR +#define TIM_DMABase_OR1 TIM_DMABASE_OR1 +#define TIM_DMABase_CCMR3 TIM_DMABASE_CCMR3 +#define TIM_DMABase_CCR5 TIM_DMABASE_CCR5 +#define TIM_DMABase_CCR6 TIM_DMABASE_CCR6 +#define TIM_DMABase_OR2 TIM_DMABASE_OR2 +#define TIM_DMABase_OR3 TIM_DMABASE_OR3 +#define TIM_DMABase_OR TIM_DMABASE_OR + +#define TIM_EventSource_Update TIM_EVENTSOURCE_UPDATE +#define TIM_EventSource_CC1 TIM_EVENTSOURCE_CC1 +#define TIM_EventSource_CC2 TIM_EVENTSOURCE_CC2 +#define TIM_EventSource_CC3 TIM_EVENTSOURCE_CC3 +#define TIM_EventSource_CC4 TIM_EVENTSOURCE_CC4 +#define TIM_EventSource_COM TIM_EVENTSOURCE_COM +#define TIM_EventSource_Trigger TIM_EVENTSOURCE_TRIGGER +#define TIM_EventSource_Break TIM_EVENTSOURCE_BREAK +#define TIM_EventSource_Break2 TIM_EVENTSOURCE_BREAK2 + +#define TIM_DMABurstLength_1Transfer TIM_DMABURSTLENGTH_1TRANSFER +#define TIM_DMABurstLength_2Transfers TIM_DMABURSTLENGTH_2TRANSFERS +#define TIM_DMABurstLength_3Transfers TIM_DMABURSTLENGTH_3TRANSFERS +#define TIM_DMABurstLength_4Transfers TIM_DMABURSTLENGTH_4TRANSFERS +#define TIM_DMABurstLength_5Transfers TIM_DMABURSTLENGTH_5TRANSFERS +#define TIM_DMABurstLength_6Transfers TIM_DMABURSTLENGTH_6TRANSFERS +#define TIM_DMABurstLength_7Transfers TIM_DMABURSTLENGTH_7TRANSFERS +#define TIM_DMABurstLength_8Transfers TIM_DMABURSTLENGTH_8TRANSFERS +#define TIM_DMABurstLength_9Transfers TIM_DMABURSTLENGTH_9TRANSFERS +#define TIM_DMABurstLength_10Transfers TIM_DMABURSTLENGTH_10TRANSFERS +#define TIM_DMABurstLength_11Transfers TIM_DMABURSTLENGTH_11TRANSFERS +#define TIM_DMABurstLength_12Transfers TIM_DMABURSTLENGTH_12TRANSFERS +#define TIM_DMABurstLength_13Transfers TIM_DMABURSTLENGTH_13TRANSFERS +#define TIM_DMABurstLength_14Transfers TIM_DMABURSTLENGTH_14TRANSFERS +#define TIM_DMABurstLength_15Transfers TIM_DMABURSTLENGTH_15TRANSFERS +#define TIM_DMABurstLength_16Transfers TIM_DMABURSTLENGTH_16TRANSFERS +#define TIM_DMABurstLength_17Transfers TIM_DMABURSTLENGTH_17TRANSFERS +#define TIM_DMABurstLength_18Transfers TIM_DMABURSTLENGTH_18TRANSFERS + +/** + * @} + */ + +/** @defgroup HAL_TSC_Aliased_Defines HAL TSC Aliased Defines maintained for legacy purpose + * @{ + */ +#define TSC_SYNC_POL_FALL TSC_SYNC_POLARITY_FALLING +#define TSC_SYNC_POL_RISE_HIGH TSC_SYNC_POLARITY_RISING +/** + * @} + */ + +/** @defgroup HAL_UART_Aliased_Defines HAL UART Aliased Defines maintained for legacy purpose + * @{ + */ +#define UART_ONEBIT_SAMPLING_DISABLED UART_ONE_BIT_SAMPLE_DISABLE +#define UART_ONEBIT_SAMPLING_ENABLED UART_ONE_BIT_SAMPLE_ENABLE +#define UART_ONE_BIT_SAMPLE_DISABLED UART_ONE_BIT_SAMPLE_DISABLE +#define UART_ONE_BIT_SAMPLE_ENABLED UART_ONE_BIT_SAMPLE_ENABLE + +#define __HAL_UART_ONEBIT_ENABLE __HAL_UART_ONE_BIT_SAMPLE_ENABLE +#define __HAL_UART_ONEBIT_DISABLE __HAL_UART_ONE_BIT_SAMPLE_DISABLE + +#define __DIV_SAMPLING16 UART_DIV_SAMPLING16 +#define __DIVMANT_SAMPLING16 UART_DIVMANT_SAMPLING16 +#define __DIVFRAQ_SAMPLING16 UART_DIVFRAQ_SAMPLING16 +#define __UART_BRR_SAMPLING16 UART_BRR_SAMPLING16 + +#define __DIV_SAMPLING8 UART_DIV_SAMPLING8 +#define __DIVMANT_SAMPLING8 UART_DIVMANT_SAMPLING8 +#define __DIVFRAQ_SAMPLING8 UART_DIVFRAQ_SAMPLING8 +#define __UART_BRR_SAMPLING8 UART_BRR_SAMPLING8 + +#define UART_WAKEUPMETHODE_IDLELINE UART_WAKEUPMETHOD_IDLELINE +#define UART_WAKEUPMETHODE_ADDRESSMARK UART_WAKEUPMETHOD_ADDRESSMARK + +/** + * @} + */ + + +/** @defgroup HAL_USART_Aliased_Defines HAL USART Aliased Defines maintained for legacy purpose + * @{ + */ + +#define USART_CLOCK_DISABLED USART_CLOCK_DISABLE +#define USART_CLOCK_ENABLED USART_CLOCK_ENABLE + +#define USARTNACK_ENABLED USART_NACK_ENABLE +#define USARTNACK_DISABLED USART_NACK_DISABLE +/** + * @} + */ + +/** @defgroup HAL_WWDG_Aliased_Defines HAL WWDG Aliased Defines maintained for legacy purpose + * @{ + */ +#define CFR_BASE WWDG_CFR_BASE + +/** + * @} + */ + +/** @defgroup HAL_CAN_Aliased_Defines HAL CAN Aliased Defines maintained for legacy purpose + * @{ + */ +#define CAN_FilterFIFO0 CAN_FILTER_FIFO0 +#define CAN_FilterFIFO1 CAN_FILTER_FIFO1 +#define CAN_IT_RQCP0 CAN_IT_TME +#define CAN_IT_RQCP1 CAN_IT_TME +#define CAN_IT_RQCP2 CAN_IT_TME +#define INAK_TIMEOUT CAN_TIMEOUT_VALUE +#define SLAK_TIMEOUT CAN_TIMEOUT_VALUE +#define CAN_TXSTATUS_FAILED ((uint8_t)0x00) +#define CAN_TXSTATUS_OK ((uint8_t)0x01) +#define CAN_TXSTATUS_PENDING ((uint8_t)0x02) + +/** + * @} + */ + +/** @defgroup HAL_ETH_Aliased_Defines HAL ETH Aliased Defines maintained for legacy purpose + * @{ + */ + +#define VLAN_TAG ETH_VLAN_TAG +#define MIN_ETH_PAYLOAD ETH_MIN_ETH_PAYLOAD +#define MAX_ETH_PAYLOAD ETH_MAX_ETH_PAYLOAD +#define JUMBO_FRAME_PAYLOAD ETH_JUMBO_FRAME_PAYLOAD +#define MACMIIAR_CR_MASK ETH_MACMIIAR_CR_MASK +#define MACCR_CLEAR_MASK ETH_MACCR_CLEAR_MASK +#define MACFCR_CLEAR_MASK ETH_MACFCR_CLEAR_MASK +#define DMAOMR_CLEAR_MASK ETH_DMAOMR_CLEAR_MASK + +#define ETH_MMCCR ((uint32_t)0x00000100) +#define ETH_MMCRIR ((uint32_t)0x00000104) +#define ETH_MMCTIR ((uint32_t)0x00000108) +#define ETH_MMCRIMR ((uint32_t)0x0000010C) +#define ETH_MMCTIMR ((uint32_t)0x00000110) +#define ETH_MMCTGFSCCR ((uint32_t)0x0000014C) +#define ETH_MMCTGFMSCCR ((uint32_t)0x00000150) +#define ETH_MMCTGFCR ((uint32_t)0x00000168) +#define ETH_MMCRFCECR ((uint32_t)0x00000194) +#define ETH_MMCRFAECR ((uint32_t)0x00000198) +#define ETH_MMCRGUFCR ((uint32_t)0x000001C4) + +/** + * @} + */ + +/** @defgroup HAL_PPP_Aliased_Defines HAL PPP Aliased Defines maintained for legacy purpose + * @{ + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup HAL_CRYP_Aliased_Functions HAL CRYP Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_CRYP_ComputationCpltCallback HAL_CRYPEx_ComputationCpltCallback +/** + * @} + */ + +/** @defgroup HAL_HASH_Aliased_Functions HAL HASH Aliased Functions maintained for legacy purpose + * @{ + */ + +#define HAL_HMAC_MD5_Finish HAL_HASH_MD5_Finish +#define HAL_HMAC_SHA1_Finish HAL_HASH_SHA1_Finish +#define HAL_HMAC_SHA224_Finish HAL_HASH_SHA224_Finish +#define HAL_HMAC_SHA256_Finish HAL_HASH_SHA256_Finish + +/*HASH Algorithm Selection*/ + +#define HASH_AlgoSelection_SHA1 HASH_ALGOSELECTION_SHA1 +#define HASH_AlgoSelection_SHA224 HASH_ALGOSELECTION_SHA224 +#define HASH_AlgoSelection_SHA256 HASH_ALGOSELECTION_SHA256 +#define HASH_AlgoSelection_MD5 HASH_ALGOSELECTION_MD5 + +#define HASH_AlgoMode_HASH HASH_ALGOMODE_HASH +#define HASH_AlgoMode_HMAC HASH_ALGOMODE_HMAC + +#define HASH_HMACKeyType_ShortKey HASH_HMAC_KEYTYPE_SHORTKEY +#define HASH_HMACKeyType_LongKey HASH_HMAC_KEYTYPE_LONGKEY +/** + * @} + */ + +/** @defgroup HAL_Aliased_Functions HAL Generic Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_EnableDBGSleepMode HAL_DBGMCU_EnableDBGSleepMode +#define HAL_DisableDBGSleepMode HAL_DBGMCU_DisableDBGSleepMode +#define HAL_EnableDBGStopMode HAL_DBGMCU_EnableDBGStopMode +#define HAL_DisableDBGStopMode HAL_DBGMCU_DisableDBGStopMode +#define HAL_EnableDBGStandbyMode HAL_DBGMCU_EnableDBGStandbyMode +#define HAL_DisableDBGStandbyMode HAL_DBGMCU_DisableDBGStandbyMode +#define HAL_DBG_LowPowerConfig(Periph, cmd) (((cmd)==ENABLE)? HAL_DBGMCU_DBG_EnableLowPowerConfig(Periph) : HAL_DBGMCU_DBG_DisableLowPowerConfig(Periph)) +#define HAL_VREFINT_OutputSelect HAL_SYSCFG_VREFINT_OutputSelect +#define HAL_Lock_Cmd(cmd) (((cmd)==ENABLE) ? HAL_SYSCFG_Enable_Lock_VREFINT() : HAL_SYSCFG_Disable_Lock_VREFINT()) +#define HAL_VREFINT_Cmd(cmd) (((cmd)==ENABLE)? HAL_SYSCFG_EnableVREFINT() : HAL_SYSCFG_DisableVREFINT()) +#define HAL_ADC_EnableBuffer_Cmd(cmd) (((cmd)==ENABLE) ? HAL_ADCEx_EnableVREFINT() : HAL_ADCEx_DisableVREFINT()) +#define HAL_ADC_EnableBufferSensor_Cmd(cmd) (((cmd)==ENABLE) ? HAL_ADCEx_EnableVREFINTTempSensor() : HAL_ADCEx_DisableVREFINTTempSensor()) +/** + * @} + */ + +/** @defgroup HAL_FLASH_Aliased_Functions HAL FLASH Aliased Functions maintained for legacy purpose + * @{ + */ +#define FLASH_HalfPageProgram HAL_FLASHEx_HalfPageProgram +#define FLASH_EnableRunPowerDown HAL_FLASHEx_EnableRunPowerDown +#define FLASH_DisableRunPowerDown HAL_FLASHEx_DisableRunPowerDown +#define HAL_DATA_EEPROMEx_Unlock HAL_FLASHEx_DATAEEPROM_Unlock +#define HAL_DATA_EEPROMEx_Lock HAL_FLASHEx_DATAEEPROM_Lock +#define HAL_DATA_EEPROMEx_Erase HAL_FLASHEx_DATAEEPROM_Erase +#define HAL_DATA_EEPROMEx_Program HAL_FLASHEx_DATAEEPROM_Program + + /** + * @} + */ + +/** @defgroup HAL_I2C_Aliased_Functions HAL I2C Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_I2CEx_AnalogFilter_Config HAL_I2CEx_ConfigAnalogFilter +#define HAL_I2CEx_DigitalFilter_Config HAL_I2CEx_ConfigDigitalFilter + +#define HAL_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus, cmd) (((cmd)==ENABLE)? HAL_I2CEx_EnableFastModePlus(SYSCFG_I2CFastModePlus): HAL_I2CEx_DisableFastModePlus(SYSCFG_I2CFastModePlus)) + /** + * @} + */ + +/** @defgroup HAL_PWR_Aliased HAL PWR Aliased maintained for legacy purpose + * @{ + */ +#define HAL_PWR_PVDConfig HAL_PWR_ConfigPVD +#define HAL_PWR_DisableBkUpReg HAL_PWREx_DisableBkUpReg +#define HAL_PWR_DisableFlashPowerDown HAL_PWREx_DisableFlashPowerDown +#define HAL_PWR_DisableVddio2Monitor HAL_PWREx_DisableVddio2Monitor +#define HAL_PWR_EnableBkUpReg HAL_PWREx_EnableBkUpReg +#define HAL_PWR_EnableFlashPowerDown HAL_PWREx_EnableFlashPowerDown +#define HAL_PWR_EnableVddio2Monitor HAL_PWREx_EnableVddio2Monitor +#define HAL_PWR_PVD_PVM_IRQHandler HAL_PWREx_PVD_PVM_IRQHandler +#define HAL_PWR_PVDLevelConfig HAL_PWR_ConfigPVD +#define HAL_PWR_Vddio2Monitor_IRQHandler HAL_PWREx_Vddio2Monitor_IRQHandler +#define HAL_PWR_Vddio2MonitorCallback HAL_PWREx_Vddio2MonitorCallback +#define HAL_PWREx_ActivateOverDrive HAL_PWREx_EnableOverDrive +#define HAL_PWREx_DeactivateOverDrive HAL_PWREx_DisableOverDrive +#define HAL_PWREx_DisableSDADCAnalog HAL_PWREx_DisableSDADC +#define HAL_PWREx_EnableSDADCAnalog HAL_PWREx_EnableSDADC +#define HAL_PWREx_PVMConfig HAL_PWREx_ConfigPVM + +#define PWR_MODE_NORMAL PWR_PVD_MODE_NORMAL +#define PWR_MODE_IT_RISING PWR_PVD_MODE_IT_RISING +#define PWR_MODE_IT_FALLING PWR_PVD_MODE_IT_FALLING +#define PWR_MODE_IT_RISING_FALLING PWR_PVD_MODE_IT_RISING_FALLING +#define PWR_MODE_EVENT_RISING PWR_PVD_MODE_EVENT_RISING +#define PWR_MODE_EVENT_FALLING PWR_PVD_MODE_EVENT_FALLING +#define PWR_MODE_EVENT_RISING_FALLING PWR_PVD_MODE_EVENT_RISING_FALLING + +#define CR_OFFSET_BB PWR_CR_OFFSET_BB +#define CSR_OFFSET_BB PWR_CSR_OFFSET_BB + +#define DBP_BitNumber DBP_BIT_NUMBER +#define PVDE_BitNumber PVDE_BIT_NUMBER +#define PMODE_BitNumber PMODE_BIT_NUMBER +#define EWUP_BitNumber EWUP_BIT_NUMBER +#define FPDS_BitNumber FPDS_BIT_NUMBER +#define ODEN_BitNumber ODEN_BIT_NUMBER +#define ODSWEN_BitNumber ODSWEN_BIT_NUMBER +#define MRLVDS_BitNumber MRLVDS_BIT_NUMBER +#define LPLVDS_BitNumber LPLVDS_BIT_NUMBER +#define BRE_BitNumber BRE_BIT_NUMBER + +#define PWR_MODE_EVT PWR_PVD_MODE_NORMAL + + /** + * @} + */ + +/** @defgroup HAL_SMBUS_Aliased_Functions HAL SMBUS Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_SMBUS_Slave_Listen_IT HAL_SMBUS_EnableListen_IT +#define HAL_SMBUS_SlaveAddrCallback HAL_SMBUS_AddrCallback +#define HAL_SMBUS_SlaveListenCpltCallback HAL_SMBUS_ListenCpltCallback +/** + * @} + */ + +/** @defgroup HAL_SPI_Aliased_Functions HAL SPI Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_SPI_FlushRxFifo HAL_SPIEx_FlushRxFifo +/** + * @} + */ + +/** @defgroup HAL_TIM_Aliased_Functions HAL TIM Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_TIM_DMADelayPulseCplt TIM_DMADelayPulseCplt +#define HAL_TIM_DMAError TIM_DMAError +#define HAL_TIM_DMACaptureCplt TIM_DMACaptureCplt +#define HAL_TIMEx_DMACommutationCplt TIMEx_DMACommutationCplt +/** + * @} + */ + +/** @defgroup HAL_UART_Aliased_Functions HAL UART Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_UART_WakeupCallback HAL_UARTEx_WakeupCallback +/** + * @} + */ + +/** @defgroup HAL_LTDC_Aliased_Functions HAL LTDC Aliased Functions maintained for legacy purpose + * @{ + */ +#define HAL_LTDC_LineEvenCallback HAL_LTDC_LineEventCallback +/** + * @} + */ + + + /** @defgroup HAL_PPP_Aliased_Functions HAL PPP Aliased Functions maintained for legacy purpose + * @{ + */ + +/** + * @} + */ + +/* Exported macros ------------------------------------------------------------*/ + +/** @defgroup HAL_AES_Aliased_Macros HAL CRYP Aliased Macros maintained for legacy purpose + * @{ + */ +#define AES_IT_CC CRYP_IT_CC +#define AES_IT_ERR CRYP_IT_ERR +#define AES_FLAG_CCF CRYP_FLAG_CCF +/** + * @} + */ + +/** @defgroup HAL_Aliased_Macros HAL Generic Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_GET_BOOT_MODE __HAL_SYSCFG_GET_BOOT_MODE +#define __HAL_REMAPMEMORY_FLASH __HAL_SYSCFG_REMAPMEMORY_FLASH +#define __HAL_REMAPMEMORY_SYSTEMFLASH __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH +#define __HAL_REMAPMEMORY_SRAM __HAL_SYSCFG_REMAPMEMORY_SRAM +#define __HAL_REMAPMEMORY_FMC __HAL_SYSCFG_REMAPMEMORY_FMC +#define __HAL_REMAPMEMORY_FMC_SDRAM __HAL_SYSCFG_REMAPMEMORY_FMC_SDRAM +#define __HAL_REMAPMEMORY_FSMC __HAL_SYSCFG_REMAPMEMORY_FSMC +#define __HAL_REMAPMEMORY_QUADSPI __HAL_SYSCFG_REMAPMEMORY_QUADSPI +#define __HAL_FMC_BANK __HAL_SYSCFG_FMC_BANK +#define __HAL_GET_FLAG __HAL_SYSCFG_GET_FLAG +#define __HAL_CLEAR_FLAG __HAL_SYSCFG_CLEAR_FLAG +#define __HAL_VREFINT_OUT_ENABLE __HAL_SYSCFG_VREFINT_OUT_ENABLE +#define __HAL_VREFINT_OUT_DISABLE __HAL_SYSCFG_VREFINT_OUT_DISABLE + +#define SYSCFG_FLAG_VREF_READY SYSCFG_FLAG_VREFINT_READY +#define SYSCFG_FLAG_RC48 RCC_FLAG_HSI48 +#define IS_SYSCFG_FASTMODEPLUS_CONFIG IS_I2C_FASTMODEPLUS +#define UFB_MODE_BitNumber UFB_MODE_BIT_NUMBER +#define CMP_PD_BitNumber CMP_PD_BIT_NUMBER + +/** + * @} + */ + + +/** @defgroup HAL_ADC_Aliased_Macros HAL ADC Aliased Macros maintained for legacy purpose + * @{ + */ +#define __ADC_ENABLE __HAL_ADC_ENABLE +#define __ADC_DISABLE __HAL_ADC_DISABLE +#define __HAL_ADC_ENABLING_CONDITIONS ADC_ENABLING_CONDITIONS +#define __HAL_ADC_DISABLING_CONDITIONS ADC_DISABLING_CONDITIONS +#define __HAL_ADC_IS_ENABLED ADC_IS_ENABLE +#define __ADC_IS_ENABLED ADC_IS_ENABLE +#define __HAL_ADC_IS_SOFTWARE_START_REGULAR ADC_IS_SOFTWARE_START_REGULAR +#define __HAL_ADC_IS_SOFTWARE_START_INJECTED ADC_IS_SOFTWARE_START_INJECTED +#define __HAL_ADC_IS_CONVERSION_ONGOING_REGULAR_INJECTED ADC_IS_CONVERSION_ONGOING_REGULAR_INJECTED +#define __HAL_ADC_IS_CONVERSION_ONGOING_REGULAR ADC_IS_CONVERSION_ONGOING_REGULAR +#define __HAL_ADC_IS_CONVERSION_ONGOING_INJECTED ADC_IS_CONVERSION_ONGOING_INJECTED +#define __HAL_ADC_IS_CONVERSION_ONGOING ADC_IS_CONVERSION_ONGOING +#define __HAL_ADC_CLEAR_ERRORCODE ADC_CLEAR_ERRORCODE + +#define __HAL_ADC_GET_RESOLUTION ADC_GET_RESOLUTION +#define __HAL_ADC_JSQR_RK ADC_JSQR_RK +#define __HAL_ADC_CFGR_AWD1CH ADC_CFGR_AWD1CH_SHIFT +#define __HAL_ADC_CFGR_AWD23CR ADC_CFGR_AWD23CR +#define __HAL_ADC_CFGR_INJECT_AUTO_CONVERSION ADC_CFGR_INJECT_AUTO_CONVERSION +#define __HAL_ADC_CFGR_INJECT_CONTEXT_QUEUE ADC_CFGR_INJECT_CONTEXT_QUEUE +#define __HAL_ADC_CFGR_INJECT_DISCCONTINUOUS ADC_CFGR_INJECT_DISCCONTINUOUS +#define __HAL_ADC_CFGR_REG_DISCCONTINUOUS ADC_CFGR_REG_DISCCONTINUOUS +#define __HAL_ADC_CFGR_DISCONTINUOUS_NUM ADC_CFGR_DISCONTINUOUS_NUM +#define __HAL_ADC_CFGR_AUTOWAIT ADC_CFGR_AUTOWAIT +#define __HAL_ADC_CFGR_CONTINUOUS ADC_CFGR_CONTINUOUS +#define __HAL_ADC_CFGR_OVERRUN ADC_CFGR_OVERRUN +#define __HAL_ADC_CFGR_DMACONTREQ ADC_CFGR_DMACONTREQ +#define __HAL_ADC_CFGR_EXTSEL ADC_CFGR_EXTSEL_SET +#define __HAL_ADC_JSQR_JEXTSEL ADC_JSQR_JEXTSEL_SET +#define __HAL_ADC_OFR_CHANNEL ADC_OFR_CHANNEL +#define __HAL_ADC_DIFSEL_CHANNEL ADC_DIFSEL_CHANNEL +#define __HAL_ADC_CALFACT_DIFF_SET ADC_CALFACT_DIFF_SET +#define __HAL_ADC_CALFACT_DIFF_GET ADC_CALFACT_DIFF_GET +#define __HAL_ADC_TRX_HIGHTHRESHOLD ADC_TRX_HIGHTHRESHOLD + +#define __HAL_ADC_OFFSET_SHIFT_RESOLUTION ADC_OFFSET_SHIFT_RESOLUTION +#define __HAL_ADC_AWD1THRESHOLD_SHIFT_RESOLUTION ADC_AWD1THRESHOLD_SHIFT_RESOLUTION +#define __HAL_ADC_AWD23THRESHOLD_SHIFT_RESOLUTION ADC_AWD23THRESHOLD_SHIFT_RESOLUTION +#define __HAL_ADC_COMMON_REGISTER ADC_COMMON_REGISTER +#define __HAL_ADC_COMMON_CCR_MULTI ADC_COMMON_CCR_MULTI +#define __HAL_ADC_MULTIMODE_IS_ENABLED ADC_MULTIMODE_IS_ENABLE +#define __ADC_MULTIMODE_IS_ENABLED ADC_MULTIMODE_IS_ENABLE +#define __HAL_ADC_NONMULTIMODE_OR_MULTIMODEMASTER ADC_NONMULTIMODE_OR_MULTIMODEMASTER +#define __HAL_ADC_COMMON_ADC_OTHER ADC_COMMON_ADC_OTHER +#define __HAL_ADC_MULTI_SLAVE ADC_MULTI_SLAVE + +#define __HAL_ADC_SQR1_L ADC_SQR1_L_SHIFT +#define __HAL_ADC_JSQR_JL ADC_JSQR_JL_SHIFT +#define __HAL_ADC_JSQR_RK_JL ADC_JSQR_RK_JL +#define __HAL_ADC_CR1_DISCONTINUOUS_NUM ADC_CR1_DISCONTINUOUS_NUM +#define __HAL_ADC_CR1_SCAN ADC_CR1_SCAN_SET +#define __HAL_ADC_CONVCYCLES_MAX_RANGE ADC_CONVCYCLES_MAX_RANGE +#define __HAL_ADC_CLOCK_PRESCALER_RANGE ADC_CLOCK_PRESCALER_RANGE +#define __HAL_ADC_GET_CLOCK_PRESCALER ADC_GET_CLOCK_PRESCALER + +#define __HAL_ADC_SQR1 ADC_SQR1 +#define __HAL_ADC_SMPR1 ADC_SMPR1 +#define __HAL_ADC_SMPR2 ADC_SMPR2 +#define __HAL_ADC_SQR3_RK ADC_SQR3_RK +#define __HAL_ADC_SQR2_RK ADC_SQR2_RK +#define __HAL_ADC_SQR1_RK ADC_SQR1_RK +#define __HAL_ADC_CR2_CONTINUOUS ADC_CR2_CONTINUOUS +#define __HAL_ADC_CR1_DISCONTINUOUS ADC_CR1_DISCONTINUOUS +#define __HAL_ADC_CR1_SCANCONV ADC_CR1_SCANCONV +#define __HAL_ADC_CR2_EOCSelection ADC_CR2_EOCSelection +#define __HAL_ADC_CR2_DMAContReq ADC_CR2_DMAContReq +#define __HAL_ADC_GET_RESOLUTION ADC_GET_RESOLUTION +#define __HAL_ADC_JSQR ADC_JSQR + +#define __HAL_ADC_CHSELR_CHANNEL ADC_CHSELR_CHANNEL +#define __HAL_ADC_CFGR1_REG_DISCCONTINUOUS ADC_CFGR1_REG_DISCCONTINUOUS +#define __HAL_ADC_CFGR1_AUTOOFF ADC_CFGR1_AUTOOFF +#define __HAL_ADC_CFGR1_AUTOWAIT ADC_CFGR1_AUTOWAIT +#define __HAL_ADC_CFGR1_CONTINUOUS ADC_CFGR1_CONTINUOUS +#define __HAL_ADC_CFGR1_OVERRUN ADC_CFGR1_OVERRUN +#define __HAL_ADC_CFGR1_SCANDIR ADC_CFGR1_SCANDIR +#define __HAL_ADC_CFGR1_DMACONTREQ ADC_CFGR1_DMACONTREQ + +/** + * @} + */ + +/** @defgroup HAL_DAC_Aliased_Macros HAL DAC Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_DHR12R1_ALIGNEMENT DAC_DHR12R1_ALIGNMENT +#define __HAL_DHR12R2_ALIGNEMENT DAC_DHR12R2_ALIGNMENT +#define __HAL_DHR12RD_ALIGNEMENT DAC_DHR12RD_ALIGNMENT +#define IS_DAC_GENERATE_WAVE IS_DAC_WAVE + +/** + * @} + */ + +/** @defgroup HAL_DBGMCU_Aliased_Macros HAL DBGMCU Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_FREEZE_TIM1_DBGMCU __HAL_DBGMCU_FREEZE_TIM1 +#define __HAL_UNFREEZE_TIM1_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM1 +#define __HAL_FREEZE_TIM2_DBGMCU __HAL_DBGMCU_FREEZE_TIM2 +#define __HAL_UNFREEZE_TIM2_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM2 +#define __HAL_FREEZE_TIM3_DBGMCU __HAL_DBGMCU_FREEZE_TIM3 +#define __HAL_UNFREEZE_TIM3_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM3 +#define __HAL_FREEZE_TIM4_DBGMCU __HAL_DBGMCU_FREEZE_TIM4 +#define __HAL_UNFREEZE_TIM4_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM4 +#define __HAL_FREEZE_TIM5_DBGMCU __HAL_DBGMCU_FREEZE_TIM5 +#define __HAL_UNFREEZE_TIM5_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM5 +#define __HAL_FREEZE_TIM6_DBGMCU __HAL_DBGMCU_FREEZE_TIM6 +#define __HAL_UNFREEZE_TIM6_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM6 +#define __HAL_FREEZE_TIM7_DBGMCU __HAL_DBGMCU_FREEZE_TIM7 +#define __HAL_UNFREEZE_TIM7_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM7 +#define __HAL_FREEZE_TIM8_DBGMCU __HAL_DBGMCU_FREEZE_TIM8 +#define __HAL_UNFREEZE_TIM8_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM8 + +#define __HAL_FREEZE_TIM9_DBGMCU __HAL_DBGMCU_FREEZE_TIM9 +#define __HAL_UNFREEZE_TIM9_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM9 +#define __HAL_FREEZE_TIM10_DBGMCU __HAL_DBGMCU_FREEZE_TIM10 +#define __HAL_UNFREEZE_TIM10_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM10 +#define __HAL_FREEZE_TIM11_DBGMCU __HAL_DBGMCU_FREEZE_TIM11 +#define __HAL_UNFREEZE_TIM11_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM11 +#define __HAL_FREEZE_TIM12_DBGMCU __HAL_DBGMCU_FREEZE_TIM12 +#define __HAL_UNFREEZE_TIM12_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM12 +#define __HAL_FREEZE_TIM13_DBGMCU __HAL_DBGMCU_FREEZE_TIM13 +#define __HAL_UNFREEZE_TIM13_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM13 +#define __HAL_FREEZE_TIM14_DBGMCU __HAL_DBGMCU_FREEZE_TIM14 +#define __HAL_UNFREEZE_TIM14_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM14 +#define __HAL_FREEZE_CAN2_DBGMCU __HAL_DBGMCU_FREEZE_CAN2 +#define __HAL_UNFREEZE_CAN2_DBGMCU __HAL_DBGMCU_UNFREEZE_CAN2 + + +#define __HAL_FREEZE_TIM15_DBGMCU __HAL_DBGMCU_FREEZE_TIM15 +#define __HAL_UNFREEZE_TIM15_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM15 +#define __HAL_FREEZE_TIM16_DBGMCU __HAL_DBGMCU_FREEZE_TIM16 +#define __HAL_UNFREEZE_TIM16_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM16 +#define __HAL_FREEZE_TIM17_DBGMCU __HAL_DBGMCU_FREEZE_TIM17 +#define __HAL_UNFREEZE_TIM17_DBGMCU __HAL_DBGMCU_UNFREEZE_TIM17 +#define __HAL_FREEZE_RTC_DBGMCU __HAL_DBGMCU_FREEZE_RTC +#define __HAL_UNFREEZE_RTC_DBGMCU __HAL_DBGMCU_UNFREEZE_RTC +#define __HAL_FREEZE_WWDG_DBGMCU __HAL_DBGMCU_FREEZE_WWDG +#define __HAL_UNFREEZE_WWDG_DBGMCU __HAL_DBGMCU_UNFREEZE_WWDG +#define __HAL_FREEZE_IWDG_DBGMCU __HAL_DBGMCU_FREEZE_IWDG +#define __HAL_UNFREEZE_IWDG_DBGMCU __HAL_DBGMCU_UNFREEZE_IWDG +#define __HAL_FREEZE_I2C1_TIMEOUT_DBGMCU __HAL_DBGMCU_FREEZE_I2C1_TIMEOUT +#define __HAL_UNFREEZE_I2C1_TIMEOUT_DBGMCU __HAL_DBGMCU_UNFREEZE_I2C1_TIMEOUT +#define __HAL_FREEZE_I2C2_TIMEOUT_DBGMCU __HAL_DBGMCU_FREEZE_I2C2_TIMEOUT +#define __HAL_UNFREEZE_I2C2_TIMEOUT_DBGMCU __HAL_DBGMCU_UNFREEZE_I2C2_TIMEOUT +#define __HAL_FREEZE_I2C3_TIMEOUT_DBGMCU __HAL_DBGMCU_FREEZE_I2C3_TIMEOUT +#define __HAL_UNFREEZE_I2C3_TIMEOUT_DBGMCU __HAL_DBGMCU_UNFREEZE_I2C3_TIMEOUT +#define __HAL_FREEZE_CAN1_DBGMCU __HAL_DBGMCU_FREEZE_CAN1 +#define __HAL_UNFREEZE_CAN1_DBGMCU __HAL_DBGMCU_UNFREEZE_CAN1 +#define __HAL_FREEZE_LPTIM1_DBGMCU __HAL_DBGMCU_FREEZE_LPTIM1 +#define __HAL_UNFREEZE_LPTIM1_DBGMCU __HAL_DBGMCU_UNFREEZE_LPTIM1 +#define __HAL_FREEZE_LPTIM2_DBGMCU __HAL_DBGMCU_FREEZE_LPTIM2 +#define __HAL_UNFREEZE_LPTIM2_DBGMCU __HAL_DBGMCU_UNFREEZE_LPTIM2 + +/** + * @} + */ + +/** @defgroup HAL_COMP_Aliased_Macros HAL COMP Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_COMP_EXTI_RISING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_RISING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_ENABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_RISING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_RISING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_DISABLE_RISING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_ENABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_ENABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_FALLING_IT_DISABLE(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_FALLING_EDGE() : \ + __HAL_COMP_COMP2_EXTI_DISABLE_FALLING_EDGE()) +#define __HAL_COMP_EXTI_ENABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_ENABLE_IT() : \ + __HAL_COMP_COMP2_EXTI_ENABLE_IT()) +#define __HAL_COMP_EXTI_DISABLE_IT(__EXTILINE__) (((__EXTILINE__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_DISABLE_IT() : \ + __HAL_COMP_COMP2_EXTI_DISABLE_IT()) +#define __HAL_COMP_EXTI_GET_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_GET_FLAG() : \ + __HAL_COMP_COMP2_EXTI_GET_FLAG()) +#define __HAL_COMP_EXTI_CLEAR_FLAG(__FLAG__) (((__FLAG__) == COMP_EXTI_LINE_COMP1) ? __HAL_COMP_COMP1_EXTI_CLEAR_FLAG() : \ + __HAL_COMP_COMP2_EXTI_CLEAR_FLAG()) +#define __HAL_COMP_GET_EXTI_LINE COMP_GET_EXTI_LINE + +/** + * @} + */ + +/** @defgroup HAL_DAC_Aliased_Macros HAL DAC Aliased Macros maintained for legacy purpose + * @{ + */ + +#define IS_DAC_WAVE(WAVE) (((WAVE) == DAC_WAVE_NONE) || \ + ((WAVE) == DAC_WAVE_NOISE)|| \ + ((WAVE) == DAC_WAVE_TRIANGLE)) + +/** + * @} + */ + +/** @defgroup HAL_FLASH_Aliased_Macros HAL FLASH Aliased Macros maintained for legacy purpose + * @{ + */ + +#define IS_WRPAREA IS_OB_WRPAREA +#define IS_TYPEPROGRAM IS_FLASH_TYPEPROGRAM +#define IS_TYPEPROGRAMFLASH IS_FLASH_TYPEPROGRAM +#define IS_TYPEERASE IS_FLASH_TYPEERASE +#define IS_NBSECTORS IS_FLASH_NBSECTORS +#define IS_OB_WDG_SOURCE IS_OB_IWDG_SOURCE + +/** + * @} + */ + +/** @defgroup HAL_I2C_Aliased_Macros HAL I2C Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_I2C_RESET_CR2 I2C_RESET_CR2 +#define __HAL_I2C_GENERATE_START I2C_GENERATE_START +#define __HAL_I2C_FREQ_RANGE I2C_FREQ_RANGE +#define __HAL_I2C_RISE_TIME I2C_RISE_TIME +#define __HAL_I2C_SPEED_STANDARD I2C_SPEED_STANDARD +#define __HAL_I2C_SPEED_FAST I2C_SPEED_FAST +#define __HAL_I2C_SPEED I2C_SPEED +#define __HAL_I2C_7BIT_ADD_WRITE I2C_7BIT_ADD_WRITE +#define __HAL_I2C_7BIT_ADD_READ I2C_7BIT_ADD_READ +#define __HAL_I2C_10BIT_ADDRESS I2C_10BIT_ADDRESS +#define __HAL_I2C_10BIT_HEADER_WRITE I2C_10BIT_HEADER_WRITE +#define __HAL_I2C_10BIT_HEADER_READ I2C_10BIT_HEADER_READ +#define __HAL_I2C_MEM_ADD_MSB I2C_MEM_ADD_MSB +#define __HAL_I2C_MEM_ADD_LSB I2C_MEM_ADD_LSB +#define __HAL_I2C_FREQRANGE I2C_FREQRANGE +/** + * @} + */ + +/** @defgroup HAL_I2S_Aliased_Macros HAL I2S Aliased Macros maintained for legacy purpose + * @{ + */ + +#define IS_I2S_INSTANCE IS_I2S_ALL_INSTANCE +#define IS_I2S_INSTANCE_EXT IS_I2S_ALL_INSTANCE_EXT + +/** + * @} + */ + +/** @defgroup HAL_IRDA_Aliased_Macros HAL IRDA Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __IRDA_DISABLE __HAL_IRDA_DISABLE +#define __IRDA_ENABLE __HAL_IRDA_ENABLE + +#define __HAL_IRDA_GETCLOCKSOURCE IRDA_GETCLOCKSOURCE +#define __HAL_IRDA_MASK_COMPUTATION IRDA_MASK_COMPUTATION +#define __IRDA_GETCLOCKSOURCE IRDA_GETCLOCKSOURCE +#define __IRDA_MASK_COMPUTATION IRDA_MASK_COMPUTATION + +#define IS_IRDA_ONEBIT_SAMPLE IS_IRDA_ONE_BIT_SAMPLE + + +/** + * @} + */ + + +/** @defgroup HAL_IWDG_Aliased_Macros HAL IWDG Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_IWDG_ENABLE_WRITE_ACCESS IWDG_ENABLE_WRITE_ACCESS +#define __HAL_IWDG_DISABLE_WRITE_ACCESS IWDG_DISABLE_WRITE_ACCESS +/** + * @} + */ + + +/** @defgroup HAL_LPTIM_Aliased_Macros HAL LPTIM Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_LPTIM_ENABLE_INTERRUPT __HAL_LPTIM_ENABLE_IT +#define __HAL_LPTIM_DISABLE_INTERRUPT __HAL_LPTIM_DISABLE_IT +#define __HAL_LPTIM_GET_ITSTATUS __HAL_LPTIM_GET_IT_SOURCE + +/** + * @} + */ + + +/** @defgroup HAL_OPAMP_Aliased_Macros HAL OPAMP Aliased Macros maintained for legacy purpose + * @{ + */ +#define __OPAMP_CSR_OPAXPD OPAMP_CSR_OPAXPD +#define __OPAMP_CSR_S3SELX OPAMP_CSR_S3SELX +#define __OPAMP_CSR_S4SELX OPAMP_CSR_S4SELX +#define __OPAMP_CSR_S5SELX OPAMP_CSR_S5SELX +#define __OPAMP_CSR_S6SELX OPAMP_CSR_S6SELX +#define __OPAMP_CSR_OPAXCAL_L OPAMP_CSR_OPAXCAL_L +#define __OPAMP_CSR_OPAXCAL_H OPAMP_CSR_OPAXCAL_H +#define __OPAMP_CSR_OPAXLPM OPAMP_CSR_OPAXLPM +#define __OPAMP_CSR_ALL_SWITCHES OPAMP_CSR_ALL_SWITCHES +#define __OPAMP_CSR_ANAWSELX OPAMP_CSR_ANAWSELX +#define __OPAMP_CSR_OPAXCALOUT OPAMP_CSR_OPAXCALOUT +#define __OPAMP_OFFSET_TRIM_BITSPOSITION OPAMP_OFFSET_TRIM_BITSPOSITION +#define __OPAMP_OFFSET_TRIM_SET OPAMP_OFFSET_TRIM_SET + +/** + * @} + */ + + +/** @defgroup HAL_PWR_Aliased_Macros HAL PWR Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_PVD_EVENT_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_EVENT +#define __HAL_PVD_EVENT_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_EVENT +#define __HAL_PVD_EXTI_FALLINGTRIGGER_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE +#define __HAL_PVD_EXTI_FALLINGTRIGGER_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE +#define __HAL_PVD_EXTI_RISINGTRIGGER_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE +#define __HAL_PVD_EXTI_RISINGTRIGGER_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE +#define __HAL_PVM_EVENT_DISABLE __HAL_PWR_PVM_EVENT_DISABLE +#define __HAL_PVM_EVENT_ENABLE __HAL_PWR_PVM_EVENT_ENABLE +#define __HAL_PVM_EXTI_FALLINGTRIGGER_DISABLE __HAL_PWR_PVM_EXTI_FALLINGTRIGGER_DISABLE +#define __HAL_PVM_EXTI_FALLINGTRIGGER_ENABLE __HAL_PWR_PVM_EXTI_FALLINGTRIGGER_ENABLE +#define __HAL_PVM_EXTI_RISINGTRIGGER_DISABLE __HAL_PWR_PVM_EXTI_RISINGTRIGGER_DISABLE +#define __HAL_PVM_EXTI_RISINGTRIGGER_ENABLE __HAL_PWR_PVM_EXTI_RISINGTRIGGER_ENABLE +#define __HAL_PWR_INTERNALWAKEUP_DISABLE HAL_PWREx_DisableInternalWakeUpLine +#define __HAL_PWR_INTERNALWAKEUP_ENABLE HAL_PWREx_EnableInternalWakeUpLine +#define __HAL_PWR_PULL_UP_DOWN_CONFIG_DISABLE HAL_PWREx_DisablePullUpPullDownConfig +#define __HAL_PWR_PULL_UP_DOWN_CONFIG_ENABLE HAL_PWREx_EnablePullUpPullDownConfig +#define __HAL_PWR_PVD_EXTI_CLEAR_EGDE_TRIGGER() __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();__HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE() +#define __HAL_PWR_PVD_EXTI_EVENT_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_EVENT +#define __HAL_PWR_PVD_EXTI_EVENT_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_EVENT +#define __HAL_PWR_PVD_EXTI_FALLINGTRIGGER_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE +#define __HAL_PWR_PVD_EXTI_FALLINGTRIGGER_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE +#define __HAL_PWR_PVD_EXTI_RISINGTRIGGER_DISABLE __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE +#define __HAL_PWR_PVD_EXTI_RISINGTRIGGER_ENABLE __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE +#define __HAL_PWR_PVD_EXTI_SET_FALLING_EGDE_TRIGGER __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE +#define __HAL_PWR_PVD_EXTI_SET_RISING_EDGE_TRIGGER __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE +#define __HAL_PWR_PVM_DISABLE() HAL_PWREx_DisablePVM1();HAL_PWREx_DisablePVM2();HAL_PWREx_DisablePVM3();HAL_PWREx_DisablePVM4() +#define __HAL_PWR_PVM_ENABLE() HAL_PWREx_EnablePVM1();HAL_PWREx_EnablePVM2();HAL_PWREx_EnablePVM3();HAL_PWREx_EnablePVM4() +#define __HAL_PWR_SRAM2CONTENT_PRESERVE_DISABLE HAL_PWREx_DisableSRAM2ContentRetention +#define __HAL_PWR_SRAM2CONTENT_PRESERVE_ENABLE HAL_PWREx_EnableSRAM2ContentRetention +#define __HAL_PWR_VDDIO2_DISABLE HAL_PWREx_DisableVddIO2 +#define __HAL_PWR_VDDIO2_ENABLE HAL_PWREx_EnableVddIO2 +#define __HAL_PWR_VDDIO2_EXTI_CLEAR_EGDE_TRIGGER __HAL_PWR_VDDIO2_EXTI_DISABLE_FALLING_EDGE +#define __HAL_PWR_VDDIO2_EXTI_SET_FALLING_EGDE_TRIGGER __HAL_PWR_VDDIO2_EXTI_ENABLE_FALLING_EDGE +#define __HAL_PWR_VDDUSB_DISABLE HAL_PWREx_DisableVddUSB +#define __HAL_PWR_VDDUSB_ENABLE HAL_PWREx_EnableVddUSB + +#if defined (STM32F4) +#define __HAL_PVD_EXTI_ENABLE_IT(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_ENABLE_IT() +#define __HAL_PVD_EXTI_DISABLE_IT(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_DISABLE_IT() +#define __HAL_PVD_EXTI_GET_FLAG(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_GET_FLAG() +#define __HAL_PVD_EXTI_CLEAR_FLAG(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_CLEAR_FLAG() +#define __HAL_PVD_EXTI_GENERATE_SWIT(PWR_EXTI_LINE_PVD) __HAL_PWR_PVD_EXTI_GENERATE_SWIT() +#else +#define __HAL_PVD_EXTI_CLEAR_FLAG __HAL_PWR_PVD_EXTI_CLEAR_FLAG +#define __HAL_PVD_EXTI_DISABLE_IT __HAL_PWR_PVD_EXTI_DISABLE_IT +#define __HAL_PVD_EXTI_ENABLE_IT __HAL_PWR_PVD_EXTI_ENABLE_IT +#define __HAL_PVD_EXTI_GENERATE_SWIT __HAL_PWR_PVD_EXTI_GENERATE_SWIT +#define __HAL_PVD_EXTI_GET_FLAG __HAL_PWR_PVD_EXTI_GET_FLAG +#endif /* STM32F4 */ +/** + * @} + */ + + +/** @defgroup HAL_RCC_Aliased HAL RCC Aliased maintained for legacy purpose + * @{ + */ + +#define RCC_StopWakeUpClock_MSI RCC_STOP_WAKEUPCLOCK_MSI +#define RCC_StopWakeUpClock_HSI RCC_STOP_WAKEUPCLOCK_HSI + +#define HAL_RCC_CCSCallback HAL_RCC_CSSCallback +#define HAL_RC48_EnableBuffer_Cmd(cmd) (((cmd)==ENABLE) ? HAL_RCCEx_EnableHSI48_VREFINT() : HAL_RCCEx_DisableHSI48_VREFINT()) + +#define __ADC_CLK_DISABLE __HAL_RCC_ADC_CLK_DISABLE +#define __ADC_CLK_ENABLE __HAL_RCC_ADC_CLK_ENABLE +#define __ADC_CLK_SLEEP_DISABLE __HAL_RCC_ADC_CLK_SLEEP_DISABLE +#define __ADC_CLK_SLEEP_ENABLE __HAL_RCC_ADC_CLK_SLEEP_ENABLE +#define __ADC_FORCE_RESET __HAL_RCC_ADC_FORCE_RESET +#define __ADC_RELEASE_RESET __HAL_RCC_ADC_RELEASE_RESET +#define __ADC1_CLK_DISABLE __HAL_RCC_ADC1_CLK_DISABLE +#define __ADC1_CLK_ENABLE __HAL_RCC_ADC1_CLK_ENABLE +#define __ADC1_FORCE_RESET __HAL_RCC_ADC1_FORCE_RESET +#define __ADC1_RELEASE_RESET __HAL_RCC_ADC1_RELEASE_RESET +#define __ADC1_CLK_SLEEP_ENABLE __HAL_RCC_ADC1_CLK_SLEEP_ENABLE +#define __ADC1_CLK_SLEEP_DISABLE __HAL_RCC_ADC1_CLK_SLEEP_DISABLE +#define __ADC2_CLK_DISABLE __HAL_RCC_ADC2_CLK_DISABLE +#define __ADC2_CLK_ENABLE __HAL_RCC_ADC2_CLK_ENABLE +#define __ADC2_FORCE_RESET __HAL_RCC_ADC2_FORCE_RESET +#define __ADC2_RELEASE_RESET __HAL_RCC_ADC2_RELEASE_RESET +#define __ADC3_CLK_DISABLE __HAL_RCC_ADC3_CLK_DISABLE +#define __ADC3_CLK_ENABLE __HAL_RCC_ADC3_CLK_ENABLE +#define __ADC3_FORCE_RESET __HAL_RCC_ADC3_FORCE_RESET +#define __ADC3_RELEASE_RESET __HAL_RCC_ADC3_RELEASE_RESET +#define __AES_CLK_DISABLE __HAL_RCC_AES_CLK_DISABLE +#define __AES_CLK_ENABLE __HAL_RCC_AES_CLK_ENABLE +#define __AES_CLK_SLEEP_DISABLE __HAL_RCC_AES_CLK_SLEEP_DISABLE +#define __AES_CLK_SLEEP_ENABLE __HAL_RCC_AES_CLK_SLEEP_ENABLE +#define __AES_FORCE_RESET __HAL_RCC_AES_FORCE_RESET +#define __AES_RELEASE_RESET __HAL_RCC_AES_RELEASE_RESET +#define __CRYP_CLK_SLEEP_ENABLE __HAL_RCC_CRYP_CLK_SLEEP_ENABLE +#define __CRYP_CLK_SLEEP_DISABLE __HAL_RCC_CRYP_CLK_SLEEP_DISABLE +#define __CRYP_CLK_ENABLE __HAL_RCC_CRYP_CLK_ENABLE +#define __CRYP_CLK_DISABLE __HAL_RCC_CRYP_CLK_DISABLE +#define __CRYP_FORCE_RESET __HAL_RCC_CRYP_FORCE_RESET +#define __CRYP_RELEASE_RESET __HAL_RCC_CRYP_RELEASE_RESET +#define __AFIO_CLK_DISABLE __HAL_RCC_AFIO_CLK_DISABLE +#define __AFIO_CLK_ENABLE __HAL_RCC_AFIO_CLK_ENABLE +#define __AFIO_FORCE_RESET __HAL_RCC_AFIO_FORCE_RESET +#define __AFIO_RELEASE_RESET __HAL_RCC_AFIO_RELEASE_RESET +#define __AHB_FORCE_RESET __HAL_RCC_AHB_FORCE_RESET +#define __AHB_RELEASE_RESET __HAL_RCC_AHB_RELEASE_RESET +#define __AHB1_FORCE_RESET __HAL_RCC_AHB1_FORCE_RESET +#define __AHB1_RELEASE_RESET __HAL_RCC_AHB1_RELEASE_RESET +#define __AHB2_FORCE_RESET __HAL_RCC_AHB2_FORCE_RESET +#define __AHB2_RELEASE_RESET __HAL_RCC_AHB2_RELEASE_RESET +#define __AHB3_FORCE_RESET __HAL_RCC_AHB3_FORCE_RESET +#define __AHB3_RELEASE_RESET __HAL_RCC_AHB3_RELEASE_RESET +#define __APB1_FORCE_RESET __HAL_RCC_APB1_FORCE_RESET +#define __APB1_RELEASE_RESET __HAL_RCC_APB1_RELEASE_RESET +#define __APB2_FORCE_RESET __HAL_RCC_APB2_FORCE_RESET +#define __APB2_RELEASE_RESET __HAL_RCC_APB2_RELEASE_RESET +#define __BKP_CLK_DISABLE __HAL_RCC_BKP_CLK_DISABLE +#define __BKP_CLK_ENABLE __HAL_RCC_BKP_CLK_ENABLE +#define __BKP_FORCE_RESET __HAL_RCC_BKP_FORCE_RESET +#define __BKP_RELEASE_RESET __HAL_RCC_BKP_RELEASE_RESET +#define __CAN1_CLK_DISABLE __HAL_RCC_CAN1_CLK_DISABLE +#define __CAN1_CLK_ENABLE __HAL_RCC_CAN1_CLK_ENABLE +#define __CAN1_CLK_SLEEP_DISABLE __HAL_RCC_CAN1_CLK_SLEEP_DISABLE +#define __CAN1_CLK_SLEEP_ENABLE __HAL_RCC_CAN1_CLK_SLEEP_ENABLE +#define __CAN1_FORCE_RESET __HAL_RCC_CAN1_FORCE_RESET +#define __CAN1_RELEASE_RESET __HAL_RCC_CAN1_RELEASE_RESET +#define __CAN_CLK_DISABLE __HAL_RCC_CAN1_CLK_DISABLE +#define __CAN_CLK_ENABLE __HAL_RCC_CAN1_CLK_ENABLE +#define __CAN_FORCE_RESET __HAL_RCC_CAN1_FORCE_RESET +#define __CAN_RELEASE_RESET __HAL_RCC_CAN1_RELEASE_RESET +#define __CAN2_CLK_DISABLE __HAL_RCC_CAN2_CLK_DISABLE +#define __CAN2_CLK_ENABLE __HAL_RCC_CAN2_CLK_ENABLE +#define __CAN2_FORCE_RESET __HAL_RCC_CAN2_FORCE_RESET +#define __CAN2_RELEASE_RESET __HAL_RCC_CAN2_RELEASE_RESET +#define __CEC_CLK_DISABLE __HAL_RCC_CEC_CLK_DISABLE +#define __CEC_CLK_ENABLE __HAL_RCC_CEC_CLK_ENABLE +#define __COMP_CLK_DISABLE __HAL_RCC_COMP_CLK_DISABLE +#define __COMP_CLK_ENABLE __HAL_RCC_COMP_CLK_ENABLE +#define __COMP_FORCE_RESET __HAL_RCC_COMP_FORCE_RESET +#define __COMP_RELEASE_RESET __HAL_RCC_COMP_RELEASE_RESET +#define __COMP_CLK_SLEEP_ENABLE __HAL_RCC_COMP_CLK_SLEEP_ENABLE +#define __COMP_CLK_SLEEP_DISABLE __HAL_RCC_COMP_CLK_SLEEP_DISABLE +#define __CEC_FORCE_RESET __HAL_RCC_CEC_FORCE_RESET +#define __CEC_RELEASE_RESET __HAL_RCC_CEC_RELEASE_RESET +#define __CRC_CLK_DISABLE __HAL_RCC_CRC_CLK_DISABLE +#define __CRC_CLK_ENABLE __HAL_RCC_CRC_CLK_ENABLE +#define __CRC_CLK_SLEEP_DISABLE __HAL_RCC_CRC_CLK_SLEEP_DISABLE +#define __CRC_CLK_SLEEP_ENABLE __HAL_RCC_CRC_CLK_SLEEP_ENABLE +#define __CRC_FORCE_RESET __HAL_RCC_CRC_FORCE_RESET +#define __CRC_RELEASE_RESET __HAL_RCC_CRC_RELEASE_RESET +#define __DAC_CLK_DISABLE __HAL_RCC_DAC_CLK_DISABLE +#define __DAC_CLK_ENABLE __HAL_RCC_DAC_CLK_ENABLE +#define __DAC_FORCE_RESET __HAL_RCC_DAC_FORCE_RESET +#define __DAC_RELEASE_RESET __HAL_RCC_DAC_RELEASE_RESET +#define __DAC1_CLK_DISABLE __HAL_RCC_DAC1_CLK_DISABLE +#define __DAC1_CLK_ENABLE __HAL_RCC_DAC1_CLK_ENABLE +#define __DAC1_CLK_SLEEP_DISABLE __HAL_RCC_DAC1_CLK_SLEEP_DISABLE +#define __DAC1_CLK_SLEEP_ENABLE __HAL_RCC_DAC1_CLK_SLEEP_ENABLE +#define __DAC1_FORCE_RESET __HAL_RCC_DAC1_FORCE_RESET +#define __DAC1_RELEASE_RESET __HAL_RCC_DAC1_RELEASE_RESET +#define __DBGMCU_CLK_ENABLE __HAL_RCC_DBGMCU_CLK_ENABLE +#define __DBGMCU_CLK_DISABLE __HAL_RCC_DBGMCU_CLK_DISABLE +#define __DBGMCU_FORCE_RESET __HAL_RCC_DBGMCU_FORCE_RESET +#define __DBGMCU_RELEASE_RESET __HAL_RCC_DBGMCU_RELEASE_RESET +#define __DFSDM_CLK_DISABLE __HAL_RCC_DFSDM_CLK_DISABLE +#define __DFSDM_CLK_ENABLE __HAL_RCC_DFSDM_CLK_ENABLE +#define __DFSDM_CLK_SLEEP_DISABLE __HAL_RCC_DFSDM_CLK_SLEEP_DISABLE +#define __DFSDM_CLK_SLEEP_ENABLE __HAL_RCC_DFSDM_CLK_SLEEP_ENABLE +#define __DFSDM_FORCE_RESET __HAL_RCC_DFSDM_FORCE_RESET +#define __DFSDM_RELEASE_RESET __HAL_RCC_DFSDM_RELEASE_RESET +#define __DMA1_CLK_DISABLE __HAL_RCC_DMA1_CLK_DISABLE +#define __DMA1_CLK_ENABLE __HAL_RCC_DMA1_CLK_ENABLE +#define __DMA1_CLK_SLEEP_DISABLE __HAL_RCC_DMA1_CLK_SLEEP_DISABLE +#define __DMA1_CLK_SLEEP_ENABLE __HAL_RCC_DMA1_CLK_SLEEP_ENABLE +#define __DMA1_FORCE_RESET __HAL_RCC_DMA1_FORCE_RESET +#define __DMA1_RELEASE_RESET __HAL_RCC_DMA1_RELEASE_RESET +#define __DMA2_CLK_DISABLE __HAL_RCC_DMA2_CLK_DISABLE +#define __DMA2_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE +#define __DMA2_CLK_SLEEP_DISABLE __HAL_RCC_DMA2_CLK_SLEEP_DISABLE +#define __DMA2_CLK_SLEEP_ENABLE __HAL_RCC_DMA2_CLK_SLEEP_ENABLE +#define __DMA2_FORCE_RESET __HAL_RCC_DMA2_FORCE_RESET +#define __DMA2_RELEASE_RESET __HAL_RCC_DMA2_RELEASE_RESET +#define __ETHMAC_CLK_DISABLE __HAL_RCC_ETHMAC_CLK_DISABLE +#define __ETHMAC_CLK_ENABLE __HAL_RCC_ETHMAC_CLK_ENABLE +#define __ETHMAC_FORCE_RESET __HAL_RCC_ETHMAC_FORCE_RESET +#define __ETHMAC_RELEASE_RESET __HAL_RCC_ETHMAC_RELEASE_RESET +#define __ETHMACRX_CLK_DISABLE __HAL_RCC_ETHMACRX_CLK_DISABLE +#define __ETHMACRX_CLK_ENABLE __HAL_RCC_ETHMACRX_CLK_ENABLE +#define __ETHMACTX_CLK_DISABLE __HAL_RCC_ETHMACTX_CLK_DISABLE +#define __ETHMACTX_CLK_ENABLE __HAL_RCC_ETHMACTX_CLK_ENABLE +#define __FIREWALL_CLK_DISABLE __HAL_RCC_FIREWALL_CLK_DISABLE +#define __FIREWALL_CLK_ENABLE __HAL_RCC_FIREWALL_CLK_ENABLE +#define __FLASH_CLK_DISABLE __HAL_RCC_FLASH_CLK_DISABLE +#define __FLASH_CLK_ENABLE __HAL_RCC_FLASH_CLK_ENABLE +#define __FLASH_CLK_SLEEP_DISABLE __HAL_RCC_FLASH_CLK_SLEEP_DISABLE +#define __FLASH_CLK_SLEEP_ENABLE __HAL_RCC_FLASH_CLK_SLEEP_ENABLE +#define __FLASH_FORCE_RESET __HAL_RCC_FLASH_FORCE_RESET +#define __FLASH_RELEASE_RESET __HAL_RCC_FLASH_RELEASE_RESET +#define __FLITF_CLK_DISABLE __HAL_RCC_FLITF_CLK_DISABLE +#define __FLITF_CLK_ENABLE __HAL_RCC_FLITF_CLK_ENABLE +#define __FLITF_FORCE_RESET __HAL_RCC_FLITF_FORCE_RESET +#define __FLITF_RELEASE_RESET __HAL_RCC_FLITF_RELEASE_RESET +#define __FLITF_CLK_SLEEP_ENABLE __HAL_RCC_FLITF_CLK_SLEEP_ENABLE +#define __FLITF_CLK_SLEEP_DISABLE __HAL_RCC_FLITF_CLK_SLEEP_DISABLE +#define __FMC_CLK_DISABLE __HAL_RCC_FMC_CLK_DISABLE +#define __FMC_CLK_ENABLE __HAL_RCC_FMC_CLK_ENABLE +#define __FMC_CLK_SLEEP_DISABLE __HAL_RCC_FMC_CLK_SLEEP_DISABLE +#define __FMC_CLK_SLEEP_ENABLE __HAL_RCC_FMC_CLK_SLEEP_ENABLE +#define __FMC_FORCE_RESET __HAL_RCC_FMC_FORCE_RESET +#define __FMC_RELEASE_RESET __HAL_RCC_FMC_RELEASE_RESET +#define __FSMC_CLK_DISABLE __HAL_RCC_FSMC_CLK_DISABLE +#define __FSMC_CLK_ENABLE __HAL_RCC_FSMC_CLK_ENABLE +#define __GPIOA_CLK_DISABLE __HAL_RCC_GPIOA_CLK_DISABLE +#define __GPIOA_CLK_ENABLE __HAL_RCC_GPIOA_CLK_ENABLE +#define __GPIOA_CLK_SLEEP_DISABLE __HAL_RCC_GPIOA_CLK_SLEEP_DISABLE +#define __GPIOA_CLK_SLEEP_ENABLE __HAL_RCC_GPIOA_CLK_SLEEP_ENABLE +#define __GPIOA_FORCE_RESET __HAL_RCC_GPIOA_FORCE_RESET +#define __GPIOA_RELEASE_RESET __HAL_RCC_GPIOA_RELEASE_RESET +#define __GPIOB_CLK_DISABLE __HAL_RCC_GPIOB_CLK_DISABLE +#define __GPIOB_CLK_ENABLE __HAL_RCC_GPIOB_CLK_ENABLE +#define __GPIOB_CLK_SLEEP_DISABLE __HAL_RCC_GPIOB_CLK_SLEEP_DISABLE +#define __GPIOB_CLK_SLEEP_ENABLE __HAL_RCC_GPIOB_CLK_SLEEP_ENABLE +#define __GPIOB_FORCE_RESET __HAL_RCC_GPIOB_FORCE_RESET +#define __GPIOB_RELEASE_RESET __HAL_RCC_GPIOB_RELEASE_RESET +#define __GPIOC_CLK_DISABLE __HAL_RCC_GPIOC_CLK_DISABLE +#define __GPIOC_CLK_ENABLE __HAL_RCC_GPIOC_CLK_ENABLE +#define __GPIOC_CLK_SLEEP_DISABLE __HAL_RCC_GPIOC_CLK_SLEEP_DISABLE +#define __GPIOC_CLK_SLEEP_ENABLE __HAL_RCC_GPIOC_CLK_SLEEP_ENABLE +#define __GPIOC_FORCE_RESET __HAL_RCC_GPIOC_FORCE_RESET +#define __GPIOC_RELEASE_RESET __HAL_RCC_GPIOC_RELEASE_RESET +#define __GPIOD_CLK_DISABLE __HAL_RCC_GPIOD_CLK_DISABLE +#define __GPIOD_CLK_ENABLE __HAL_RCC_GPIOD_CLK_ENABLE +#define __GPIOD_CLK_SLEEP_DISABLE __HAL_RCC_GPIOD_CLK_SLEEP_DISABLE +#define __GPIOD_CLK_SLEEP_ENABLE __HAL_RCC_GPIOD_CLK_SLEEP_ENABLE +#define __GPIOD_FORCE_RESET __HAL_RCC_GPIOD_FORCE_RESET +#define __GPIOD_RELEASE_RESET __HAL_RCC_GPIOD_RELEASE_RESET +#define __GPIOE_CLK_DISABLE __HAL_RCC_GPIOE_CLK_DISABLE +#define __GPIOE_CLK_ENABLE __HAL_RCC_GPIOE_CLK_ENABLE +#define __GPIOE_CLK_SLEEP_DISABLE __HAL_RCC_GPIOE_CLK_SLEEP_DISABLE +#define __GPIOE_CLK_SLEEP_ENABLE __HAL_RCC_GPIOE_CLK_SLEEP_ENABLE +#define __GPIOE_FORCE_RESET __HAL_RCC_GPIOE_FORCE_RESET +#define __GPIOE_RELEASE_RESET __HAL_RCC_GPIOE_RELEASE_RESET +#define __GPIOF_CLK_DISABLE __HAL_RCC_GPIOF_CLK_DISABLE +#define __GPIOF_CLK_ENABLE __HAL_RCC_GPIOF_CLK_ENABLE +#define __GPIOF_CLK_SLEEP_DISABLE __HAL_RCC_GPIOF_CLK_SLEEP_DISABLE +#define __GPIOF_CLK_SLEEP_ENABLE __HAL_RCC_GPIOF_CLK_SLEEP_ENABLE +#define __GPIOF_FORCE_RESET __HAL_RCC_GPIOF_FORCE_RESET +#define __GPIOF_RELEASE_RESET __HAL_RCC_GPIOF_RELEASE_RESET +#define __GPIOG_CLK_DISABLE __HAL_RCC_GPIOG_CLK_DISABLE +#define __GPIOG_CLK_ENABLE __HAL_RCC_GPIOG_CLK_ENABLE +#define __GPIOG_CLK_SLEEP_DISABLE __HAL_RCC_GPIOG_CLK_SLEEP_DISABLE +#define __GPIOG_CLK_SLEEP_ENABLE __HAL_RCC_GPIOG_CLK_SLEEP_ENABLE +#define __GPIOG_FORCE_RESET __HAL_RCC_GPIOG_FORCE_RESET +#define __GPIOG_RELEASE_RESET __HAL_RCC_GPIOG_RELEASE_RESET +#define __GPIOH_CLK_DISABLE __HAL_RCC_GPIOH_CLK_DISABLE +#define __GPIOH_CLK_ENABLE __HAL_RCC_GPIOH_CLK_ENABLE +#define __GPIOH_CLK_SLEEP_DISABLE __HAL_RCC_GPIOH_CLK_SLEEP_DISABLE +#define __GPIOH_CLK_SLEEP_ENABLE __HAL_RCC_GPIOH_CLK_SLEEP_ENABLE +#define __GPIOH_FORCE_RESET __HAL_RCC_GPIOH_FORCE_RESET +#define __GPIOH_RELEASE_RESET __HAL_RCC_GPIOH_RELEASE_RESET +#define __I2C1_CLK_DISABLE __HAL_RCC_I2C1_CLK_DISABLE +#define __I2C1_CLK_ENABLE __HAL_RCC_I2C1_CLK_ENABLE +#define __I2C1_CLK_SLEEP_DISABLE __HAL_RCC_I2C1_CLK_SLEEP_DISABLE +#define __I2C1_CLK_SLEEP_ENABLE __HAL_RCC_I2C1_CLK_SLEEP_ENABLE +#define __I2C1_FORCE_RESET __HAL_RCC_I2C1_FORCE_RESET +#define __I2C1_RELEASE_RESET __HAL_RCC_I2C1_RELEASE_RESET +#define __I2C2_CLK_DISABLE __HAL_RCC_I2C2_CLK_DISABLE +#define __I2C2_CLK_ENABLE __HAL_RCC_I2C2_CLK_ENABLE +#define __I2C2_CLK_SLEEP_DISABLE __HAL_RCC_I2C2_CLK_SLEEP_DISABLE +#define __I2C2_CLK_SLEEP_ENABLE __HAL_RCC_I2C2_CLK_SLEEP_ENABLE +#define __I2C2_FORCE_RESET __HAL_RCC_I2C2_FORCE_RESET +#define __I2C2_RELEASE_RESET __HAL_RCC_I2C2_RELEASE_RESET +#define __I2C3_CLK_DISABLE __HAL_RCC_I2C3_CLK_DISABLE +#define __I2C3_CLK_ENABLE __HAL_RCC_I2C3_CLK_ENABLE +#define __I2C3_CLK_SLEEP_DISABLE __HAL_RCC_I2C3_CLK_SLEEP_DISABLE +#define __I2C3_CLK_SLEEP_ENABLE __HAL_RCC_I2C3_CLK_SLEEP_ENABLE +#define __I2C3_FORCE_RESET __HAL_RCC_I2C3_FORCE_RESET +#define __I2C3_RELEASE_RESET __HAL_RCC_I2C3_RELEASE_RESET +#define __LCD_CLK_DISABLE __HAL_RCC_LCD_CLK_DISABLE +#define __LCD_CLK_ENABLE __HAL_RCC_LCD_CLK_ENABLE +#define __LCD_CLK_SLEEP_DISABLE __HAL_RCC_LCD_CLK_SLEEP_DISABLE +#define __LCD_CLK_SLEEP_ENABLE __HAL_RCC_LCD_CLK_SLEEP_ENABLE +#define __LCD_FORCE_RESET __HAL_RCC_LCD_FORCE_RESET +#define __LCD_RELEASE_RESET __HAL_RCC_LCD_RELEASE_RESET +#define __LPTIM1_CLK_DISABLE __HAL_RCC_LPTIM1_CLK_DISABLE +#define __LPTIM1_CLK_ENABLE __HAL_RCC_LPTIM1_CLK_ENABLE +#define __LPTIM1_CLK_SLEEP_DISABLE __HAL_RCC_LPTIM1_CLK_SLEEP_DISABLE +#define __LPTIM1_CLK_SLEEP_ENABLE __HAL_RCC_LPTIM1_CLK_SLEEP_ENABLE +#define __LPTIM1_FORCE_RESET __HAL_RCC_LPTIM1_FORCE_RESET +#define __LPTIM1_RELEASE_RESET __HAL_RCC_LPTIM1_RELEASE_RESET +#define __LPTIM2_CLK_DISABLE __HAL_RCC_LPTIM2_CLK_DISABLE +#define __LPTIM2_CLK_ENABLE __HAL_RCC_LPTIM2_CLK_ENABLE +#define __LPTIM2_CLK_SLEEP_DISABLE __HAL_RCC_LPTIM2_CLK_SLEEP_DISABLE +#define __LPTIM2_CLK_SLEEP_ENABLE __HAL_RCC_LPTIM2_CLK_SLEEP_ENABLE +#define __LPTIM2_FORCE_RESET __HAL_RCC_LPTIM2_FORCE_RESET +#define __LPTIM2_RELEASE_RESET __HAL_RCC_LPTIM2_RELEASE_RESET +#define __LPUART1_CLK_DISABLE __HAL_RCC_LPUART1_CLK_DISABLE +#define __LPUART1_CLK_ENABLE __HAL_RCC_LPUART1_CLK_ENABLE +#define __LPUART1_CLK_SLEEP_DISABLE __HAL_RCC_LPUART1_CLK_SLEEP_DISABLE +#define __LPUART1_CLK_SLEEP_ENABLE __HAL_RCC_LPUART1_CLK_SLEEP_ENABLE +#define __LPUART1_FORCE_RESET __HAL_RCC_LPUART1_FORCE_RESET +#define __LPUART1_RELEASE_RESET __HAL_RCC_LPUART1_RELEASE_RESET +#define __OPAMP_CLK_DISABLE __HAL_RCC_OPAMP_CLK_DISABLE +#define __OPAMP_CLK_ENABLE __HAL_RCC_OPAMP_CLK_ENABLE +#define __OPAMP_CLK_SLEEP_DISABLE __HAL_RCC_OPAMP_CLK_SLEEP_DISABLE +#define __OPAMP_CLK_SLEEP_ENABLE __HAL_RCC_OPAMP_CLK_SLEEP_ENABLE +#define __OPAMP_FORCE_RESET __HAL_RCC_OPAMP_FORCE_RESET +#define __OPAMP_RELEASE_RESET __HAL_RCC_OPAMP_RELEASE_RESET +#define __OTGFS_CLK_DISABLE __HAL_RCC_OTGFS_CLK_DISABLE +#define __OTGFS_CLK_ENABLE __HAL_RCC_OTGFS_CLK_ENABLE +#define __OTGFS_CLK_SLEEP_DISABLE __HAL_RCC_OTGFS_CLK_SLEEP_DISABLE +#define __OTGFS_CLK_SLEEP_ENABLE __HAL_RCC_OTGFS_CLK_SLEEP_ENABLE +#define __OTGFS_FORCE_RESET __HAL_RCC_OTGFS_FORCE_RESET +#define __OTGFS_RELEASE_RESET __HAL_RCC_OTGFS_RELEASE_RESET +#define __PWR_CLK_DISABLE __HAL_RCC_PWR_CLK_DISABLE +#define __PWR_CLK_ENABLE __HAL_RCC_PWR_CLK_ENABLE +#define __PWR_CLK_SLEEP_DISABLE __HAL_RCC_PWR_CLK_SLEEP_DISABLE +#define __PWR_CLK_SLEEP_ENABLE __HAL_RCC_PWR_CLK_SLEEP_ENABLE +#define __PWR_FORCE_RESET __HAL_RCC_PWR_FORCE_RESET +#define __PWR_RELEASE_RESET __HAL_RCC_PWR_RELEASE_RESET +#define __QSPI_CLK_DISABLE __HAL_RCC_QSPI_CLK_DISABLE +#define __QSPI_CLK_ENABLE __HAL_RCC_QSPI_CLK_ENABLE +#define __QSPI_CLK_SLEEP_DISABLE __HAL_RCC_QSPI_CLK_SLEEP_DISABLE +#define __QSPI_CLK_SLEEP_ENABLE __HAL_RCC_QSPI_CLK_SLEEP_ENABLE +#define __QSPI_FORCE_RESET __HAL_RCC_QSPI_FORCE_RESET +#define __QSPI_RELEASE_RESET __HAL_RCC_QSPI_RELEASE_RESET +#define __RNG_CLK_DISABLE __HAL_RCC_RNG_CLK_DISABLE +#define __RNG_CLK_ENABLE __HAL_RCC_RNG_CLK_ENABLE +#define __RNG_CLK_SLEEP_DISABLE __HAL_RCC_RNG_CLK_SLEEP_DISABLE +#define __RNG_CLK_SLEEP_ENABLE __HAL_RCC_RNG_CLK_SLEEP_ENABLE +#define __RNG_FORCE_RESET __HAL_RCC_RNG_FORCE_RESET +#define __RNG_RELEASE_RESET __HAL_RCC_RNG_RELEASE_RESET +#define __SAI1_CLK_DISABLE __HAL_RCC_SAI1_CLK_DISABLE +#define __SAI1_CLK_ENABLE __HAL_RCC_SAI1_CLK_ENABLE +#define __SAI1_CLK_SLEEP_DISABLE __HAL_RCC_SAI1_CLK_SLEEP_DISABLE +#define __SAI1_CLK_SLEEP_ENABLE __HAL_RCC_SAI1_CLK_SLEEP_ENABLE +#define __SAI1_FORCE_RESET __HAL_RCC_SAI1_FORCE_RESET +#define __SAI1_RELEASE_RESET __HAL_RCC_SAI1_RELEASE_RESET +#define __SAI2_CLK_DISABLE __HAL_RCC_SAI2_CLK_DISABLE +#define __SAI2_CLK_ENABLE __HAL_RCC_SAI2_CLK_ENABLE +#define __SAI2_CLK_SLEEP_DISABLE __HAL_RCC_SAI2_CLK_SLEEP_DISABLE +#define __SAI2_CLK_SLEEP_ENABLE __HAL_RCC_SAI2_CLK_SLEEP_ENABLE +#define __SAI2_FORCE_RESET __HAL_RCC_SAI2_FORCE_RESET +#define __SAI2_RELEASE_RESET __HAL_RCC_SAI2_RELEASE_RESET +#define __SDIO_CLK_DISABLE __HAL_RCC_SDIO_CLK_DISABLE +#define __SDIO_CLK_ENABLE __HAL_RCC_SDIO_CLK_ENABLE +#define __SDMMC_CLK_DISABLE __HAL_RCC_SDMMC_CLK_DISABLE +#define __SDMMC_CLK_ENABLE __HAL_RCC_SDMMC_CLK_ENABLE +#define __SDMMC_CLK_SLEEP_DISABLE __HAL_RCC_SDMMC_CLK_SLEEP_DISABLE +#define __SDMMC_CLK_SLEEP_ENABLE __HAL_RCC_SDMMC_CLK_SLEEP_ENABLE +#define __SDMMC_FORCE_RESET __HAL_RCC_SDMMC_FORCE_RESET +#define __SDMMC_RELEASE_RESET __HAL_RCC_SDMMC_RELEASE_RESET +#define __SPI1_CLK_DISABLE __HAL_RCC_SPI1_CLK_DISABLE +#define __SPI1_CLK_ENABLE __HAL_RCC_SPI1_CLK_ENABLE +#define __SPI1_CLK_SLEEP_DISABLE __HAL_RCC_SPI1_CLK_SLEEP_DISABLE +#define __SPI1_CLK_SLEEP_ENABLE __HAL_RCC_SPI1_CLK_SLEEP_ENABLE +#define __SPI1_FORCE_RESET __HAL_RCC_SPI1_FORCE_RESET +#define __SPI1_RELEASE_RESET __HAL_RCC_SPI1_RELEASE_RESET +#define __SPI2_CLK_DISABLE __HAL_RCC_SPI2_CLK_DISABLE +#define __SPI2_CLK_ENABLE __HAL_RCC_SPI2_CLK_ENABLE +#define __SPI2_CLK_SLEEP_DISABLE __HAL_RCC_SPI2_CLK_SLEEP_DISABLE +#define __SPI2_CLK_SLEEP_ENABLE __HAL_RCC_SPI2_CLK_SLEEP_ENABLE +#define __SPI2_FORCE_RESET __HAL_RCC_SPI2_FORCE_RESET +#define __SPI2_RELEASE_RESET __HAL_RCC_SPI2_RELEASE_RESET +#define __SPI3_CLK_DISABLE __HAL_RCC_SPI3_CLK_DISABLE +#define __SPI3_CLK_ENABLE __HAL_RCC_SPI3_CLK_ENABLE +#define __SPI3_CLK_SLEEP_DISABLE __HAL_RCC_SPI3_CLK_SLEEP_DISABLE +#define __SPI3_CLK_SLEEP_ENABLE __HAL_RCC_SPI3_CLK_SLEEP_ENABLE +#define __SPI3_FORCE_RESET __HAL_RCC_SPI3_FORCE_RESET +#define __SPI3_RELEASE_RESET __HAL_RCC_SPI3_RELEASE_RESET +#define __SRAM_CLK_DISABLE __HAL_RCC_SRAM_CLK_DISABLE +#define __SRAM_CLK_ENABLE __HAL_RCC_SRAM_CLK_ENABLE +#define __SRAM1_CLK_SLEEP_DISABLE __HAL_RCC_SRAM1_CLK_SLEEP_DISABLE +#define __SRAM1_CLK_SLEEP_ENABLE __HAL_RCC_SRAM1_CLK_SLEEP_ENABLE +#define __SRAM2_CLK_SLEEP_DISABLE __HAL_RCC_SRAM2_CLK_SLEEP_DISABLE +#define __SRAM2_CLK_SLEEP_ENABLE __HAL_RCC_SRAM2_CLK_SLEEP_ENABLE +#define __SWPMI1_CLK_DISABLE __HAL_RCC_SWPMI1_CLK_DISABLE +#define __SWPMI1_CLK_ENABLE __HAL_RCC_SWPMI1_CLK_ENABLE +#define __SWPMI1_CLK_SLEEP_DISABLE __HAL_RCC_SWPMI1_CLK_SLEEP_DISABLE +#define __SWPMI1_CLK_SLEEP_ENABLE __HAL_RCC_SWPMI1_CLK_SLEEP_ENABLE +#define __SWPMI1_FORCE_RESET __HAL_RCC_SWPMI1_FORCE_RESET +#define __SWPMI1_RELEASE_RESET __HAL_RCC_SWPMI1_RELEASE_RESET +#define __SYSCFG_CLK_DISABLE __HAL_RCC_SYSCFG_CLK_DISABLE +#define __SYSCFG_CLK_ENABLE __HAL_RCC_SYSCFG_CLK_ENABLE +#define __SYSCFG_CLK_SLEEP_DISABLE __HAL_RCC_SYSCFG_CLK_SLEEP_DISABLE +#define __SYSCFG_CLK_SLEEP_ENABLE __HAL_RCC_SYSCFG_CLK_SLEEP_ENABLE +#define __SYSCFG_FORCE_RESET __HAL_RCC_SYSCFG_FORCE_RESET +#define __SYSCFG_RELEASE_RESET __HAL_RCC_SYSCFG_RELEASE_RESET +#define __TIM1_CLK_DISABLE __HAL_RCC_TIM1_CLK_DISABLE +#define __TIM1_CLK_ENABLE __HAL_RCC_TIM1_CLK_ENABLE +#define __TIM1_CLK_SLEEP_DISABLE __HAL_RCC_TIM1_CLK_SLEEP_DISABLE +#define __TIM1_CLK_SLEEP_ENABLE __HAL_RCC_TIM1_CLK_SLEEP_ENABLE +#define __TIM1_FORCE_RESET __HAL_RCC_TIM1_FORCE_RESET +#define __TIM1_RELEASE_RESET __HAL_RCC_TIM1_RELEASE_RESET +#define __TIM10_CLK_DISABLE __HAL_RCC_TIM10_CLK_DISABLE +#define __TIM10_CLK_ENABLE __HAL_RCC_TIM10_CLK_ENABLE +#define __TIM10_FORCE_RESET __HAL_RCC_TIM10_FORCE_RESET +#define __TIM10_RELEASE_RESET __HAL_RCC_TIM10_RELEASE_RESET +#define __TIM11_CLK_DISABLE __HAL_RCC_TIM11_CLK_DISABLE +#define __TIM11_CLK_ENABLE __HAL_RCC_TIM11_CLK_ENABLE +#define __TIM11_FORCE_RESET __HAL_RCC_TIM11_FORCE_RESET +#define __TIM11_RELEASE_RESET __HAL_RCC_TIM11_RELEASE_RESET +#define __TIM12_CLK_DISABLE __HAL_RCC_TIM12_CLK_DISABLE +#define __TIM12_CLK_ENABLE __HAL_RCC_TIM12_CLK_ENABLE +#define __TIM12_FORCE_RESET __HAL_RCC_TIM12_FORCE_RESET +#define __TIM12_RELEASE_RESET __HAL_RCC_TIM12_RELEASE_RESET +#define __TIM13_CLK_DISABLE __HAL_RCC_TIM13_CLK_DISABLE +#define __TIM13_CLK_ENABLE __HAL_RCC_TIM13_CLK_ENABLE +#define __TIM13_FORCE_RESET __HAL_RCC_TIM13_FORCE_RESET +#define __TIM13_RELEASE_RESET __HAL_RCC_TIM13_RELEASE_RESET +#define __TIM14_CLK_DISABLE __HAL_RCC_TIM14_CLK_DISABLE +#define __TIM14_CLK_ENABLE __HAL_RCC_TIM14_CLK_ENABLE +#define __TIM14_FORCE_RESET __HAL_RCC_TIM14_FORCE_RESET +#define __TIM14_RELEASE_RESET __HAL_RCC_TIM14_RELEASE_RESET +#define __TIM15_CLK_DISABLE __HAL_RCC_TIM15_CLK_DISABLE +#define __TIM15_CLK_ENABLE __HAL_RCC_TIM15_CLK_ENABLE +#define __TIM15_CLK_SLEEP_DISABLE __HAL_RCC_TIM15_CLK_SLEEP_DISABLE +#define __TIM15_CLK_SLEEP_ENABLE __HAL_RCC_TIM15_CLK_SLEEP_ENABLE +#define __TIM15_FORCE_RESET __HAL_RCC_TIM15_FORCE_RESET +#define __TIM15_RELEASE_RESET __HAL_RCC_TIM15_RELEASE_RESET +#define __TIM16_CLK_DISABLE __HAL_RCC_TIM16_CLK_DISABLE +#define __TIM16_CLK_ENABLE __HAL_RCC_TIM16_CLK_ENABLE +#define __TIM16_CLK_SLEEP_DISABLE __HAL_RCC_TIM16_CLK_SLEEP_DISABLE +#define __TIM16_CLK_SLEEP_ENABLE __HAL_RCC_TIM16_CLK_SLEEP_ENABLE +#define __TIM16_FORCE_RESET __HAL_RCC_TIM16_FORCE_RESET +#define __TIM16_RELEASE_RESET __HAL_RCC_TIM16_RELEASE_RESET +#define __TIM17_CLK_DISABLE __HAL_RCC_TIM17_CLK_DISABLE +#define __TIM17_CLK_ENABLE __HAL_RCC_TIM17_CLK_ENABLE +#define __TIM17_CLK_SLEEP_DISABLE __HAL_RCC_TIM17_CLK_SLEEP_DISABLE +#define __TIM17_CLK_SLEEP_ENABLE __HAL_RCC_TIM17_CLK_SLEEP_ENABLE +#define __TIM17_FORCE_RESET __HAL_RCC_TIM17_FORCE_RESET +#define __TIM17_RELEASE_RESET __HAL_RCC_TIM17_RELEASE_RESET +#define __TIM2_CLK_DISABLE __HAL_RCC_TIM2_CLK_DISABLE +#define __TIM2_CLK_ENABLE __HAL_RCC_TIM2_CLK_ENABLE +#define __TIM2_CLK_SLEEP_DISABLE __HAL_RCC_TIM2_CLK_SLEEP_DISABLE +#define __TIM2_CLK_SLEEP_ENABLE __HAL_RCC_TIM2_CLK_SLEEP_ENABLE +#define __TIM2_FORCE_RESET __HAL_RCC_TIM2_FORCE_RESET +#define __TIM2_RELEASE_RESET __HAL_RCC_TIM2_RELEASE_RESET +#define __TIM3_CLK_DISABLE __HAL_RCC_TIM3_CLK_DISABLE +#define __TIM3_CLK_ENABLE __HAL_RCC_TIM3_CLK_ENABLE +#define __TIM3_CLK_SLEEP_DISABLE __HAL_RCC_TIM3_CLK_SLEEP_DISABLE +#define __TIM3_CLK_SLEEP_ENABLE __HAL_RCC_TIM3_CLK_SLEEP_ENABLE +#define __TIM3_FORCE_RESET __HAL_RCC_TIM3_FORCE_RESET +#define __TIM3_RELEASE_RESET __HAL_RCC_TIM3_RELEASE_RESET +#define __TIM4_CLK_DISABLE __HAL_RCC_TIM4_CLK_DISABLE +#define __TIM4_CLK_ENABLE __HAL_RCC_TIM4_CLK_ENABLE +#define __TIM4_CLK_SLEEP_DISABLE __HAL_RCC_TIM4_CLK_SLEEP_DISABLE +#define __TIM4_CLK_SLEEP_ENABLE __HAL_RCC_TIM4_CLK_SLEEP_ENABLE +#define __TIM4_FORCE_RESET __HAL_RCC_TIM4_FORCE_RESET +#define __TIM4_RELEASE_RESET __HAL_RCC_TIM4_RELEASE_RESET +#define __TIM5_CLK_DISABLE __HAL_RCC_TIM5_CLK_DISABLE +#define __TIM5_CLK_ENABLE __HAL_RCC_TIM5_CLK_ENABLE +#define __TIM5_CLK_SLEEP_DISABLE __HAL_RCC_TIM5_CLK_SLEEP_DISABLE +#define __TIM5_CLK_SLEEP_ENABLE __HAL_RCC_TIM5_CLK_SLEEP_ENABLE +#define __TIM5_FORCE_RESET __HAL_RCC_TIM5_FORCE_RESET +#define __TIM5_RELEASE_RESET __HAL_RCC_TIM5_RELEASE_RESET +#define __TIM6_CLK_DISABLE __HAL_RCC_TIM6_CLK_DISABLE +#define __TIM6_CLK_ENABLE __HAL_RCC_TIM6_CLK_ENABLE +#define __TIM6_CLK_SLEEP_DISABLE __HAL_RCC_TIM6_CLK_SLEEP_DISABLE +#define __TIM6_CLK_SLEEP_ENABLE __HAL_RCC_TIM6_CLK_SLEEP_ENABLE +#define __TIM6_FORCE_RESET __HAL_RCC_TIM6_FORCE_RESET +#define __TIM6_RELEASE_RESET __HAL_RCC_TIM6_RELEASE_RESET +#define __TIM7_CLK_DISABLE __HAL_RCC_TIM7_CLK_DISABLE +#define __TIM7_CLK_ENABLE __HAL_RCC_TIM7_CLK_ENABLE +#define __TIM7_CLK_SLEEP_DISABLE __HAL_RCC_TIM7_CLK_SLEEP_DISABLE +#define __TIM7_CLK_SLEEP_ENABLE __HAL_RCC_TIM7_CLK_SLEEP_ENABLE +#define __TIM7_FORCE_RESET __HAL_RCC_TIM7_FORCE_RESET +#define __TIM7_RELEASE_RESET __HAL_RCC_TIM7_RELEASE_RESET +#define __TIM8_CLK_DISABLE __HAL_RCC_TIM8_CLK_DISABLE +#define __TIM8_CLK_ENABLE __HAL_RCC_TIM8_CLK_ENABLE +#define __TIM8_CLK_SLEEP_DISABLE __HAL_RCC_TIM8_CLK_SLEEP_DISABLE +#define __TIM8_CLK_SLEEP_ENABLE __HAL_RCC_TIM8_CLK_SLEEP_ENABLE +#define __TIM8_FORCE_RESET __HAL_RCC_TIM8_FORCE_RESET +#define __TIM8_RELEASE_RESET __HAL_RCC_TIM8_RELEASE_RESET +#define __TIM9_CLK_DISABLE __HAL_RCC_TIM9_CLK_DISABLE +#define __TIM9_CLK_ENABLE __HAL_RCC_TIM9_CLK_ENABLE +#define __TIM9_FORCE_RESET __HAL_RCC_TIM9_FORCE_RESET +#define __TIM9_RELEASE_RESET __HAL_RCC_TIM9_RELEASE_RESET +#define __TSC_CLK_DISABLE __HAL_RCC_TSC_CLK_DISABLE +#define __TSC_CLK_ENABLE __HAL_RCC_TSC_CLK_ENABLE +#define __TSC_CLK_SLEEP_DISABLE __HAL_RCC_TSC_CLK_SLEEP_DISABLE +#define __TSC_CLK_SLEEP_ENABLE __HAL_RCC_TSC_CLK_SLEEP_ENABLE +#define __TSC_FORCE_RESET __HAL_RCC_TSC_FORCE_RESET +#define __TSC_RELEASE_RESET __HAL_RCC_TSC_RELEASE_RESET +#define __UART4_CLK_DISABLE __HAL_RCC_UART4_CLK_DISABLE +#define __UART4_CLK_ENABLE __HAL_RCC_UART4_CLK_ENABLE +#define __UART4_CLK_SLEEP_DISABLE __HAL_RCC_UART4_CLK_SLEEP_DISABLE +#define __UART4_CLK_SLEEP_ENABLE __HAL_RCC_UART4_CLK_SLEEP_ENABLE +#define __UART4_FORCE_RESET __HAL_RCC_UART4_FORCE_RESET +#define __UART4_RELEASE_RESET __HAL_RCC_UART4_RELEASE_RESET +#define __UART5_CLK_DISABLE __HAL_RCC_UART5_CLK_DISABLE +#define __UART5_CLK_ENABLE __HAL_RCC_UART5_CLK_ENABLE +#define __UART5_CLK_SLEEP_DISABLE __HAL_RCC_UART5_CLK_SLEEP_DISABLE +#define __UART5_CLK_SLEEP_ENABLE __HAL_RCC_UART5_CLK_SLEEP_ENABLE +#define __UART5_FORCE_RESET __HAL_RCC_UART5_FORCE_RESET +#define __UART5_RELEASE_RESET __HAL_RCC_UART5_RELEASE_RESET +#define __USART1_CLK_DISABLE __HAL_RCC_USART1_CLK_DISABLE +#define __USART1_CLK_ENABLE __HAL_RCC_USART1_CLK_ENABLE +#define __USART1_CLK_SLEEP_DISABLE __HAL_RCC_USART1_CLK_SLEEP_DISABLE +#define __USART1_CLK_SLEEP_ENABLE __HAL_RCC_USART1_CLK_SLEEP_ENABLE +#define __USART1_FORCE_RESET __HAL_RCC_USART1_FORCE_RESET +#define __USART1_RELEASE_RESET __HAL_RCC_USART1_RELEASE_RESET +#define __USART2_CLK_DISABLE __HAL_RCC_USART2_CLK_DISABLE +#define __USART2_CLK_ENABLE __HAL_RCC_USART2_CLK_ENABLE +#define __USART2_CLK_SLEEP_DISABLE __HAL_RCC_USART2_CLK_SLEEP_DISABLE +#define __USART2_CLK_SLEEP_ENABLE __HAL_RCC_USART2_CLK_SLEEP_ENABLE +#define __USART2_FORCE_RESET __HAL_RCC_USART2_FORCE_RESET +#define __USART2_RELEASE_RESET __HAL_RCC_USART2_RELEASE_RESET +#define __USART3_CLK_DISABLE __HAL_RCC_USART3_CLK_DISABLE +#define __USART3_CLK_ENABLE __HAL_RCC_USART3_CLK_ENABLE +#define __USART3_CLK_SLEEP_DISABLE __HAL_RCC_USART3_CLK_SLEEP_DISABLE +#define __USART3_CLK_SLEEP_ENABLE __HAL_RCC_USART3_CLK_SLEEP_ENABLE +#define __USART3_FORCE_RESET __HAL_RCC_USART3_FORCE_RESET +#define __USART3_RELEASE_RESET __HAL_RCC_USART3_RELEASE_RESET +#define __USART4_CLK_DISABLE __HAL_RCC_USART4_CLK_DISABLE +#define __USART4_CLK_ENABLE __HAL_RCC_USART4_CLK_ENABLE +#define __USART4_CLK_SLEEP_ENABLE __HAL_RCC_USART4_CLK_SLEEP_ENABLE +#define __USART4_CLK_SLEEP_DISABLE __HAL_RCC_USART4_CLK_SLEEP_DISABLE +#define __USART4_FORCE_RESET __HAL_RCC_USART4_FORCE_RESET +#define __USART4_RELEASE_RESET __HAL_RCC_USART4_RELEASE_RESET +#define __USART5_CLK_DISABLE __HAL_RCC_USART5_CLK_DISABLE +#define __USART5_CLK_ENABLE __HAL_RCC_USART5_CLK_ENABLE +#define __USART5_CLK_SLEEP_ENABLE __HAL_RCC_USART5_CLK_SLEEP_ENABLE +#define __USART5_CLK_SLEEP_DISABLE __HAL_RCC_USART5_CLK_SLEEP_DISABLE +#define __USART5_FORCE_RESET __HAL_RCC_USART5_FORCE_RESET +#define __USART5_RELEASE_RESET __HAL_RCC_USART5_RELEASE_RESET +#define __USART7_CLK_DISABLE __HAL_RCC_USART7_CLK_DISABLE +#define __USART7_CLK_ENABLE __HAL_RCC_USART7_CLK_ENABLE +#define __USART7_FORCE_RESET __HAL_RCC_USART7_FORCE_RESET +#define __USART7_RELEASE_RESET __HAL_RCC_USART7_RELEASE_RESET +#define __USART8_CLK_DISABLE __HAL_RCC_USART8_CLK_DISABLE +#define __USART8_CLK_ENABLE __HAL_RCC_USART8_CLK_ENABLE +#define __USART8_FORCE_RESET __HAL_RCC_USART8_FORCE_RESET +#define __USART8_RELEASE_RESET __HAL_RCC_USART8_RELEASE_RESET +#define __USB_CLK_DISABLE __HAL_RCC_USB_CLK_DISABLE +#define __USB_CLK_ENABLE __HAL_RCC_USB_CLK_ENABLE +#define __USB_FORCE_RESET __HAL_RCC_USB_FORCE_RESET +#define __USB_CLK_SLEEP_ENABLE __HAL_RCC_USB_CLK_SLEEP_ENABLE +#define __USB_CLK_SLEEP_DISABLE __HAL_RCC_USB_CLK_SLEEP_DISABLE +#define __USB_OTG_FS_CLK_DISABLE __HAL_RCC_USB_OTG_FS_CLK_DISABLE +#define __USB_OTG_FS_CLK_ENABLE __HAL_RCC_USB_OTG_FS_CLK_ENABLE +#define __USB_RELEASE_RESET __HAL_RCC_USB_RELEASE_RESET +#define __WWDG_CLK_DISABLE __HAL_RCC_WWDG_CLK_DISABLE +#define __WWDG_CLK_ENABLE __HAL_RCC_WWDG_CLK_ENABLE +#define __WWDG_CLK_SLEEP_DISABLE __HAL_RCC_WWDG_CLK_SLEEP_DISABLE +#define __WWDG_CLK_SLEEP_ENABLE __HAL_RCC_WWDG_CLK_SLEEP_ENABLE +#define __WWDG_FORCE_RESET __HAL_RCC_WWDG_FORCE_RESET +#define __WWDG_RELEASE_RESET __HAL_RCC_WWDG_RELEASE_RESET +#define __TIM21_CLK_ENABLE __HAL_RCC_TIM21_CLK_ENABLE +#define __TIM21_CLK_DISABLE __HAL_RCC_TIM21_CLK_DISABLE +#define __TIM21_FORCE_RESET __HAL_RCC_TIM21_FORCE_RESET +#define __TIM21_RELEASE_RESET __HAL_RCC_TIM21_RELEASE_RESET +#define __TIM21_CLK_SLEEP_ENABLE __HAL_RCC_TIM21_CLK_SLEEP_ENABLE +#define __TIM21_CLK_SLEEP_DISABLE __HAL_RCC_TIM21_CLK_SLEEP_DISABLE +#define __TIM22_CLK_ENABLE __HAL_RCC_TIM22_CLK_ENABLE +#define __TIM22_CLK_DISABLE __HAL_RCC_TIM22_CLK_DISABLE +#define __TIM22_FORCE_RESET __HAL_RCC_TIM22_FORCE_RESET +#define __TIM22_RELEASE_RESET __HAL_RCC_TIM22_RELEASE_RESET +#define __TIM22_CLK_SLEEP_ENABLE __HAL_RCC_TIM22_CLK_SLEEP_ENABLE +#define __TIM22_CLK_SLEEP_DISABLE __HAL_RCC_TIM22_CLK_SLEEP_DISABLE +#define __CRS_CLK_DISABLE __HAL_RCC_CRS_CLK_DISABLE +#define __CRS_CLK_ENABLE __HAL_RCC_CRS_CLK_ENABLE +#define __CRS_CLK_SLEEP_DISABLE __HAL_RCC_CRS_CLK_SLEEP_DISABLE +#define __CRS_CLK_SLEEP_ENABLE __HAL_RCC_CRS_CLK_SLEEP_ENABLE +#define __CRS_FORCE_RESET __HAL_RCC_CRS_FORCE_RESET +#define __CRS_RELEASE_RESET __HAL_RCC_CRS_RELEASE_RESET +#define __RCC_BACKUPRESET_FORCE __HAL_RCC_BACKUPRESET_FORCE +#define __RCC_BACKUPRESET_RELEASE __HAL_RCC_BACKUPRESET_RELEASE + +#define __USB_OTG_FS_FORCE_RESET __HAL_RCC_USB_OTG_FS_FORCE_RESET +#define __USB_OTG_FS_RELEASE_RESET __HAL_RCC_USB_OTG_FS_RELEASE_RESET +#define __USB_OTG_FS_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_FS_CLK_SLEEP_ENABLE +#define __USB_OTG_FS_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_FS_CLK_SLEEP_DISABLE +#define __USB_OTG_HS_CLK_DISABLE __HAL_RCC_USB_OTG_HS_CLK_DISABLE +#define __USB_OTG_HS_CLK_ENABLE __HAL_RCC_USB_OTG_HS_CLK_ENABLE +#define __USB_OTG_HS_ULPI_CLK_ENABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE +#define __USB_OTG_HS_ULPI_CLK_DISABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_DISABLE +#define __TIM9_CLK_SLEEP_ENABLE __HAL_RCC_TIM9_CLK_SLEEP_ENABLE +#define __TIM9_CLK_SLEEP_DISABLE __HAL_RCC_TIM9_CLK_SLEEP_DISABLE +#define __TIM10_CLK_SLEEP_ENABLE __HAL_RCC_TIM10_CLK_SLEEP_ENABLE +#define __TIM10_CLK_SLEEP_DISABLE __HAL_RCC_TIM10_CLK_SLEEP_DISABLE +#define __TIM11_CLK_SLEEP_ENABLE __HAL_RCC_TIM11_CLK_SLEEP_ENABLE +#define __TIM11_CLK_SLEEP_DISABLE __HAL_RCC_TIM11_CLK_SLEEP_DISABLE +#define __ETHMACPTP_CLK_SLEEP_ENABLE __HAL_RCC_ETHMACPTP_CLK_SLEEP_ENABLE +#define __ETHMACPTP_CLK_SLEEP_DISABLE __HAL_RCC_ETHMACPTP_CLK_SLEEP_DISABLE +#define __ETHMACPTP_CLK_ENABLE __HAL_RCC_ETHMACPTP_CLK_ENABLE +#define __ETHMACPTP_CLK_DISABLE __HAL_RCC_ETHMACPTP_CLK_DISABLE +#define __HASH_CLK_ENABLE __HAL_RCC_HASH_CLK_ENABLE +#define __HASH_FORCE_RESET __HAL_RCC_HASH_FORCE_RESET +#define __HASH_RELEASE_RESET __HAL_RCC_HASH_RELEASE_RESET +#define __HASH_CLK_SLEEP_ENABLE __HAL_RCC_HASH_CLK_SLEEP_ENABLE +#define __HASH_CLK_SLEEP_DISABLE __HAL_RCC_HASH_CLK_SLEEP_DISABLE +#define __HASH_CLK_DISABLE __HAL_RCC_HASH_CLK_DISABLE +#define __SPI5_CLK_ENABLE __HAL_RCC_SPI5_CLK_ENABLE +#define __SPI5_CLK_DISABLE __HAL_RCC_SPI5_CLK_DISABLE +#define __SPI5_FORCE_RESET __HAL_RCC_SPI5_FORCE_RESET +#define __SPI5_RELEASE_RESET __HAL_RCC_SPI5_RELEASE_RESET +#define __SPI5_CLK_SLEEP_ENABLE __HAL_RCC_SPI5_CLK_SLEEP_ENABLE +#define __SPI5_CLK_SLEEP_DISABLE __HAL_RCC_SPI5_CLK_SLEEP_DISABLE +#define __SPI6_CLK_ENABLE __HAL_RCC_SPI6_CLK_ENABLE +#define __SPI6_CLK_DISABLE __HAL_RCC_SPI6_CLK_DISABLE +#define __SPI6_FORCE_RESET __HAL_RCC_SPI6_FORCE_RESET +#define __SPI6_RELEASE_RESET __HAL_RCC_SPI6_RELEASE_RESET +#define __SPI6_CLK_SLEEP_ENABLE __HAL_RCC_SPI6_CLK_SLEEP_ENABLE +#define __SPI6_CLK_SLEEP_DISABLE __HAL_RCC_SPI6_CLK_SLEEP_DISABLE +#define __LTDC_CLK_ENABLE __HAL_RCC_LTDC_CLK_ENABLE +#define __LTDC_CLK_DISABLE __HAL_RCC_LTDC_CLK_DISABLE +#define __LTDC_FORCE_RESET __HAL_RCC_LTDC_FORCE_RESET +#define __LTDC_RELEASE_RESET __HAL_RCC_LTDC_RELEASE_RESET +#define __LTDC_CLK_SLEEP_ENABLE __HAL_RCC_LTDC_CLK_SLEEP_ENABLE +#define __ETHMAC_CLK_SLEEP_ENABLE __HAL_RCC_ETHMAC_CLK_SLEEP_ENABLE +#define __ETHMAC_CLK_SLEEP_DISABLE __HAL_RCC_ETHMAC_CLK_SLEEP_DISABLE +#define __ETHMACTX_CLK_SLEEP_ENABLE __HAL_RCC_ETHMACTX_CLK_SLEEP_ENABLE +#define __ETHMACTX_CLK_SLEEP_DISABLE __HAL_RCC_ETHMACTX_CLK_SLEEP_DISABLE +#define __ETHMACRX_CLK_SLEEP_ENABLE __HAL_RCC_ETHMACRX_CLK_SLEEP_ENABLE +#define __ETHMACRX_CLK_SLEEP_DISABLE __HAL_RCC_ETHMACRX_CLK_SLEEP_DISABLE +#define __TIM12_CLK_SLEEP_ENABLE __HAL_RCC_TIM12_CLK_SLEEP_ENABLE +#define __TIM12_CLK_SLEEP_DISABLE __HAL_RCC_TIM12_CLK_SLEEP_DISABLE +#define __TIM13_CLK_SLEEP_ENABLE __HAL_RCC_TIM13_CLK_SLEEP_ENABLE +#define __TIM13_CLK_SLEEP_DISABLE __HAL_RCC_TIM13_CLK_SLEEP_DISABLE +#define __TIM14_CLK_SLEEP_ENABLE __HAL_RCC_TIM14_CLK_SLEEP_ENABLE +#define __TIM14_CLK_SLEEP_DISABLE __HAL_RCC_TIM14_CLK_SLEEP_DISABLE +#define __BKPSRAM_CLK_ENABLE __HAL_RCC_BKPSRAM_CLK_ENABLE +#define __BKPSRAM_CLK_DISABLE __HAL_RCC_BKPSRAM_CLK_DISABLE +#define __BKPSRAM_CLK_SLEEP_ENABLE __HAL_RCC_BKPSRAM_CLK_SLEEP_ENABLE +#define __BKPSRAM_CLK_SLEEP_DISABLE __HAL_RCC_BKPSRAM_CLK_SLEEP_DISABLE +#define __CCMDATARAMEN_CLK_ENABLE __HAL_RCC_CCMDATARAMEN_CLK_ENABLE +#define __CCMDATARAMEN_CLK_DISABLE __HAL_RCC_CCMDATARAMEN_CLK_DISABLE +#define __USART6_CLK_ENABLE __HAL_RCC_USART6_CLK_ENABLE +#define __USART6_CLK_DISABLE __HAL_RCC_USART6_CLK_DISABLE +#define __USART6_FORCE_RESET __HAL_RCC_USART6_FORCE_RESET +#define __USART6_RELEASE_RESET __HAL_RCC_USART6_RELEASE_RESET +#define __USART6_CLK_SLEEP_ENABLE __HAL_RCC_USART6_CLK_SLEEP_ENABLE +#define __USART6_CLK_SLEEP_DISABLE __HAL_RCC_USART6_CLK_SLEEP_DISABLE +#define __SPI4_CLK_ENABLE __HAL_RCC_SPI4_CLK_ENABLE +#define __SPI4_CLK_DISABLE __HAL_RCC_SPI4_CLK_DISABLE +#define __SPI4_FORCE_RESET __HAL_RCC_SPI4_FORCE_RESET +#define __SPI4_RELEASE_RESET __HAL_RCC_SPI4_RELEASE_RESET +#define __SPI4_CLK_SLEEP_ENABLE __HAL_RCC_SPI4_CLK_SLEEP_ENABLE +#define __SPI4_CLK_SLEEP_DISABLE __HAL_RCC_SPI4_CLK_SLEEP_DISABLE +#define __GPIOI_CLK_ENABLE __HAL_RCC_GPIOI_CLK_ENABLE +#define __GPIOI_CLK_DISABLE __HAL_RCC_GPIOI_CLK_DISABLE +#define __GPIOI_FORCE_RESET __HAL_RCC_GPIOI_FORCE_RESET +#define __GPIOI_RELEASE_RESET __HAL_RCC_GPIOI_RELEASE_RESET +#define __GPIOI_CLK_SLEEP_ENABLE __HAL_RCC_GPIOI_CLK_SLEEP_ENABLE +#define __GPIOI_CLK_SLEEP_DISABLE __HAL_RCC_GPIOI_CLK_SLEEP_DISABLE +#define __GPIOJ_CLK_ENABLE __HAL_RCC_GPIOJ_CLK_ENABLE +#define __GPIOJ_CLK_DISABLE __HAL_RCC_GPIOJ_CLK_DISABLE +#define __GPIOJ_FORCE_RESET __HAL_RCC_GPIOJ_FORCE_RESET +#define __GPIOJ_RELEASE_RESET __HAL_RCC_GPIOJ_RELEASE_RESET +#define __GPIOJ_CLK_SLEEP_ENABLE __HAL_RCC_GPIOJ_CLK_SLEEP_ENABLE +#define __GPIOJ_CLK_SLEEP_DISABLE __HAL_RCC_GPIOJ_CLK_SLEEP_DISABLE +#define __GPIOK_CLK_ENABLE __HAL_RCC_GPIOK_CLK_ENABLE +#define __GPIOK_CLK_DISABLE __HAL_RCC_GPIOK_CLK_DISABLE +#define __GPIOK_RELEASE_RESET __HAL_RCC_GPIOK_RELEASE_RESET +#define __GPIOK_CLK_SLEEP_ENABLE __HAL_RCC_GPIOK_CLK_SLEEP_ENABLE +#define __GPIOK_CLK_SLEEP_DISABLE __HAL_RCC_GPIOK_CLK_SLEEP_DISABLE +#define __ETH_CLK_ENABLE __HAL_RCC_ETH_CLK_ENABLE +#define __ETH_CLK_DISABLE __HAL_RCC_ETH_CLK_DISABLE +#define __DCMI_CLK_ENABLE __HAL_RCC_DCMI_CLK_ENABLE +#define __DCMI_CLK_DISABLE __HAL_RCC_DCMI_CLK_DISABLE +#define __DCMI_FORCE_RESET __HAL_RCC_DCMI_FORCE_RESET +#define __DCMI_RELEASE_RESET __HAL_RCC_DCMI_RELEASE_RESET +#define __DCMI_CLK_SLEEP_ENABLE __HAL_RCC_DCMI_CLK_SLEEP_ENABLE +#define __DCMI_CLK_SLEEP_DISABLE __HAL_RCC_DCMI_CLK_SLEEP_DISABLE +#define __UART7_CLK_ENABLE __HAL_RCC_UART7_CLK_ENABLE +#define __UART7_CLK_DISABLE __HAL_RCC_UART7_CLK_DISABLE +#define __UART7_RELEASE_RESET __HAL_RCC_UART7_RELEASE_RESET +#define __UART7_FORCE_RESET __HAL_RCC_UART7_FORCE_RESET +#define __UART7_CLK_SLEEP_ENABLE __HAL_RCC_UART7_CLK_SLEEP_ENABLE +#define __UART7_CLK_SLEEP_DISABLE __HAL_RCC_UART7_CLK_SLEEP_DISABLE +#define __UART8_CLK_ENABLE __HAL_RCC_UART8_CLK_ENABLE +#define __UART8_CLK_DISABLE __HAL_RCC_UART8_CLK_DISABLE +#define __UART8_FORCE_RESET __HAL_RCC_UART8_FORCE_RESET +#define __UART8_RELEASE_RESET __HAL_RCC_UART8_RELEASE_RESET +#define __UART8_CLK_SLEEP_ENABLE __HAL_RCC_UART8_CLK_SLEEP_ENABLE +#define __UART8_CLK_SLEEP_DISABLE __HAL_RCC_UART8_CLK_SLEEP_DISABLE +#define __OTGHS_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE +#define __OTGHS_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_CLK_SLEEP_DISABLE +#define __OTGHS_FORCE_RESET __HAL_RCC_USB_OTG_HS_FORCE_RESET +#define __OTGHS_RELEASE_RESET __HAL_RCC_USB_OTG_HS_RELEASE_RESET +#define __OTGHSULPI_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE +#define __OTGHSULPI_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE +#define __HAL_RCC_OTGHS_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE +#define __HAL_RCC_OTGHS_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_CLK_SLEEP_DISABLE +#define __HAL_RCC_OTGHS_IS_CLK_SLEEP_ENABLED __HAL_RCC_USB_OTG_HS_IS_CLK_SLEEP_ENABLED +#define __HAL_RCC_OTGHS_IS_CLK_SLEEP_DISABLED __HAL_RCC_USB_OTG_HS_IS_CLK_SLEEP_DISABLED +#define __HAL_RCC_OTGHS_FORCE_RESET __HAL_RCC_USB_OTG_HS_FORCE_RESET +#define __HAL_RCC_OTGHS_RELEASE_RESET __HAL_RCC_USB_OTG_HS_RELEASE_RESET +#define __HAL_RCC_OTGHSULPI_CLK_SLEEP_ENABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE +#define __HAL_RCC_OTGHSULPI_CLK_SLEEP_DISABLE __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE +#define __HAL_RCC_OTGHSULPI_IS_CLK_SLEEP_ENABLED __HAL_RCC_USB_OTG_HS_ULPI_IS_CLK_SLEEP_ENABLED +#define __HAL_RCC_OTGHSULPI_IS_CLK_SLEEP_DISABLED __HAL_RCC_USB_OTG_HS_ULPI_IS_CLK_SLEEP_DISABLED +#define __CRYP_FORCE_RESET __HAL_RCC_CRYP_FORCE_RESET +#define __SRAM3_CLK_SLEEP_ENABLE __HAL_RCC_SRAM3_CLK_SLEEP_ENABLE +#define __CAN2_CLK_SLEEP_ENABLE __HAL_RCC_CAN2_CLK_SLEEP_ENABLE +#define __CAN2_CLK_SLEEP_DISABLE __HAL_RCC_CAN2_CLK_SLEEP_DISABLE +#define __DAC_CLK_SLEEP_ENABLE __HAL_RCC_DAC_CLK_SLEEP_ENABLE +#define __DAC_CLK_SLEEP_DISABLE __HAL_RCC_DAC_CLK_SLEEP_DISABLE +#define __ADC2_CLK_SLEEP_ENABLE __HAL_RCC_ADC2_CLK_SLEEP_ENABLE +#define __ADC2_CLK_SLEEP_DISABLE __HAL_RCC_ADC2_CLK_SLEEP_DISABLE +#define __ADC3_CLK_SLEEP_ENABLE __HAL_RCC_ADC3_CLK_SLEEP_ENABLE +#define __ADC3_CLK_SLEEP_DISABLE __HAL_RCC_ADC3_CLK_SLEEP_DISABLE +#define __FSMC_FORCE_RESET __HAL_RCC_FSMC_FORCE_RESET +#define __FSMC_RELEASE_RESET __HAL_RCC_FSMC_RELEASE_RESET +#define __FSMC_CLK_SLEEP_ENABLE __HAL_RCC_FSMC_CLK_SLEEP_ENABLE +#define __FSMC_CLK_SLEEP_DISABLE __HAL_RCC_FSMC_CLK_SLEEP_DISABLE +#define __SDIO_FORCE_RESET __HAL_RCC_SDIO_FORCE_RESET +#define __SDIO_RELEASE_RESET __HAL_RCC_SDIO_RELEASE_RESET +#define __SDIO_CLK_SLEEP_DISABLE __HAL_RCC_SDIO_CLK_SLEEP_DISABLE +#define __SDIO_CLK_SLEEP_ENABLE __HAL_RCC_SDIO_CLK_SLEEP_ENABLE +#define __DMA2D_CLK_ENABLE __HAL_RCC_DMA2D_CLK_ENABLE +#define __DMA2D_CLK_DISABLE __HAL_RCC_DMA2D_CLK_DISABLE +#define __DMA2D_FORCE_RESET __HAL_RCC_DMA2D_FORCE_RESET +#define __DMA2D_RELEASE_RESET __HAL_RCC_DMA2D_RELEASE_RESET +#define __DMA2D_CLK_SLEEP_ENABLE __HAL_RCC_DMA2D_CLK_SLEEP_ENABLE +#define __DMA2D_CLK_SLEEP_DISABLE __HAL_RCC_DMA2D_CLK_SLEEP_DISABLE + +/* alias define maintained for legacy */ +#define __HAL_RCC_OTGFS_FORCE_RESET __HAL_RCC_USB_OTG_FS_FORCE_RESET +#define __HAL_RCC_OTGFS_RELEASE_RESET __HAL_RCC_USB_OTG_FS_RELEASE_RESET + +#if defined(STM32F4) +#define __HAL_RCC_SDMMC1_CLK_ENABLE __HAL_RCC_SDIO_CLK_ENABLE +#define __HAL_RCC_SDMMC1_FORCE_RESET __HAL_RCC_SDIO_FORCE_RESET +#define __HAL_RCC_SDMMC1_RELEASE_RESET __HAL_RCC_SDIO_RELEASE_RESET +#define __HAL_RCC_SDMMC1_CLK_SLEEP_ENABLE __HAL_RCC_SDIO_CLK_SLEEP_ENABLE +#define __HAL_RCC_SDMMC1_CLK_SLEEP_DISABLE __HAL_RCC_SDIO_CLK_SLEEP_DISABLE +#define __HAL_RCC_SDMMC1_CLK_ENABLE __HAL_RCC_SDIO_CLK_ENABLE +#define __HAL_RCC_SDMMC1_CLK_DISABLE __HAL_RCC_SDIO_CLK_DISABLE +#define Sdmmc1ClockSelection SdioClockSelection +#define RCC_PERIPHCLK_SDMMC1 RCC_PERIPHCLK_SDIO +#define RCC_SDMMC1CLKSOURCE_CLK48 RCC_SDIOCLKSOURCE_CK48 +#define RCC_SDMMC1CLKSOURCE_SYSCLK RCC_SDIOCLKSOURCE_SYSCLK +#define __HAL_RCC_SDMMC1_CONFIG __HAL_RCC_SDIO_CONFIG +#define __HAL_RCC_GET_SDMMC1_SOURCE __HAL_RCC_GET_SDIO_SOURCE +#endif + +#if defined(STM32F7) || defined(STM32L4) +#define __HAL_RCC_SDIO_CLK_ENABLE __HAL_RCC_SDMMC1_CLK_ENABLE +#define __HAL_RCC_SDIO_FORCE_RESET __HAL_RCC_SDMMC1_FORCE_RESET +#define __HAL_RCC_SDIO_RELEASE_RESET __HAL_RCC_SDMMC1_RELEASE_RESET +#define __HAL_RCC_SDIO_CLK_SLEEP_ENABLE __HAL_RCC_SDMMC1_CLK_SLEEP_ENABLE +#define __HAL_RCC_SDIO_CLK_SLEEP_DISABLE __HAL_RCC_SDMMC1_CLK_SLEEP_DISABLE +#define __HAL_RCC_SDIO_CLK_ENABLE __HAL_RCC_SDMMC1_CLK_ENABLE +#define __HAL_RCC_SDIO_CLK_DISABLE __HAL_RCC_SDMMC1_CLK_DISABLE +#define SdioClockSelection Sdmmc1ClockSelection +#define RCC_PERIPHCLK_SDIO RCC_PERIPHCLK_SDMMC1 +#define __HAL_RCC_SDIO_CONFIG __HAL_RCC_SDMMC1_CONFIG +#define __HAL_RCC_GET_SDIO_SOURCE __HAL_RCC_GET_SDMMC1_SOURCE +#endif + +#if defined(STM32F7) +#define RCC_SDIOCLKSOURCE_CK48 RCC_SDMMC1CLKSOURCE_CLK48 +#define RCC_SDIOCLKSOURCE_SYSCLK RCC_SDMMC1CLKSOURCE_SYSCLK +#endif + +#define __HAL_RCC_I2SCLK __HAL_RCC_I2S_CONFIG +#define __HAL_RCC_I2SCLK_CONFIG __HAL_RCC_I2S_CONFIG + +#define __RCC_PLLSRC RCC_GET_PLL_OSCSOURCE + +#define IS_RCC_MSIRANGE IS_RCC_MSI_CLOCK_RANGE +#define IS_RCC_RTCCLK_SOURCE IS_RCC_RTCCLKSOURCE +#define IS_RCC_SYSCLK_DIV IS_RCC_HCLK +#define IS_RCC_HCLK_DIV IS_RCC_PCLK + +#define IS_RCC_MCOSOURCE IS_RCC_MCO1SOURCE +#define RCC_MCO_NODIV RCC_MCODIV_1 +#define RCC_RTCCLKSOURCE_NONE RCC_RTCCLKSOURCE_NO_CLK + +#define HSION_BitNumber RCC_HSION_BIT_NUMBER +#define CSSON_BitNumber RCC_CSSON_BIT_NUMBER +#define PLLON_BitNumber RCC_PLLON_BIT_NUMBER +#define PLLI2SON_BitNumber RCC_PLLI2SON_BIT_NUMBER +#define I2SSRC_BitNumber RCC_I2SSRC_BIT_NUMBER +#define RTCEN_BitNumber RCC_RTCEN_BIT_NUMBER +#define BDRST_BitNumber RCC_BDRST_BIT_NUMBER +#define LSION_BitNumber RCC_LSION_BIT_NUMBER +#define PLLSAION_BitNumber RCC_PLLSAION_BIT_NUMBER +#define TIMPRE_BitNumber RCC_TIMPRE_BIT_NUMBER + +#define CR_BYTE2_ADDRESS RCC_CR_BYTE2_ADDRESS +#define CIR_BYTE1_ADDRESS RCC_CIR_BYTE1_ADDRESS +#define CIR_BYTE2_ADDRESS RCC_CIR_BYTE2_ADDRESS +#define BDCR_BYTE0_ADDRESS RCC_BDCR_BYTE0_ADDRESS +#define DBP_TIMEOUT_VALUE RCC_DBP_TIMEOUT_VALUE +#define LSE_TIMEOUT_VALUE RCC_LSE_TIMEOUT_VALUE + +#define CR_HSION_BB RCC_CR_HSION_BB +#define CR_CSSON_BB RCC_CR_CSSON_BB +#define CR_PLLON_BB RCC_CR_PLLON_BB +#define CR_PLLI2SON_BB RCC_CR_PLLI2SON_BB +#define CR_MSION_BB RCC_CR_MSION_BB +#define CSR_LSION_BB RCC_CSR_LSION_BB +#define CSR_LSEON_BB RCC_CSR_LSEON_BB +#define CSR_LSEBYP_BB RCC_CSR_LSEBYP_BB +#define CSR_RTCEN_BB RCC_CSR_RTCEN_BB +#define CSR_RTCRST_BB RCC_CSR_RTCRST_BB +#define CFGR_I2SSRC_BB RCC_CFGR_I2SSRC_BB +#define BDCR_RTCEN_BB RCC_BDCR_RTCEN_BB +#define BDCR_BDRST_BB RCC_BDCR_BDRST_BB +#define CR_PLLSAION_BB RCC_CR_PLLSAION_BB +#define DCKCFGR_TIMPRE_BB RCC_DCKCFGR_TIMPRE_BB + +/** + * @} + */ + +/** @defgroup HAL_RNG_Aliased_Macros HAL RNG Aliased Macros maintained for legacy purpose + * @{ + */ +#define HAL_RNG_ReadyCallback(__HANDLE__) HAL_RNG_ReadyDataCallback((__HANDLE__), uint32_t random32bit) + +/** + * @} + */ + +/** @defgroup HAL_RTC_Aliased_Macros HAL RTC Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_RTC_CLEAR_FLAG __HAL_RTC_EXTI_CLEAR_FLAG +#define __HAL_RTC_DISABLE_IT __HAL_RTC_EXTI_DISABLE_IT +#define __HAL_RTC_ENABLE_IT __HAL_RTC_EXTI_ENABLE_IT + +#if defined (STM32F1) +#define __HAL_RTC_EXTI_CLEAR_FLAG(RTC_EXTI_LINE_ALARM_EVENT) __HAL_RTC_ALARM_EXTI_CLEAR_FLAG() + +#define __HAL_RTC_EXTI_ENABLE_IT(RTC_EXTI_LINE_ALARM_EVENT) __HAL_RTC_ALARM_EXTI_ENABLE_IT() + +#define __HAL_RTC_EXTI_DISABLE_IT(RTC_EXTI_LINE_ALARM_EVENT) __HAL_RTC_ALARM_EXTI_DISABLE_IT() + +#define __HAL_RTC_EXTI_GET_FLAG(RTC_EXTI_LINE_ALARM_EVENT) __HAL_RTC_ALARM_EXTI_GET_FLAG() + +#define __HAL_RTC_EXTI_GENERATE_SWIT(RTC_EXTI_LINE_ALARM_EVENT) __HAL_RTC_ALARM_EXTI_GENERATE_SWIT() +#else +#define __HAL_RTC_EXTI_CLEAR_FLAG(__EXTI_LINE__) (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) ? __HAL_RTC_ALARM_EXTI_CLEAR_FLAG() : \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) ? __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG() : \ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_CLEAR_FLAG())) +#define __HAL_RTC_EXTI_ENABLE_IT(__EXTI_LINE__) (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) ? __HAL_RTC_ALARM_EXTI_ENABLE_IT() : \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) ? __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT() : \ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_ENABLE_IT())) +#define __HAL_RTC_EXTI_DISABLE_IT(__EXTI_LINE__) (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) ? __HAL_RTC_ALARM_EXTI_DISABLE_IT() : \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) ? __HAL_RTC_WAKEUPTIMER_EXTI_DISABLE_IT() : \ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_DISABLE_IT())) +#define __HAL_RTC_EXTI_GET_FLAG(__EXTI_LINE__) (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) ? __HAL_RTC_ALARM_EXTI_GET_FLAG() : \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) ? __HAL_RTC_WAKEUPTIMER_EXTI_GET_FLAG() : \ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_GET_FLAG())) +#define __HAL_RTC_EXTI_GENERATE_SWIT(__EXTI_LINE__) (((__EXTI_LINE__) == RTC_EXTI_LINE_ALARM_EVENT) ? __HAL_RTC_ALARM_EXTI_GENERATE_SWIT() : \ + (((__EXTI_LINE__) == RTC_EXTI_LINE_WAKEUPTIMER_EVENT) ? __HAL_RTC_WAKEUPTIMER_EXTI_GENERATE_SWIT() : \ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_GENERATE_SWIT())) +#endif /* STM32F1 */ + +#define IS_ALARM IS_RTC_ALARM +#define IS_ALARM_MASK IS_RTC_ALARM_MASK +#define IS_TAMPER IS_RTC_TAMPER +#define IS_TAMPER_ERASE_MODE IS_RTC_TAMPER_ERASE_MODE +#define IS_TAMPER_FILTER IS_RTC_TAMPER_FILTER +#define IS_TAMPER_INTERRUPT IS_RTC_TAMPER_INTERRUPT +#define IS_TAMPER_MASKFLAG_STATE IS_RTC_TAMPER_MASKFLAG_STATE +#define IS_TAMPER_PRECHARGE_DURATION IS_RTC_TAMPER_PRECHARGE_DURATION +#define IS_TAMPER_PULLUP_STATE IS_RTC_TAMPER_PULLUP_STATE +#define IS_TAMPER_SAMPLING_FREQ IS_RTC_TAMPER_SAMPLING_FREQ +#define IS_TAMPER_TIMESTAMPONTAMPER_DETECTION IS_RTC_TAMPER_TIMESTAMPONTAMPER_DETECTION +#define IS_TAMPER_TRIGGER IS_RTC_TAMPER_TRIGGER +#define IS_WAKEUP_CLOCK IS_RTC_WAKEUP_CLOCK +#define IS_WAKEUP_COUNTER IS_RTC_WAKEUP_COUNTER + +#define __RTC_WRITEPROTECTION_ENABLE __HAL_RTC_WRITEPROTECTION_ENABLE +#define __RTC_WRITEPROTECTION_DISABLE __HAL_RTC_WRITEPROTECTION_DISABLE + +/** + * @} + */ + +/** @defgroup HAL_SD_Aliased_Macros HAL SD Aliased Macros maintained for legacy purpose + * @{ + */ + +#define SD_OCR_CID_CSD_OVERWRIETE SD_OCR_CID_CSD_OVERWRITE +#define SD_CMD_SD_APP_STAUS SD_CMD_SD_APP_STATUS + +#if defined(STM32F4) +#define SD_SDMMC_DISABLED SD_SDIO_DISABLED +#define SD_SDMMC_FUNCTION_BUSY SD_SDIO_FUNCTION_BUSY +#define SD_SDMMC_FUNCTION_FAILED SD_SDIO_FUNCTION_FAILED +#define SD_SDMMC_UNKNOWN_FUNCTION SD_SDIO_UNKNOWN_FUNCTION +#define SD_CMD_SDMMC_SEN_OP_COND SD_CMD_SDIO_SEN_OP_COND +#define SD_CMD_SDMMC_RW_DIRECT SD_CMD_SDIO_RW_DIRECT +#define SD_CMD_SDMMC_RW_EXTENDED SD_CMD_SDIO_RW_EXTENDED +#define __HAL_SD_SDMMC_ENABLE __HAL_SD_SDIO_ENABLE +#define __HAL_SD_SDMMC_DISABLE __HAL_SD_SDIO_DISABLE +#define __HAL_SD_SDMMC_DMA_ENABLE __HAL_SD_SDIO_DMA_ENABLE +#define __HAL_SD_SDMMC_DMA_DISABLE __HAL_SD_SDIO_DMA_DISABL +#define __HAL_SD_SDMMC_ENABLE_IT __HAL_SD_SDIO_ENABLE_IT +#define __HAL_SD_SDMMC_DISABLE_IT __HAL_SD_SDIO_DISABLE_IT +#define __HAL_SD_SDMMC_GET_FLAG __HAL_SD_SDIO_GET_FLAG +#define __HAL_SD_SDMMC_CLEAR_FLAG __HAL_SD_SDIO_CLEAR_FLAG +#define __HAL_SD_SDMMC_GET_IT __HAL_SD_SDIO_GET_IT +#define __HAL_SD_SDMMC_CLEAR_IT __HAL_SD_SDIO_CLEAR_IT +#define SDMMC_STATIC_FLAGS SDIO_STATIC_FLAGS +#define SDMMC_CMD0TIMEOUT SDIO_CMD0TIMEOUT +#define SD_SDMMC_SEND_IF_COND SD_SDIO_SEND_IF_COND +/* alias CMSIS */ +#define SDMMC1_IRQn SDIO_IRQn +#define SDMMC1_IRQHandler SDIO_IRQHandler +#endif + +#if defined(STM32F7) || defined(STM32L4) +#define SD_SDIO_DISABLED SD_SDMMC_DISABLED +#define SD_SDIO_FUNCTION_BUSY SD_SDMMC_FUNCTION_BUSY +#define SD_SDIO_FUNCTION_FAILED SD_SDMMC_FUNCTION_FAILED +#define SD_SDIO_UNKNOWN_FUNCTION SD_SDMMC_UNKNOWN_FUNCTION +#define SD_CMD_SDIO_SEN_OP_COND SD_CMD_SDMMC_SEN_OP_COND +#define SD_CMD_SDIO_RW_DIRECT SD_CMD_SDMMC_RW_DIRECT +#define SD_CMD_SDIO_RW_EXTENDED SD_CMD_SDMMC_RW_EXTENDED +#define __HAL_SD_SDIO_ENABLE __HAL_SD_SDMMC_ENABLE +#define __HAL_SD_SDIO_DISABLE __HAL_SD_SDMMC_DISABLE +#define __HAL_SD_SDIO_DMA_ENABLE __HAL_SD_SDMMC_DMA_ENABLE +#define __HAL_SD_SDIO_DMA_DISABL __HAL_SD_SDMMC_DMA_DISABLE +#define __HAL_SD_SDIO_ENABLE_IT __HAL_SD_SDMMC_ENABLE_IT +#define __HAL_SD_SDIO_DISABLE_IT __HAL_SD_SDMMC_DISABLE_IT +#define __HAL_SD_SDIO_GET_FLAG __HAL_SD_SDMMC_GET_FLAG +#define __HAL_SD_SDIO_CLEAR_FLAG __HAL_SD_SDMMC_CLEAR_FLAG +#define __HAL_SD_SDIO_GET_IT __HAL_SD_SDMMC_GET_IT +#define __HAL_SD_SDIO_CLEAR_IT __HAL_SD_SDMMC_CLEAR_IT +#define SDIO_STATIC_FLAGS SDMMC_STATIC_FLAGS +#define SDIO_CMD0TIMEOUT SDMMC_CMD0TIMEOUT +#define SD_SDIO_SEND_IF_COND SD_SDMMC_SEND_IF_COND +/* alias CMSIS for compatibilities */ +#define SDIO_IRQn SDMMC1_IRQn +#define SDIO_IRQHandler SDMMC1_IRQHandler +#endif +/** + * @} + */ + +/** @defgroup HAL_SMARTCARD_Aliased_Macros HAL SMARTCARD Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __SMARTCARD_ENABLE_IT __HAL_SMARTCARD_ENABLE_IT +#define __SMARTCARD_DISABLE_IT __HAL_SMARTCARD_DISABLE_IT +#define __SMARTCARD_ENABLE __HAL_SMARTCARD_ENABLE +#define __SMARTCARD_DISABLE __HAL_SMARTCARD_DISABLE +#define __SMARTCARD_DMA_REQUEST_ENABLE __HAL_SMARTCARD_DMA_REQUEST_ENABLE +#define __SMARTCARD_DMA_REQUEST_DISABLE __HAL_SMARTCARD_DMA_REQUEST_DISABLE + +#define __HAL_SMARTCARD_GETCLOCKSOURCE SMARTCARD_GETCLOCKSOURCE +#define __SMARTCARD_GETCLOCKSOURCE SMARTCARD_GETCLOCKSOURCE + +#define IS_SMARTCARD_ONEBIT_SAMPLING IS_SMARTCARD_ONE_BIT_SAMPLE + +/** + * @} + */ + +/** @defgroup HAL_SMBUS_Aliased_Macros HAL SMBUS Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_SMBUS_RESET_CR1 SMBUS_RESET_CR1 +#define __HAL_SMBUS_RESET_CR2 SMBUS_RESET_CR2 +#define __HAL_SMBUS_GENERATE_START SMBUS_GENERATE_START +#define __HAL_SMBUS_GET_ADDR_MATCH SMBUS_GET_ADDR_MATCH +#define __HAL_SMBUS_GET_DIR SMBUS_GET_DIR +#define __HAL_SMBUS_GET_STOP_MODE SMBUS_GET_STOP_MODE +#define __HAL_SMBUS_GET_PEC_MODE SMBUS_GET_PEC_MODE +#define __HAL_SMBUS_GET_ALERT_ENABLED SMBUS_GET_ALERT_ENABLED +/** + * @} + */ + +/** @defgroup HAL_SPI_Aliased_Macros HAL SPI Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_SPI_1LINE_TX SPI_1LINE_TX +#define __HAL_SPI_1LINE_RX SPI_1LINE_RX +#define __HAL_SPI_RESET_CRC SPI_RESET_CRC + +/** + * @} + */ + +/** @defgroup HAL_UART_Aliased_Macros HAL UART Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_UART_GETCLOCKSOURCE UART_GETCLOCKSOURCE +#define __HAL_UART_MASK_COMPUTATION UART_MASK_COMPUTATION +#define __UART_GETCLOCKSOURCE UART_GETCLOCKSOURCE +#define __UART_MASK_COMPUTATION UART_MASK_COMPUTATION + +#define IS_UART_WAKEUPMETHODE IS_UART_WAKEUPMETHOD + +#define IS_UART_ONEBIT_SAMPLE IS_UART_ONE_BIT_SAMPLE +#define IS_UART_ONEBIT_SAMPLING IS_UART_ONE_BIT_SAMPLE + +/** + * @} + */ + + +/** @defgroup HAL_USART_Aliased_Macros HAL USART Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __USART_ENABLE_IT __HAL_USART_ENABLE_IT +#define __USART_DISABLE_IT __HAL_USART_DISABLE_IT +#define __USART_ENABLE __HAL_USART_ENABLE +#define __USART_DISABLE __HAL_USART_DISABLE + +#define __HAL_USART_GETCLOCKSOURCE USART_GETCLOCKSOURCE +#define __USART_GETCLOCKSOURCE USART_GETCLOCKSOURCE + +/** + * @} + */ + +/** @defgroup HAL_USB_Aliased_Macros HAL USB Aliased Macros maintained for legacy purpose + * @{ + */ +#define USB_EXTI_LINE_WAKEUP USB_WAKEUP_EXTI_LINE + +#define USB_FS_EXTI_TRIGGER_RISING_EDGE USB_OTG_FS_WAKEUP_EXTI_RISING_EDGE +#define USB_FS_EXTI_TRIGGER_FALLING_EDGE USB_OTG_FS_WAKEUP_EXTI_FALLING_EDGE +#define USB_FS_EXTI_TRIGGER_BOTH_EDGE USB_OTG_FS_WAKEUP_EXTI_RISING_FALLING_EDGE +#define USB_FS_EXTI_LINE_WAKEUP USB_OTG_FS_WAKEUP_EXTI_LINE + +#define USB_HS_EXTI_TRIGGER_RISING_EDGE USB_OTG_HS_WAKEUP_EXTI_RISING_EDGE +#define USB_HS_EXTI_TRIGGER_FALLING_EDGE USB_OTG_HS_WAKEUP_EXTI_FALLING_EDGE +#define USB_HS_EXTI_TRIGGER_BOTH_EDGE USB_OTG_HS_WAKEUP_EXTI_RISING_FALLING_EDGE +#define USB_HS_EXTI_LINE_WAKEUP USB_OTG_HS_WAKEUP_EXTI_LINE + +#define __HAL_USB_EXTI_ENABLE_IT __HAL_USB_WAKEUP_EXTI_ENABLE_IT +#define __HAL_USB_EXTI_DISABLE_IT __HAL_USB_WAKEUP_EXTI_DISABLE_IT +#define __HAL_USB_EXTI_GET_FLAG __HAL_USB_WAKEUP_EXTI_GET_FLAG +#define __HAL_USB_EXTI_CLEAR_FLAG __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG +#define __HAL_USB_EXTI_SET_RISING_EDGE_TRIGGER __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_EDGE +#define __HAL_USB_EXTI_SET_FALLING_EDGE_TRIGGER __HAL_USB_WAKEUP_EXTI_ENABLE_FALLING_EDGE +#define __HAL_USB_EXTI_SET_FALLINGRISING_TRIGGER __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE + +#define __HAL_USB_FS_EXTI_ENABLE_IT __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT +#define __HAL_USB_FS_EXTI_DISABLE_IT __HAL_USB_OTG_FS_WAKEUP_EXTI_DISABLE_IT +#define __HAL_USB_FS_EXTI_GET_FLAG __HAL_USB_OTG_FS_WAKEUP_EXTI_GET_FLAG +#define __HAL_USB_FS_EXTI_CLEAR_FLAG __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG +#define __HAL_USB_FS_EXTI_SET_RISING_EGDE_TRIGGER __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE +#define __HAL_USB_FS_EXTI_SET_FALLING_EGDE_TRIGGER __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_FALLING_EDGE +#define __HAL_USB_FS_EXTI_SET_FALLINGRISING_TRIGGER __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE +#define __HAL_USB_FS_EXTI_GENERATE_SWIT __HAL_USB_OTG_FS_WAKEUP_EXTI_GENERATE_SWIT + +#define __HAL_USB_HS_EXTI_ENABLE_IT __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_IT +#define __HAL_USB_HS_EXTI_DISABLE_IT __HAL_USB_OTG_HS_WAKEUP_EXTI_DISABLE_IT +#define __HAL_USB_HS_EXTI_GET_FLAG __HAL_USB_OTG_HS_WAKEUP_EXTI_GET_FLAG +#define __HAL_USB_HS_EXTI_CLEAR_FLAG __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG +#define __HAL_USB_HS_EXTI_SET_RISING_EGDE_TRIGGER __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_EDGE +#define __HAL_USB_HS_EXTI_SET_FALLING_EGDE_TRIGGER __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_FALLING_EDGE +#define __HAL_USB_HS_EXTI_SET_FALLINGRISING_TRIGGER __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE +#define __HAL_USB_HS_EXTI_GENERATE_SWIT __HAL_USB_OTG_HS_WAKEUP_EXTI_GENERATE_SWIT + +#define HAL_PCD_ActiveRemoteWakeup HAL_PCD_ActivateRemoteWakeup +#define HAL_PCD_DeActiveRemoteWakeup HAL_PCD_DeActivateRemoteWakeup + +#define HAL_PCD_SetTxFiFo HAL_PCDEx_SetTxFiFo +#define HAL_PCD_SetRxFiFo HAL_PCDEx_SetRxFiFo +/** + * @} + */ + +/** @defgroup HAL_TIM_Aliased_Macros HAL TIM Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_TIM_SetICPrescalerValue TIM_SET_ICPRESCALERVALUE +#define __HAL_TIM_ResetICPrescalerValue TIM_RESET_ICPRESCALERVALUE + +#define TIM_GET_ITSTATUS __HAL_TIM_GET_IT_SOURCE +#define TIM_GET_CLEAR_IT __HAL_TIM_CLEAR_IT + +#define __HAL_TIM_GET_ITSTATUS __HAL_TIM_GET_IT_SOURCE + +#define __HAL_TIM_DIRECTION_STATUS __HAL_TIM_IS_TIM_COUNTING_DOWN +#define __HAL_TIM_PRESCALER __HAL_TIM_SET_PRESCALER +#define __HAL_TIM_SetCounter __HAL_TIM_SET_COUNTER +#define __HAL_TIM_GetCounter __HAL_TIM_GET_COUNTER +#define __HAL_TIM_SetAutoreload __HAL_TIM_SET_AUTORELOAD +#define __HAL_TIM_GetAutoreload __HAL_TIM_GET_AUTORELOAD +#define __HAL_TIM_SetClockDivision __HAL_TIM_SET_CLOCKDIVISION +#define __HAL_TIM_GetClockDivision __HAL_TIM_GET_CLOCKDIVISION +#define __HAL_TIM_SetICPrescaler __HAL_TIM_SET_ICPRESCALER +#define __HAL_TIM_GetICPrescaler __HAL_TIM_GET_ICPRESCALER +#define __HAL_TIM_SetCompare __HAL_TIM_SET_COMPARE +#define __HAL_TIM_GetCompare __HAL_TIM_GET_COMPARE + +#define TIM_TS_ITR0 ((uint32_t)0x0000) +#define TIM_TS_ITR1 ((uint32_t)0x0010) +#define TIM_TS_ITR2 ((uint32_t)0x0020) +#define TIM_TS_ITR3 ((uint32_t)0x0030) +#define IS_TIM_INTERNAL_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ + ((SELECTION) == TIM_TS_ITR1) || \ + ((SELECTION) == TIM_TS_ITR2) || \ + ((SELECTION) == TIM_TS_ITR3)) + +#define TIM_CHANNEL_1 ((uint32_t)0x0000) +#define TIM_CHANNEL_2 ((uint32_t)0x0004) +#define IS_TIM_PWMI_CHANNELS(CHANNEL) (((CHANNEL) == TIM_CHANNEL_1) || \ + ((CHANNEL) == TIM_CHANNEL_2)) + +#define TIM_OUTPUTNSTATE_DISABLE ((uint32_t)0x0000) +#define TIM_OUTPUTNSTATE_ENABLE (TIM_CCER_CC1NE) + +#define IS_TIM_OUTPUTN_STATE(STATE) (((STATE) == TIM_OUTPUTNSTATE_DISABLE) || \ + ((STATE) == TIM_OUTPUTNSTATE_ENABLE)) + +#define TIM_OUTPUTSTATE_DISABLE ((uint32_t)0x0000) +#define TIM_OUTPUTSTATE_ENABLE (TIM_CCER_CC1E) + +#define IS_TIM_OUTPUT_STATE(STATE) (((STATE) == TIM_OUTPUTSTATE_DISABLE) || \ + ((STATE) == TIM_OUTPUTSTATE_ENABLE)) +/** + * @} + */ + +/** @defgroup HAL_ETH_Aliased_Macros HAL ETH Aliased Macros maintained for legacy purpose + * @{ + */ + +#define __HAL_ETH_EXTI_ENABLE_IT __HAL_ETH_WAKEUP_EXTI_ENABLE_IT +#define __HAL_ETH_EXTI_DISABLE_IT __HAL_ETH_WAKEUP_EXTI_DISABLE_IT +#define __HAL_ETH_EXTI_GET_FLAG __HAL_ETH_WAKEUP_EXTI_GET_FLAG +#define __HAL_ETH_EXTI_CLEAR_FLAG __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG +#define __HAL_ETH_EXTI_SET_RISING_EGDE_TRIGGER __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE_TRIGGER +#define __HAL_ETH_EXTI_SET_FALLING_EGDE_TRIGGER __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE_TRIGGER +#define __HAL_ETH_EXTI_SET_FALLINGRISING_TRIGGER __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLINGRISING_TRIGGER + +#define ETH_PROMISCIOUSMODE_ENABLE ETH_PROMISCUOUS_MODE_ENABLE +#define ETH_PROMISCIOUSMODE_DISABLE ETH_PROMISCUOUS_MODE_DISABLE +#define IS_ETH_PROMISCIOUS_MODE IS_ETH_PROMISCUOUS_MODE +/** + * @} + */ + +/** @defgroup HAL_LTDC_Aliased_Macros HAL LTDC Aliased Macros maintained for legacy purpose + * @{ + */ +#define __HAL_LTDC_LAYER LTDC_LAYER +/** + * @} + */ + +/** @defgroup HAL_SAI_Aliased_Macros HAL SAI Aliased Macros maintained for legacy purpose + * @{ + */ +#define SAI_OUTPUTDRIVE_DISABLED SAI_OUTPUTDRIVE_DISABLE +#define SAI_OUTPUTDRIVE_ENABLED SAI_OUTPUTDRIVE_ENABLE +#define SAI_MASTERDIVIDER_ENABLED SAI_MASTERDIVIDER_ENABLE +#define SAI_MASTERDIVIDER_DISABLED SAI_MASTERDIVIDER_DISABLE +#define SAI_STREOMODE SAI_STEREOMODE +#define SAI_FIFOStatus_Empty SAI_FIFOSTATUS_EMPTY +#define SAI_FIFOStatus_Less1QuarterFull SAI_FIFOSTATUS_LESS1QUARTERFULL +#define SAI_FIFOStatus_1QuarterFull SAI_FIFOSTATUS_1QUARTERFULL +#define SAI_FIFOStatus_HalfFull SAI_FIFOSTATUS_HALFFULL +#define SAI_FIFOStatus_3QuartersFull SAI_FIFOSTATUS_3QUARTERFULL +#define SAI_FIFOStatus_Full SAI_FIFOSTATUS_FULL +#define IS_SAI_BLOCK_MONO_STREO_MODE IS_SAI_BLOCK_MONO_STEREO_MODE + +/** + * @} + */ + + +/** @defgroup HAL_PPP_Aliased_Macros HAL PPP Aliased Macros maintained for legacy purpose + * @{ + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ___STM32_HAL_LEGACY */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h new file mode 100644 index 0000000..97d6b26 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h @@ -0,0 +1,234 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief This file contains all the functions prototypes for the HAL + * module driver. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_H +#define __STM32F4xx_HAL_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "hal_config.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup HAL + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup HAL_Exported_Macros HAL Exported Macros + * @{ + */ + +/** @brief Freeze/Unfreeze Peripherals in Debug mode + */ +#define __HAL_DBGMCU_FREEZE_TIM2() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM2_STOP)) +#define __HAL_DBGMCU_FREEZE_TIM3() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM3_STOP)) +#define __HAL_DBGMCU_FREEZE_TIM4() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM4_STOP)) +#define __HAL_DBGMCU_FREEZE_TIM5() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM5_STOP)) +#define __HAL_DBGMCU_FREEZE_TIM6() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM6_STOP)) +#define __HAL_DBGMCU_FREEZE_TIM7() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM7_STOP)) +#define __HAL_DBGMCU_FREEZE_TIM12() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM12_STOP)) +#define __HAL_DBGMCU_FREEZE_TIM13() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM13_STOP)) +#define __HAL_DBGMCU_FREEZE_TIM14() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_TIM14_STOP)) +#define __HAL_DBGMCU_FREEZE_RTC() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_RTC_STOP)) +#define __HAL_DBGMCU_FREEZE_WWDG() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_WWDG_STOP)) +#define __HAL_DBGMCU_FREEZE_IWDG() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_IWDG_STOP)) +#define __HAL_DBGMCU_FREEZE_I2C1_TIMEOUT() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT)) +#define __HAL_DBGMCU_FREEZE_I2C2_TIMEOUT() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_I2C2_SMBUS_TIMEOUT)) +#define __HAL_DBGMCU_FREEZE_I2C3_TIMEOUT() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_I2C3_SMBUS_TIMEOUT)) +#define __HAL_DBGMCU_FREEZE_CAN1() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_CAN1_STOP)) +#define __HAL_DBGMCU_FREEZE_CAN2() (DBGMCU->APB1FZ |= (DBGMCU_APB1_FZ_DBG_CAN2_STOP)) +#define __HAL_DBGMCU_FREEZE_TIM1() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM1_STOP)) +#define __HAL_DBGMCU_FREEZE_TIM8() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM8_STOP)) +#define __HAL_DBGMCU_FREEZE_TIM9() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM9_STOP)) +#define __HAL_DBGMCU_FREEZE_TIM10() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM10_STOP)) +#define __HAL_DBGMCU_FREEZE_TIM11() (DBGMCU->APB2FZ |= (DBGMCU_APB2_FZ_DBG_TIM11_STOP)) + +#define __HAL_DBGMCU_UNFREEZE_TIM2() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM2_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM3() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM3_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM4() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM4_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM5() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM5_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM6() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM6_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM7() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM7_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM12() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM12_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM13() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM13_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM14() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_TIM14_STOP)) +#define __HAL_DBGMCU_UNFREEZE_RTC() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_RTC_STOP)) +#define __HAL_DBGMCU_UNFREEZE_WWDG() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_WWDG_STOP)) +#define __HAL_DBGMCU_UNFREEZE_IWDG() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_IWDG_STOP)) +#define __HAL_DBGMCU_UNFREEZE_I2C1_TIMEOUT() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_I2C1_SMBUS_TIMEOUT)) +#define __HAL_DBGMCU_UNFREEZE_I2C2_TIMEOUT() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_I2C2_SMBUS_TIMEOUT)) +#define __HAL_DBGMCU_UNFREEZE_I2C3_TIMEOUT() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_I2C3_SMBUS_TIMEOUT)) +#define __HAL_DBGMCU_UNFREEZE_CAN1() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_CAN1_STOP)) +#define __HAL_DBGMCU_UNFREEZE_CAN2() (DBGMCU->APB1FZ &= ~(DBGMCU_APB1_FZ_DBG_CAN2_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM1() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM1_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM8() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM8_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM9() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM9_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM10() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM10_STOP)) +#define __HAL_DBGMCU_UNFREEZE_TIM11() (DBGMCU->APB2FZ &= ~(DBGMCU_APB2_FZ_DBG_TIM11_STOP)) + +/** @brief Main Flash memory mapped at 0x00000000 + */ +#define __HAL_SYSCFG_REMAPMEMORY_FLASH() (SYSCFG->MEMRMP &= ~(SYSCFG_MEMRMP_MEM_MODE)) + +/** @brief System Flash memory mapped at 0x00000000 + */ +#define __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH() do {SYSCFG->MEMRMP &= ~(SYSCFG_MEMRMP_MEM_MODE);\ + SYSCFG->MEMRMP |= SYSCFG_MEMRMP_MEM_MODE_0;\ + }while(0); + +/** @brief Embedded SRAM mapped at 0x00000000 + */ +#define __HAL_SYSCFG_REMAPMEMORY_SRAM() do {SYSCFG->MEMRMP &= ~(SYSCFG_MEMRMP_MEM_MODE);\ + SYSCFG->MEMRMP |= (SYSCFG_MEMRMP_MEM_MODE_0 | SYSCFG_MEMRMP_MEM_MODE_1);\ + }while(0); + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) +/** @brief FSMC Bank1 (NOR/PSRAM 1 and 2) mapped at 0x00000000 + */ +#define __HAL_SYSCFG_REMAPMEMORY_FSMC() do {SYSCFG->MEMRMP &= ~(SYSCFG_MEMRMP_MEM_MODE);\ + SYSCFG->MEMRMP |= (SYSCFG_MEMRMP_MEM_MODE_1);\ + }while(0); +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) +/** @brief FMC Bank1 (NOR/PSRAM 1 and 2) mapped at 0x00000000 + */ +#define __HAL_SYSCFG_REMAPMEMORY_FMC() do {SYSCFG->MEMRMP &= ~(SYSCFG_MEMRMP_MEM_MODE);\ + SYSCFG->MEMRMP |= (SYSCFG_MEMRMP_MEM_MODE_1);\ + }while(0); + +/** @brief FMC/SDRAM Bank 1 and 2 mapped at 0x00000000 + */ +#define __HAL_SYSCFG_REMAPMEMORY_FMC_SDRAM() do {SYSCFG->MEMRMP &= ~(SYSCFG_MEMRMP_MEM_MODE);\ + SYSCFG->MEMRMP |= (SYSCFG_MEMRMP_MEM_MODE_2);\ + }while(0); +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HAL_Exported_Functions + * @{ + */ +/** @addtogroup HAL_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions ******************************/ +HAL_StatusTypeDef HAL_Init(void); +HAL_StatusTypeDef HAL_DeInit(void); +void HAL_MspInit(void); +void HAL_MspDeInit(void); +uint32_t HAL_GetHSECrystalFreqMHz(void); +HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority); +/** + * @} + */ + +/** @addtogroup HAL_Exported_Functions_Group2 + * @{ + */ +/* Peripheral Control functions ************************************************/ +void HAL_IncTick(void); +void HAL_Delay(__IO uint32_t Delay); +uint32_t HAL_GetTick(void); +void HAL_SuspendTick(void); +void HAL_ResumeTick(void); +uint32_t HAL_GetHalVersion(void); +uint32_t HAL_GetREVID(void); +uint32_t HAL_GetDEVID(void); +void HAL_DBGMCU_EnableDBGSleepMode(void); +void HAL_DBGMCU_DisableDBGSleepMode(void); +void HAL_DBGMCU_EnableDBGStopMode(void); +void HAL_DBGMCU_DisableDBGStopMode(void); +void HAL_DBGMCU_EnableDBGStandbyMode(void); +void HAL_DBGMCU_DisableDBGStandbyMode(void); +void HAL_EnableCompensationCell(void); +void HAL_DisableCompensationCell(void); +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) +void HAL_EnableMemorySwappingBank(void); +void HAL_DisableMemorySwappingBank(void); +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @defgroup HAL_Private_Variables HAL Private Variables + * @{ + */ +/** + * @} + */ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup HAL_Private_Constants HAL Private Constants + * @{ + */ +/** + * @} + */ +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h new file mode 100644 index 0000000..74a2f15 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h @@ -0,0 +1,766 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_adc.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of ADC HAL extension module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_ADC_H +#define __STM32F4xx_ADC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup ADC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup ADC_Exported_Types ADC Exported Types + * @{ + */ + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_ADC_STATE_RESET = 0x00, /*!< ADC not yet initialized or disabled */ + HAL_ADC_STATE_READY = 0x01, /*!< ADC peripheral ready for use */ + HAL_ADC_STATE_BUSY = 0x02, /*!< An internal process is ongoing */ + HAL_ADC_STATE_BUSY_REG = 0x12, /*!< Regular conversion is ongoing */ + HAL_ADC_STATE_BUSY_INJ = 0x22, /*!< Injected conversion is ongoing */ + HAL_ADC_STATE_BUSY_INJ_REG = 0x32, /*!< Injected and regular conversion are ongoing */ + HAL_ADC_STATE_TIMEOUT = 0x03, /*!< Timeout state */ + HAL_ADC_STATE_ERROR = 0x04, /*!< ADC state error */ + HAL_ADC_STATE_EOC = 0x05, /*!< Conversion is completed */ + HAL_ADC_STATE_EOC_REG = 0x15, /*!< Regular conversion is completed */ + HAL_ADC_STATE_EOC_INJ = 0x25, /*!< Injected conversion is completed */ + HAL_ADC_STATE_EOC_INJ_REG = 0x35, /*!< Injected and regular conversion are completed */ + HAL_ADC_STATE_AWD = 0x06 /*!< ADC state analog watchdog */ + +}HAL_ADC_StateTypeDef; + +/** + * @brief ADC Init structure definition + */ +typedef struct +{ + uint32_t ClockPrescaler; /*!< Select the frequency of the clock to the ADC. The clock is common for + all the ADCs. + This parameter can be a value of @ref ADC_ClockPrescaler */ + uint32_t Resolution; /*!< Configures the ADC resolution dual mode. + This parameter can be a value of @ref ADC_Resolution */ + uint32_t DataAlign; /*!< Specifies whether the ADC data alignment is left or right. + This parameter can be a value of @ref ADC_data_align */ + uint32_t ScanConvMode; /*!< Specifies whether the conversion is performed in Scan (multi channels) or + Single (one channel) mode. + This parameter can be set to ENABLE or DISABLE */ + uint32_t EOCSelection; /*!< Specifies whether the EOC flag is set + at the end of single channel conversion or at the end of all conversions. + This parameter can be a value of @ref ADC_EOCSelection + Note: Impact on overrun when not using DMA: When EOCSelection is set to ADC_EOC_SINGLE_CONV, + overrun detection is automatically enabled, in this case each conversion data must be read. + To perform ADC conversions without having to read all conversion data, this parameter must + be set to ADC_EOC_SEQ_CONV */ + uint32_t ContinuousConvMode; /*!< Specifies whether the conversion is performed in Continuous or Single mode. + This parameter can be set to ENABLE or DISABLE. */ + uint32_t DMAContinuousRequests; /*!< Specifies whether the DMA requests is performed in Continuous or in Single mode. + This parameter can be set to ENABLE or DISABLE. */ + uint32_t NbrOfConversion; /*!< Specifies the number of ADC conversions that will be done using the sequencer for + regular channel group. + This parameter must be a number between Min_Data = 1 and Max_Data = 16. */ + uint32_t DiscontinuousConvMode; /*!< Specifies whether the conversion is performed in Discontinuous or not + for regular channels. + This parameter can be set to ENABLE or DISABLE. */ + uint32_t NbrOfDiscConversion; /*!< Specifies the number of ADC discontinuous conversions that will be done + using the sequencer for regular channel group. + This parameter must be a number between Min_Data = 1 and Max_Data = 8. */ + uint32_t ExternalTrigConv; /*!< Selects the external event used to trigger the conversion start of regular group. + If set to ADC_SOFTWARE_START, external triggers are disabled. + This parameter can be a value of @ref ADC_External_trigger_Source_Regular + Note: This parameter can be modified only if there is no conversion is ongoing. */ + uint32_t ExternalTrigConvEdge; /*!< Selects the external trigger edge of regular group. + If trigger is set to ADC_SOFTWARE_START, this parameter is discarded. + This parameter can be a value of @ref ADC_External_trigger_edge_Regular + Note: This parameter can be modified only if there is no conversion is ongoing. */ +}ADC_InitTypeDef; + +/** + * @brief ADC handle Structure definition + */ +typedef struct +{ + ADC_TypeDef *Instance; /*!< Register base address */ + + ADC_InitTypeDef Init; /*!< ADC required parameters */ + + __IO uint32_t NbrOfCurrentConversionRank; /*!< ADC number of current conversion rank */ + + DMA_HandleTypeDef *DMA_Handle; /*!< Pointer DMA Handler */ + + HAL_LockTypeDef Lock; /*!< ADC locking object */ + + __IO HAL_ADC_StateTypeDef State; /*!< ADC communication state */ + + __IO uint32_t ErrorCode; /*!< ADC Error code */ +}ADC_HandleTypeDef; + +/** + * @brief ADC Configuration regular Channel structure definition + */ +typedef struct +{ + uint32_t Channel; /*!< The ADC channel to configure. + This parameter can be a value of @ref ADC_channels */ + uint32_t Rank; /*!< The rank in the regular group sequencer. + This parameter must be a number between Min_Data = 1 and Max_Data = 16 */ + uint32_t SamplingTime; /*!< The sample time value to be set for the selected channel. + This parameter can be a value of @ref ADC_sampling_times */ + uint32_t Offset; /*!< Reserved for future use, can be set to 0 */ +}ADC_ChannelConfTypeDef; + +/** + * @brief ADC Configuration multi-mode structure definition + */ +typedef struct +{ + uint32_t WatchdogMode; /*!< Configures the ADC analog watchdog mode. + This parameter can be a value of @ref ADC_analog_watchdog_selection */ + uint32_t HighThreshold; /*!< Configures the ADC analog watchdog High threshold value. + This parameter must be a 12-bit value. */ + uint32_t LowThreshold; /*!< Configures the ADC analog watchdog High threshold value. + This parameter must be a 12-bit value. */ + uint32_t Channel; /*!< Configures ADC channel for the analog watchdog. + This parameter has an effect only if watchdog mode is configured on single channel + This parameter can be a value of @ref ADC_channels */ + uint32_t ITMode; /*!< Specifies whether the analog watchdog is configured + is interrupt mode or in polling mode. + This parameter can be set to ENABLE or DISABLE */ + uint32_t WatchdogNumber; /*!< Reserved for future use, can be set to 0 */ +}ADC_AnalogWDGConfTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup ADC_Exported_Constants ADC Exported Constants + * @{ + */ + +/** @defgroup ADC_Error_Code ADC Error Code + * @{ + */ +#define HAL_ADC_ERROR_NONE ((uint32_t)0x00) /*!< No error */ +#define HAL_ADC_ERROR_OVR ((uint32_t)0x01) /*!< OVR error */ +#define HAL_ADC_ERROR_DMA ((uint32_t)0x02) /*!< DMA transfer error */ +/** + * @} + */ + + +/** @defgroup ADC_ClockPrescaler ADC Clock Prescaler + * @{ + */ +#define ADC_CLOCKPRESCALER_PCLK_DIV2 ((uint32_t)0x00000000) +#define ADC_CLOCKPRESCALER_PCLK_DIV4 ((uint32_t)ADC_CCR_ADCPRE_0) +#define ADC_CLOCKPRESCALER_PCLK_DIV6 ((uint32_t)ADC_CCR_ADCPRE_1) +#define ADC_CLOCKPRESCALER_PCLK_DIV8 ((uint32_t)ADC_CCR_ADCPRE) +/** + * @} + */ + +/** @defgroup ADC_delay_between_2_sampling_phases ADC Delay Between 2 Sampling Phases + * @{ + */ +#define ADC_TWOSAMPLINGDELAY_5CYCLES ((uint32_t)0x00000000) +#define ADC_TWOSAMPLINGDELAY_6CYCLES ((uint32_t)ADC_CCR_DELAY_0) +#define ADC_TWOSAMPLINGDELAY_7CYCLES ((uint32_t)ADC_CCR_DELAY_1) +#define ADC_TWOSAMPLINGDELAY_8CYCLES ((uint32_t)(ADC_CCR_DELAY_1 | ADC_CCR_DELAY_0)) +#define ADC_TWOSAMPLINGDELAY_9CYCLES ((uint32_t)ADC_CCR_DELAY_2) +#define ADC_TWOSAMPLINGDELAY_10CYCLES ((uint32_t)(ADC_CCR_DELAY_2 | ADC_CCR_DELAY_0)) +#define ADC_TWOSAMPLINGDELAY_11CYCLES ((uint32_t)(ADC_CCR_DELAY_2 | ADC_CCR_DELAY_1)) +#define ADC_TWOSAMPLINGDELAY_12CYCLES ((uint32_t)(ADC_CCR_DELAY_2 | ADC_CCR_DELAY_1 | ADC_CCR_DELAY_0)) +#define ADC_TWOSAMPLINGDELAY_13CYCLES ((uint32_t)ADC_CCR_DELAY_3) +#define ADC_TWOSAMPLINGDELAY_14CYCLES ((uint32_t)(ADC_CCR_DELAY_3 | ADC_CCR_DELAY_0)) +#define ADC_TWOSAMPLINGDELAY_15CYCLES ((uint32_t)(ADC_CCR_DELAY_3 | ADC_CCR_DELAY_1)) +#define ADC_TWOSAMPLINGDELAY_16CYCLES ((uint32_t)(ADC_CCR_DELAY_3 | ADC_CCR_DELAY_1 | ADC_CCR_DELAY_0)) +#define ADC_TWOSAMPLINGDELAY_17CYCLES ((uint32_t)(ADC_CCR_DELAY_3 | ADC_CCR_DELAY_2)) +#define ADC_TWOSAMPLINGDELAY_18CYCLES ((uint32_t)(ADC_CCR_DELAY_3 | ADC_CCR_DELAY_2 | ADC_CCR_DELAY_0)) +#define ADC_TWOSAMPLINGDELAY_19CYCLES ((uint32_t)(ADC_CCR_DELAY_3 | ADC_CCR_DELAY_2 | ADC_CCR_DELAY_1)) +#define ADC_TWOSAMPLINGDELAY_20CYCLES ((uint32_t)ADC_CCR_DELAY) +/** + * @} + */ + +/** @defgroup ADC_Resolution ADC Resolution + * @{ + */ +#define ADC_RESOLUTION_12B ((uint32_t)0x00000000) +#define ADC_RESOLUTION_10B ((uint32_t)ADC_CR1_RES_0) +#define ADC_RESOLUTION_8B ((uint32_t)ADC_CR1_RES_1) +#define ADC_RESOLUTION_6B ((uint32_t)ADC_CR1_RES) +/** + * @} + */ + +/** @defgroup ADC_External_trigger_edge_Regular ADC External Trigger Edge Regular + * @{ + */ +#define ADC_EXTERNALTRIGCONVEDGE_NONE ((uint32_t)0x00000000) +#define ADC_EXTERNALTRIGCONVEDGE_RISING ((uint32_t)ADC_CR2_EXTEN_0) +#define ADC_EXTERNALTRIGCONVEDGE_FALLING ((uint32_t)ADC_CR2_EXTEN_1) +#define ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING ((uint32_t)ADC_CR2_EXTEN) +/** + * @} + */ + +/** @defgroup ADC_External_trigger_Source_Regular ADC External Trigger Source Regular + * @{ + */ +/* Note: Parameter ADC_SOFTWARE_START is a software parameter used for */ +/* compatibility with other STM32 devices. */ +#define ADC_EXTERNALTRIGCONV_T1_CC1 ((uint32_t)0x00000000) +#define ADC_EXTERNALTRIGCONV_T1_CC2 ((uint32_t)ADC_CR2_EXTSEL_0) +#define ADC_EXTERNALTRIGCONV_T1_CC3 ((uint32_t)ADC_CR2_EXTSEL_1) +#define ADC_EXTERNALTRIGCONV_T2_CC2 ((uint32_t)(ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0)) +#define ADC_EXTERNALTRIGCONV_T2_CC3 ((uint32_t)ADC_CR2_EXTSEL_2) +#define ADC_EXTERNALTRIGCONV_T2_CC4 ((uint32_t)(ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_0)) +#define ADC_EXTERNALTRIGCONV_T2_TRGO ((uint32_t)(ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1)) +#define ADC_EXTERNALTRIGCONV_T3_CC1 ((uint32_t)(ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0)) +#define ADC_EXTERNALTRIGCONV_T3_TRGO ((uint32_t)ADC_CR2_EXTSEL_3) +#define ADC_EXTERNALTRIGCONV_T4_CC4 ((uint32_t)(ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_0)) +#define ADC_EXTERNALTRIGCONV_T5_CC1 ((uint32_t)(ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_1)) +#define ADC_EXTERNALTRIGCONV_T5_CC2 ((uint32_t)(ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0)) +#define ADC_EXTERNALTRIGCONV_T5_CC3 ((uint32_t)(ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_2)) +#define ADC_EXTERNALTRIGCONV_T8_CC1 ((uint32_t)(ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_0)) +#define ADC_EXTERNALTRIGCONV_T8_TRGO ((uint32_t)(ADC_CR2_EXTSEL_3 | ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1)) +#define ADC_EXTERNALTRIGCONV_Ext_IT11 ((uint32_t)ADC_CR2_EXTSEL) +#define ADC_SOFTWARE_START ((uint32_t)ADC_CR2_EXTSEL + 1) +/** + * @} + */ + +/** @defgroup ADC_data_align ADC Data Align + * @{ + */ +#define ADC_DATAALIGN_RIGHT ((uint32_t)0x00000000) +#define ADC_DATAALIGN_LEFT ((uint32_t)ADC_CR2_ALIGN) +/** + * @} + */ + +/** @defgroup ADC_channels ADC Common Channels + * @{ + */ +#define ADC_CHANNEL_0 ((uint32_t)0x00000000) +#define ADC_CHANNEL_1 ((uint32_t)ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_2 ((uint32_t)ADC_CR1_AWDCH_1) +#define ADC_CHANNEL_3 ((uint32_t)(ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0)) +#define ADC_CHANNEL_4 ((uint32_t)ADC_CR1_AWDCH_2) +#define ADC_CHANNEL_5 ((uint32_t)(ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_0)) +#define ADC_CHANNEL_6 ((uint32_t)(ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1)) +#define ADC_CHANNEL_7 ((uint32_t)(ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0)) +#define ADC_CHANNEL_8 ((uint32_t)ADC_CR1_AWDCH_3) +#define ADC_CHANNEL_9 ((uint32_t)(ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_0)) +#define ADC_CHANNEL_10 ((uint32_t)(ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_1)) +#define ADC_CHANNEL_11 ((uint32_t)(ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0)) +#define ADC_CHANNEL_12 ((uint32_t)(ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2)) +#define ADC_CHANNEL_13 ((uint32_t)(ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_0)) +#define ADC_CHANNEL_14 ((uint32_t)(ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1)) +#define ADC_CHANNEL_15 ((uint32_t)(ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0)) +#define ADC_CHANNEL_16 ((uint32_t)ADC_CR1_AWDCH_4) +#define ADC_CHANNEL_17 ((uint32_t)(ADC_CR1_AWDCH_4 | ADC_CR1_AWDCH_0)) +#define ADC_CHANNEL_18 ((uint32_t)(ADC_CR1_AWDCH_4 | ADC_CR1_AWDCH_1)) + +#define ADC_CHANNEL_VREFINT ((uint32_t)ADC_CHANNEL_17) +#define ADC_CHANNEL_VBAT ((uint32_t)ADC_CHANNEL_18) +/** + * @} + */ + +/** @defgroup ADC_sampling_times ADC Sampling Times + * @{ + */ +#define ADC_SAMPLETIME_3CYCLES ((uint32_t)0x00000000) +#define ADC_SAMPLETIME_15CYCLES ((uint32_t)ADC_SMPR1_SMP10_0) +#define ADC_SAMPLETIME_28CYCLES ((uint32_t)ADC_SMPR1_SMP10_1) +#define ADC_SAMPLETIME_56CYCLES ((uint32_t)(ADC_SMPR1_SMP10_1 | ADC_SMPR1_SMP10_0)) +#define ADC_SAMPLETIME_84CYCLES ((uint32_t)ADC_SMPR1_SMP10_2) +#define ADC_SAMPLETIME_112CYCLES ((uint32_t)(ADC_SMPR1_SMP10_2 | ADC_SMPR1_SMP10_0)) +#define ADC_SAMPLETIME_144CYCLES ((uint32_t)(ADC_SMPR1_SMP10_2 | ADC_SMPR1_SMP10_1)) +#define ADC_SAMPLETIME_480CYCLES ((uint32_t)ADC_SMPR1_SMP10) +/** + * @} + */ + + /** @defgroup ADC_EOCSelection ADC EOC Selection + * @{ + */ +#define ADC_EOC_SEQ_CONV ((uint32_t)0x00000000) +#define ADC_EOC_SINGLE_CONV ((uint32_t)0x00000001) +#define ADC_EOC_SINGLE_SEQ_CONV ((uint32_t)0x00000002) /*!< reserved for future use */ +/** + * @} + */ + +/** @defgroup ADC_Event_type ADC Event Type + * @{ + */ +#define ADC_AWD_EVENT ((uint32_t)ADC_FLAG_AWD) +#define ADC_OVR_EVENT ((uint32_t)ADC_FLAG_OVR) +/** + * @} + */ + +/** @defgroup ADC_analog_watchdog_selection ADC Analog Watchdog Selection + * @{ + */ +#define ADC_ANALOGWATCHDOG_SINGLE_REG ((uint32_t)(ADC_CR1_AWDSGL | ADC_CR1_AWDEN)) +#define ADC_ANALOGWATCHDOG_SINGLE_INJEC ((uint32_t)(ADC_CR1_AWDSGL | ADC_CR1_JAWDEN)) +#define ADC_ANALOGWATCHDOG_SINGLE_REGINJEC ((uint32_t)(ADC_CR1_AWDSGL | ADC_CR1_AWDEN | ADC_CR1_JAWDEN)) +#define ADC_ANALOGWATCHDOG_ALL_REG ((uint32_t)ADC_CR1_AWDEN) +#define ADC_ANALOGWATCHDOG_ALL_INJEC ((uint32_t)ADC_CR1_JAWDEN) +#define ADC_ANALOGWATCHDOG_ALL_REGINJEC ((uint32_t)(ADC_CR1_AWDEN | ADC_CR1_JAWDEN)) +#define ADC_ANALOGWATCHDOG_NONE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ADC_interrupts_definition ADC Interrupts Definition + * @{ + */ +#define ADC_IT_EOC ((uint32_t)ADC_CR1_EOCIE) +#define ADC_IT_AWD ((uint32_t)ADC_CR1_AWDIE) +#define ADC_IT_JEOC ((uint32_t)ADC_CR1_JEOCIE) +#define ADC_IT_OVR ((uint32_t)ADC_CR1_OVRIE) +/** + * @} + */ + +/** @defgroup ADC_flags_definition ADC Flags Definition + * @{ + */ +#define ADC_FLAG_AWD ((uint32_t)ADC_SR_AWD) +#define ADC_FLAG_EOC ((uint32_t)ADC_SR_EOC) +#define ADC_FLAG_JEOC ((uint32_t)ADC_SR_JEOC) +#define ADC_FLAG_JSTRT ((uint32_t)ADC_SR_JSTRT) +#define ADC_FLAG_STRT ((uint32_t)ADC_SR_STRT) +#define ADC_FLAG_OVR ((uint32_t)ADC_SR_OVR) +/** + * @} + */ + +/** @defgroup ADC_channels_type ADC Channels Type + * @{ + */ +#define ADC_ALL_CHANNELS ((uint32_t)0x00000001) +#define ADC_REGULAR_CHANNELS ((uint32_t)0x00000002) /*!< reserved for future use */ +#define ADC_INJECTED_CHANNELS ((uint32_t)0x00000003) /*!< reserved for future use */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup ADC_Exported_Macros ADC Exported Macros + * @{ + */ + +/** @brief Reset ADC handle state + * @param __HANDLE__: ADC handle + * @retval None + */ +#define __HAL_ADC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_ADC_STATE_RESET) + +/** + * @brief Enable the ADC peripheral. + * @param __HANDLE__: ADC handle + * @retval None + */ +#define __HAL_ADC_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR2 |= ADC_CR2_ADON) + +/** + * @brief Disable the ADC peripheral. + * @param __HANDLE__: ADC handle + * @retval None + */ +#define __HAL_ADC_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR2 &= ~ADC_CR2_ADON) + +/** + * @brief Enable the ADC end of conversion interrupt. + * @param __HANDLE__: specifies the ADC Handle. + * @param __INTERRUPT__: ADC Interrupt. + * @retval None + */ +#define __HAL_ADC_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR1) |= (__INTERRUPT__)) + +/** + * @brief Disable the ADC end of conversion interrupt. + * @param __HANDLE__: specifies the ADC Handle. + * @param __INTERRUPT__: ADC interrupt. + * @retval None + */ +#define __HAL_ADC_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR1) &= ~(__INTERRUPT__)) + +/** @brief Check if the specified ADC interrupt source is enabled or disabled. + * @param __HANDLE__: specifies the ADC Handle. + * @param __INTERRUPT__: specifies the ADC interrupt source to check. + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_ADC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR1 & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @brief Clear the ADC's pending flags. + * @param __HANDLE__: specifies the ADC Handle. + * @param __FLAG__: ADC flag. + * @retval None + */ +#define __HAL_ADC_CLEAR_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR) = ~(__FLAG__)) + +/** + * @brief Get the selected ADC's flag status. + * @param __HANDLE__: specifies the ADC Handle. + * @param __FLAG__: ADC flag. + * @retval None + */ +#define __HAL_ADC_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__)) + +/** + * @} + */ + +/* Include ADC HAL Extension module */ +#include "stm32f4xx_hal_adc_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup ADC_Exported_Functions + * @{ + */ + +/** @addtogroup ADC_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions ***********************************/ +HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc); +HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc); +void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc); +void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc); +/** + * @} + */ + +/** @addtogroup ADC_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions ******************************************************/ +HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc); +HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc); +HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout); + +HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout); + +HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc); +HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc); + +void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc); + +HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length); +HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc); + +uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc); + +void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc); +void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc); +void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc); +void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc); +/** + * @} + */ + +/** @addtogroup ADC_Exported_Functions_Group3 + * @{ + */ +/* Peripheral Control functions *************************************************/ +HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig); +HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDGConfTypeDef* AnalogWDGConfig); +/** + * @} + */ + +/** @addtogroup ADC_Exported_Functions_Group4 + * @{ + */ +/* Peripheral State functions ***************************************************/ +HAL_ADC_StateTypeDef HAL_ADC_GetState(ADC_HandleTypeDef* hadc); +uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup ADC_Private_Constants ADC Private Constants + * @{ + */ +/* Delay for ADC stabilization time. */ +/* Maximum delay is 1us (refer to device datasheet, parameter tSTAB). */ +/* Unit: us */ +#define ADC_STAB_DELAY_US ((uint32_t) 3) +/* Delay for temperature sensor stabilization time. */ +/* Maximum delay is 10us (refer to device datasheet, parameter tSTART). */ +/* Unit: us */ +#define ADC_TEMPSENSOR_DELAY_US ((uint32_t) 10) +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup ADC_Private_Macros ADC Private Macros + * @{ + */ +#define IS_ADC_CLOCKPRESCALER(ADC_CLOCK) (((ADC_CLOCK) == ADC_CLOCKPRESCALER_PCLK_DIV2) || \ + ((ADC_CLOCK) == ADC_CLOCKPRESCALER_PCLK_DIV4) || \ + ((ADC_CLOCK) == ADC_CLOCKPRESCALER_PCLK_DIV6) || \ + ((ADC_CLOCK) == ADC_CLOCKPRESCALER_PCLK_DIV8)) +#define IS_ADC_SAMPLING_DELAY(DELAY) (((DELAY) == ADC_TWOSAMPLINGDELAY_5CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_6CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_7CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_8CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_9CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_10CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_11CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_12CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_13CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_14CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_15CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_16CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_17CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_18CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_19CYCLES) || \ + ((DELAY) == ADC_TWOSAMPLINGDELAY_20CYCLES)) +#define IS_ADC_RESOLUTION(RESOLUTION) (((RESOLUTION) == ADC_RESOLUTION_12B) || \ + ((RESOLUTION) == ADC_RESOLUTION_10B) || \ + ((RESOLUTION) == ADC_RESOLUTION_8B) || \ + ((RESOLUTION) == ADC_RESOLUTION_6B)) +#define IS_ADC_EXT_TRIG_EDGE(EDGE) (((EDGE) == ADC_EXTERNALTRIGCONVEDGE_NONE) || \ + ((EDGE) == ADC_EXTERNALTRIGCONVEDGE_RISING) || \ + ((EDGE) == ADC_EXTERNALTRIGCONVEDGE_FALLING) || \ + ((EDGE) == ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING)) +#define IS_ADC_EXT_TRIG(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC2) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC3) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC2) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC3) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T4_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T5_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T5_CC2) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T5_CC3) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T8_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T8_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_Ext_IT11)|| \ + ((REGTRIG) == ADC_SOFTWARE_START)) +#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DATAALIGN_RIGHT) || \ + ((ALIGN) == ADC_DATAALIGN_LEFT)) +#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SAMPLETIME_3CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_15CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_28CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_56CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_84CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_112CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_144CYCLES) || \ + ((TIME) == ADC_SAMPLETIME_480CYCLES)) +#define IS_ADC_EOCSelection(EOCSelection) (((EOCSelection) == ADC_EOC_SINGLE_CONV) || \ + ((EOCSelection) == ADC_EOC_SEQ_CONV) || \ + ((EOCSelection) == ADC_EOC_SINGLE_SEQ_CONV)) +#define IS_ADC_EVENT_TYPE(EVENT) (((EVENT) == ADC_AWD_EVENT) || \ + ((EVENT) == ADC_OVR_EVENT)) +#define IS_ADC_ANALOG_WATCHDOG(WATCHDOG) (((WATCHDOG) == ADC_ANALOGWATCHDOG_SINGLE_REG) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_SINGLE_INJEC) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_ALL_REG) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_ALL_INJEC) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_ALL_REGINJEC) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_NONE)) +#define IS_ADC_CHANNELS_TYPE(CHANNEL_TYPE) (((CHANNEL_TYPE) == ADC_ALL_CHANNELS) || \ + ((CHANNEL_TYPE) == ADC_REGULAR_CHANNELS) || \ + ((CHANNEL_TYPE) == ADC_INJECTED_CHANNELS)) +#define IS_ADC_THRESHOLD(THRESHOLD) ((THRESHOLD) <= ((uint32_t)0xFFF)) + +#define IS_ADC_REGULAR_LENGTH(LENGTH) (((LENGTH) >= ((uint32_t)1)) && ((LENGTH) <= ((uint32_t)16))) +#define IS_ADC_REGULAR_RANK(RANK) (((RANK) >= ((uint32_t)1)) && ((RANK) <= ((uint32_t)16))) +#define IS_ADC_REGULAR_DISC_NUMBER(NUMBER) (((NUMBER) >= ((uint32_t)1)) && ((NUMBER) <= ((uint32_t)8))) +#define IS_ADC_RANGE(RESOLUTION, ADC_VALUE) \ + ((((RESOLUTION) == ADC_RESOLUTION_12B) && ((ADC_VALUE) <= ((uint32_t)0x0FFF))) || \ + (((RESOLUTION) == ADC_RESOLUTION_10B) && ((ADC_VALUE) <= ((uint32_t)0x03FF))) || \ + (((RESOLUTION) == ADC_RESOLUTION_8B) && ((ADC_VALUE) <= ((uint32_t)0x00FF))) || \ + (((RESOLUTION) == ADC_RESOLUTION_6B) && ((ADC_VALUE) <= ((uint32_t)0x003F)))) + +/** + * @brief Set ADC Regular channel sequence length. + * @param _NbrOfConversion_: Regular channel sequence length. + * @retval None + */ +#define ADC_SQR1(_NbrOfConversion_) (((_NbrOfConversion_) - (uint8_t)1) << 20) + +/** + * @brief Set the ADC's sample time for channel numbers between 10 and 18. + * @param _SAMPLETIME_: Sample time parameter. + * @param _CHANNELNB_: Channel number. + * @retval None + */ +#define ADC_SMPR1(_SAMPLETIME_, _CHANNELNB_) ((_SAMPLETIME_) << (3 * (((uint32_t)((uint16_t)(_CHANNELNB_))) - 10))) + +/** + * @brief Set the ADC's sample time for channel numbers between 0 and 9. + * @param _SAMPLETIME_: Sample time parameter. + * @param _CHANNELNB_: Channel number. + * @retval None + */ +#define ADC_SMPR2(_SAMPLETIME_, _CHANNELNB_) ((_SAMPLETIME_) << (3 * ((uint32_t)((uint16_t)(_CHANNELNB_))))) + +/** + * @brief Set the selected regular channel rank for rank between 1 and 6. + * @param _CHANNELNB_: Channel number. + * @param _RANKNB_: Rank number. + * @retval None + */ +#define ADC_SQR3_RK(_CHANNELNB_, _RANKNB_) (((uint32_t)((uint16_t)(_CHANNELNB_))) << (5 * ((_RANKNB_) - 1))) + +/** + * @brief Set the selected regular channel rank for rank between 7 and 12. + * @param _CHANNELNB_: Channel number. + * @param _RANKNB_: Rank number. + * @retval None + */ +#define ADC_SQR2_RK(_CHANNELNB_, _RANKNB_) (((uint32_t)((uint16_t)(_CHANNELNB_))) << (5 * ((_RANKNB_) - 7))) + +/** + * @brief Set the selected regular channel rank for rank between 13 and 16. + * @param _CHANNELNB_: Channel number. + * @param _RANKNB_: Rank number. + * @retval None + */ +#define ADC_SQR1_RK(_CHANNELNB_, _RANKNB_) (((uint32_t)((uint16_t)(_CHANNELNB_))) << (5 * ((_RANKNB_) - 13))) + +/** + * @brief Enable ADC continuous conversion mode. + * @param _CONTINUOUS_MODE_: Continuous mode. + * @retval None + */ +#define ADC_CR2_CONTINUOUS(_CONTINUOUS_MODE_) ((_CONTINUOUS_MODE_) << 1) + +/** + * @brief Configures the number of discontinuous conversions for the regular group channels. + * @param _NBR_DISCONTINUOUSCONV_: Number of discontinuous conversions. + * @retval None + */ +#define ADC_CR1_DISCONTINUOUS(_NBR_DISCONTINUOUSCONV_) (((_NBR_DISCONTINUOUSCONV_) - 1) << POSITION_VAL(ADC_CR1_DISCNUM)) + +/** + * @brief Enable ADC scan mode. + * @param _SCANCONV_MODE_: Scan conversion mode. + * @retval None + */ +#define ADC_CR1_SCANCONV(_SCANCONV_MODE_) ((_SCANCONV_MODE_) << 8) + +/** + * @brief Enable the ADC end of conversion selection. + * @param _EOCSelection_MODE_: End of conversion selection mode. + * @retval None + */ +#define ADC_CR2_EOCSelection(_EOCSelection_MODE_) ((_EOCSelection_MODE_) << 10) + +/** + * @brief Enable the ADC DMA continuous request. + * @param _DMAContReq_MODE_: DMA continuous request mode. + * @retval None + */ +#define ADC_CR2_DMAContReq(_DMAContReq_MODE_) ((_DMAContReq_MODE_) << 9) + +/** + * @brief Return resolution bits in CR1 register. + * @param __HANDLE__: ADC handle + * @retval None + */ +#define ADC_GET_RESOLUTION(__HANDLE__) (((__HANDLE__)->Instance->CR1) & ADC_CR1_RES) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup ADC_Private_Functions ADC Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_ADC_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h new file mode 100644 index 0000000..24a010a --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h @@ -0,0 +1,352 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_adc_ex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of ADC HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_ADC_EX_H +#define __STM32F4xx_ADC_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup ADCEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup ADCEx_Exported_Types ADC Exported Types + * @{ + */ + +/** + * @brief ADC Configuration injected Channel structure definition + */ +typedef struct +{ + uint32_t InjectedChannel; /*!< Configure the ADC injected channel. + This parameter can be a value of @ref ADC_channels */ + uint32_t InjectedRank; /*!< The rank in the injected group sequencer + This parameter must be a number between Min_Data = 1 and Max_Data = 4. */ + uint32_t InjectedSamplingTime; /*!< The sample time value to be set for the selected channel. + This parameter can be a value of @ref ADC_sampling_times */ + uint32_t InjectedOffset; /*!< Defines the offset to be subtracted from the raw converted data when convert injected channels. + This parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF. */ + uint32_t InjectedNbrOfConversion; /*!< Specifies the number of ADC conversions that will be done using the sequencer for + injected channel group. + This parameter must be a number between Min_Data = 1 and Max_Data = 4. */ + uint32_t AutoInjectedConv; /*!< Enables or disables the selected ADC automatic injected group + conversion after regular one */ + uint32_t InjectedDiscontinuousConvMode; /*!< Specifies whether the conversion is performed in Discontinuous mode or not for injected channels. + This parameter can be set to ENABLE or DISABLE. */ + uint32_t ExternalTrigInjecConvEdge; /*!< Select the external trigger edge and enable the trigger of an injected channels. + This parameter can be a value of @ref ADCEx_External_trigger_edge_Injected */ + uint32_t ExternalTrigInjecConv; /*!< Select the external event used to trigger the start of conversion of a injected channels. + This parameter can be a value of @ref ADCEx_External_trigger_Source_Injected */ +}ADC_InjectionConfTypeDef; + +/** + * @brief ADC Configuration multi-mode structure definition + */ +typedef struct +{ + uint32_t Mode; /*!< Configures the ADC to operate in independent or multi mode. + This parameter can be a value of @ref ADCEx_Common_mode */ + uint32_t DMAAccessMode; /*!< Configures the Direct memory access mode for multi ADC mode. + This parameter can be a value of @ref ADCEx_Direct_memory_access_mode_for_multi_mode */ + uint32_t TwoSamplingDelay; /*!< Configures the Delay between 2 sampling phases. + This parameter can be a value of @ref ADC_delay_between_2_sampling_phases */ +}ADC_MultiModeTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup ADCEx_Exported_Constants ADC Exported Constants + * @{ + */ + +/** @defgroup ADCEx_Common_mode ADC Common Mode + * @{ + */ +#define ADC_MODE_INDEPENDENT ((uint32_t)0x00000000) +#define ADC_DUALMODE_REGSIMULT_INJECSIMULT ((uint32_t)ADC_CCR_MULTI_0) +#define ADC_DUALMODE_REGSIMULT_ALTERTRIG ((uint32_t)ADC_CCR_MULTI_1) +#define ADC_DUALMODE_INJECSIMULT ((uint32_t)(ADC_CCR_MULTI_2 | ADC_CCR_MULTI_0)) +#define ADC_DUALMODE_REGSIMULT ((uint32_t)(ADC_CCR_MULTI_2 | ADC_CCR_MULTI_1)) +#define ADC_DUALMODE_INTERL ((uint32_t)(ADC_CCR_MULTI_2 | ADC_CCR_MULTI_1 | ADC_CCR_MULTI_0)) +#define ADC_DUALMODE_ALTERTRIG ((uint32_t)(ADC_CCR_MULTI_3 | ADC_CCR_MULTI_0)) +#define ADC_TRIPLEMODE_REGSIMULT_INJECSIMULT ((uint32_t)(ADC_CCR_MULTI_4 | ADC_CCR_MULTI_0)) +#define ADC_TRIPLEMODE_REGSIMULT_AlterTrig ((uint32_t)(ADC_CCR_MULTI_4 | ADC_CCR_MULTI_1)) +#define ADC_TRIPLEMODE_INJECSIMULT ((uint32_t)(ADC_CCR_MULTI_4 | ADC_CCR_MULTI_2 | ADC_CCR_MULTI_0)) +#define ADC_TRIPLEMODE_REGSIMULT ((uint32_t)(ADC_CCR_MULTI_4 | ADC_CCR_MULTI_2 | ADC_CCR_MULTI_1)) +#define ADC_TRIPLEMODE_INTERL ((uint32_t)(ADC_CCR_MULTI_4 | ADC_CCR_MULTI_2 | ADC_CCR_MULTI_1 | ADC_CCR_MULTI_0)) +#define ADC_TRIPLEMODE_ALTERTRIG ((uint32_t)(ADC_CCR_MULTI_4 | ADC_CCR_MULTI_3 | ADC_CCR_MULTI_0)) +/** + * @} + */ + +/** @defgroup ADCEx_Direct_memory_access_mode_for_multi_mode ADC Direct Memory Access Mode For Multi Mode + * @{ + */ +#define ADC_DMAACCESSMODE_DISABLED ((uint32_t)0x00000000) /*!< DMA mode disabled */ +#define ADC_DMAACCESSMODE_1 ((uint32_t)ADC_CCR_DMA_0) /*!< DMA mode 1 enabled (2 / 3 half-words one by one - 1 then 2 then 3)*/ +#define ADC_DMAACCESSMODE_2 ((uint32_t)ADC_CCR_DMA_1) /*!< DMA mode 2 enabled (2 / 3 half-words by pairs - 2&1 then 1&3 then 3&2)*/ +#define ADC_DMAACCESSMODE_3 ((uint32_t)ADC_CCR_DMA) /*!< DMA mode 3 enabled (2 / 3 bytes by pairs - 2&1 then 1&3 then 3&2) */ +/** + * @} + */ + +/** @defgroup ADCEx_External_trigger_edge_Injected ADC External Trigger Edge Injected + * @{ + */ +#define ADC_EXTERNALTRIGINJECCONVEDGE_NONE ((uint32_t)0x00000000) +#define ADC_EXTERNALTRIGINJECCONVEDGE_RISING ((uint32_t)ADC_CR2_JEXTEN_0) +#define ADC_EXTERNALTRIGINJECCONVEDGE_FALLING ((uint32_t)ADC_CR2_JEXTEN_1) +#define ADC_EXTERNALTRIGINJECCONVEDGE_RISINGFALLING ((uint32_t)ADC_CR2_JEXTEN) +/** + * @} + */ + +/** @defgroup ADCEx_External_trigger_Source_Injected ADC External Trigger Source Injected + * @{ + */ +#define ADC_EXTERNALTRIGINJECCONV_T1_CC4 ((uint32_t)0x00000000) +#define ADC_EXTERNALTRIGINJECCONV_T1_TRGO ((uint32_t)ADC_CR2_JEXTSEL_0) +#define ADC_EXTERNALTRIGINJECCONV_T2_CC1 ((uint32_t)ADC_CR2_JEXTSEL_1) +#define ADC_EXTERNALTRIGINJECCONV_T2_TRGO ((uint32_t)(ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0)) +#define ADC_EXTERNALTRIGINJECCONV_T3_CC2 ((uint32_t)ADC_CR2_JEXTSEL_2) +#define ADC_EXTERNALTRIGINJECCONV_T3_CC4 ((uint32_t)(ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_0)) +#define ADC_EXTERNALTRIGINJECCONV_T4_CC1 ((uint32_t)(ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1)) +#define ADC_EXTERNALTRIGINJECCONV_T4_CC2 ((uint32_t)(ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0)) +#define ADC_EXTERNALTRIGINJECCONV_T4_CC3 ((uint32_t)ADC_CR2_JEXTSEL_3) +#define ADC_EXTERNALTRIGINJECCONV_T4_TRGO ((uint32_t)(ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_0)) +#define ADC_EXTERNALTRIGINJECCONV_T5_CC4 ((uint32_t)(ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_1)) +#define ADC_EXTERNALTRIGINJECCONV_T5_TRGO ((uint32_t)(ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0)) +#define ADC_EXTERNALTRIGINJECCONV_T8_CC2 ((uint32_t)(ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_2)) +#define ADC_EXTERNALTRIGINJECCONV_T8_CC3 ((uint32_t)(ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_0)) +#define ADC_EXTERNALTRIGINJECCONV_T8_CC4 ((uint32_t)(ADC_CR2_JEXTSEL_3 | ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1)) +#define ADC_EXTERNALTRIGINJECCONV_EXT_IT15 ((uint32_t)ADC_CR2_JEXTSEL) +#define ADC_INJECTED_SOFTWARE_START ((uint32_t)ADC_CR2_JEXTSEL + 1) +/** + * @} + */ + +/** @defgroup ADCEx_injected_channel_selection ADC Injected Channel Selection + * @{ + */ +#define ADC_INJECTED_RANK_1 ((uint32_t)0x00000001) +#define ADC_INJECTED_RANK_2 ((uint32_t)0x00000002) +#define ADC_INJECTED_RANK_3 ((uint32_t)0x00000003) +#define ADC_INJECTED_RANK_4 ((uint32_t)0x00000004) +/** + * @} + */ + +/** @defgroup ADCEx_channels ADC Specific Channels + * @{ + */ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) +#define ADC_CHANNEL_TEMPSENSOR ((uint32_t)ADC_CHANNEL_16) +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F411xE */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) +#define ADC_CHANNEL_DIFFERENCIATION_TEMPSENSOR_VBAT ((uint32_t)0x10000000) /* Dummy bit for driver internal usage, not used in ADC channel setting registers CR1 or SQRx */ +#define ADC_CHANNEL_TEMPSENSOR ((uint32_t)ADC_CHANNEL_18 | ADC_CHANNEL_DIFFERENCIATION_TEMPSENSOR_VBAT) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ +/** + * @} + */ + + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup ADC_Exported_Macros ADC Exported Macros + * @{ + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup ADCEx_Exported_Functions + * @{ + */ + +/** @addtogroup ADCEx_Exported_Functions_Group1 + * @{ + */ + +/* I/O operation functions ******************************************************/ +HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef* hadc); +HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef* hadc); +HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout); +HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef* hadc); +HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef* hadc); +uint32_t HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef* hadc, uint32_t InjectedRank); +HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length); +HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef* hadc); +uint32_t HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef* hadc); +void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc); + +/* Peripheral Control functions *************************************************/ +HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc,ADC_InjectionConfTypeDef* sConfigInjected); +HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef* hadc, ADC_MultiModeTypeDef* multimode); + +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup ADCEx_Private_Constants ADC Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup ADCEx_Private_Macros ADC Private Macros + * @{ + */ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) +#define IS_ADC_CHANNEL(CHANNEL) ((CHANNEL) <= ADC_CHANNEL_18) +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F411xE */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) +#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) <= ADC_CHANNEL_18) || \ + ((CHANNEL) == ADC_CHANNEL_TEMPSENSOR)) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ + +#define IS_ADC_MODE(MODE) (((MODE) == ADC_MODE_INDEPENDENT) || \ + ((MODE) == ADC_DUALMODE_REGSIMULT_INJECSIMULT) || \ + ((MODE) == ADC_DUALMODE_REGSIMULT_ALTERTRIG) || \ + ((MODE) == ADC_DUALMODE_INJECSIMULT) || \ + ((MODE) == ADC_DUALMODE_REGSIMULT) || \ + ((MODE) == ADC_DUALMODE_INTERL) || \ + ((MODE) == ADC_DUALMODE_ALTERTRIG) || \ + ((MODE) == ADC_TRIPLEMODE_REGSIMULT_INJECSIMULT) || \ + ((MODE) == ADC_TRIPLEMODE_REGSIMULT_AlterTrig) || \ + ((MODE) == ADC_TRIPLEMODE_INJECSIMULT) || \ + ((MODE) == ADC_TRIPLEMODE_REGSIMULT) || \ + ((MODE) == ADC_TRIPLEMODE_INTERL) || \ + ((MODE) == ADC_TRIPLEMODE_ALTERTRIG)) +#define IS_ADC_DMA_ACCESS_MODE(MODE) (((MODE) == ADC_DMAACCESSMODE_DISABLED) || \ + ((MODE) == ADC_DMAACCESSMODE_1) || \ + ((MODE) == ADC_DMAACCESSMODE_2) || \ + ((MODE) == ADC_DMAACCESSMODE_3)) +#define IS_ADC_EXT_INJEC_TRIG_EDGE(EDGE) (((EDGE) == ADC_EXTERNALTRIGINJECCONVEDGE_NONE) || \ + ((EDGE) == ADC_EXTERNALTRIGINJECCONVEDGE_RISING) || \ + ((EDGE) == ADC_EXTERNALTRIGINJECCONVEDGE_FALLING) || \ + ((EDGE) == ADC_EXTERNALTRIGINJECCONVEDGE_RISINGFALLING)) +#define IS_ADC_EXT_INJEC_TRIG(INJTRIG) (((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_CC4) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_TRGO) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_CC1) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_TRGO) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T3_CC2) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T3_CC4) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_CC1) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_CC2) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_CC3) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_TRGO) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T5_CC4) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T5_TRGO) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T8_CC2) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T8_CC3) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_T8_CC4) || \ + ((INJTRIG) == ADC_EXTERNALTRIGINJECCONV_EXT_IT15)|| \ + ((INJTRIG) == ADC_INJECTED_SOFTWARE_START)) +#define IS_ADC_INJECTED_LENGTH(LENGTH) (((LENGTH) >= ((uint32_t)1)) && ((LENGTH) <= ((uint32_t)4))) +#define IS_ADC_INJECTED_RANK(RANK) (((RANK) >= ((uint32_t)1)) && ((RANK) <= ((uint32_t)4))) + +/** + * @brief Set the selected injected Channel rank. + * @param _CHANNELNB_: Channel number. + * @param _RANKNB_: Rank number. + * @param _JSQR_JL_: Sequence length. + * @retval None + */ +#define ADC_JSQR(_CHANNELNB_, _RANKNB_, _JSQR_JL_) (((uint32_t)((uint16_t)(_CHANNELNB_))) << (5 * (uint8_t)(((_RANKNB_) + 3) - (_JSQR_JL_)))) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup ADCEx_Private_Functions ADC Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_ADC_EX_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_can.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_can.h new file mode 100644 index 0000000..210d89f --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_can.h @@ -0,0 +1,775 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_can.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of CAN HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_CAN_H +#define __STM32F4xx_HAL_CAN_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F446xx) +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup CAN + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup CAN_Exported_Types CAN Exported Types + * @{ + */ + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_CAN_STATE_RESET = 0x00, /*!< CAN not yet initialized or disabled */ + HAL_CAN_STATE_READY = 0x01, /*!< CAN initialized and ready for use */ + HAL_CAN_STATE_BUSY = 0x02, /*!< CAN process is ongoing */ + HAL_CAN_STATE_BUSY_TX = 0x12, /*!< CAN process is ongoing */ + HAL_CAN_STATE_BUSY_RX = 0x22, /*!< CAN process is ongoing */ + HAL_CAN_STATE_BUSY_TX_RX = 0x32, /*!< CAN process is ongoing */ + HAL_CAN_STATE_TIMEOUT = 0x03, /*!< Timeout state */ + HAL_CAN_STATE_ERROR = 0x04 /*!< CAN error state */ + +}HAL_CAN_StateTypeDef; + +/** + * @brief CAN init structure definition + */ +typedef struct +{ + uint32_t Prescaler; /*!< Specifies the length of a time quantum. + This parameter must be a number between Min_Data = 1 and Max_Data = 1024 */ + + uint32_t Mode; /*!< Specifies the CAN operating mode. + This parameter can be a value of @ref CAN_operating_mode */ + + uint32_t SJW; /*!< Specifies the maximum number of time quanta + the CAN hardware is allowed to lengthen or + shorten a bit to perform resynchronization. + This parameter can be a value of @ref CAN_synchronisation_jump_width */ + + uint32_t BS1; /*!< Specifies the number of time quanta in Bit Segment 1. + This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_1 */ + + uint32_t BS2; /*!< Specifies the number of time quanta in Bit Segment 2. + This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 */ + + uint32_t TTCM; /*!< Enable or disable the time triggered communication mode. + This parameter can be set to ENABLE or DISABLE. */ + + uint32_t ABOM; /*!< Enable or disable the automatic bus-off management. + This parameter can be set to ENABLE or DISABLE */ + + uint32_t AWUM; /*!< Enable or disable the automatic wake-up mode. + This parameter can be set to ENABLE or DISABLE */ + + uint32_t NART; /*!< Enable or disable the non-automatic retransmission mode. + This parameter can be set to ENABLE or DISABLE */ + + uint32_t RFLM; /*!< Enable or disable the receive FIFO Locked mode. + This parameter can be set to ENABLE or DISABLE */ + + uint32_t TXFP; /*!< Enable or disable the transmit FIFO priority. + This parameter can be set to ENABLE or DISABLE */ +}CAN_InitTypeDef; + +/** + * @brief CAN filter configuration structure definition + */ +typedef struct +{ + uint32_t FilterIdHigh; /*!< Specifies the filter identification number (MSBs for a 32-bit + configuration, first one for a 16-bit configuration). + This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ + + uint32_t FilterIdLow; /*!< Specifies the filter identification number (LSBs for a 32-bit + configuration, second one for a 16-bit configuration). + This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ + + uint32_t FilterMaskIdHigh; /*!< Specifies the filter mask number or identification number, + according to the mode (MSBs for a 32-bit configuration, + first one for a 16-bit configuration). + This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ + + uint32_t FilterMaskIdLow; /*!< Specifies the filter mask number or identification number, + according to the mode (LSBs for a 32-bit configuration, + second one for a 16-bit configuration). + This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ + + uint32_t FilterFIFOAssignment; /*!< Specifies the FIFO (0 or 1) which will be assigned to the filter. + This parameter can be a value of @ref CAN_filter_FIFO */ + + uint32_t FilterNumber; /*!< Specifies the filter which will be initialized. + This parameter must be a number between Min_Data = 0 and Max_Data = 27 */ + + uint32_t FilterMode; /*!< Specifies the filter mode to be initialized. + This parameter can be a value of @ref CAN_filter_mode */ + + uint32_t FilterScale; /*!< Specifies the filter scale. + This parameter can be a value of @ref CAN_filter_scale */ + + uint32_t FilterActivation; /*!< Enable or disable the filter. + This parameter can be set to ENABLE or DISABLE. */ + + uint32_t BankNumber; /*!< Select the start slave bank filter. + This parameter must be a number between Min_Data = 0 and Max_Data = 28 */ + +}CAN_FilterConfTypeDef; + +/** + * @brief CAN Tx message structure definition + */ +typedef struct +{ + uint32_t StdId; /*!< Specifies the standard identifier. + This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF */ + + uint32_t ExtId; /*!< Specifies the extended identifier. + This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF */ + + uint32_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted. + This parameter can be a value of @ref CAN_Identifier_Type */ + + uint32_t RTR; /*!< Specifies the type of frame for the message that will be transmitted. + This parameter can be a value of @ref CAN_remote_transmission_request */ + + uint32_t DLC; /*!< Specifies the length of the frame that will be transmitted. + This parameter must be a number between Min_Data = 0 and Max_Data = 8 */ + + uint8_t Data[8]; /*!< Contains the data to be transmitted. + This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */ + +}CanTxMsgTypeDef; + +/** + * @brief CAN Rx message structure definition + */ +typedef struct +{ + uint32_t StdId; /*!< Specifies the standard identifier. + This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF */ + + uint32_t ExtId; /*!< Specifies the extended identifier. + This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF */ + + uint32_t IDE; /*!< Specifies the type of identifier for the message that will be received. + This parameter can be a value of @ref CAN_Identifier_Type */ + + uint32_t RTR; /*!< Specifies the type of frame for the received message. + This parameter can be a value of @ref CAN_remote_transmission_request */ + + uint32_t DLC; /*!< Specifies the length of the frame that will be received. + This parameter must be a number between Min_Data = 0 and Max_Data = 8 */ + + uint8_t Data[8]; /*!< Contains the data to be received. + This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */ + + uint32_t FMI; /*!< Specifies the index of the filter the message stored in the mailbox passes through. + This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */ + + uint32_t FIFONumber; /*!< Specifies the receive FIFO number. + This parameter can be CAN_FIFO0 or CAN_FIFO1 */ + +}CanRxMsgTypeDef; + +/** + * @brief CAN handle Structure definition + */ +typedef struct +{ + CAN_TypeDef *Instance; /*!< Register base address */ + + CAN_InitTypeDef Init; /*!< CAN required parameters */ + + CanTxMsgTypeDef* pTxMsg; /*!< Pointer to transmit structure */ + + CanRxMsgTypeDef* pRxMsg; /*!< Pointer to reception structure */ + + __IO HAL_CAN_StateTypeDef State; /*!< CAN communication state */ + + HAL_LockTypeDef Lock; /*!< CAN locking object */ + + __IO uint32_t ErrorCode; /*!< CAN Error code */ + +}CAN_HandleTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CAN_Exported_Constants CAN Exported Constants + * @{ + */ + +/** @defgroup HAL_CAN_Error_Code HAL CAN Error Code + * @{ + */ +#define HAL_CAN_ERROR_NONE 0x00 /*!< No error */ +#define HAL_CAN_ERROR_EWG 0x01 /*!< EWG error */ +#define HAL_CAN_ERROR_EPV 0x02 /*!< EPV error */ +#define HAL_CAN_ERROR_BOF 0x04 /*!< BOF error */ +#define HAL_CAN_ERROR_STF 0x08 /*!< Stuff error */ +#define HAL_CAN_ERROR_FOR 0x10 /*!< Form error */ +#define HAL_CAN_ERROR_ACK 0x20 /*!< Acknowledgment error */ +#define HAL_CAN_ERROR_BR 0x40 /*!< Bit recessive */ +#define HAL_CAN_ERROR_BD 0x80 /*!< LEC dominant */ +#define HAL_CAN_ERROR_CRC 0x100 /*!< LEC transfer error */ +/** + * @} + */ + +/** @defgroup CAN_InitStatus CAN InitStatus + * @{ + */ +#define CAN_INITSTATUS_FAILED ((uint8_t)0x00) /*!< CAN initialization failed */ +#define CAN_INITSTATUS_SUCCESS ((uint8_t)0x01) /*!< CAN initialization OK */ +/** + * @} + */ + +/** @defgroup CAN_operating_mode CAN Operating Mode + * @{ + */ +#define CAN_MODE_NORMAL ((uint32_t)0x00000000) /*!< Normal mode */ +#define CAN_MODE_LOOPBACK ((uint32_t)CAN_BTR_LBKM) /*!< Loopback mode */ +#define CAN_MODE_SILENT ((uint32_t)CAN_BTR_SILM) /*!< Silent mode */ +#define CAN_MODE_SILENT_LOOPBACK ((uint32_t)(CAN_BTR_LBKM | CAN_BTR_SILM)) /*!< Loopback combined with silent mode */ +/** + * @} + */ + +/** @defgroup CAN_synchronisation_jump_width CAN Synchronisation Jump Width + * @{ + */ +#define CAN_SJW_1TQ ((uint32_t)0x00000000) /*!< 1 time quantum */ +#define CAN_SJW_2TQ ((uint32_t)CAN_BTR_SJW_0) /*!< 2 time quantum */ +#define CAN_SJW_3TQ ((uint32_t)CAN_BTR_SJW_1) /*!< 3 time quantum */ +#define CAN_SJW_4TQ ((uint32_t)CAN_BTR_SJW) /*!< 4 time quantum */ +/** + * @} + */ + +/** @defgroup CAN_time_quantum_in_bit_segment_1 CAN Time Quantum in bit segment 1 + * @{ + */ +#define CAN_BS1_1TQ ((uint32_t)0x00000000) /*!< 1 time quantum */ +#define CAN_BS1_2TQ ((uint32_t)CAN_BTR_TS1_0) /*!< 2 time quantum */ +#define CAN_BS1_3TQ ((uint32_t)CAN_BTR_TS1_1) /*!< 3 time quantum */ +#define CAN_BS1_4TQ ((uint32_t)(CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 4 time quantum */ +#define CAN_BS1_5TQ ((uint32_t)CAN_BTR_TS1_2) /*!< 5 time quantum */ +#define CAN_BS1_6TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 6 time quantum */ +#define CAN_BS1_7TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 7 time quantum */ +#define CAN_BS1_8TQ ((uint32_t)(CAN_BTR_TS1_2 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 8 time quantum */ +#define CAN_BS1_9TQ ((uint32_t)CAN_BTR_TS1_3) /*!< 9 time quantum */ +#define CAN_BS1_10TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_0)) /*!< 10 time quantum */ +#define CAN_BS1_11TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1)) /*!< 11 time quantum */ +#define CAN_BS1_12TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_1 | CAN_BTR_TS1_0)) /*!< 12 time quantum */ +#define CAN_BS1_13TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2)) /*!< 13 time quantum */ +#define CAN_BS1_14TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_0)) /*!< 14 time quantum */ +#define CAN_BS1_15TQ ((uint32_t)(CAN_BTR_TS1_3 | CAN_BTR_TS1_2 | CAN_BTR_TS1_1)) /*!< 15 time quantum */ +#define CAN_BS1_16TQ ((uint32_t)CAN_BTR_TS1) /*!< 16 time quantum */ +/** + * @} + */ + +/** @defgroup CAN_time_quantum_in_bit_segment_2 CAN Time Quantum in bit segment 2 + * @{ + */ +#define CAN_BS2_1TQ ((uint32_t)0x00000000) /*!< 1 time quantum */ +#define CAN_BS2_2TQ ((uint32_t)CAN_BTR_TS2_0) /*!< 2 time quantum */ +#define CAN_BS2_3TQ ((uint32_t)CAN_BTR_TS2_1) /*!< 3 time quantum */ +#define CAN_BS2_4TQ ((uint32_t)(CAN_BTR_TS2_1 | CAN_BTR_TS2_0)) /*!< 4 time quantum */ +#define CAN_BS2_5TQ ((uint32_t)CAN_BTR_TS2_2) /*!< 5 time quantum */ +#define CAN_BS2_6TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_0)) /*!< 6 time quantum */ +#define CAN_BS2_7TQ ((uint32_t)(CAN_BTR_TS2_2 | CAN_BTR_TS2_1)) /*!< 7 time quantum */ +#define CAN_BS2_8TQ ((uint32_t)CAN_BTR_TS2) /*!< 8 time quantum */ +/** + * @} + */ + +/** @defgroup CAN_filter_mode CAN Filter Mode + * @{ + */ +#define CAN_FILTERMODE_IDMASK ((uint8_t)0x00) /*!< Identifier mask mode */ +#define CAN_FILTERMODE_IDLIST ((uint8_t)0x01) /*!< Identifier list mode */ +/** + * @} + */ + +/** @defgroup CAN_filter_scale CAN Filter Scale + * @{ + */ +#define CAN_FILTERSCALE_16BIT ((uint8_t)0x00) /*!< Two 16-bit filters */ +#define CAN_FILTERSCALE_32BIT ((uint8_t)0x01) /*!< One 32-bit filter */ +/** + * @} + */ + +/** @defgroup CAN_filter_FIFO CAN Filter FIFO + * @{ + */ +#define CAN_FILTER_FIFO0 ((uint8_t)0x00) /*!< Filter FIFO 0 assignment for filter x */ +#define CAN_FILTER_FIFO1 ((uint8_t)0x01) /*!< Filter FIFO 1 assignment for filter x */ +/** + * @} + */ + +/** @defgroup CAN_Identifier_Type CAN Identifier Type + * @{ + */ +#define CAN_ID_STD ((uint32_t)0x00000000) /*!< Standard Id */ +#define CAN_ID_EXT ((uint32_t)0x00000004) /*!< Extended Id */ +/** + * @} + */ + +/** @defgroup CAN_remote_transmission_request CAN Remote Transmission Request + * @{ + */ +#define CAN_RTR_DATA ((uint32_t)0x00000000) /*!< Data frame */ +#define CAN_RTR_REMOTE ((uint32_t)0x00000002) /*!< Remote frame */ +/** + * @} + */ + +/** @defgroup CAN_receive_FIFO_number_constants CAN Receive FIFO Number Constants + * @{ + */ +#define CAN_FIFO0 ((uint8_t)0x00) /*!< CAN FIFO 0 used to receive */ +#define CAN_FIFO1 ((uint8_t)0x01) /*!< CAN FIFO 1 used to receive */ +/** + * @} + */ + +/** @defgroup CAN_flags CAN Flags + * @{ + */ +/* If the flag is 0x3XXXXXXX, it means that it can be used with CAN_GetFlagStatus() + and CAN_ClearFlag() functions. */ +/* If the flag is 0x1XXXXXXX, it means that it can only be used with + CAN_GetFlagStatus() function. */ + +/* Transmit Flags */ +#define CAN_FLAG_RQCP0 ((uint32_t)0x00000500) /*!< Request MailBox0 flag */ +#define CAN_FLAG_RQCP1 ((uint32_t)0x00000508) /*!< Request MailBox1 flag */ +#define CAN_FLAG_RQCP2 ((uint32_t)0x00000510) /*!< Request MailBox2 flag */ +#define CAN_FLAG_TXOK0 ((uint32_t)0x00000501) /*!< Transmission OK MailBox0 flag */ +#define CAN_FLAG_TXOK1 ((uint32_t)0x00000509) /*!< Transmission OK MailBox1 flag */ +#define CAN_FLAG_TXOK2 ((uint32_t)0x00000511) /*!< Transmission OK MailBox2 flag */ +#define CAN_FLAG_TME0 ((uint32_t)0x0000051A) /*!< Transmit mailbox 0 empty flag */ +#define CAN_FLAG_TME1 ((uint32_t)0x0000051B) /*!< Transmit mailbox 0 empty flag */ +#define CAN_FLAG_TME2 ((uint32_t)0x0000051C) /*!< Transmit mailbox 0 empty flag */ + +/* Receive Flags */ +#define CAN_FLAG_FF0 ((uint32_t)0x00000203) /*!< FIFO 0 Full flag */ +#define CAN_FLAG_FOV0 ((uint32_t)0x00000204) /*!< FIFO 0 Overrun flag */ + +#define CAN_FLAG_FF1 ((uint32_t)0x00000403) /*!< FIFO 1 Full flag */ +#define CAN_FLAG_FOV1 ((uint32_t)0x00000404) /*!< FIFO 1 Overrun flag */ + +/* Operating Mode Flags */ +#define CAN_FLAG_WKU ((uint32_t)0x00000103) /*!< Wake up flag */ +#define CAN_FLAG_SLAK ((uint32_t)0x00000101) /*!< Sleep acknowledge flag */ +#define CAN_FLAG_SLAKI ((uint32_t)0x00000104) /*!< Sleep acknowledge flag */ +/* @note When SLAK interrupt is disabled (SLKIE=0), no polling on SLAKI is possible. + In this case the SLAK bit can be polled.*/ + +/* Error Flags */ +#define CAN_FLAG_EWG ((uint32_t)0x00000300) /*!< Error warning flag */ +#define CAN_FLAG_EPV ((uint32_t)0x00000301) /*!< Error passive flag */ +#define CAN_FLAG_BOF ((uint32_t)0x00000302) /*!< Bus-Off flag */ +/** + * @} + */ + +/** @defgroup CAN_Interrupts CAN Interrupts + * @{ + */ +#define CAN_IT_TME ((uint32_t)CAN_IER_TMEIE) /*!< Transmit mailbox empty interrupt */ + +/* Receive Interrupts */ +#define CAN_IT_FMP0 ((uint32_t)CAN_IER_FMPIE0) /*!< FIFO 0 message pending interrupt */ +#define CAN_IT_FF0 ((uint32_t)CAN_IER_FFIE0) /*!< FIFO 0 full interrupt */ +#define CAN_IT_FOV0 ((uint32_t)CAN_IER_FOVIE0) /*!< FIFO 0 overrun interrupt */ +#define CAN_IT_FMP1 ((uint32_t)CAN_IER_FMPIE1) /*!< FIFO 1 message pending interrupt */ +#define CAN_IT_FF1 ((uint32_t)CAN_IER_FFIE1) /*!< FIFO 1 full interrupt */ +#define CAN_IT_FOV1 ((uint32_t)CAN_IER_FOVIE1) /*!< FIFO 1 overrun interrupt */ + +/* Operating Mode Interrupts */ +#define CAN_IT_WKU ((uint32_t)CAN_IER_WKUIE) /*!< Wake-up interrupt */ +#define CAN_IT_SLK ((uint32_t)CAN_IER_SLKIE) /*!< Sleep acknowledge interrupt */ + +/* Error Interrupts */ +#define CAN_IT_EWG ((uint32_t)CAN_IER_EWGIE) /*!< Error warning interrupt */ +#define CAN_IT_EPV ((uint32_t)CAN_IER_EPVIE) /*!< Error passive interrupt */ +#define CAN_IT_BOF ((uint32_t)CAN_IER_BOFIE) /*!< Bus-off interrupt */ +#define CAN_IT_LEC ((uint32_t)CAN_IER_LECIE) /*!< Last error code interrupt */ +#define CAN_IT_ERR ((uint32_t)CAN_IER_ERRIE) /*!< Error Interrupt */ +/** + * @} + */ + +/** @defgroup CAN_Mailboxes_Definition CAN Mailboxes Definition + * @{ + */ +#define CAN_TXMAILBOX_0 ((uint8_t)0x00) +#define CAN_TXMAILBOX_1 ((uint8_t)0x01) +#define CAN_TXMAILBOX_2 ((uint8_t)0x02) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup CAN_Exported_Macros CAN Exported Macros + * @{ + */ + +/** @brief Reset CAN handle state + * @param __HANDLE__: specifies the CAN Handle. + * @retval None + */ +#define __HAL_CAN_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_CAN_STATE_RESET) + +/** + * @brief Enable the specified CAN interrupts. + * @param __HANDLE__: CAN handle + * @param __INTERRUPT__: CAN Interrupt + * @retval None + */ +#define __HAL_CAN_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) |= (__INTERRUPT__)) + +/** + * @brief Disable the specified CAN interrupts. + * @param __HANDLE__: CAN handle + * @param __INTERRUPT__: CAN Interrupt + * @retval None + */ +#define __HAL_CAN_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IER) &= ~(__INTERRUPT__)) + +/** + * @brief Return the number of pending received messages. + * @param __HANDLE__: CAN handle + * @param __FIFONUMBER__: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1. + * @retval The number of pending message. + */ +#define __HAL_CAN_MSG_PENDING(__HANDLE__, __FIFONUMBER__) (((__FIFONUMBER__) == CAN_FIFO0)? \ +((uint8_t)((__HANDLE__)->Instance->RF0R&(uint32_t)0x03)) : ((uint8_t)((__HANDLE__)->Instance->RF1R&(uint32_t)0x03))) + +/** @brief Check whether the specified CAN flag is set or not. + * @param __HANDLE__: CAN Handle + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg CAN_TSR_RQCP0: Request MailBox0 Flag + * @arg CAN_TSR_RQCP1: Request MailBox1 Flag + * @arg CAN_TSR_RQCP2: Request MailBox2 Flag + * @arg CAN_FLAG_TXOK0: Transmission OK MailBox0 Flag + * @arg CAN_FLAG_TXOK1: Transmission OK MailBox1 Flag + * @arg CAN_FLAG_TXOK2: Transmission OK MailBox2 Flag + * @arg CAN_FLAG_TME0: Transmit mailbox 0 empty Flag + * @arg CAN_FLAG_TME1: Transmit mailbox 1 empty Flag + * @arg CAN_FLAG_TME2: Transmit mailbox 2 empty Flag + * @arg CAN_FLAG_FMP0: FIFO 0 Message Pending Flag + * @arg CAN_FLAG_FF0: FIFO 0 Full Flag + * @arg CAN_FLAG_FOV0: FIFO 0 Overrun Flag + * @arg CAN_FLAG_FMP1: FIFO 1 Message Pending Flag + * @arg CAN_FLAG_FF1: FIFO 1 Full Flag + * @arg CAN_FLAG_FOV1: FIFO 1 Overrun Flag + * @arg CAN_FLAG_WKU: Wake up Flag + * @arg CAN_FLAG_SLAK: Sleep acknowledge Flag + * @arg CAN_FLAG_SLAKI: Sleep acknowledge Flag + * @arg CAN_FLAG_EWG: Error Warning Flag + * @arg CAN_FLAG_EPV: Error Passive Flag + * @arg CAN_FLAG_BOF: Bus-Off Flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_CAN_GET_FLAG(__HANDLE__, __FLAG__) \ +((((__FLAG__) >> 8) == 5)? ((((__HANDLE__)->Instance->TSR) & (1 << ((__FLAG__) & CAN_FLAG_MASK))) == (1 << ((__FLAG__) & CAN_FLAG_MASK))): \ + (((__FLAG__) >> 8) == 2)? ((((__HANDLE__)->Instance->RF0R) & (1 << ((__FLAG__) & CAN_FLAG_MASK))) == (1 << ((__FLAG__) & CAN_FLAG_MASK))): \ + (((__FLAG__) >> 8) == 4)? ((((__HANDLE__)->Instance->RF1R) & (1 << ((__FLAG__) & CAN_FLAG_MASK))) == (1 << ((__FLAG__) & CAN_FLAG_MASK))): \ + (((__FLAG__) >> 8) == 1)? ((((__HANDLE__)->Instance->MSR) & (1 << ((__FLAG__) & CAN_FLAG_MASK))) == (1 << ((__FLAG__) & CAN_FLAG_MASK))): \ + ((((__HANDLE__)->Instance->ESR) & (1 << ((__FLAG__) & CAN_FLAG_MASK))) == (1 << ((__FLAG__) & CAN_FLAG_MASK)))) + +/** @brief Clear the specified CAN pending flag. + * @param __HANDLE__: CAN Handle. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg CAN_TSR_RQCP0: Request MailBox0 Flag + * @arg CAN_TSR_RQCP1: Request MailBox1 Flag + * @arg CAN_TSR_RQCP2: Request MailBox2 Flag + * @arg CAN_FLAG_TXOK0: Transmission OK MailBox0 Flag + * @arg CAN_FLAG_TXOK1: Transmission OK MailBox1 Flag + * @arg CAN_FLAG_TXOK2: Transmission OK MailBox2 Flag + * @arg CAN_FLAG_TME0: Transmit mailbox 0 empty Flag + * @arg CAN_FLAG_TME1: Transmit mailbox 1 empty Flag + * @arg CAN_FLAG_TME2: Transmit mailbox 2 empty Flag + * @arg CAN_FLAG_FMP0: FIFO 0 Message Pending Flag + * @arg CAN_FLAG_FF0: FIFO 0 Full Flag + * @arg CAN_FLAG_FOV0: FIFO 0 Overrun Flag + * @arg CAN_FLAG_FMP1: FIFO 1 Message Pending Flag + * @arg CAN_FLAG_FF1: FIFO 1 Full Flag + * @arg CAN_FLAG_FOV1: FIFO 1 Overrun Flag + * @arg CAN_FLAG_WKU: Wake up Flag + * @arg CAN_FLAG_SLAK: Sleep acknowledge Flag + * @arg CAN_FLAG_SLAKI: Sleep acknowledge Flag + * @arg CAN_FLAG_EWG: Error Warning Flag + * @arg CAN_FLAG_EPV: Error Passive Flag + * @arg CAN_FLAG_BOF: Bus-Off Flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_CAN_CLEAR_FLAG(__HANDLE__, __FLAG__) \ +((((__FLAG__) >> 8) == 5)? (((__HANDLE__)->Instance->TSR) = ~((uint32_t)1 << ((__FLAG__) & CAN_FLAG_MASK))): \ + (((__FLAG__) >> 8) == 2)? (((__HANDLE__)->Instance->RF0R) = ~((uint32_t)1 << ((__FLAG__) & CAN_FLAG_MASK))): \ + (((__FLAG__) >> 8) == 4)? (((__HANDLE__)->Instance->RF1R) = ~((uint32_t)1 << ((__FLAG__) & CAN_FLAG_MASK))): \ + (((__FLAG__) >> 8) == 1)? (((__HANDLE__)->Instance->MSR) = ~((uint32_t)1 << ((__FLAG__) & CAN_FLAG_MASK))): \ + (((__HANDLE__)->Instance->ESR) = ~((uint32_t)1 << ((__FLAG__) & CAN_FLAG_MASK)))) + +/** @brief Check if the specified CAN interrupt source is enabled or disabled. + * @param __HANDLE__: CAN Handle + * @param __INTERRUPT__: specifies the CAN interrupt source to check. + * This parameter can be one of the following values: + * @arg CAN_IT_TME: Transmit mailbox empty interrupt enable + * @arg CAN_IT_FMP0: FIFO0 message pending interrupt enable + * @arg CAN_IT_FMP1: FIFO1 message pending interrupt enable + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_CAN_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->IER & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** + * @brief Check the transmission status of a CAN Frame. + * @param __HANDLE__: CAN Handle + * @param __TRANSMITMAILBOX__: the number of the mailbox that is used for transmission. + * @retval The new status of transmission (TRUE or FALSE). + */ +#define __HAL_CAN_TRANSMIT_STATUS(__HANDLE__, __TRANSMITMAILBOX__)\ +(((__TRANSMITMAILBOX__) == CAN_TXMAILBOX_0)? ((((__HANDLE__)->Instance->TSR) & (CAN_TSR_RQCP0 | CAN_TSR_TXOK0 | CAN_TSR_TME0)) == (CAN_TSR_RQCP0 | CAN_TSR_TXOK0 | CAN_TSR_TME0)) :\ + ((__TRANSMITMAILBOX__) == CAN_TXMAILBOX_1)? ((((__HANDLE__)->Instance->TSR) & (CAN_TSR_RQCP1 | CAN_TSR_TXOK1 | CAN_TSR_TME1)) == (CAN_TSR_RQCP1 | CAN_TSR_TXOK1 | CAN_TSR_TME1)) :\ + ((((__HANDLE__)->Instance->TSR) & (CAN_TSR_RQCP2 | CAN_TSR_TXOK2 | CAN_TSR_TME2)) == (CAN_TSR_RQCP2 | CAN_TSR_TXOK2 | CAN_TSR_TME2))) + +/** + * @brief Release the specified receive FIFO. + * @param __HANDLE__: CAN handle + * @param __FIFONUMBER__: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1. + * @retval None + */ +#define __HAL_CAN_FIFO_RELEASE(__HANDLE__, __FIFONUMBER__) (((__FIFONUMBER__) == CAN_FIFO0)? \ +((__HANDLE__)->Instance->RF0R |= CAN_RF0R_RFOM0) : ((__HANDLE__)->Instance->RF1R |= CAN_RF1R_RFOM1)) + +/** + * @brief Cancel a transmit request. + * @param __HANDLE__: CAN Handle + * @param __TRANSMITMAILBOX__: the number of the mailbox that is used for transmission. + * @retval None + */ +#define __HAL_CAN_CANCEL_TRANSMIT(__HANDLE__, __TRANSMITMAILBOX__)\ +(((__TRANSMITMAILBOX__) == CAN_TXMAILBOX_0)? ((__HANDLE__)->Instance->TSR |= CAN_TSR_ABRQ0) :\ + ((__TRANSMITMAILBOX__) == CAN_TXMAILBOX_1)? ((__HANDLE__)->Instance->TSR |= CAN_TSR_ABRQ1) :\ + ((__HANDLE__)->Instance->TSR |= CAN_TSR_ABRQ2)) + +/** + * @brief Enable or disable the DBG Freeze for CAN. + * @param __HANDLE__: CAN Handle + * @param __NEWSTATE__: new state of the CAN peripheral. + * This parameter can be: ENABLE (CAN reception/transmission is frozen + * during debug. Reception FIFOs can still be accessed/controlled normally) + * or DISABLE (CAN is working during debug). + * @retval None + */ +#define __HAL_CAN_DBG_FREEZE(__HANDLE__, __NEWSTATE__) (((__NEWSTATE__) == ENABLE)? \ +((__HANDLE__)->Instance->MCR |= CAN_MCR_DBF) : ((__HANDLE__)->Instance->MCR &= ~CAN_MCR_DBF)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup CAN_Exported_Functions + * @{ + */ + +/** @addtogroup CAN_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions ***********************************/ +HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan); +HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig); +HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan); +void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan); +void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan); +/** + * @} + */ + +/** @addtogroup CAN_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions ******************************************************/ +HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef *hcan, uint32_t Timeout); +HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef *hcan); +HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef *hcan, uint8_t FIFONumber, uint32_t Timeout); +HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef *hcan, uint8_t FIFONumber); +HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef *hcan); +HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan); +void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan); +void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan); +void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan); +void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan); +/** + * @} + */ + +/** @addtogroup CAN_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State functions ***************************************************/ +uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan); +HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/** @defgroup CAN_Private_Types CAN Private Types + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup CAN_Private_Variables CAN Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup CAN_Private_Constants CAN Private Constants + * @{ + */ +#define CAN_TXSTATUS_NOMAILBOX ((uint8_t)0x04) /*!< CAN cell did not provide CAN_TxStatus_NoMailBox */ +#define CAN_FLAG_MASK ((uint32_t)0x000000FF) +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup CAN_Private_Macros CAN Private Macros + * @{ + */ +#define IS_CAN_MODE(MODE) (((MODE) == CAN_MODE_NORMAL) || \ + ((MODE) == CAN_MODE_LOOPBACK)|| \ + ((MODE) == CAN_MODE_SILENT) || \ + ((MODE) == CAN_MODE_SILENT_LOOPBACK)) +#define IS_CAN_SJW(SJW) (((SJW) == CAN_SJW_1TQ) || ((SJW) == CAN_SJW_2TQ)|| \ + ((SJW) == CAN_SJW_3TQ) || ((SJW) == CAN_SJW_4TQ)) +#define IS_CAN_BS1(BS1) ((BS1) <= CAN_BS1_16TQ) +#define IS_CAN_BS2(BS2) ((BS2) <= CAN_BS2_8TQ) +#define IS_CAN_PRESCALER(PRESCALER) (((PRESCALER) >= 1) && ((PRESCALER) <= 1024)) +#define IS_CAN_FILTER_NUMBER(NUMBER) ((NUMBER) <= 27) +#define IS_CAN_FILTER_MODE(MODE) (((MODE) == CAN_FILTERMODE_IDMASK) || \ + ((MODE) == CAN_FILTERMODE_IDLIST)) +#define IS_CAN_FILTER_SCALE(SCALE) (((SCALE) == CAN_FILTERSCALE_16BIT) || \ + ((SCALE) == CAN_FILTERSCALE_32BIT)) +#define IS_CAN_FILTER_FIFO(FIFO) (((FIFO) == CAN_FILTER_FIFO0) || \ + ((FIFO) == CAN_FILTER_FIFO1)) +#define IS_CAN_BANKNUMBER(BANKNUMBER) ((BANKNUMBER) <= 28) + +#define IS_CAN_TRANSMITMAILBOX(TRANSMITMAILBOX) ((TRANSMITMAILBOX) <= ((uint8_t)0x02)) +#define IS_CAN_STDID(STDID) ((STDID) <= ((uint32_t)0x7FF)) +#define IS_CAN_EXTID(EXTID) ((EXTID) <= ((uint32_t)0x1FFFFFFF)) +#define IS_CAN_DLC(DLC) ((DLC) <= ((uint8_t)0x08)) + +#define IS_CAN_IDTYPE(IDTYPE) (((IDTYPE) == CAN_ID_STD) || \ + ((IDTYPE) == CAN_ID_EXT)) +#define IS_CAN_RTR(RTR) (((RTR) == CAN_RTR_DATA) || ((RTR) == CAN_RTR_REMOTE)) +#define IS_CAN_FIFO(FIFO) (((FIFO) == CAN_FIFO0) || ((FIFO) == CAN_FIFO1)) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup CAN_Private_Functions CAN Private Functions + * @{ + */ + +/** + * @} + */ + +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_CAN_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cec.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cec.h new file mode 100644 index 0000000..14cb738 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cec.h @@ -0,0 +1,681 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_cec.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of CEC HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_CEC_H +#define __STM32F4xx_HAL_CEC_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F446xx) +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup CEC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup CEC_Exported_Types CEC Exported Types + * @{ + */ + +/** + * @brief CEC Init Structure definition + */ +typedef struct +{ + uint32_t SignalFreeTime; /*!< Set SFT field, specifies the Signal Free Time. + It can be one of @ref CEC_Signal_Free_Time + and belongs to the set {0,...,7} where + 0x0 is the default configuration + else means 0.5 + (SignalFreeTime - 1) nominal data bit periods */ + + uint32_t Tolerance; /*!< Set RXTOL bit, specifies the tolerance accepted on the received waveforms, + it can be a value of @ref CEC_Tolerance : it is either CEC_STANDARD_TOLERANCE + or CEC_EXTENDED_TOLERANCE */ + + uint32_t BRERxStop; /*!< Set BRESTP bit @ref CEC_BRERxStop : specifies whether or not a Bit Rising Error stops the reception. + CEC_NO_RX_STOP_ON_BRE: reception is not stopped. + CEC_RX_STOP_ON_BRE: reception is stopped. */ + + uint32_t BREErrorBitGen; /*!< Set BREGEN bit @ref CEC_BREErrorBitGen : specifies whether or not an Error-Bit is generated on the + CEC line upon Bit Rising Error detection. + CEC_BRE_ERRORBIT_NO_GENERATION: no error-bit generation. + CEC_BRE_ERRORBIT_GENERATION: error-bit generation if BRESTP is set. */ + + uint32_t LBPEErrorBitGen; /*!< Set LBPEGEN bit @ref CEC_LBPEErrorBitGen : specifies whether or not an Error-Bit is generated on the + CEC line upon Long Bit Period Error detection. + CEC_LBPE_ERRORBIT_NO_GENERATION: no error-bit generation. + CEC_LBPE_ERRORBIT_GENERATION: error-bit generation. */ + + uint32_t BroadcastMsgNoErrorBitGen; /*!< Set BRDNOGEN bit @ref CEC_BroadCastMsgErrorBitGen : allows to avoid an Error-Bit generation on the CEC line + upon an error detected on a broadcast message. + + It supersedes BREGEN and LBPEGEN bits for a broadcast message error handling. It can take two values: + + 1) CEC_BROADCASTERROR_ERRORBIT_GENERATION. + a) BRE detection: error-bit generation on the CEC line if BRESTP=CEC_RX_STOP_ON_BRE + and BREGEN=CEC_BRE_ERRORBIT_NO_GENERATION. + b) LBPE detection: error-bit generation on the CEC line + if LBPGEN=CEC_LBPE_ERRORBIT_NO_GENERATION. + + 2) CEC_BROADCASTERROR_NO_ERRORBIT_GENERATION. + no error-bit generation in case neither a) nor b) are satisfied. Additionally, + there is no error-bit generation in case of Short Bit Period Error detection in + a broadcast message while LSTN bit is set. */ + + uint32_t SignalFreeTimeOption; /*!< Set SFTOP bit @ref CEC_SFT_Option : specifies when SFT timer starts. + CEC_SFT_START_ON_TXSOM SFT: timer starts when TXSOM is set by software. + CEC_SFT_START_ON_TX_RX_END: SFT timer starts automatically at the end of message transmission/reception. */ + + uint32_t OwnAddress; /*!< Set OAR field, specifies CEC device address within a 15-bit long field */ + + uint32_t ListenMode; /*!< Set LSTN bit @ref CEC_Listening_Mode : specifies device listening mode. It can take two values: + + CEC_REDUCED_LISTENING_MODE: CEC peripheral receives only message addressed to its + own address (OAR). Messages addressed to different destination are ignored. + Broadcast messages are always received. + + CEC_FULL_LISTENING_MODE: CEC peripheral receives messages addressed to its own + address (OAR) with positive acknowledge. Messages addressed to different destination + are received, but without interfering with the CEC bus: no acknowledge sent. */ + + uint8_t InitiatorAddress; /* Initiator address (source logical address, sent in each header) */ + +}CEC_InitTypeDef; + +/** + * @brief HAL CEC State structures definition + */ +typedef enum +{ + HAL_CEC_STATE_RESET = 0x00, /*!< Peripheral Reset state */ + HAL_CEC_STATE_READY = 0x01, /*!< Peripheral Initialized and ready for use */ + HAL_CEC_STATE_BUSY = 0x02, /*!< an internal process is ongoing */ + HAL_CEC_STATE_BUSY_TX = 0x03, /*!< Data Transmission process is ongoing */ + HAL_CEC_STATE_BUSY_RX = 0x04, /*!< Data Reception process is ongoing */ + HAL_CEC_STATE_STANDBY_RX = 0x05, /*!< IP ready to receive, doesn't prevent IP to transmit */ + HAL_CEC_STATE_TIMEOUT = 0x06, /*!< Timeout state */ + HAL_CEC_STATE_ERROR = 0x07 /*!< State Error */ +}HAL_CEC_StateTypeDef; + +/** + * @brief CEC handle Structure definition + */ +typedef struct +{ + CEC_TypeDef *Instance; /* CEC registers base address */ + + CEC_InitTypeDef Init; /* CEC communication parameters */ + + uint8_t *pTxBuffPtr; /* Pointer to CEC Tx transfer Buffer */ + + uint16_t TxXferCount; /* CEC Tx Transfer Counter */ + + uint8_t *pRxBuffPtr; /* Pointer to CEC Rx transfer Buffer */ + + uint16_t RxXferSize; /* CEC Rx Transfer size, 0: header received only */ + + uint32_t ErrorCode; /* For errors handling purposes, copy of ISR register + in case error is reported */ + + HAL_LockTypeDef Lock; /* Locking object */ + + HAL_CEC_StateTypeDef State; /* CEC communication state */ + +}CEC_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CEC_Exported_Constants CEC Exported Constants + * @{ + */ + +/** @defgroup CEC_Error_Code CEC Error Code + * @{ + */ +#define HAL_CEC_ERROR_NONE (uint32_t) 0x0 /*!< no error */ +#define HAL_CEC_ERROR_RXOVR CEC_ISR_RXOVR /*!< CEC Rx-Overrun */ +#define HAL_CEC_ERROR_BRE CEC_ISR_BRE /*!< CEC Rx Bit Rising Error */ +#define HAL_CEC_ERROR_SBPE CEC_ISR_SBPE /*!< CEC Rx Short Bit period Error */ +#define HAL_CEC_ERROR_LBPE CEC_ISR_LBPE /*!< CEC Rx Long Bit period Error */ +#define HAL_CEC_ERROR_RXACKE CEC_ISR_RXACKE /*!< CEC Rx Missing Acknowledge */ +#define HAL_CEC_ERROR_ARBLST CEC_ISR_ARBLST /*!< CEC Arbitration Lost */ +#define HAL_CEC_ERROR_TXUDR CEC_ISR_TXUDR /*!< CEC Tx-Buffer Underrun */ +#define HAL_CEC_ERROR_TXERR CEC_ISR_TXERR /*!< CEC Tx-Error */ +#define HAL_CEC_ERROR_TXACKE CEC_ISR_TXACKE /*!< CEC Tx Missing Acknowledge */ +/** + * @} + */ + +/** @defgroup CEC_Signal_Free_Time CEC Signal Free Time setting parameter + * @{ + */ +#define CEC_DEFAULT_SFT ((uint32_t)0x00000000) +#define CEC_0_5_BITPERIOD_SFT ((uint32_t)0x00000001) +#define CEC_1_5_BITPERIOD_SFT ((uint32_t)0x00000002) +#define CEC_2_5_BITPERIOD_SFT ((uint32_t)0x00000003) +#define CEC_3_5_BITPERIOD_SFT ((uint32_t)0x00000004) +#define CEC_4_5_BITPERIOD_SFT ((uint32_t)0x00000005) +#define CEC_5_5_BITPERIOD_SFT ((uint32_t)0x00000006) +#define CEC_6_5_BITPERIOD_SFT ((uint32_t)0x00000007) +/** + * @} + */ + +/** @defgroup CEC_Tolerance CEC Receiver Tolerance + * @{ + */ +#define CEC_STANDARD_TOLERANCE ((uint32_t)0x00000000) +#define CEC_EXTENDED_TOLERANCE ((uint32_t)CEC_CFGR_RXTOL) +/** + * @} + */ + +/** @defgroup CEC_BRERxStop CEC Reception Stop on Error + * @{ + */ +#define CEC_NO_RX_STOP_ON_BRE ((uint32_t)0x00000000) +#define CEC_RX_STOP_ON_BRE ((uint32_t)CEC_CFGR_BRESTP) +/** + * @} + */ + +/** @defgroup CEC_BREErrorBitGen CEC Error Bit Generation if Bit Rise Error reported + * @{ + */ +#define CEC_BRE_ERRORBIT_NO_GENERATION ((uint32_t)0x00000000) +#define CEC_BRE_ERRORBIT_GENERATION ((uint32_t)CEC_CFGR_BREGEN) +/** + * @} + */ + +/** @defgroup CEC_LBPEErrorBitGen CEC Error Bit Generation if Long Bit Period Error reported + * @{ + */ +#define CEC_LBPE_ERRORBIT_NO_GENERATION ((uint32_t)0x00000000) +#define CEC_LBPE_ERRORBIT_GENERATION ((uint32_t)CEC_CFGR_LBPEGEN) +/** + * @} + */ + +/** @defgroup CEC_BroadCastMsgErrorBitGen CEC Error Bit Generation on Broadcast message + * @{ + */ +#define CEC_BROADCASTERROR_ERRORBIT_GENERATION ((uint32_t)0x00000000) +#define CEC_BROADCASTERROR_NO_ERRORBIT_GENERATION ((uint32_t)CEC_CFGR_BRDNOGEN) +/** + * @} + */ + +/** @defgroup CEC_SFT_Option CEC Signal Free Time start option + * @{ + */ +#define CEC_SFT_START_ON_TXSOM ((uint32_t)0x00000000) +#define CEC_SFT_START_ON_TX_RX_END ((uint32_t)CEC_CFGR_SFTOPT) +/** + * @} + */ + +/** @defgroup CEC_Listening_Mode CEC Listening mode option + * @{ + */ +#define CEC_REDUCED_LISTENING_MODE ((uint32_t)0x00000000) +#define CEC_FULL_LISTENING_MODE ((uint32_t)CEC_CFGR_LSTN) +/** + * @} + */ + +/** @defgroup CEC_OAR_Position CEC Device Own Address position in CEC CFGR register + * @{ + */ +#define CEC_CFGR_OAR_LSB_POS ((uint32_t) 16) +/** + * @} + */ + +/** @defgroup CEC_Initiator_Position CEC Initiator logical address position in message header + * @{ + */ +#define CEC_INITIATOR_LSB_POS ((uint32_t) 4) +/** + * @} + */ + +/** @defgroup CEC_Interrupts_Definitions CEC Interrupts definition + * @{ + */ +#define CEC_IT_TXACKE CEC_IER_TXACKEIE +#define CEC_IT_TXERR CEC_IER_TXERRIE +#define CEC_IT_TXUDR CEC_IER_TXUDRIE +#define CEC_IT_TXEND CEC_IER_TXENDIE +#define CEC_IT_TXBR CEC_IER_TXBRIE +#define CEC_IT_ARBLST CEC_IER_ARBLSTIE +#define CEC_IT_RXACKE CEC_IER_RXACKEIE +#define CEC_IT_LBPE CEC_IER_LBPEIE +#define CEC_IT_SBPE CEC_IER_SBPEIE +#define CEC_IT_BRE CEC_IER_BREIE +#define CEC_IT_RXOVR CEC_IER_RXOVRIE +#define CEC_IT_RXEND CEC_IER_RXENDIE +#define CEC_IT_RXBR CEC_IER_RXBRIE +/** + * @} + */ + +/** @defgroup CEC_Flags_Definitions CEC Flags definition + * @{ + */ +#define CEC_FLAG_TXACKE CEC_ISR_TXACKE +#define CEC_FLAG_TXERR CEC_ISR_TXERR +#define CEC_FLAG_TXUDR CEC_ISR_TXUDR +#define CEC_FLAG_TXEND CEC_ISR_TXEND +#define CEC_FLAG_TXBR CEC_ISR_TXBR +#define CEC_FLAG_ARBLST CEC_ISR_ARBLST +#define CEC_FLAG_RXACKE CEC_ISR_RXACKE +#define CEC_FLAG_LBPE CEC_ISR_LBPE +#define CEC_FLAG_SBPE CEC_ISR_SBPE +#define CEC_FLAG_BRE CEC_ISR_BRE +#define CEC_FLAG_RXOVR CEC_ISR_RXOVR +#define CEC_FLAG_RXEND CEC_ISR_RXEND +#define CEC_FLAG_RXBR CEC_ISR_RXBR +/** + * @} + */ + +/** @defgroup CEC_ALL_ERROR CEC all RX or TX errors flags + * @{ + */ +#define CEC_ISR_ALL_ERROR ((uint32_t)CEC_ISR_RXOVR|CEC_ISR_BRE|CEC_ISR_SBPE|CEC_ISR_LBPE|CEC_ISR_RXACKE|\ + CEC_ISR_ARBLST|CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE) +/** + * @} + */ + +/** @defgroup CEC_IER_ALL_RX CEC all RX errors interrupts enabling flag + * @{ + */ +#define CEC_IER_RX_ALL_ERR ((uint32_t)CEC_IER_RXACKEIE|CEC_IER_LBPEIE|CEC_IER_SBPEIE|CEC_IER_BREIE|CEC_IER_RXOVRIE) +/** + * @} + */ + +/** @defgroup CEC_IER_ALL_TX CEC all TX errors interrupts enabling flag + * @{ + */ +#define CEC_IER_TX_ALL_ERR ((uint32_t)CEC_IER_TXACKEIE|CEC_IER_TXERRIE|CEC_IER_TXUDRIE|CEC_IER_ARBLSTIE) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup CEC_Exported_Macros CEC Exported Macros + * @{ + */ + +/** @brief Reset CEC handle state + * @param __HANDLE__: CEC handle. + * @retval None + */ +#define __HAL_CEC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_CEC_STATE_RESET) + +/** @brief Checks whether or not the specified CEC interrupt flag is set. + * @param __HANDLE__: specifies the CEC Handle. + * @param __FLAG__: specifies the interrupt to check. + * @arg CEC_FLAG_TXACKE: Tx Missing acknowledge Error + * @arg CEC_FLAG_TXERR: Tx Error. + * @arg CEC_FLAG_TXUDR: Tx-Buffer Underrun. + * @arg CEC_FLAG_TXEND: End of transmission (successful transmission of the last byte). + * @arg CEC_FLAG_TXBR: Tx-Byte Request. + * @arg CEC_FLAG_ARBLST: Arbitration Lost + * @arg CEC_FLAG_RXACKE: Rx-Missing Acknowledge + * @arg CEC_FLAG_LBPE: Rx Long period Error + * @arg CEC_FLAG_SBPE: Rx Short period Error + * @arg CEC_FLAG_BRE: Rx Bit Rissing Error + * @arg CEC_FLAG_RXOVR: Rx Overrun. + * @arg CEC_FLAG_RXEND: End Of Reception. + * @arg CEC_FLAG_RXBR: Rx-Byte Received. + * @retval ITStatus + */ +#define __HAL_CEC_GET_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ISR & (__FLAG__)) + +/** @brief Clears the interrupt or status flag when raised (write at 1) + * @param __HANDLE__: specifies the CEC Handle. + * @param __FLAG__: specifies the interrupt/status flag to clear. + * This parameter can be one of the following values: + * @arg CEC_FLAG_TXACKE: Tx Missing acknowledge Error + * @arg CEC_FLAG_TXERR: Tx Error. + * @arg CEC_FLAG_TXUDR: Tx-Buffer Underrun. + * @arg CEC_FLAG_TXEND: End of transmission (successful transmission of the last byte). + * @arg CEC_FLAG_TXBR: Tx-Byte Request. + * @arg CEC_FLAG_ARBLST: Arbitration Lost + * @arg CEC_FLAG_RXACKE: Rx-Missing Acknowledge + * @arg CEC_FLAG_LBPE: Rx Long period Error + * @arg CEC_FLAG_SBPE: Rx Short period Error + * @arg CEC_FLAG_BRE: Rx Bit Rissing Error + * @arg CEC_FLAG_RXOVR: Rx Overrun. + * @arg CEC_FLAG_RXEND: End Of Reception. + * @arg CEC_FLAG_RXBR: Rx-Byte Received. + * @retval none + */ +#define __HAL_CEC_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ISR |= (__FLAG__)) + +/** @brief Enables the specified CEC interrupt. + * @param __HANDLE__: specifies the CEC Handle. + * @param __INTERRUPT__: specifies the CEC interrupt to enable. + * This parameter can be one of the following values: + * @arg CEC_IT_TXACKE: Tx Missing acknowledge Error IT Enable + * @arg CEC_IT_TXERR: Tx Error IT Enable + * @arg CEC_IT_TXUDR: Tx-Buffer Underrun IT Enable + * @arg CEC_IT_TXEND: End of transmission IT Enable + * @arg CEC_IT_TXBR: Tx-Byte Request IT Enable + * @arg CEC_IT_ARBLST: Arbitration Lost IT Enable + * @arg CEC_IT_RXACKE: Rx-Missing Acknowledge IT Enable + * @arg CEC_IT_LBPE: Rx Long period Error IT Enable + * @arg CEC_IT_SBPE: Rx Short period Error IT Enable + * @arg CEC_IT_BRE: Rx Bit Rising Error IT Enable + * @arg CEC_IT_RXOVR: Rx Overrun IT Enable + * @arg CEC_IT_RXEND: End Of Reception IT Enable + * @arg CEC_IT_RXBR: Rx-Byte Received IT Enable + * @retval none + */ +#define __HAL_CEC_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER |= (__INTERRUPT__)) + +/** @brief Disables the specified CEC interrupt. + * @param __HANDLE__: specifies the CEC Handle. + * @param __INTERRUPT__: specifies the CEC interrupt to disable. + * This parameter can be one of the following values: + * @arg CEC_IT_TXACKE: Tx Missing acknowledge Error IT Enable + * @arg CEC_IT_TXERR: Tx Error IT Enable + * @arg CEC_IT_TXUDR: Tx-Buffer Underrun IT Enable + * @arg CEC_IT_TXEND: End of transmission IT Enable + * @arg CEC_IT_TXBR: Tx-Byte Request IT Enable + * @arg CEC_IT_ARBLST: Arbitration Lost IT Enable + * @arg CEC_IT_RXACKE: Rx-Missing Acknowledge IT Enable + * @arg CEC_IT_LBPE: Rx Long period Error IT Enable + * @arg CEC_IT_SBPE: Rx Short period Error IT Enable + * @arg CEC_IT_BRE: Rx Bit Rising Error IT Enable + * @arg CEC_IT_RXOVR: Rx Overrun IT Enable + * @arg CEC_IT_RXEND: End Of Reception IT Enable + * @arg CEC_IT_RXBR: Rx-Byte Received IT Enable + * @retval none + */ +#define __HAL_CEC_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER &= (~(__INTERRUPT__))) + +/** @brief Checks whether or not the specified CEC interrupt is enabled. + * @param __HANDLE__: specifies the CEC Handle. + * @param __INTERRUPT__: specifies the CEC interrupt to check. + * This parameter can be one of the following values: + * @arg CEC_IT_TXACKE: Tx Missing acknowledge Error IT Enable + * @arg CEC_IT_TXERR: Tx Error IT Enable + * @arg CEC_IT_TXUDR: Tx-Buffer Underrun IT Enable + * @arg CEC_IT_TXEND: End of transmission IT Enable + * @arg CEC_IT_TXBR: Tx-Byte Request IT Enable + * @arg CEC_IT_ARBLST: Arbitration Lost IT Enable + * @arg CEC_IT_RXACKE: Rx-Missing Acknowledge IT Enable + * @arg CEC_IT_LBPE: Rx Long period Error IT Enable + * @arg CEC_IT_SBPE: Rx Short period Error IT Enable + * @arg CEC_IT_BRE: Rx Bit Rising Error IT Enable + * @arg CEC_IT_RXOVR: Rx Overrun IT Enable + * @arg CEC_IT_RXEND: End Of Reception IT Enable + * @arg CEC_IT_RXBR: Rx-Byte Received IT Enable + * @retval FlagStatus + */ +#define __HAL_CEC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER & (__INTERRUPT__)) + +/** @brief Enables the CEC device + * @param __HANDLE__: specifies the CEC Handle. + * @retval none + */ +#define __HAL_CEC_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= CEC_CR_CECEN) + +/** @brief Disables the CEC device + * @param __HANDLE__: specifies the CEC Handle. + * @retval none + */ +#define __HAL_CEC_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~CEC_CR_CECEN) + +/** @brief Set Transmission Start flag + * @param __HANDLE__: specifies the CEC Handle. + * @retval none + */ +#define __HAL_CEC_FIRST_BYTE_TX_SET(__HANDLE__) ((__HANDLE__)->Instance->CR |= CEC_CR_TXSOM) + +/** @brief Set Transmission End flag + * @param __HANDLE__: specifies the CEC Handle. + * @retval none + * If the CEC message consists of only one byte, TXEOM must be set before of TXSOM. + */ +#define __HAL_CEC_LAST_BYTE_TX_SET(__HANDLE__) ((__HANDLE__)->Instance->CR |= CEC_CR_TXEOM) + +/** @brief Get Transmission Start flag + * @param __HANDLE__: specifies the CEC Handle. + * @retval FlagStatus + */ +#define __HAL_CEC_GET_TRANSMISSION_START_FLAG(__HANDLE__) ((__HANDLE__)->Instance->CR & CEC_CR_TXSOM) + +/** @brief Get Transmission End flag + * @param __HANDLE__: specifies the CEC Handle. + * @retval FlagStatus + */ +#define __HAL_CEC_GET_TRANSMISSION_END_FLAG(__HANDLE__) ((__HANDLE__)->Instance->CR & CEC_CR_TXEOM) + +/** @brief Clear OAR register + * @param __HANDLE__: specifies the CEC Handle. + * @retval none + */ +#define __HAL_CEC_CLEAR_OAR(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CFGR, CEC_CFGR_OAR) + +/** @brief Set OAR register (without resetting previously set address in case of multi-address mode) + * To reset OAR, __HAL_CEC_CLEAR_OAR() needs to be called beforehand + * @param __HANDLE__: specifies the CEC Handle. + * @param __ADDRESS__: Own Address value (CEC logical address is identified by bit position) + * @retval none + */ +#define __HAL_CEC_SET_OAR(__HANDLE__,__ADDRESS__) SET_BIT((__HANDLE__)->Instance->CFGR, (__ADDRESS__)<< CEC_CFGR_OAR_LSB_POS) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup CEC_Exported_Functions + * @{ + */ + +/** @addtogroup CEC_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions ****************************/ +HAL_StatusTypeDef HAL_CEC_Init(CEC_HandleTypeDef *hcec); +HAL_StatusTypeDef HAL_CEC_DeInit(CEC_HandleTypeDef *hcec); +void HAL_CEC_MspInit(CEC_HandleTypeDef *hcec); +void HAL_CEC_MspDeInit(CEC_HandleTypeDef *hcec); +/** + * @} + */ + +/** @addtogroup CEC_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions ***************************************************/ +HAL_StatusTypeDef HAL_CEC_Transmit(CEC_HandleTypeDef *hcec, uint8_t DestinationAddress, uint8_t *pData, uint32_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_CEC_Receive(CEC_HandleTypeDef *hcec, uint8_t *pData, uint32_t Timeout); +HAL_StatusTypeDef HAL_CEC_Transmit_IT(CEC_HandleTypeDef *hcec, uint8_t DestinationAddress, uint8_t *pData, uint32_t Size); +HAL_StatusTypeDef HAL_CEC_Receive_IT(CEC_HandleTypeDef *hcec, uint8_t *pData); +uint32_t HAL_CEC_GetReceivedFrameSize(CEC_HandleTypeDef *hcec); +void HAL_CEC_IRQHandler(CEC_HandleTypeDef *hcec); +void HAL_CEC_TxCpltCallback(CEC_HandleTypeDef *hcec); +void HAL_CEC_RxCpltCallback(CEC_HandleTypeDef *hcec); +void HAL_CEC_ErrorCallback(CEC_HandleTypeDef *hcec); +/** + * @} + */ + +/** @addtogroup CEC_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State functions ************************************************/ +HAL_CEC_StateTypeDef HAL_CEC_GetState(CEC_HandleTypeDef *hcec); +uint32_t HAL_CEC_GetError(CEC_HandleTypeDef *hcec); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/** @defgroup CEC_Private_Types CEC Private Types + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup CEC_Private_Variables CEC Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup CEC_Private_Constants CEC Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup CEC_Private_Macros CEC Private Macros + * @{ + */ + +#define IS_CEC_SIGNALFREETIME(__SFT__) ((__SFT__) <= CEC_CFGR_SFT) + +#define IS_CEC_TOLERANCE(__RXTOL__) (((__RXTOL__) == CEC_STANDARD_TOLERANCE) || \ + ((__RXTOL__) == CEC_EXTENDED_TOLERANCE)) + +#define IS_CEC_BRERXSTOP(__BRERXSTOP__) (((__BRERXSTOP__) == CEC_NO_RX_STOP_ON_BRE) || \ + ((__BRERXSTOP__) == CEC_RX_STOP_ON_BRE)) + +#define IS_CEC_BREERRORBITGEN(__ERRORBITGEN__) (((__ERRORBITGEN__) == CEC_BRE_ERRORBIT_NO_GENERATION) || \ + ((__ERRORBITGEN__) == CEC_BRE_ERRORBIT_GENERATION)) + +#define IS_CEC_LBPEERRORBITGEN(__ERRORBITGEN__) (((__ERRORBITGEN__) == CEC_LBPE_ERRORBIT_NO_GENERATION) || \ + ((__ERRORBITGEN__) == CEC_LBPE_ERRORBIT_GENERATION)) + +#define IS_CEC_BROADCASTERROR_NO_ERRORBIT_GENERATION(__ERRORBITGEN__) (((__ERRORBITGEN__) == CEC_BROADCASTERROR_ERRORBIT_GENERATION) || \ + ((__ERRORBITGEN__) == CEC_BROADCASTERROR_NO_ERRORBIT_GENERATION)) + +#define IS_CEC_SFTOP(__SFTOP__) (((__SFTOP__) == CEC_SFT_START_ON_TXSOM) || \ + ((__SFTOP__) == CEC_SFT_START_ON_TX_RX_END)) + +#define IS_CEC_LISTENING_MODE(__MODE__) (((__MODE__) == CEC_REDUCED_LISTENING_MODE) || \ + ((__MODE__) == CEC_FULL_LISTENING_MODE)) + +/** @brief Check CEC device Own Address Register (OAR) setting. + * OAR address is written in a 15-bit field within CEC_CFGR register. + * @param __ADDRESS__: CEC own address. + * @retval Test result (TRUE or FALSE). + */ +#define IS_CEC_OAR_ADDRESS(__ADDRESS__) ((__ADDRESS__) <= 0x07FFF) + +/** @brief Check CEC initiator or destination logical address setting. + * Initiator and destination addresses are coded over 4 bits. + * @param __ADDRESS__: CEC initiator or logical address. + * @retval Test result (TRUE or FALSE). + */ +#define IS_CEC_ADDRESS(__ADDRESS__) ((__ADDRESS__) <= 0xF) + +/** @brief Check CEC message size. + * The message size is the payload size: without counting the header, + * it varies from 0 byte (ping operation, one header only, no payload) to + * 15 bytes (1 opcode and up to 14 operands following the header). + * @param __SIZE__: CEC message size. + * @retval Test result (TRUE or FALSE). + */ +#define IS_CEC_MSGSIZE(__SIZE__) ((__SIZE__) <= 0xF) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup CEC_Private_Functions CEC Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F446xx */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CEC_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_conf_template.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_conf_template.h new file mode 100644 index 0000000..bf3d798 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_conf_template.h @@ -0,0 +1,427 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf_template.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief HAL configuration template file. + * This file should be copied to the application folder and renamed + * to stm32f4xx_hal_conf.h. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_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 + + +/* ########################## 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_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 */ + +/* 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****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h new file mode 100644 index 0000000..71807bf --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h @@ -0,0 +1,200 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_cortex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of CORTEX HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_CORTEX_H +#define __STM32F4xx_HAL_CORTEX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup CORTEX + * @{ + */ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup CORTEX_Exported_Constants CORTEX Exported Constants + * @{ + */ + +/** @defgroup CORTEX_Preemption_Priority_Group CORTEX Preemption Priority Group + * @{ + */ +#define NVIC_PRIORITYGROUP_0 ((uint32_t)0x00000007) /*!< 0 bits for pre-emption priority + 4 bits for subpriority */ +#define NVIC_PRIORITYGROUP_1 ((uint32_t)0x00000006) /*!< 1 bits for pre-emption priority + 3 bits for subpriority */ +#define NVIC_PRIORITYGROUP_2 ((uint32_t)0x00000005) /*!< 2 bits for pre-emption priority + 2 bits for subpriority */ +#define NVIC_PRIORITYGROUP_3 ((uint32_t)0x00000004) /*!< 3 bits for pre-emption priority + 1 bits for subpriority */ +#define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003) /*!< 4 bits for pre-emption priority + 0 bits for subpriority */ +/** + * @} + */ + +/** @defgroup CORTEX_SysTick_clock_source CORTEX _SysTick clock source + * @{ + */ +#define SYSTICK_CLKSOURCE_HCLK_DIV8 ((uint32_t)0x00000000) +#define SYSTICK_CLKSOURCE_HCLK ((uint32_t)0x00000004) + +/** + * @} + */ + +/** + * @} + */ + + +/* Exported Macros -----------------------------------------------------------*/ +/** @defgroup CORTEX_Exported_Macros CORTEX Exported Macros + * @{ + */ + +/** @brief Configures the SysTick clock source. + * @param __CLKSRC__: specifies the SysTick clock source. + * This parameter can be one of the following values: + * @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source. + * @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source. + * @retval None + */ +#define __HAL_CORTEX_SYSTICKCLK_CONFIG(__CLKSRC__) \ + do { \ + if ((__CLKSRC__) == SYSTICK_CLKSOURCE_HCLK) \ + { \ + SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK; \ + } \ + else \ + SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK; \ + } while(0) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup CORTEX_Exported_Functions + * @{ + */ + +/** @addtogroup CORTEX_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions *****************************/ +void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup); +void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority); +void HAL_NVIC_EnableIRQ(IRQn_Type IRQn); +void HAL_NVIC_DisableIRQ(IRQn_Type IRQn); +void HAL_NVIC_SystemReset(void); +uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb); +/** + * @} + */ + +/** @addtogroup CORTEX_Exported_Functions_Group2 + * @{ + */ +/* Peripheral Control functions ***********************************************/ +uint32_t HAL_NVIC_GetPriorityGrouping(void); +void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority); +uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn); +void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn); +void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn); +uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn); +void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource); +void HAL_SYSTICK_IRQHandler(void); +void HAL_SYSTICK_Callback(void); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup CORTEX_Private_Macros CORTEX Private Macros + * @{ + */ +#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PRIORITYGROUP_0) || \ + ((GROUP) == NVIC_PRIORITYGROUP_1) || \ + ((GROUP) == NVIC_PRIORITYGROUP_2) || \ + ((GROUP) == NVIC_PRIORITYGROUP_3) || \ + ((GROUP) == NVIC_PRIORITYGROUP_4)) + +#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) + +#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) + +#define IS_NVIC_DEVICE_IRQ(IRQ) ((IRQ) >= 0x00) + +#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SYSTICK_CLKSOURCE_HCLK) || \ + ((SOURCE) == SYSTICK_CLKSOURCE_HCLK_DIV8)) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CORTEX_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_crc.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_crc.h new file mode 100644 index 0000000..24a4aed --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_crc.h @@ -0,0 +1,249 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_crc.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of CRC HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_CRC_H +#define __STM32F4xx_HAL_CRC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup CRC CRC + * @brief CRC HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup CRC_Exported_Types CRC Exported Types + * @{ + */ + +/** @defgroup CRC_Exported_Types_Group1 CRC State Structure definition + * @{ + */ +typedef enum +{ + HAL_CRC_STATE_RESET = 0x00, /*!< CRC not yet initialized or disabled */ + HAL_CRC_STATE_READY = 0x01, /*!< CRC initialized and ready for use */ + HAL_CRC_STATE_BUSY = 0x02, /*!< CRC internal process is ongoing */ + HAL_CRC_STATE_TIMEOUT = 0x03, /*!< CRC timeout state */ + HAL_CRC_STATE_ERROR = 0x04 /*!< CRC error state */ + +}HAL_CRC_StateTypeDef; +/** + * @} + */ + +/** @defgroup CRC_Exported_Types_Group2 CRC Handle Structure definition + * @{ + */ +typedef struct +{ + CRC_TypeDef *Instance; /*!< Register base address */ + + HAL_LockTypeDef Lock; /*!< CRC locking object */ + + __IO HAL_CRC_StateTypeDef State; /*!< CRC communication state */ + +}CRC_HandleTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup CRC_Exported_Macros CRC Exported Macros + * @{ + */ + +/** @brief Resets CRC handle state + * @param __HANDLE__: CRC handle + * @retval None + */ +#define __HAL_CRC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_CRC_STATE_RESET) + +/** + * @brief Resets CRC Data Register. + * @param __HANDLE__: CRC handle + * @retval None + */ +#define __HAL_CRC_DR_RESET(__HANDLE__) ((__HANDLE__)->Instance->CR |= CRC_CR_RESET) + +/** + * @brief Stores a 8-bit data in the Independent Data(ID) register. + * @param __HANDLE__: CRC handle + * @param __VALUE__: 8-bit value to be stored in the ID register + * @retval None + */ +#define __HAL_CRC_SET_IDR(__HANDLE__, __VALUE__) (WRITE_REG((__HANDLE__)->Instance->IDR, (__VALUE__))) + +/** + * @brief Returns the 8-bit data stored in the Independent Data(ID) register. + * @param __HANDLE__: CRC handle + * @retval 8-bit value of the ID register + */ +#define __HAL_CRC_GET_IDR(__HANDLE__) (((__HANDLE__)->Instance->IDR) & CRC_IDR_IDR) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup CRC_Exported_Functions CRC Exported Functions + * @{ + */ + +/** @defgroup CRC_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc); +HAL_StatusTypeDef HAL_CRC_DeInit (CRC_HandleTypeDef *hcrc); +void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc); +void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc); +/** + * @} + */ + +/** @defgroup CRC_Exported_Functions_Group2 Peripheral Control functions + * @{ + */ +uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength); +uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength); +/** + * @} + */ + +/** @defgroup CRC_Exported_Functions_Group3 Peripheral State functions + * @{ + */ +HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/** @defgroup CRC_Private_Types CRC Private Types + * @{ + */ + +/** + * @} + */ + +/* Private defines -----------------------------------------------------------*/ +/** @defgroup CRC_Private_Defines CRC Private Defines + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup CRC_Private_Variables CRC Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup CRC_Private_Constants CRC Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup CRC_Private_Macros CRC Private Macros + * @{ + */ + +/** + * @} + */ + +/* Private functions prototypes ----------------------------------------------*/ +/** @defgroup CRC_Private_Functions_Prototypes CRC Private Functions Prototypes + * @{ + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup CRC_Private_Functions CRC Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CRC_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cryp.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cryp.h new file mode 100644 index 0000000..e0219ce --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cryp.h @@ -0,0 +1,536 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_cryp.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of CRYP HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_CRYP_H +#define __STM32F4xx_HAL_CRYP_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F415xx) || defined(STM32F417xx) || defined(STM32F437xx) || defined(STM32F439xx) +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup CRYP + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup CRYP_Exported_Types CRYP Exported Types + * @{ + */ + +/** @defgroup CRYP_Exported_Types_Group1 CRYP Configuration Structure definition + * @{ + */ + +typedef struct +{ + uint32_t DataType; /*!< 32-bit data, 16-bit data, 8-bit data or 1-bit string. + This parameter can be a value of @ref CRYP CRYP_Data_Type */ + + uint32_t KeySize; /*!< Used only in AES mode only : 128, 192 or 256 bit key length. + This parameter can be a value of @ref CRYP CRYP_Key_Size */ + + uint8_t* pKey; /*!< The key used for encryption/decryption */ + + uint8_t* pInitVect; /*!< The initialization vector used also as initialization + counter in CTR mode */ + + uint8_t IVSize; /*!< The size of initialization vector. + This parameter (called nonce size in CCM) is used only + in AES-128/192/256 encryption/decryption CCM mode */ + + uint8_t TagSize; /*!< The size of returned authentication TAG. + This parameter is used only in AES-128/192/256 + encryption/decryption CCM mode */ + + uint8_t* Header; /*!< The header used in GCM and CCM modes */ + + uint32_t HeaderSize; /*!< The size of header buffer in bytes */ + + uint8_t* pScratch; /*!< Scratch buffer used to append the header. It's size must be equal to header size + 21 bytes. + This parameter is used only in AES-128/192/256 encryption/decryption CCM mode */ +}CRYP_InitTypeDef; + +/** + * @} + */ + +/** @defgroup CRYP_Exported_Types_Group2 CRYP State structures definition + * @{ + */ + + +typedef enum +{ + HAL_CRYP_STATE_RESET = 0x00, /*!< CRYP not yet initialized or disabled */ + HAL_CRYP_STATE_READY = 0x01, /*!< CRYP initialized and ready for use */ + HAL_CRYP_STATE_BUSY = 0x02, /*!< CRYP internal processing is ongoing */ + HAL_CRYP_STATE_TIMEOUT = 0x03, /*!< CRYP timeout state */ + HAL_CRYP_STATE_ERROR = 0x04 /*!< CRYP error state */ +}HAL_CRYP_STATETypeDef; + +/** + * @} + */ + +/** @defgroup CRYP_Exported_Types_Group3 CRYP phase structures definition + * @{ + */ + + +typedef enum +{ + HAL_CRYP_PHASE_READY = 0x01, /*!< CRYP peripheral is ready for initialization. */ + HAL_CRYP_PHASE_PROCESS = 0x02, /*!< CRYP peripheral is in processing phase */ + HAL_CRYP_PHASE_FINAL = 0x03 /*!< CRYP peripheral is in final phase + This is relevant only with CCM and GCM modes */ +}HAL_PhaseTypeDef; + +/** + * @} + */ + +/** @defgroup CRYP_Exported_Types_Group4 CRYP handle Structure definition + * @{ + */ + +typedef struct +{ + CRYP_TypeDef *Instance; /*!< CRYP registers base address */ + + CRYP_InitTypeDef Init; /*!< CRYP required parameters */ + + uint8_t *pCrypInBuffPtr; /*!< Pointer to CRYP processing (encryption, decryption,...) buffer */ + + uint8_t *pCrypOutBuffPtr; /*!< Pointer to CRYP processing (encryption, decryption,...) buffer */ + + __IO uint16_t CrypInCount; /*!< Counter of inputed data */ + + __IO uint16_t CrypOutCount; /*!< Counter of outputted data */ + + HAL_StatusTypeDef Status; /*!< CRYP peripheral status */ + + HAL_PhaseTypeDef Phase; /*!< CRYP peripheral phase */ + + DMA_HandleTypeDef *hdmain; /*!< CRYP In DMA handle parameters */ + + DMA_HandleTypeDef *hdmaout; /*!< CRYP Out DMA handle parameters */ + + HAL_LockTypeDef Lock; /*!< CRYP locking object */ + + __IO HAL_CRYP_STATETypeDef State; /*!< CRYP peripheral state */ +}CRYP_HandleTypeDef; + +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup CRYP_Exported_Constants CRYP Exported Constants + * @{ + */ + +/** @defgroup CRYP_Exported_Constants_Group1 CRYP CRYP_Key_Size + * @{ + */ +#define CRYP_KEYSIZE_128B ((uint32_t)0x00000000) +#define CRYP_KEYSIZE_192B CRYP_CR_KEYSIZE_0 +#define CRYP_KEYSIZE_256B CRYP_CR_KEYSIZE_1 +/** + * @} + */ + +/** @defgroup CRYP_Exported_Constants_Group2 CRYP CRYP_Data_Type + * @{ + */ +#define CRYP_DATATYPE_32B ((uint32_t)0x00000000) +#define CRYP_DATATYPE_16B CRYP_CR_DATATYPE_0 +#define CRYP_DATATYPE_8B CRYP_CR_DATATYPE_1 +#define CRYP_DATATYPE_1B CRYP_CR_DATATYPE +/** + * @} + */ + +/** @defgroup CRYP_Exported_Constants_Group3 CRYP CRYP_AlgoModeDirection + * @{ + */ +#define CRYP_CR_ALGOMODE_DIRECTION ((uint32_t)0x0008003C) +#define CRYP_CR_ALGOMODE_TDES_ECB_ENCRYPT ((uint32_t)0x00000000) +#define CRYP_CR_ALGOMODE_TDES_ECB_DECRYPT ((uint32_t)0x00000004) +#define CRYP_CR_ALGOMODE_TDES_CBC_ENCRYPT ((uint32_t)0x00000008) +#define CRYP_CR_ALGOMODE_TDES_CBC_DECRYPT ((uint32_t)0x0000000C) +#define CRYP_CR_ALGOMODE_DES_ECB_ENCRYPT ((uint32_t)0x00000010) +#define CRYP_CR_ALGOMODE_DES_ECB_DECRYPT ((uint32_t)0x00000014) +#define CRYP_CR_ALGOMODE_DES_CBC_ENCRYPT ((uint32_t)0x00000018) +#define CRYP_CR_ALGOMODE_DES_CBC_DECRYPT ((uint32_t)0x0000001C) +#define CRYP_CR_ALGOMODE_AES_ECB_ENCRYPT ((uint32_t)0x00000020) +#define CRYP_CR_ALGOMODE_AES_ECB_DECRYPT ((uint32_t)0x00000024) +#define CRYP_CR_ALGOMODE_AES_CBC_ENCRYPT ((uint32_t)0x00000028) +#define CRYP_CR_ALGOMODE_AES_CBC_DECRYPT ((uint32_t)0x0000002C) +#define CRYP_CR_ALGOMODE_AES_CTR_ENCRYPT ((uint32_t)0x00000030) +#define CRYP_CR_ALGOMODE_AES_CTR_DECRYPT ((uint32_t)0x00000034) +/** + * @} + */ + +/** @defgroup CRYP_Exported_Constants_Group4 CRYP CRYP_Interrupt + * @{ + */ +#define CRYP_IT_INI ((uint32_t)CRYP_IMSCR_INIM) /*!< Input FIFO Interrupt */ +#define CRYP_IT_OUTI ((uint32_t)CRYP_IMSCR_OUTIM) /*!< Output FIFO Interrupt */ +/** + * @} + */ + +/** @defgroup CRYP_Exported_Constants_Group5 CRYP CRYP_Flags + * @{ + */ +#define CRYP_FLAG_BUSY ((uint32_t)0x00000010) /*!< The CRYP core is currently + processing a block of data + or a key preparation (for + AES decryption). */ +#define CRYP_FLAG_IFEM ((uint32_t)0x00000001) /*!< Input FIFO is empty */ +#define CRYP_FLAG_IFNF ((uint32_t)0x00000002) /*!< Input FIFO is not Full */ +#define CRYP_FLAG_OFNE ((uint32_t)0x00000004) /*!< Output FIFO is not empty */ +#define CRYP_FLAG_OFFU ((uint32_t)0x00000008) /*!< Output FIFO is Full */ +#define CRYP_FLAG_OUTRIS ((uint32_t)0x01000002) /*!< Output FIFO service raw + interrupt status */ +#define CRYP_FLAG_INRIS ((uint32_t)0x01000001) /*!< Input FIFO service raw + interrupt status */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup CRYP_Exported_Macros CRYP Exported Macros + * @{ + */ + +/** @brief Reset CRYP handle state + * @param __HANDLE__: specifies the CRYP handle. + * @retval None + */ +#define __HAL_CRYP_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_CRYP_STATE_RESET) + +/** + * @brief Enable/Disable the CRYP peripheral. + * @param __HANDLE__: specifies the CRYP handle. + * @retval None + */ +#define __HAL_CRYP_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= CRYP_CR_CRYPEN) +#define __HAL_CRYP_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~CRYP_CR_CRYPEN) + +/** + * @brief Flush the data FIFO. + * @param __HANDLE__: specifies the CRYP handle. + * @retval None + */ +#define __HAL_CRYP_FIFO_FLUSH(__HANDLE__) ((__HANDLE__)->Instance->CR |= CRYP_CR_FFLUSH) + +/** + * @brief Set the algorithm mode: AES-ECB, AES-CBC, AES-CTR, DES-ECB, DES-CBC. + * @param __HANDLE__: specifies the CRYP handle. + * @param MODE: The algorithm mode. + * @retval None + */ +#define __HAL_CRYP_SET_MODE(__HANDLE__, MODE) ((__HANDLE__)->Instance->CR |= (uint32_t)(MODE)) + +/** @brief Check whether the specified CRYP flag is set or not. + * @param __HANDLE__: specifies the CRYP handle. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg CRYP_FLAG_BUSY: The CRYP core is currently processing a block of data + * or a key preparation (for AES decryption). + * @arg CRYP_FLAG_IFEM: Input FIFO is empty + * @arg CRYP_FLAG_IFNF: Input FIFO is not full + * @arg CRYP_FLAG_INRIS: Input FIFO service raw interrupt is pending + * @arg CRYP_FLAG_OFNE: Output FIFO is not empty + * @arg CRYP_FLAG_OFFU: Output FIFO is full + * @arg CRYP_FLAG_OUTRIS: Input FIFO service raw interrupt is pending + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ + +#define __HAL_CRYP_GET_FLAG(__HANDLE__, __FLAG__) ((((uint8_t)((__FLAG__) >> 24)) == 0x01)?((((__HANDLE__)->Instance->RISR) & ((__FLAG__) & CRYP_FLAG_MASK)) == ((__FLAG__) & CRYP_FLAG_MASK)): \ + ((((__HANDLE__)->Instance->RISR) & ((__FLAG__) & CRYP_FLAG_MASK)) == ((__FLAG__) & CRYP_FLAG_MASK))) + +/** @brief Check whether the specified CRYP interrupt is set or not. + * @param __HANDLE__: specifies the CRYP handle. + * @param __INTERRUPT__: specifies the interrupt to check. + * This parameter can be one of the following values: + * @arg CRYP_IT_INRIS: Input FIFO service raw interrupt is pending + * @arg CRYP_IT_OUTRIS: Output FIFO service raw interrupt is pending + * @retval The new state of __INTERRUPT__ (TRUE or FALSE). + */ +#define __HAL_CRYP_GET_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->MISR & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @brief Enable the CRYP interrupt. + * @param __HANDLE__: specifies the CRYP handle. + * @param __INTERRUPT__: CRYP Interrupt. + * @retval None + */ +#define __HAL_CRYP_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IMSCR) |= (__INTERRUPT__)) + +/** + * @brief Disable the CRYP interrupt. + * @param __HANDLE__: specifies the CRYP handle. + * @param __INTERRUPT__: CRYP interrupt. + * @retval None + */ +#define __HAL_CRYP_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->IMSCR) &= ~(__INTERRUPT__)) + +/** + * @} + */ + +/* Include CRYP HAL Extension module */ +#include "stm32f4xx_hal_cryp_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup CRYP_Exported_Functions CRYP Exported Functions + * @{ + */ + +/** @addtogroup CRYP_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_CRYP_Init(CRYP_HandleTypeDef *hcryp); +HAL_StatusTypeDef HAL_CRYP_DeInit(CRYP_HandleTypeDef *hcryp); +void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp); +void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp); +/** + * @} + */ + +/** @addtogroup CRYP_Exported_Functions_Group2 + * @{ + */ +/* AES encryption/decryption using polling ***********************************/ +HAL_StatusTypeDef HAL_CRYP_AESECB_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYP_AESECB_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYP_AESCBC_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYP_AESCBC_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYP_AESCTR_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYP_AESCTR_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout); + +/* AES encryption/decryption using interrupt *********************************/ +HAL_StatusTypeDef HAL_CRYP_AESECB_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYP_AESCBC_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYP_AESCTR_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYP_AESECB_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); +HAL_StatusTypeDef HAL_CRYP_AESCTR_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); +HAL_StatusTypeDef HAL_CRYP_AESCBC_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); + +/* AES encryption/decryption using DMA ***************************************/ +HAL_StatusTypeDef HAL_CRYP_AESECB_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYP_AESECB_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); +HAL_StatusTypeDef HAL_CRYP_AESCBC_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYP_AESCBC_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); +HAL_StatusTypeDef HAL_CRYP_AESCTR_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYP_AESCTR_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); +/** + * @} + */ + +/** @addtogroup CRYP_Exported_Functions_Group3 + * @{ + */ +/* DES encryption/decryption using polling ***********************************/ +HAL_StatusTypeDef HAL_CRYP_DESECB_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYP_DESCBC_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYP_DESECB_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYP_DESCBC_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout); + +/* DES encryption/decryption using interrupt *********************************/ +HAL_StatusTypeDef HAL_CRYP_DESECB_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYP_DESECB_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); +HAL_StatusTypeDef HAL_CRYP_DESCBC_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYP_DESCBC_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); + +/* DES encryption/decryption using DMA ***************************************/ +HAL_StatusTypeDef HAL_CRYP_DESECB_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYP_DESECB_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); +HAL_StatusTypeDef HAL_CRYP_DESCBC_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYP_DESCBC_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); +/** + * @} + */ + +/** @addtogroup CRYP_Exported_Functions_Group4 + * @{ + */ +/* TDES encryption/decryption using polling **********************************/ +HAL_StatusTypeDef HAL_CRYP_TDESECB_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYP_TDESCBC_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYP_TDESECB_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYP_TDESCBC_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout); + +/* TDES encryption/decryption using interrupt ********************************/ +HAL_StatusTypeDef HAL_CRYP_TDESECB_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYP_TDESECB_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); +HAL_StatusTypeDef HAL_CRYP_TDESCBC_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYP_TDESCBC_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); + +/* TDES encryption/decryption using DMA **************************************/ +HAL_StatusTypeDef HAL_CRYP_TDESECB_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYP_TDESECB_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); +HAL_StatusTypeDef HAL_CRYP_TDESCBC_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYP_TDESCBC_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); +/** + * @} + */ + +/** @addtogroup CRYP_Exported_Functions_Group5 + * @{ + */ +void HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef *hcryp); +void HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef *hcryp); +void HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef *hcryp); +/** + * @} + */ + +/** @addtogroup CRYP_Exported_Functions_Group6 + * @{ + */ +void HAL_CRYP_IRQHandler(CRYP_HandleTypeDef *hcryp); +/** + * @} + */ + +/** @addtogroup CRYP_Exported_Functions_Group7 + * @{ + */ +HAL_CRYP_STATETypeDef HAL_CRYP_GetState(CRYP_HandleTypeDef *hcryp); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/** @defgroup CRYP_Private_Types CRYP Private Types + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup CRYP_Private_Variables CRYP Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup CRYP_Private_Constants CRYP Private Constants + * @{ + */ +#define CRYP_FLAG_MASK ((uint32_t)0x0000001F) +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup CRYP_Private_Macros CRYP Private Macros + * @{ + */ + +#define IS_CRYP_KEYSIZE(__KEYSIZE__) (((__KEYSIZE__) == CRYP_KEYSIZE_128B) || \ + ((__KEYSIZE__) == CRYP_KEYSIZE_192B) || \ + ((__KEYSIZE__) == CRYP_KEYSIZE_256B)) + + +#define IS_CRYP_DATATYPE(__DATATYPE__) (((__DATATYPE__) == CRYP_DATATYPE_32B) || \ + ((__DATATYPE__) == CRYP_DATATYPE_16B) || \ + ((__DATATYPE__) == CRYP_DATATYPE_8B) || \ + ((__DATATYPE__) == CRYP_DATATYPE_1B)) + + + /** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup CRYP_Private_Functions CRYP Private Functions + * @{ + */ + +/** + * @} + */ + +#endif /* STM32F415xx || STM32F417xx || STM32F437xx || STM32F439xx */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CRYP_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cryp_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cryp_ex.h new file mode 100644 index 0000000..e73ed53 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cryp_ex.h @@ -0,0 +1,221 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_cryp_ex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of CRYP HAL Extension module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_CRYP_EX_H +#define __STM32F4xx_HAL_CRYP_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F437xx) || defined(STM32F439xx) +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup CRYPEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup CRYPEx_Exported_Constants CRYPEx Exported Constants + * @{ + */ + +/** @defgroup CRYPEx_Exported_Constants_Group1 CRYP AlgoModeDirection + * @{ + */ +#define CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT ((uint32_t)0x00080000) +#define CRYP_CR_ALGOMODE_AES_GCM_DECRYPT ((uint32_t)0x00080004) +#define CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT ((uint32_t)0x00080008) +#define CRYP_CR_ALGOMODE_AES_CCM_DECRYPT ((uint32_t)0x0008000C) + +/** + * @} + */ + +/** @defgroup CRYPEx_Exported_Constants_Group3 CRYP PhaseConfig + * @brief The phases are relevant only to AES-GCM and AES-CCM + * @{ + */ +#define CRYP_PHASE_INIT ((uint32_t)0x00000000) +#define CRYP_PHASE_HEADER CRYP_CR_GCM_CCMPH_0 +#define CRYP_PHASE_PAYLOAD CRYP_CR_GCM_CCMPH_1 +#define CRYP_PHASE_FINAL CRYP_CR_GCM_CCMPH +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup CRYPEx_Exported_Macros CRYP Exported Macros + * @{ + */ + +/** + * @brief Set the phase: Init, header, payload, final. + * This is relevant only for GCM and CCM modes. + * @param __HANDLE__: specifies the CRYP handle. + * @param __PHASE__: The phase. + * @retval None + */ +#define __HAL_CRYP_SET_PHASE(__HANDLE__, __PHASE__) do{(__HANDLE__)->Instance->CR &= (uint32_t)(~CRYP_CR_GCM_CCMPH);\ + (__HANDLE__)->Instance->CR |= (uint32_t)(__PHASE__);\ + }while(0) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup CRYPEx_Exported_Functions CRYPEx Exported Functions + * @{ + */ + +/** @addtogroup CRYPEx_Exported_Functions_Group1 + * @{ + */ + +/* AES encryption/decryption using polling ***********************************/ +HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Finish(CRYP_HandleTypeDef *hcryp, uint32_t Size, uint8_t *AuthTag, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout); +HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Finish(CRYP_HandleTypeDef *hcryp, uint8_t *AuthTag, uint32_t Timeout); + +/* AES encryption/decryption using interrupt *********************************/ +HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); +HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); + +/* AES encryption/decryption using DMA ***************************************/ +HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); +HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData); +HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData); + +/** + * @} + */ + +/** @addtogroup CRYPEx_Exported_Functions_Group2 + * @{ + */ + +void HAL_CRYPEx_GCMCCM_IRQHandler(CRYP_HandleTypeDef *hcryp); + +/** + * @} + */ + + /** + * @} + */ + + + /* Private types -------------------------------------------------------------*/ +/** @defgroup CRYPEx_Private_Types CRYPEx Private Types + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup CRYPEx_Private_Variables CRYPEx Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup CRYPEx_Private_Constants CRYPEx Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup CRYPEx_Private_Macros CRYPEx Private Macros + * @{ + */ + + /** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup CRYPEx_Private_Functions CRYPEx Private Functions + * @{ + */ + +/** + * @} + */ + +#endif /* STM32F437xx || STM32F439xx */ +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CRYP_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dac.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dac.h new file mode 100644 index 0000000..bfc1259 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dac.h @@ -0,0 +1,412 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_dac.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of DAC HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_DAC_H +#define __STM32F4xx_HAL_DAC_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F446xx) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup DAC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup DAC_Exported_Types DAC Exported Types + * @{ + */ + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_DAC_STATE_RESET = 0x00, /*!< DAC not yet initialized or disabled */ + HAL_DAC_STATE_READY = 0x01, /*!< DAC initialized and ready for use */ + HAL_DAC_STATE_BUSY = 0x02, /*!< DAC internal processing is ongoing */ + HAL_DAC_STATE_TIMEOUT = 0x03, /*!< DAC timeout state */ + HAL_DAC_STATE_ERROR = 0x04 /*!< DAC error state */ +}HAL_DAC_StateTypeDef; + +/** + * @brief DAC handle Structure definition + */ +typedef struct +{ + DAC_TypeDef *Instance; /*!< Register base address */ + + __IO HAL_DAC_StateTypeDef State; /*!< DAC communication state */ + + HAL_LockTypeDef Lock; /*!< DAC locking object */ + + DMA_HandleTypeDef *DMA_Handle1; /*!< Pointer DMA handler for channel 1 */ + + DMA_HandleTypeDef *DMA_Handle2; /*!< Pointer DMA handler for channel 2 */ + + __IO uint32_t ErrorCode; /*!< DAC Error code */ + +}DAC_HandleTypeDef; + +/** + * @brief DAC Configuration regular Channel structure definition + */ +typedef struct +{ + uint32_t DAC_Trigger; /*!< Specifies the external trigger for the selected DAC channel. + This parameter can be a value of @ref DAC_trigger_selection */ + + uint32_t DAC_OutputBuffer; /*!< Specifies whether the DAC channel output buffer is enabled or disabled. + This parameter can be a value of @ref DAC_output_buffer */ +}DAC_ChannelConfTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup DAC_Exported_Constants DAC Exported Constants + * @{ + */ + +/** @defgroup DAC_Error_Code DAC Error Code + * @{ + */ +#define HAL_DAC_ERROR_NONE 0x00 /*!< No error */ +#define HAL_DAC_ERROR_DMAUNDERRUNCH1 0x01 /*!< DAC channel1 DAM underrun error */ +#define HAL_DAC_ERROR_DMAUNDERRUNCH2 0x02 /*!< DAC channel2 DAM underrun error */ +#define HAL_DAC_ERROR_DMA 0x04 /*!< DMA error */ +/** + * @} + */ + +/** @defgroup DAC_trigger_selection DAC Trigger Selection + * @{ + */ + +#define DAC_TRIGGER_NONE ((uint32_t)0x00000000) /*!< Conversion is automatic once the DAC1_DHRxxxx register + has been loaded, and not by external trigger */ +#define DAC_TRIGGER_T2_TRGO ((uint32_t)(DAC_CR_TSEL1_2 | DAC_CR_TEN1)) /*!< TIM2 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_T4_TRGO ((uint32_t)(DAC_CR_TSEL1_2 | DAC_CR_TSEL1_0 | DAC_CR_TEN1)) /*!< TIM4 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_T5_TRGO ((uint32_t)(DAC_CR_TSEL1_1 | DAC_CR_TSEL1_0 | DAC_CR_TEN1)) /*!< TIM5 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_T6_TRGO ((uint32_t)DAC_CR_TEN1) /*!< TIM6 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_T7_TRGO ((uint32_t)(DAC_CR_TSEL1_1 | DAC_CR_TEN1)) /*!< TIM7 TRGO selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_T8_TRGO ((uint32_t)(DAC_CR_TSEL1_0 | DAC_CR_TEN1)) /*!< TIM8 TRGO selected as external conversion trigger for DAC channel */ + +#define DAC_TRIGGER_EXT_IT9 ((uint32_t)(DAC_CR_TSEL1_2 | DAC_CR_TSEL1_1 | DAC_CR_TEN1)) /*!< EXTI Line9 event selected as external conversion trigger for DAC channel */ +#define DAC_TRIGGER_SOFTWARE ((uint32_t)(DAC_CR_TSEL1 | DAC_CR_TEN1)) /*!< Conversion started by software trigger for DAC channel */ +/** + * @} + */ + +/** @defgroup DAC_output_buffer DAC Output Buffer + * @{ + */ +#define DAC_OUTPUTBUFFER_ENABLE ((uint32_t)0x00000000) +#define DAC_OUTPUTBUFFER_DISABLE ((uint32_t)DAC_CR_BOFF1) +/** + * @} + */ + +/** @defgroup DAC_Channel_selection DAC Channel Selection + * @{ + */ +#define DAC_CHANNEL_1 ((uint32_t)0x00000000) +#define DAC_CHANNEL_2 ((uint32_t)0x00000010) +/** + * @} + */ + +/** @defgroup DAC_data_alignment DAC Data Alignment + * @{ + */ +#define DAC_ALIGN_12B_R ((uint32_t)0x00000000) +#define DAC_ALIGN_12B_L ((uint32_t)0x00000004) +#define DAC_ALIGN_8B_R ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup DAC_flags_definition DAC Flags Definition + * @{ + */ +#define DAC_FLAG_DMAUDR1 ((uint32_t)DAC_SR_DMAUDR1) +#define DAC_FLAG_DMAUDR2 ((uint32_t)DAC_SR_DMAUDR2) +/** + * @} + */ + +/** @defgroup DAC_IT_definition DAC IT Definition + * @{ + */ +#define DAC_IT_DMAUDR1 ((uint32_t)DAC_SR_DMAUDR1) +#define DAC_IT_DMAUDR2 ((uint32_t)DAC_SR_DMAUDR2) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup DAC_Exported_Macros DAC Exported Macros + * @{ + */ + +/** @brief Reset DAC handle state + * @param __HANDLE__: specifies the DAC handle. + * @retval None + */ +#define __HAL_DAC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_DAC_STATE_RESET) + +/** @brief Enable the DAC channel + * @param __HANDLE__: specifies the DAC handle. + * @param __DAC_Channel__: specifies the DAC channel + * @retval None + */ +#define __HAL_DAC_ENABLE(__HANDLE__, __DAC_Channel__) ((__HANDLE__)->Instance->CR |= (DAC_CR_EN1 << (__DAC_Channel__))) + +/** @brief Disable the DAC channel + * @param __HANDLE__: specifies the DAC handle + * @param __DAC_Channel__: specifies the DAC channel. + * @retval None + */ +#define __HAL_DAC_DISABLE(__HANDLE__, __DAC_Channel__) ((__HANDLE__)->Instance->CR &= ~(DAC_CR_EN1 << (__DAC_Channel__))) + +/** @brief Enable the DAC interrupt + * @param __HANDLE__: specifies the DAC handle + * @param __INTERRUPT__: specifies the DAC interrupt. + * @retval None + */ +#define __HAL_DAC_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR) |= (__INTERRUPT__)) + +/** @brief Disable the DAC interrupt + * @param __HANDLE__: specifies the DAC handle + * @param __INTERRUPT__: specifies the DAC interrupt. + * @retval None + */ +#define __HAL_DAC_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR) &= ~(__INTERRUPT__)) + +/** @brief Checks if the specified DAC interrupt source is enabled or disabled. + * @param __HANDLE__: DAC handle + * @param __INTERRUPT__: DAC interrupt source to check + * This parameter can be any combination of the following values: + * @arg DAC_IT_DMAUDR1: DAC channel 1 DMA underrun interrupt + * @arg DAC_IT_DMAUDR2: DAC channel 2 DMA underrun interrupt + * @retval State of interruption (SET or RESET) + */ +#define __HAL_DAC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CR & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** @brief Get the selected DAC's flag status. + * @param __HANDLE__: specifies the DAC handle. + * @param __FLAG__: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg DAC_FLAG_DMAUDR1: DMA underrun 1 flag + * @arg DAC_FLAG_DMAUDR2: DMA underrun 2 flag + * @retval None + */ +#define __HAL_DAC_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the DAC's flag. + * @param __HANDLE__: specifies the DAC handle. + * @param __FLAG__: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg DAC_FLAG_DMAUDR1: DMA underrun 1 flag + * @arg DAC_FLAG_DMAUDR2: DMA underrun 2 flag + * @retval None + */ +#define __HAL_DAC_CLEAR_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR) = (__FLAG__)) +/** + * @} + */ + +/* Include DAC HAL Extension module */ +#include "stm32f4xx_hal_dac_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup DAC_Exported_Functions + * @{ + */ + +/** @addtogroup DAC_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions *********************************/ +HAL_StatusTypeDef HAL_DAC_Init(DAC_HandleTypeDef* hdac); +HAL_StatusTypeDef HAL_DAC_DeInit(DAC_HandleTypeDef* hdac); +void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac); +void HAL_DAC_MspDeInit(DAC_HandleTypeDef* hdac); +/** + * @} + */ + +/** @addtogroup DAC_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions ****************************************************/ +HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef* hdac, uint32_t Channel); +HAL_StatusTypeDef HAL_DAC_Stop(DAC_HandleTypeDef* hdac, uint32_t Channel); +HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment); +HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel); +uint32_t HAL_DAC_GetValue(DAC_HandleTypeDef* hdac, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup DAC_Exported_Functions_Group3 + * @{ + */ +/* Peripheral Control functions ***********************************************/ +HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef* hdac, DAC_ChannelConfTypeDef* sConfig, uint32_t Channel); +HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data); +/** + * @} + */ + +/** @addtogroup DAC_Exported_Functions_Group4 + * @{ + */ +/* Peripheral State functions *************************************************/ +HAL_DAC_StateTypeDef HAL_DAC_GetState(DAC_HandleTypeDef* hdac); +void HAL_DAC_IRQHandler(DAC_HandleTypeDef* hdac); +uint32_t HAL_DAC_GetError(DAC_HandleTypeDef *hdac); + +void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef* hdac); +void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef* hdac); +void HAL_DAC_ErrorCallbackCh1(DAC_HandleTypeDef *hdac); +void HAL_DAC_DMAUnderrunCallbackCh1(DAC_HandleTypeDef *hdac); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup DAC_Private_Constants DAC Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup DAC_Private_Macros DAC Private Macros + * @{ + */ +#define IS_DAC_DATA(DATA) ((DATA) <= 0xFFF0) +#define IS_DAC_ALIGN(ALIGN) (((ALIGN) == DAC_ALIGN_12B_R) || \ + ((ALIGN) == DAC_ALIGN_12B_L) || \ + ((ALIGN) == DAC_ALIGN_8B_R)) +#define IS_DAC_CHANNEL(CHANNEL) (((CHANNEL) == DAC_CHANNEL_1) || \ + ((CHANNEL) == DAC_CHANNEL_2)) +#define IS_DAC_OUTPUT_BUFFER_STATE(STATE) (((STATE) == DAC_OUTPUTBUFFER_ENABLE) || \ + ((STATE) == DAC_OUTPUTBUFFER_DISABLE)) + +#define IS_DAC_TRIGGER(TRIGGER) (((TRIGGER) == DAC_TRIGGER_NONE) || \ + ((TRIGGER) == DAC_TRIGGER_T2_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T8_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T7_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T5_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T6_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_T4_TRGO) || \ + ((TRIGGER) == DAC_TRIGGER_EXT_IT9) || \ + ((TRIGGER) == DAC_TRIGGER_SOFTWARE)) + +/** @brief Set DHR12R1 alignment + * @param __ALIGNMENT__: specifies the DAC alignment + * @retval None + */ +#define DAC_DHR12R1_ALIGNMENT(__ALIGNMENT__) (((uint32_t)0x00000008) + (__ALIGNMENT__)) + +/** @brief Set DHR12R2 alignment + * @param __ALIGNMENT__: specifies the DAC alignment + * @retval None + */ +#define DAC_DHR12R2_ALIGNMENT(__ALIGNMENT__) (((uint32_t)0x00000014) + (__ALIGNMENT__)) + +/** @brief Set DHR12RD alignment + * @param __ALIGNMENT__: specifies the DAC alignment + * @retval None + */ +#define DAC_DHR12RD_ALIGNMENT(__ALIGNMENT__) (((uint32_t)0x00000020) + (__ALIGNMENT__)) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup DAC_Private_Functions DAC Private Functions + * @{ + */ +/** + * @} + */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx ||\ + STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||\ + STM32F446xx */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_HAL_DAC_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dac_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dac_ex.h new file mode 100644 index 0000000..10a118b --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dac_ex.h @@ -0,0 +1,199 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_dac.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of DAC HAL Extension module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_DAC_EX_H +#define __STM32F4xx_HAL_DAC_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F446xx) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup DACEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup DACEx_Exported_Constants DAC Exported Constants + * @{ + */ + +/** @defgroup DACEx_lfsrunmask_triangleamplitude DAC LFS Run Mask Triangle Amplitude + * @{ + */ +#define DAC_LFSRUNMASK_BIT0 ((uint32_t)0x00000000) /*!< Unmask DAC channel LFSR bit0 for noise wave generation */ +#define DAC_LFSRUNMASK_BITS1_0 ((uint32_t)DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[1:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS2_0 ((uint32_t)DAC_CR_MAMP1_1) /*!< Unmask DAC channel LFSR bit[2:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS3_0 ((uint32_t)DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0)/*!< Unmask DAC channel LFSR bit[3:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS4_0 ((uint32_t)DAC_CR_MAMP1_2) /*!< Unmask DAC channel LFSR bit[4:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS5_0 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[5:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS6_0 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1) /*!< Unmask DAC channel LFSR bit[6:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS7_0 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[7:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS8_0 ((uint32_t)DAC_CR_MAMP1_3) /*!< Unmask DAC channel LFSR bit[8:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS9_0 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[9:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS10_0 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1) /*!< Unmask DAC channel LFSR bit[10:0] for noise wave generation */ +#define DAC_LFSRUNMASK_BITS11_0 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Unmask DAC channel LFSR bit[11:0] for noise wave generation */ +#define DAC_TRIANGLEAMPLITUDE_1 ((uint32_t)0x00000000) /*!< Select max triangle amplitude of 1 */ +#define DAC_TRIANGLEAMPLITUDE_3 ((uint32_t)DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 3 */ +#define DAC_TRIANGLEAMPLITUDE_7 ((uint32_t)DAC_CR_MAMP1_1) /*!< Select max triangle amplitude of 7 */ +#define DAC_TRIANGLEAMPLITUDE_15 ((uint32_t)DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 15 */ +#define DAC_TRIANGLEAMPLITUDE_31 ((uint32_t)DAC_CR_MAMP1_2) /*!< Select max triangle amplitude of 31 */ +#define DAC_TRIANGLEAMPLITUDE_63 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 63 */ +#define DAC_TRIANGLEAMPLITUDE_127 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1) /*!< Select max triangle amplitude of 127 */ +#define DAC_TRIANGLEAMPLITUDE_255 ((uint32_t)DAC_CR_MAMP1_2 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 255 */ +#define DAC_TRIANGLEAMPLITUDE_511 ((uint32_t)DAC_CR_MAMP1_3) /*!< Select max triangle amplitude of 511 */ +#define DAC_TRIANGLEAMPLITUDE_1023 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 1023 */ +#define DAC_TRIANGLEAMPLITUDE_2047 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1) /*!< Select max triangle amplitude of 2047 */ +#define DAC_TRIANGLEAMPLITUDE_4095 ((uint32_t)DAC_CR_MAMP1_3 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_0) /*!< Select max triangle amplitude of 4095 */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup DACEx_Exported_Functions + * @{ + */ + +/** @addtogroup DACEx_Exported_Functions_Group1 + * @{ + */ +/* Extension features functions ***********************************************/ +uint32_t HAL_DACEx_DualGetValue(DAC_HandleTypeDef* hdac); +HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude); +HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude); +HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef* hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2); + +void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef* hdac); +void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef* hdac); +void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef* hdac); +void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef* hdac); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup DACEx_Private_Constants DAC Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup DACEx_Private_Macros DAC Private Macros + * @{ + */ +#define IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(VALUE) (((VALUE) == DAC_LFSRUNMASK_BIT0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS1_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS2_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS3_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS4_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS5_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS6_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS7_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS8_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS9_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS10_0) || \ + ((VALUE) == DAC_LFSRUNMASK_BITS11_0) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_1) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_3) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_7) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_15) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_31) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_63) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_127) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_255) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_511) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_1023) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_2047) || \ + ((VALUE) == DAC_TRIANGLEAMPLITUDE_4095)) +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup DACEx_Private_Functions DAC Private Functions + * @{ + */ +void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma); +void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma); +void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma); +/** + * @} + */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx ||\ + STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||\ + STM32F446xx */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_HAL_DAC_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dcmi.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dcmi.h new file mode 100644 index 0000000..644f7a8 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dcmi.h @@ -0,0 +1,515 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_dcmi.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of DCMI HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_DCMI_H +#define __STM32F4xx_HAL_DCMI_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) ||\ + defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/* Include DCMI HAL Extended module */ +/* (include on top of file since DCMI structures are defined in extended file) */ +#include "stm32f4xx_hal_dcmi_ex.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup DCMI DCMI + * @brief DCMI HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup DCMI_Exported_Types DCMI Exported Types + * @{ + */ +/** + * @brief DCMI Error source + */ +typedef enum +{ + DCMI_ERROR_SYNC = 1, /*!< Synchronisation error */ + DCMI_OVERRUN = 2, /*!< DCMI Overrun */ +}DCMI_ErrorTypeDef; + + +/** + * @brief HAL DCMI State structures definition + */ +typedef enum +{ + HAL_DCMI_STATE_RESET = 0x00, /*!< DCMI not yet initialized or disabled */ + HAL_DCMI_STATE_READY = 0x01, /*!< DCMI initialized and ready for use */ + HAL_DCMI_STATE_BUSY = 0x02, /*!< DCMI internal processing is ongoing */ + HAL_DCMI_STATE_TIMEOUT = 0x03, /*!< DCMI timeout state */ + HAL_DCMI_STATE_ERROR = 0x04 /*!< DCMI error state */ +}HAL_DCMI_StateTypeDef; + +/** + * @brief DCMI handle Structure definition + */ +typedef struct +{ + DCMI_TypeDef *Instance; /*!< DCMI Register base address */ + + DCMI_InitTypeDef Init; /*!< DCMI parameters */ + + HAL_LockTypeDef Lock; /*!< DCMI locking object */ + + __IO HAL_DCMI_StateTypeDef State; /*!< DCMI state */ + + __IO uint32_t XferCount; /*!< DMA transfer counter */ + + __IO uint32_t XferSize; /*!< DMA transfer size */ + + uint32_t XferTransferNumber; /*!< DMA transfer number */ + + uint32_t pBuffPtr; /*!< Pointer to DMA output buffer */ + + DMA_HandleTypeDef *DMA_Handle; /*!< Pointer to the DMA handler */ + + __IO uint32_t ErrorCode; /*!< DCMI Error code */ + +}DCMI_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup DCMI_Exported_Constants DCMI Exported Constants + * @{ + */ + +/** @defgroup DCMI_Error_Code DCMI Error Code + * @{ + */ +#define HAL_DCMI_ERROR_NONE ((uint32_t)0x00000000) /*!< No error */ +#define HAL_DCMI_ERROR_OVF ((uint32_t)0x00000001) /*!< Overflow error */ +#define HAL_DCMI_ERROR_SYNC ((uint32_t)0x00000002) /*!< Synchronization error */ +#define HAL_DCMI_ERROR_TIMEOUT ((uint32_t)0x00000020) /*!< Timeout error */ +/** + * @} + */ + +/** @defgroup DCMI_Capture_Mode DCMI Capture Mode + * @{ + */ +#define DCMI_MODE_CONTINUOUS ((uint32_t)0x00000000) /*!< The received data are transferred continuously + into the destination memory through the DMA */ +#define DCMI_MODE_SNAPSHOT ((uint32_t)DCMI_CR_CM) /*!< Once activated, the interface waits for the start of + frame and then transfers a single frame through the DMA */ +/** + * @} + */ + +/** @defgroup DCMI_Synchronization_Mode DCMI Synchronization Mode + * @{ + */ +#define DCMI_SYNCHRO_HARDWARE ((uint32_t)0x00000000) /*!< Hardware synchronization data capture (frame/line start/stop) + is synchronized with the HSYNC/VSYNC signals */ +#define DCMI_SYNCHRO_EMBEDDED ((uint32_t)DCMI_CR_ESS) /*!< Embedded synchronization data capture is synchronized with + synchronization codes embedded in the data flow */ + +/** + * @} + */ + +/** @defgroup DCMI_PIXCK_Polarity DCMI PIXCK Polarity + * @{ + */ +#define DCMI_PCKPOLARITY_FALLING ((uint32_t)0x00000000) /*!< Pixel clock active on Falling edge */ +#define DCMI_PCKPOLARITY_RISING ((uint32_t)DCMI_CR_PCKPOL) /*!< Pixel clock active on Rising edge */ + +/** + * @} + */ + +/** @defgroup DCMI_VSYNC_Polarity DCMI VSYNC Polarity + * @{ + */ +#define DCMI_VSPOLARITY_LOW ((uint32_t)0x00000000) /*!< Vertical synchronization active Low */ +#define DCMI_VSPOLARITY_HIGH ((uint32_t)DCMI_CR_VSPOL) /*!< Vertical synchronization active High */ + +/** + * @} + */ + +/** @defgroup DCMI_HSYNC_Polarity DCMI HSYNC Polarity + * @{ + */ +#define DCMI_HSPOLARITY_LOW ((uint32_t)0x00000000) /*!< Horizontal synchronization active Low */ +#define DCMI_HSPOLARITY_HIGH ((uint32_t)DCMI_CR_HSPOL) /*!< Horizontal synchronization active High */ + +/** + * @} + */ + +/** @defgroup DCMI_MODE_JPEG DCMI MODE JPEG + * @{ + */ +#define DCMI_JPEG_DISABLE ((uint32_t)0x00000000) /*!< Mode JPEG Disabled */ +#define DCMI_JPEG_ENABLE ((uint32_t)DCMI_CR_JPEG) /*!< Mode JPEG Enabled */ + +/** + * @} + */ + +/** @defgroup DCMI_Capture_Rate DCMI Capture Rate + * @{ + */ +#define DCMI_CR_ALL_FRAME ((uint32_t)0x00000000) /*!< All frames are captured */ +#define DCMI_CR_ALTERNATE_2_FRAME ((uint32_t)DCMI_CR_FCRC_0) /*!< Every alternate frame captured */ +#define DCMI_CR_ALTERNATE_4_FRAME ((uint32_t)DCMI_CR_FCRC_1) /*!< One frame in 4 frames captured */ + +/** + * @} + */ + +/** @defgroup DCMI_Extended_Data_Mode DCMI Extended Data Mode + * @{ + */ +#define DCMI_EXTEND_DATA_8B ((uint32_t)0x00000000) /*!< Interface captures 8-bit data on every pixel clock */ +#define DCMI_EXTEND_DATA_10B ((uint32_t)DCMI_CR_EDM_0) /*!< Interface captures 10-bit data on every pixel clock */ +#define DCMI_EXTEND_DATA_12B ((uint32_t)DCMI_CR_EDM_1) /*!< Interface captures 12-bit data on every pixel clock */ +#define DCMI_EXTEND_DATA_14B ((uint32_t)(DCMI_CR_EDM_0 | DCMI_CR_EDM_1)) /*!< Interface captures 14-bit data on every pixel clock */ + +/** + * @} + */ + +/** @defgroup DCMI_Window_Coordinate DCMI Window Coordinate + * @{ + */ +#define DCMI_WINDOW_COORDINATE ((uint32_t)0x3FFF) /*!< Window coordinate */ + +/** + * @} + */ + +/** @defgroup DCMI_Window_Height DCMI Window Height + * @{ + */ +#define DCMI_WINDOW_HEIGHT ((uint32_t)0x1FFF) /*!< Window Height */ + +/** + * @} + */ + +/** @defgroup DCMI_interrupt_sources DCMI interrupt sources + * @{ + */ +#define DCMI_IT_FRAME ((uint32_t)DCMI_IER_FRAME_IE) +#define DCMI_IT_OVF ((uint32_t)DCMI_IER_OVF_IE) +#define DCMI_IT_ERR ((uint32_t)DCMI_IER_ERR_IE) +#define DCMI_IT_VSYNC ((uint32_t)DCMI_IER_VSYNC_IE) +#define DCMI_IT_LINE ((uint32_t)DCMI_IER_LINE_IE) +/** + * @} + */ + +/** @defgroup DCMI_Flags DCMI Flags + * @{ + */ + +/** + * @brief DCMI SR register + */ +#define DCMI_FLAG_HSYNC ((uint32_t)0x2001) +#define DCMI_FLAG_VSYNC ((uint32_t)0x2002) +#define DCMI_FLAG_FNE ((uint32_t)0x2004) +/** + * @brief DCMI RISR register + */ +#define DCMI_FLAG_FRAMERI ((uint32_t)DCMI_RISR_FRAME_RIS) +#define DCMI_FLAG_OVFRI ((uint32_t)DCMI_RISR_OVF_RIS) +#define DCMI_FLAG_ERRRI ((uint32_t)DCMI_RISR_ERR_RIS) +#define DCMI_FLAG_VSYNCRI ((uint32_t)DCMI_RISR_VSYNC_RIS) +#define DCMI_FLAG_LINERI ((uint32_t)DCMI_RISR_LINE_RIS) +/** + * @brief DCMI MISR register + */ +#define DCMI_FLAG_FRAMEMI ((uint32_t)0x1001) +#define DCMI_FLAG_OVFMI ((uint32_t)0x1002) +#define DCMI_FLAG_ERRMI ((uint32_t)0x1004) +#define DCMI_FLAG_VSYNCMI ((uint32_t)0x1008) +#define DCMI_FLAG_LINEMI ((uint32_t)0x1010) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup DCMI_Exported_Macros DCMI Exported Macros + * @{ + */ + +/** @brief Reset DCMI handle state + * @param __HANDLE__: specifies the DCMI handle. + * @retval None + */ +#define __HAL_DCMI_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_DCMI_STATE_RESET) + +/** + * @brief Enable the DCMI. + * @param __HANDLE__: DCMI handle + * @retval None + */ +#define __HAL_DCMI_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= DCMI_CR_ENABLE) + +/** + * @brief Disable the DCMI. + * @param __HANDLE__: DCMI handle + * @retval None + */ +#define __HAL_DCMI_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~(DCMI_CR_ENABLE)) + +/* Interrupt & Flag management */ +/** + * @brief Get the DCMI pending flags. + * @param __HANDLE__: DCMI handle + * @param __FLAG__: Get the specified flag. + * This parameter can be any combination of the following values: + * @arg DCMI_FLAG_FRAMERI: Frame capture complete flag mask + * @arg DCMI_FLAG_OVFRI: Overflow flag mask + * @arg DCMI_FLAG_ERRRI: Synchronization error flag mask + * @arg DCMI_FLAG_VSYNCRI: VSYNC flag mask + * @arg DCMI_FLAG_LINERI: Line flag mask + * @retval The state of FLAG. + */ +#define __HAL_DCMI_GET_FLAG(__HANDLE__, __FLAG__)\ +((((__FLAG__) & 0x3000) == 0x0)? ((__HANDLE__)->Instance->RISR & (__FLAG__)) :\ + (((__FLAG__) & 0x2000) == 0x0)? ((__HANDLE__)->Instance->MISR & (__FLAG__)) : ((__HANDLE__)->Instance->SR & (__FLAG__))) + +/** + * @brief Clear the DCMI pending flags. + * @param __HANDLE__: DCMI handle + * @param __FLAG__: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg DCMI_FLAG_FRAMERI: Frame capture complete flag mask + * @arg DCMI_FLAG_OVFRI: Overflow flag mask + * @arg DCMI_FLAG_ERRRI: Synchronization error flag mask + * @arg DCMI_FLAG_VSYNCRI: VSYNC flag mask + * @arg DCMI_FLAG_LINERI: Line flag mask + * @retval None + */ +#define __HAL_DCMI_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) + +/** + * @brief Enable the specified DCMI interrupts. + * @param __HANDLE__: DCMI handle + * @param __INTERRUPT__: specifies the DCMI interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg DCMI_IT_FRAME: Frame capture complete interrupt mask + * @arg DCMI_IT_OVF: Overflow interrupt mask + * @arg DCMI_IT_ERR: Synchronization error interrupt mask + * @arg DCMI_IT_VSYNC: VSYNC interrupt mask + * @arg DCMI_IT_LINE: Line interrupt mask + * @retval None + */ +#define __HAL_DCMI_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER |= (__INTERRUPT__)) + +/** + * @brief Disable the specified DCMI interrupts. + * @param __HANDLE__: DCMI handle + * @param __INTERRUPT__: specifies the DCMI interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg DCMI_IT_FRAME: Frame capture complete interrupt mask + * @arg DCMI_IT_OVF: Overflow interrupt mask + * @arg DCMI_IT_ERR: Synchronization error interrupt mask + * @arg DCMI_IT_VSYNC: VSYNC interrupt mask + * @arg DCMI_IT_LINE: Line interrupt mask + * @retval None + */ +#define __HAL_DCMI_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER &= ~(__INTERRUPT__)) + +/** + * @brief Check whether the specified DCMI interrupt has occurred or not. + * @param __HANDLE__: DCMI handle + * @param __INTERRUPT__: specifies the DCMI interrupt source to check. + * This parameter can be one of the following values: + * @arg DCMI_IT_FRAME: Frame capture complete interrupt mask + * @arg DCMI_IT_OVF: Overflow interrupt mask + * @arg DCMI_IT_ERR: Synchronization error interrupt mask + * @arg DCMI_IT_VSYNC: VSYNC interrupt mask + * @arg DCMI_IT_LINE: Line interrupt mask + * @retval The state of INTERRUPT. + */ +#define __HAL_DCMI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MISR & (__INTERRUPT__)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup DCMI_Exported_Functions + * @{ + */ + +/** @addtogroup DCMI_Exported_Functions_Group1 + * @{ + */ + +/* Initialization and de-initialization functions *****************************/ +HAL_StatusTypeDef HAL_DCMI_Init(DCMI_HandleTypeDef *hdcmi); +HAL_StatusTypeDef HAL_DCMI_DeInit(DCMI_HandleTypeDef *hdcmi); +void HAL_DCMI_MspInit(DCMI_HandleTypeDef* hdcmi); +void HAL_DCMI_MspDeInit(DCMI_HandleTypeDef* hdcmi); +/** + * @} + */ + +/** @addtogroup DCMI_Exported_Functions_Group2 + * @{ + */ + +/* IO operation functions *****************************************************/ +HAL_StatusTypeDef HAL_DCMI_Start_DMA(DCMI_HandleTypeDef* hdcmi, uint32_t DCMI_Mode, uint32_t pData, uint32_t Length); +HAL_StatusTypeDef HAL_DCMI_Stop(DCMI_HandleTypeDef* hdcmi); +void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi); +void HAL_DCMI_LineEventCallback(DCMI_HandleTypeDef *hdcmi); +void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi); +void HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef *hdcmi); +void HAL_DCMI_IRQHandler(DCMI_HandleTypeDef *hdcmi); +/** + * @} + */ + +/** @addtogroup DCMI_Exported_Functions_Group3 + * @{ + */ +/* Peripheral Control functions ***********************************************/ +HAL_StatusTypeDef HAL_DCMI_ConfigCROP(DCMI_HandleTypeDef *hdcmi, uint32_t X0, uint32_t Y0, uint32_t XSize, uint32_t YSize); +HAL_StatusTypeDef HAL_DCMI_EnableCROP(DCMI_HandleTypeDef *hdcmi); +HAL_StatusTypeDef HAL_DCMI_DisableCROP(DCMI_HandleTypeDef *hdcmi); +/** + * @} + */ + +/** @addtogroup DCMI_Exported_Functions_Group4 + * @{ + */ +/* Peripheral State functions *************************************************/ +HAL_DCMI_StateTypeDef HAL_DCMI_GetState(DCMI_HandleTypeDef *hdcmi); +uint32_t HAL_DCMI_GetError(DCMI_HandleTypeDef *hdcmi); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/** @defgroup DCMI_Private_Macros DCMI Private Macros + * @{ + */ +#define IS_DCMI_CAPTURE_MODE(MODE)(((MODE) == DCMI_MODE_CONTINUOUS) || \ + ((MODE) == DCMI_MODE_SNAPSHOT)) + +#define IS_DCMI_SYNCHRO(MODE)(((MODE) == DCMI_SYNCHRO_HARDWARE) || \ + ((MODE) == DCMI_SYNCHRO_EMBEDDED)) + +#define IS_DCMI_PCKPOLARITY(POLARITY)(((POLARITY) == DCMI_PCKPOLARITY_FALLING) || \ + ((POLARITY) == DCMI_PCKPOLARITY_RISING)) + +#define IS_DCMI_VSPOLARITY(POLARITY)(((POLARITY) == DCMI_VSPOLARITY_LOW) || \ + ((POLARITY) == DCMI_VSPOLARITY_HIGH)) + +#define IS_DCMI_HSPOLARITY(POLARITY)(((POLARITY) == DCMI_HSPOLARITY_LOW) || \ + ((POLARITY) == DCMI_HSPOLARITY_HIGH)) + +#define IS_DCMI_MODE_JPEG(JPEG_MODE)(((JPEG_MODE) == DCMI_JPEG_DISABLE) || \ + ((JPEG_MODE) == DCMI_JPEG_ENABLE)) + +#define IS_DCMI_CAPTURE_RATE(RATE) (((RATE) == DCMI_CR_ALL_FRAME) || \ + ((RATE) == DCMI_CR_ALTERNATE_2_FRAME) || \ + ((RATE) == DCMI_CR_ALTERNATE_4_FRAME)) + +#define IS_DCMI_EXTENDED_DATA(DATA)(((DATA) == DCMI_EXTEND_DATA_8B) || \ + ((DATA) == DCMI_EXTEND_DATA_10B) || \ + ((DATA) == DCMI_EXTEND_DATA_12B) || \ + ((DATA) == DCMI_EXTEND_DATA_14B)) + +#define IS_DCMI_WINDOW_COORDINATE(COORDINATE) ((COORDINATE) <= DCMI_WINDOW_COORDINATE) + +#define IS_DCMI_WINDOW_HEIGHT(HEIGHT) ((HEIGHT) <= DCMI_WINDOW_HEIGHT) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup DCMI_Private_Functions DCMI Private Functions + * @{ + */ + +/** + * @} + */ + +#endif /* STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\ + STM32F429xx || STM32F439xx || STM32F446xx */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_DCMI_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dcmi_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dcmi_ex.h new file mode 100644 index 0000000..6355fb5 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dcmi_ex.h @@ -0,0 +1,221 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_dcmi_ex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of DCMI Extension HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_DCMI_EX_H +#define __STM32F4xx_HAL_DCMI_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) ||\ + defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup DCMIEx DCMI Extended + * @brief DCMI HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup DCMIEx_Exported_Types DCMI Extende Exported Types + * @{ + */ +/** + * @brief DCMIEx Embedded Synchronisation CODE Init structure definition + */ +typedef struct +{ + uint8_t FrameStartCode; /*!< Specifies the code of the frame start delimiter. */ + uint8_t LineStartCode; /*!< Specifies the code of the line start delimiter. */ + uint8_t LineEndCode; /*!< Specifies the code of the line end delimiter. */ + uint8_t FrameEndCode; /*!< Specifies the code of the frame end delimiter. */ +}DCMI_CodesInitTypeDef; + +/** + * @brief DCMI Init structure definition + */ +typedef struct +{ + uint32_t SynchroMode; /*!< Specifies the Synchronization Mode: Hardware or Embedded. + This parameter can be a value of @ref DCMI_Synchronization_Mode */ + + uint32_t PCKPolarity; /*!< Specifies the Pixel clock polarity: Falling or Rising. + This parameter can be a value of @ref DCMI_PIXCK_Polarity */ + + uint32_t VSPolarity; /*!< Specifies the Vertical synchronization polarity: High or Low. + This parameter can be a value of @ref DCMI_VSYNC_Polarity */ + + uint32_t HSPolarity; /*!< Specifies the Horizontal synchronization polarity: High or Low. + This parameter can be a value of @ref DCMI_HSYNC_Polarity */ + + uint32_t CaptureRate; /*!< Specifies the frequency of frame capture: All, 1/2 or 1/4. + This parameter can be a value of @ref DCMI_Capture_Rate */ + + uint32_t ExtendedDataMode; /*!< Specifies the data width: 8-bit, 10-bit, 12-bit or 14-bit. + This parameter can be a value of @ref DCMI_Extended_Data_Mode */ + + DCMI_CodesInitTypeDef SyncroCode; /*!< Specifies the code of the frame start delimiter. */ + + uint32_t JPEGMode; /*!< Enable or Disable the JPEG mode. + This parameter can be a value of @ref DCMI_MODE_JPEG */ +#if defined(STM32F446xx) + uint32_t ByteSelectMode; /*!< Specifies the data to be captured by the interface + This parameter can be a value of @ref DCMIEx_Byte_Select_Mode */ + + uint32_t ByteSelectStart; /*!< Specifies if the data to be captured by the interface is even or odd + This parameter can be a value of @ref DCMIEx_Byte_Select_Start */ + + uint32_t LineSelectMode; /*!< Specifies the line of data to be captured by the interface + This parameter can be a value of @ref DCMIEx_Line_Select_Mode */ + + uint32_t LineSelectStart; /*!< Specifies if the line of data to be captured by the interface is even or odd + This parameter can be a value of @ref DCMIEx_Line_Select_Start */ + +#endif /* STM32F446xx */ +}DCMI_InitTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +#if defined(STM32F446xx) +/** @defgroup DCMIEx_Exported_Constants DCMI Exported Constants + * @{ + */ + +/** @defgroup DCMIEx_Byte_Select_Mode DCMI Byte Select Mode + * @{ + */ +#define DCMI_BSM_ALL ((uint32_t)0x00000000) /*!< Interface captures all received data */ +#define DCMI_BSM_OTHER ((uint32_t)DCMI_CR_BSM_0) /*!< Interface captures every other byte from the received data */ +#define DCMI_BSM_ALTERNATE_4 ((uint32_t)DCMI_CR_BSM_1) /*!< Interface captures one byte out of four */ +#define DCMI_BSM_ALTERNATE_2 ((uint32_t)(DCMI_CR_BSM_0 | DCMI_CR_BSM_1)) /*!< Interface captures two bytes out of four */ + +/** + * @} + */ + +/** @defgroup DCMIEx_Byte_Select_Start DCMI Byte Select Start + * @{ + */ +#define DCMI_OEBS_ODD ((uint32_t)0x00000000) /*!< Interface captures first data from the frame/line start, second one being dropped */ +#define DCMI_OEBS_EVEN ((uint32_t)DCMI_CR_OEBS) /*!< Interface captures second data from the frame/line start, first one being dropped */ + +/** + * @} + */ + +/** @defgroup DCMIEx_Line_Select_Mode DCMI Line Select Mode + * @{ + */ +#define DCMI_LSM_ALL ((uint32_t)0x00000000) /*!< Interface captures all received lines */ +#define DCMI_LSM_ALTERNATE_2 ((uint32_t)DCMI_CR_LSM) /*!< Interface captures one line out of two */ + +/** + * @} + */ + +/** @defgroup DCMIEx_Line_Select_Start DCMI Line Select Start + * @{ + */ +#define DCMI_OELS_ODD ((uint32_t)0x00000000) /*!< Interface captures first line from the frame start, second one being dropped */ +#define DCMI_OELS_EVEN ((uint32_t)DCMI_CR_OELS) /*!< Interface captures second line from the frame start, first one being dropped */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ + +/** @defgroup DCMIEx_Private_Macros DCMI Extended Private Macros + * @{ + */ +#define IS_DCMI_BYTE_SELECT_MODE(MODE)(((MODE) == DCMI_BSM_ALL) || \ + ((MODE) == DCMI_BSM_OTHER) || \ + ((MODE) == DCMI_BSM_ALTERNATE_4) || \ + ((MODE) == DCMI_BSM_ALTERNATE_2)) + +#define IS_DCMI_BYTE_SELECT_START(POLARITY)(((POLARITY) == DCMI_OEBS_ODD) || \ + ((POLARITY) == DCMI_OEBS_EVEN)) + +#define IS_DCMI_LINE_SELECT_MODE(MODE)(((MODE) == DCMI_LSM_ALL) || \ + ((MODE) == DCMI_LSM_ALTERNATE_2)) + +#define IS_DCMI_LINE_SELECT_START(POLARITY)(((POLARITY) == DCMI_OELS_ODD) || \ + ((POLARITY) == DCMI_OELS_EVEN)) +#endif /* STM32F446xx */ +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +#endif /* STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\ + STM32F429xx || STM32F439xx || STM32F446xx */ +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_DCMI_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h new file mode 100644 index 0000000..0a38f5e --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h @@ -0,0 +1,214 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_def.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief This file contains HAL common defines, enumeration, macros and + * structures definitions. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_DEF +#define __STM32F4xx_HAL_DEF + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" +#include "Legacy/stm32_hal_legacy.h" +#include + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief HAL Status structures definition + */ +typedef enum +{ + HAL_OK = 0x00, + HAL_ERROR = 0x01, + HAL_BUSY = 0x02, + HAL_TIMEOUT = 0x03 +} HAL_StatusTypeDef; + +/** + * @brief HAL Lock structures definition + */ +typedef enum +{ + HAL_UNLOCKED = 0x00, + HAL_LOCKED = 0x01 +} HAL_LockTypeDef; + +/* Exported macro ------------------------------------------------------------*/ +#define HAL_MAX_DELAY 0xFFFFFFFF + +#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) != RESET) +#define HAL_IS_BIT_CLR(REG, BIT) (((REG) & (BIT)) == RESET) + +#define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__) \ + do{ \ + (__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \ + (__DMA_HANDLE__).Parent = (__HANDLE__); \ + } while(0) + +#define UNUSED(x) ((void)(x)) + +/** @brief Reset the Handle's State field. + * @param __HANDLE__: specifies the Peripheral Handle. + * @note This macro can be used for the following purpose: + * - When the Handle is declared as local variable; before passing it as parameter + * to HAL_PPP_Init() for the first time, it is mandatory to use this macro + * to set to 0 the Handle's "State" field. + * Otherwise, "State" field may have any random value and the first time the function + * HAL_PPP_Init() is called, the low level hardware initialization will be missed + * (i.e. HAL_PPP_MspInit() will not be executed). + * - When there is a need to reconfigure the low level hardware: instead of calling + * HAL_PPP_DeInit() then HAL_PPP_Init(), user can make a call to this macro then HAL_PPP_Init(). + * In this later function, when the Handle's "State" field is set to 0, it will execute the function + * HAL_PPP_MspInit() which will reconfigure the low level hardware. + * @retval None + */ +#define __HAL_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = 0) + +#if (USE_RTOS == 1) + /* Reserved for future use */ + #error “USE_RTOS should be 0 in the current HAL release” +#else + #define __HAL_LOCK(__HANDLE__) \ + do{ \ + if((__HANDLE__)->Lock == HAL_LOCKED) \ + { \ + return HAL_BUSY; \ + } \ + else \ + { \ + (__HANDLE__)->Lock = HAL_LOCKED; \ + } \ + }while (0) + + #define __HAL_UNLOCK(__HANDLE__) \ + do{ \ + (__HANDLE__)->Lock = HAL_UNLOCKED; \ + }while (0) +#endif /* USE_RTOS */ + +#if defined ( __GNUC__ ) + #ifndef __weak + #define __weak __attribute__((weak)) + #endif /* __weak */ + #ifndef __packed + #define __packed __attribute__((__packed__)) + #endif /* __packed */ +#endif /* __GNUC__ */ + + +/* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" must be used instead */ +#if defined (__GNUC__) /* GNU Compiler */ + #ifndef __ALIGN_END + #define __ALIGN_END __attribute__ ((aligned (4))) + #endif /* __ALIGN_END */ + #ifndef __ALIGN_BEGIN + #define __ALIGN_BEGIN + #endif /* __ALIGN_BEGIN */ +#else + #ifndef __ALIGN_END + #define __ALIGN_END + #endif /* __ALIGN_END */ + #ifndef __ALIGN_BEGIN + #if defined (__CC_ARM) /* ARM Compiler */ + #define __ALIGN_BEGIN __align(4) + #elif defined (__ICCARM__) /* IAR Compiler */ + #define __ALIGN_BEGIN + #endif /* __CC_ARM */ + #endif /* __ALIGN_BEGIN */ +#endif /* __GNUC__ */ + + +/** + * @brief __RAM_FUNC definition + */ +#if defined ( __CC_ARM ) +/* ARM Compiler + ------------ + RAM functions are defined using the toolchain options. + Functions that are executed in RAM should reside in a separate source module. + Using the 'Options for File' dialog you can simply change the 'Code / Const' + area of a module to a memory space in physical RAM. + Available memory areas are declared in the 'Target' tab of the 'Options for Target' + dialog. +*/ +#define __RAM_FUNC HAL_StatusTypeDef + +#elif defined ( __ICCARM__ ) +/* ICCARM Compiler + --------------- + RAM functions are defined using a specific toolchain keyword "__ramfunc". +*/ +#define __RAM_FUNC __ramfunc HAL_StatusTypeDef + +#elif defined ( __GNUC__ ) +/* GNU Compiler + ------------ + RAM functions are defined using a specific toolchain attribute + "__attribute__((section(".RamFunc")))". +*/ +#define __RAM_FUNC HAL_StatusTypeDef __attribute__((section(".RamFunc"))) + +#endif + +/** + * @brief __NOINLINE definition + */ +#if defined ( __CC_ARM ) || defined ( __GNUC__ ) +/* ARM & GNUCompiler + ---------------- +*/ +#define __NOINLINE __attribute__ ( (noinline) ) + +#elif defined ( __ICCARM__ ) +/* ICCARM Compiler + --------------- +*/ +#define __NOINLINE _Pragma("optimize = no_inline") + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ___STM32F4xx_HAL_DEF */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h new file mode 100644 index 0000000..d4585b1 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h @@ -0,0 +1,767 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_dma.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of DMA HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_DMA_H +#define __STM32F4xx_HAL_DMA_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup DMA + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup DMA_Exported_Types DMA Exported Types + * @brief DMA Exported Types + * @{ + */ + +/** + * @brief DMA Configuration Structure definition + */ +typedef struct +{ + uint32_t Channel; /*!< Specifies the channel used for the specified stream. + This parameter can be a value of @ref DMA_Channel_selection */ + + uint32_t Direction; /*!< Specifies if the data will be transferred from memory to peripheral, + from memory to memory or from peripheral to memory. + This parameter can be a value of @ref DMA_Data_transfer_direction */ + + uint32_t PeriphInc; /*!< Specifies whether the Peripheral address register should be incremented or not. + This parameter can be a value of @ref DMA_Peripheral_incremented_mode */ + + uint32_t MemInc; /*!< Specifies whether the memory address register should be incremented or not. + This parameter can be a value of @ref DMA_Memory_incremented_mode */ + + uint32_t PeriphDataAlignment; /*!< Specifies the Peripheral data width. + This parameter can be a value of @ref DMA_Peripheral_data_size */ + + uint32_t MemDataAlignment; /*!< Specifies the Memory data width. + This parameter can be a value of @ref DMA_Memory_data_size */ + + uint32_t Mode; /*!< Specifies the operation mode of the DMAy Streamx. + This parameter can be a value of @ref DMA_mode + @note The circular buffer mode cannot be used if the memory-to-memory + data transfer is configured on the selected Stream */ + + uint32_t Priority; /*!< Specifies the software priority for the DMAy Streamx. + This parameter can be a value of @ref DMA_Priority_level */ + + uint32_t FIFOMode; /*!< Specifies if the FIFO mode or Direct mode will be used for the specified stream. + This parameter can be a value of @ref DMA_FIFO_direct_mode + @note The Direct mode (FIFO mode disabled) cannot be used if the + memory-to-memory data transfer is configured on the selected stream */ + + uint32_t FIFOThreshold; /*!< Specifies the FIFO threshold level. + This parameter can be a value of @ref DMA_FIFO_threshold_level */ + + uint32_t MemBurst; /*!< Specifies the Burst transfer configuration for the memory transfers. + It specifies the amount of data to be transferred in a single non interruptible + transaction. + This parameter can be a value of @ref DMA_Memory_burst + @note The burst mode is possible only if the address Increment mode is enabled. */ + + uint32_t PeriphBurst; /*!< Specifies the Burst transfer configuration for the peripheral transfers. + It specifies the amount of data to be transferred in a single non interruptable + transaction. + This parameter can be a value of @ref DMA_Peripheral_burst + @note The burst mode is possible only if the address Increment mode is enabled. */ +}DMA_InitTypeDef; + + +/** + * @brief HAL DMA State structures definition + */ +typedef enum +{ + HAL_DMA_STATE_RESET = 0x00, /*!< DMA not yet initialized or disabled */ + HAL_DMA_STATE_READY = 0x01, /*!< DMA initialized and ready for use */ + HAL_DMA_STATE_READY_MEM0 = 0x11, /*!< DMA Mem0 process success */ + HAL_DMA_STATE_READY_MEM1 = 0x21, /*!< DMA Mem1 process success */ + HAL_DMA_STATE_READY_HALF_MEM0 = 0x31, /*!< DMA Mem0 Half process success */ + HAL_DMA_STATE_READY_HALF_MEM1 = 0x41, /*!< DMA Mem1 Half process success */ + HAL_DMA_STATE_BUSY = 0x02, /*!< DMA process is ongoing */ + HAL_DMA_STATE_BUSY_MEM0 = 0x12, /*!< DMA Mem0 process is ongoing */ + HAL_DMA_STATE_BUSY_MEM1 = 0x22, /*!< DMA Mem1 process is ongoing */ + HAL_DMA_STATE_TIMEOUT = 0x03, /*!< DMA timeout state */ + HAL_DMA_STATE_ERROR = 0x04, /*!< DMA error state */ +}HAL_DMA_StateTypeDef; + +/** + * @brief HAL DMA Error Code structure definition + */ +typedef enum +{ + HAL_DMA_FULL_TRANSFER = 0x00, /*!< Full transfer */ + HAL_DMA_HALF_TRANSFER = 0x01, /*!< Half Transfer */ +}HAL_DMA_LevelCompleteTypeDef; + +/** + * @brief DMA handle Structure definition + */ +typedef struct __DMA_HandleTypeDef +{ + DMA_Stream_TypeDef *Instance; /*!< Register base address */ + + DMA_InitTypeDef Init; /*!< DMA communication parameters */ + + HAL_LockTypeDef Lock; /*!< DMA locking object */ + + __IO HAL_DMA_StateTypeDef State; /*!< DMA transfer state */ + + void *Parent; /*!< Parent object state */ + + void (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer complete callback */ + + void (* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA Half transfer complete callback */ + + void (* XferM1CpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer complete Memory1 callback */ + + void (* XferErrorCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer error callback */ + + __IO uint32_t ErrorCode; /*!< DMA Error code */ +}DMA_HandleTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup DMA_Exported_Constants DMA Exported Constants + * @brief DMA Exported constants + * @{ + */ + +/** @defgroup DMA_Error_Code DMA Error Code + * @brief DMA Error Code + * @{ + */ +#define HAL_DMA_ERROR_NONE ((uint32_t)0x00000000) /*!< No error */ +#define HAL_DMA_ERROR_TE ((uint32_t)0x00000001) /*!< Transfer error */ +#define HAL_DMA_ERROR_FE ((uint32_t)0x00000002) /*!< FIFO error */ +#define HAL_DMA_ERROR_DME ((uint32_t)0x00000004) /*!< Direct Mode error */ +#define HAL_DMA_ERROR_TIMEOUT ((uint32_t)0x00000020) /*!< Timeout error */ +/** + * @} + */ + +/** @defgroup DMA_Channel_selection DMA Channel selection + * @brief DMA channel selection + * @{ + */ +#define DMA_CHANNEL_0 ((uint32_t)0x00000000) /*!< DMA Channel 0 */ +#define DMA_CHANNEL_1 ((uint32_t)0x02000000) /*!< DMA Channel 1 */ +#define DMA_CHANNEL_2 ((uint32_t)0x04000000) /*!< DMA Channel 2 */ +#define DMA_CHANNEL_3 ((uint32_t)0x06000000) /*!< DMA Channel 3 */ +#define DMA_CHANNEL_4 ((uint32_t)0x08000000) /*!< DMA Channel 4 */ +#define DMA_CHANNEL_5 ((uint32_t)0x0A000000) /*!< DMA Channel 5 */ +#define DMA_CHANNEL_6 ((uint32_t)0x0C000000) /*!< DMA Channel 6 */ +#define DMA_CHANNEL_7 ((uint32_t)0x0E000000) /*!< DMA Channel 7 */ +/** + * @} + */ + +/** @defgroup DMA_Data_transfer_direction DMA Data transfer direction + * @brief DMA data transfer direction + * @{ + */ +#define DMA_PERIPH_TO_MEMORY ((uint32_t)0x00000000) /*!< Peripheral to memory direction */ +#define DMA_MEMORY_TO_PERIPH ((uint32_t)DMA_SxCR_DIR_0) /*!< Memory to peripheral direction */ +#define DMA_MEMORY_TO_MEMORY ((uint32_t)DMA_SxCR_DIR_1) /*!< Memory to memory direction */ +/** + * @} + */ + +/** @defgroup DMA_Peripheral_incremented_mode DMA Peripheral incremented mode + * @brief DMA peripheral incremented mode + * @{ + */ +#define DMA_PINC_ENABLE ((uint32_t)DMA_SxCR_PINC) /*!< Peripheral increment mode enable */ +#define DMA_PINC_DISABLE ((uint32_t)0x00000000) /*!< Peripheral increment mode disable */ +/** + * @} + */ + +/** @defgroup DMA_Memory_incremented_mode DMA Memory incremented mode + * @brief DMA memory incremented mode + * @{ + */ +#define DMA_MINC_ENABLE ((uint32_t)DMA_SxCR_MINC) /*!< Memory increment mode enable */ +#define DMA_MINC_DISABLE ((uint32_t)0x00000000) /*!< Memory increment mode disable */ +/** + * @} + */ + +/** @defgroup DMA_Peripheral_data_size DMA Peripheral data size + * @brief DMA peripheral data size + * @{ + */ +#define DMA_PDATAALIGN_BYTE ((uint32_t)0x00000000) /*!< Peripheral data alignment: Byte */ +#define DMA_PDATAALIGN_HALFWORD ((uint32_t)DMA_SxCR_PSIZE_0) /*!< Peripheral data alignment: HalfWord */ +#define DMA_PDATAALIGN_WORD ((uint32_t)DMA_SxCR_PSIZE_1) /*!< Peripheral data alignment: Word */ +/** + * @} + */ + +/** @defgroup DMA_Memory_data_size DMA Memory data size + * @brief DMA memory data size + * @{ + */ +#define DMA_MDATAALIGN_BYTE ((uint32_t)0x00000000) /*!< Memory data alignment: Byte */ +#define DMA_MDATAALIGN_HALFWORD ((uint32_t)DMA_SxCR_MSIZE_0) /*!< Memory data alignment: HalfWord */ +#define DMA_MDATAALIGN_WORD ((uint32_t)DMA_SxCR_MSIZE_1) /*!< Memory data alignment: Word */ +/** + * @} + */ + +/** @defgroup DMA_mode DMA mode + * @brief DMA mode + * @{ + */ +#define DMA_NORMAL ((uint32_t)0x00000000) /*!< Normal mode */ +#define DMA_CIRCULAR ((uint32_t)DMA_SxCR_CIRC) /*!< Circular mode */ +#define DMA_PFCTRL ((uint32_t)DMA_SxCR_PFCTRL) /*!< Peripheral flow control mode */ +/** + * @} + */ + +/** @defgroup DMA_Priority_level DMA Priority level + * @brief DMA priority levels + * @{ + */ +#define DMA_PRIORITY_LOW ((uint32_t)0x00000000) /*!< Priority level: Low */ +#define DMA_PRIORITY_MEDIUM ((uint32_t)DMA_SxCR_PL_0) /*!< Priority level: Medium */ +#define DMA_PRIORITY_HIGH ((uint32_t)DMA_SxCR_PL_1) /*!< Priority level: High */ +#define DMA_PRIORITY_VERY_HIGH ((uint32_t)DMA_SxCR_PL) /*!< Priority level: Very High */ +/** + * @} + */ + +/** @defgroup DMA_FIFO_direct_mode DMA FIFO direct mode + * @brief DMA FIFO direct mode + * @{ + */ +#define DMA_FIFOMODE_DISABLE ((uint32_t)0x00000000) /*!< FIFO mode disable */ +#define DMA_FIFOMODE_ENABLE ((uint32_t)DMA_SxFCR_DMDIS) /*!< FIFO mode enable */ +/** + * @} + */ + +/** @defgroup DMA_FIFO_threshold_level DMA FIFO threshold level + * @brief DMA FIFO level + * @{ + */ +#define DMA_FIFO_THRESHOLD_1QUARTERFULL ((uint32_t)0x00000000) /*!< FIFO threshold 1 quart full configuration */ +#define DMA_FIFO_THRESHOLD_HALFFULL ((uint32_t)DMA_SxFCR_FTH_0) /*!< FIFO threshold half full configuration */ +#define DMA_FIFO_THRESHOLD_3QUARTERSFULL ((uint32_t)DMA_SxFCR_FTH_1) /*!< FIFO threshold 3 quarts full configuration */ +#define DMA_FIFO_THRESHOLD_FULL ((uint32_t)DMA_SxFCR_FTH) /*!< FIFO threshold full configuration */ +/** + * @} + */ + +/** @defgroup DMA_Memory_burst DMA Memory burst + * @brief DMA memory burst + * @{ + */ +#define DMA_MBURST_SINGLE ((uint32_t)0x00000000) +#define DMA_MBURST_INC4 ((uint32_t)DMA_SxCR_MBURST_0) +#define DMA_MBURST_INC8 ((uint32_t)DMA_SxCR_MBURST_1) +#define DMA_MBURST_INC16 ((uint32_t)DMA_SxCR_MBURST) +/** + * @} + */ + +/** @defgroup DMA_Peripheral_burst DMA Peripheral burst + * @brief DMA peripheral burst + * @{ + */ +#define DMA_PBURST_SINGLE ((uint32_t)0x00000000) +#define DMA_PBURST_INC4 ((uint32_t)DMA_SxCR_PBURST_0) +#define DMA_PBURST_INC8 ((uint32_t)DMA_SxCR_PBURST_1) +#define DMA_PBURST_INC16 ((uint32_t)DMA_SxCR_PBURST) +/** + * @} + */ + +/** @defgroup DMA_interrupt_enable_definitions DMA interrupt enable definitions + * @brief DMA interrupts definition + * @{ + */ +#define DMA_IT_TC ((uint32_t)DMA_SxCR_TCIE) +#define DMA_IT_HT ((uint32_t)DMA_SxCR_HTIE) +#define DMA_IT_TE ((uint32_t)DMA_SxCR_TEIE) +#define DMA_IT_DME ((uint32_t)DMA_SxCR_DMEIE) +#define DMA_IT_FE ((uint32_t)0x00000080) +/** + * @} + */ + +/** @defgroup DMA_flag_definitions DMA flag definitions + * @brief DMA flag definitions + * @{ + */ +#define DMA_FLAG_FEIF0_4 ((uint32_t)0x00800001) +#define DMA_FLAG_DMEIF0_4 ((uint32_t)0x00800004) +#define DMA_FLAG_TEIF0_4 ((uint32_t)0x00000008) +#define DMA_FLAG_HTIF0_4 ((uint32_t)0x00000010) +#define DMA_FLAG_TCIF0_4 ((uint32_t)0x00000020) +#define DMA_FLAG_FEIF1_5 ((uint32_t)0x00000040) +#define DMA_FLAG_DMEIF1_5 ((uint32_t)0x00000100) +#define DMA_FLAG_TEIF1_5 ((uint32_t)0x00000200) +#define DMA_FLAG_HTIF1_5 ((uint32_t)0x00000400) +#define DMA_FLAG_TCIF1_5 ((uint32_t)0x00000800) +#define DMA_FLAG_FEIF2_6 ((uint32_t)0x00010000) +#define DMA_FLAG_DMEIF2_6 ((uint32_t)0x00040000) +#define DMA_FLAG_TEIF2_6 ((uint32_t)0x00080000) +#define DMA_FLAG_HTIF2_6 ((uint32_t)0x00100000) +#define DMA_FLAG_TCIF2_6 ((uint32_t)0x00200000) +#define DMA_FLAG_FEIF3_7 ((uint32_t)0x00400000) +#define DMA_FLAG_DMEIF3_7 ((uint32_t)0x01000000) +#define DMA_FLAG_TEIF3_7 ((uint32_t)0x02000000) +#define DMA_FLAG_HTIF3_7 ((uint32_t)0x04000000) +#define DMA_FLAG_TCIF3_7 ((uint32_t)0x08000000) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + +/** @brief Reset DMA handle state + * @param __HANDLE__: specifies the DMA handle. + * @retval None + */ +#define __HAL_DMA_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_DMA_STATE_RESET) + +/** + * @brief Return the current DMA Stream FIFO filled level. + * @param __HANDLE__: DMA handle + * @retval The FIFO filling state. + * - DMA_FIFOStatus_Less1QuarterFull: when FIFO is less than 1 quarter-full + * and not empty. + * - DMA_FIFOStatus_1QuarterFull: if more than 1 quarter-full. + * - DMA_FIFOStatus_HalfFull: if more than 1 half-full. + * - DMA_FIFOStatus_3QuartersFull: if more than 3 quarters-full. + * - DMA_FIFOStatus_Empty: when FIFO is empty + * - DMA_FIFOStatus_Full: when FIFO is full + */ +#define __HAL_DMA_GET_FS(__HANDLE__) (((__HANDLE__)->Instance->FCR & (DMA_SxFCR_FS))) + +/** + * @brief Enable the specified DMA Stream. + * @param __HANDLE__: DMA handle + * @retval None + */ +#define __HAL_DMA_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= DMA_SxCR_EN) + +/** + * @brief Disable the specified DMA Stream. + * @param __HANDLE__: DMA handle + * @retval None + */ +#define __HAL_DMA_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~DMA_SxCR_EN) + +/* Interrupt & Flag management */ + +/** + * @brief Return the current DMA Stream transfer complete flag. + * @param __HANDLE__: DMA handle + * @retval The specified transfer complete flag index. + */ +#define __HAL_DMA_GET_TC_FLAG_INDEX(__HANDLE__) \ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream0))? DMA_FLAG_TCIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream0))? DMA_FLAG_TCIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream4))? DMA_FLAG_TCIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream4))? DMA_FLAG_TCIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream1))? DMA_FLAG_TCIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream1))? DMA_FLAG_TCIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream5))? DMA_FLAG_TCIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream5))? DMA_FLAG_TCIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream2))? DMA_FLAG_TCIF2_6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream2))? DMA_FLAG_TCIF2_6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream6))? DMA_FLAG_TCIF2_6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream6))? DMA_FLAG_TCIF2_6 :\ + DMA_FLAG_TCIF3_7) + +/** + * @brief Return the current DMA Stream half transfer complete flag. + * @param __HANDLE__: DMA handle + * @retval The specified half transfer complete flag index. + */ +#define __HAL_DMA_GET_HT_FLAG_INDEX(__HANDLE__)\ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream0))? DMA_FLAG_HTIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream0))? DMA_FLAG_HTIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream4))? DMA_FLAG_HTIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream4))? DMA_FLAG_HTIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream1))? DMA_FLAG_HTIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream1))? DMA_FLAG_HTIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream5))? DMA_FLAG_HTIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream5))? DMA_FLAG_HTIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream2))? DMA_FLAG_HTIF2_6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream2))? DMA_FLAG_HTIF2_6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream6))? DMA_FLAG_HTIF2_6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream6))? DMA_FLAG_HTIF2_6 :\ + DMA_FLAG_HTIF3_7) + +/** + * @brief Return the current DMA Stream transfer error flag. + * @param __HANDLE__: DMA handle + * @retval The specified transfer error flag index. + */ +#define __HAL_DMA_GET_TE_FLAG_INDEX(__HANDLE__)\ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream0))? DMA_FLAG_TEIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream0))? DMA_FLAG_TEIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream4))? DMA_FLAG_TEIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream4))? DMA_FLAG_TEIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream1))? DMA_FLAG_TEIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream1))? DMA_FLAG_TEIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream5))? DMA_FLAG_TEIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream5))? DMA_FLAG_TEIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream2))? DMA_FLAG_TEIF2_6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream2))? DMA_FLAG_TEIF2_6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream6))? DMA_FLAG_TEIF2_6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream6))? DMA_FLAG_TEIF2_6 :\ + DMA_FLAG_TEIF3_7) + +/** + * @brief Return the current DMA Stream FIFO error flag. + * @param __HANDLE__: DMA handle + * @retval The specified FIFO error flag index. + */ +#define __HAL_DMA_GET_FE_FLAG_INDEX(__HANDLE__)\ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream0))? DMA_FLAG_FEIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream0))? DMA_FLAG_FEIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream4))? DMA_FLAG_FEIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream4))? DMA_FLAG_FEIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream1))? DMA_FLAG_FEIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream1))? DMA_FLAG_FEIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream5))? DMA_FLAG_FEIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream5))? DMA_FLAG_FEIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream2))? DMA_FLAG_FEIF2_6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream2))? DMA_FLAG_FEIF2_6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream6))? DMA_FLAG_FEIF2_6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream6))? DMA_FLAG_FEIF2_6 :\ + DMA_FLAG_FEIF3_7) + +/** + * @brief Return the current DMA Stream direct mode error flag. + * @param __HANDLE__: DMA handle + * @retval The specified direct mode error flag index. + */ +#define __HAL_DMA_GET_DME_FLAG_INDEX(__HANDLE__)\ +(((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream0))? DMA_FLAG_DMEIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream0))? DMA_FLAG_DMEIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream4))? DMA_FLAG_DMEIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream4))? DMA_FLAG_DMEIF0_4 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream1))? DMA_FLAG_DMEIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream1))? DMA_FLAG_DMEIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream5))? DMA_FLAG_DMEIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream5))? DMA_FLAG_DMEIF1_5 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream2))? DMA_FLAG_DMEIF2_6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream2))? DMA_FLAG_DMEIF2_6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA1_Stream6))? DMA_FLAG_DMEIF2_6 :\ + ((uint32_t)((__HANDLE__)->Instance) == ((uint32_t)DMA2_Stream6))? DMA_FLAG_DMEIF2_6 :\ + DMA_FLAG_DMEIF3_7) + +/** + * @brief Get the DMA Stream pending flags. + * @param __HANDLE__: DMA handle + * @param __FLAG__: Get the specified flag. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TCIFx: Transfer complete flag. + * @arg DMA_FLAG_HTIFx: Half transfer complete flag. + * @arg DMA_FLAG_TEIFx: Transfer error flag. + * @arg DMA_FLAG_DMEIFx: Direct mode error flag. + * @arg DMA_FLAG_FEIFx: FIFO error flag. + * Where x can be 0_4, 1_5, 2_6 or 3_7 to select the DMA Stream flag. + * @retval The state of FLAG (SET or RESET). + */ +#define __HAL_DMA_GET_FLAG(__HANDLE__, __FLAG__)\ +(((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA2_Stream3)? (DMA2->HISR & (__FLAG__)) :\ + ((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA1_Stream7)? (DMA2->LISR & (__FLAG__)) :\ + ((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA1_Stream3)? (DMA1->HISR & (__FLAG__)) : (DMA1->LISR & (__FLAG__))) + +/** + * @brief Clear the DMA Stream pending flags. + * @param __HANDLE__: DMA handle + * @param __FLAG__: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg DMA_FLAG_TCIFx: Transfer complete flag. + * @arg DMA_FLAG_HTIFx: Half transfer complete flag. + * @arg DMA_FLAG_TEIFx: Transfer error flag. + * @arg DMA_FLAG_DMEIFx: Direct mode error flag. + * @arg DMA_FLAG_FEIFx: FIFO error flag. + * Where x can be 0_4, 1_5, 2_6 or 3_7 to select the DMA Stream flag. + * @retval None + */ +#define __HAL_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) \ +(((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA2_Stream3)? (DMA2->HIFCR = (__FLAG__)) :\ + ((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA1_Stream7)? (DMA2->LIFCR = (__FLAG__)) :\ + ((uint32_t)((__HANDLE__)->Instance) > (uint32_t)DMA1_Stream3)? (DMA1->HIFCR = (__FLAG__)) : (DMA1->LIFCR = (__FLAG__))) + +/** + * @brief Enable the specified DMA Stream interrupts. + * @param __HANDLE__: DMA handle + * @param __INTERRUPT__: specifies the DMA interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg DMA_IT_TC: Transfer complete interrupt mask. + * @arg DMA_IT_HT: Half transfer complete interrupt mask. + * @arg DMA_IT_TE: Transfer error interrupt mask. + * @arg DMA_IT_FE: FIFO error interrupt mask. + * @arg DMA_IT_DME: Direct mode error interrupt. + * @retval None + */ +#define __HAL_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__) (((__INTERRUPT__) != DMA_IT_FE)? \ +((__HANDLE__)->Instance->CR |= (__INTERRUPT__)) : ((__HANDLE__)->Instance->FCR |= (__INTERRUPT__))) + +/** + * @brief Disable the specified DMA Stream interrupts. + * @param __HANDLE__: DMA handle + * @param __INTERRUPT__: specifies the DMA interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg DMA_IT_TC: Transfer complete interrupt mask. + * @arg DMA_IT_HT: Half transfer complete interrupt mask. + * @arg DMA_IT_TE: Transfer error interrupt mask. + * @arg DMA_IT_FE: FIFO error interrupt mask. + * @arg DMA_IT_DME: Direct mode error interrupt. + * @retval None + */ +#define __HAL_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__) (((__INTERRUPT__) != DMA_IT_FE)? \ +((__HANDLE__)->Instance->CR &= ~(__INTERRUPT__)) : ((__HANDLE__)->Instance->FCR &= ~(__INTERRUPT__))) + +/** + * @brief Check whether the specified DMA Stream interrupt is enabled or disabled. + * @param __HANDLE__: DMA handle + * @param __INTERRUPT__: specifies the DMA interrupt source to check. + * This parameter can be one of the following values: + * @arg DMA_IT_TC: Transfer complete interrupt mask. + * @arg DMA_IT_HT: Half transfer complete interrupt mask. + * @arg DMA_IT_TE: Transfer error interrupt mask. + * @arg DMA_IT_FE: FIFO error interrupt mask. + * @arg DMA_IT_DME: Direct mode error interrupt. + * @retval The state of DMA_IT. + */ +#define __HAL_DMA_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__INTERRUPT__) != DMA_IT_FE)? \ + ((__HANDLE__)->Instance->CR & (__INTERRUPT__)) : \ + ((__HANDLE__)->Instance->FCR & (__INTERRUPT__))) + +/** + * @brief Writes the number of data units to be transferred on the DMA Stream. + * @param __HANDLE__: DMA handle + * @param __COUNTER__: Number of data units to be transferred (from 0 to 65535) + * Number of data items depends only on the Peripheral data format. + * + * @note If Peripheral data format is Bytes: number of data units is equal + * to total number of bytes to be transferred. + * + * @note If Peripheral data format is Half-Word: number of data units is + * equal to total number of bytes to be transferred / 2. + * + * @note If Peripheral data format is Word: number of data units is equal + * to total number of bytes to be transferred / 4. + * + * @retval The number of remaining data units in the current DMAy Streamx transfer. + */ +#define __HAL_DMA_SET_COUNTER(__HANDLE__, __COUNTER__) ((__HANDLE__)->Instance->NDTR = (uint16_t)(__COUNTER__)) + +/** + * @brief Returns the number of remaining data units in the current DMAy Streamx transfer. + * @param __HANDLE__: DMA handle + * + * @retval The number of remaining data units in the current DMA Stream transfer. + */ +#define __HAL_DMA_GET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->NDTR) + + +/* Include DMA HAL Extension module */ +#include "stm32f4xx_hal_dma_ex.h" + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup DMA_Exported_Functions DMA Exported Functions + * @brief DMA Exported functions + * @{ + */ + +/** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * @{ + */ +HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma); +HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/** @defgroup DMA_Exported_Functions_Group2 I/O operation functions + * @brief I/O operation functions + * @{ + */ +HAL_StatusTypeDef HAL_DMA_Start (DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength); +HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength); +HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma); +HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout); +void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/** @defgroup DMA_Exported_Functions_Group3 Peripheral State functions + * @brief Peripheral State functions + * @{ + */ +HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma); +uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma); +/** + * @} + */ +/** + * @} + */ +/* Private Constants -------------------------------------------------------------*/ +/** @defgroup DMA_Private_Constants DMA Private Constants + * @brief DMA private defines and constants + * @{ + */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup DMA_Private_Macros DMA Private Macros + * @brief DMA private macros + * @{ + */ +#define IS_DMA_CHANNEL(CHANNEL) (((CHANNEL) == DMA_CHANNEL_0) || \ + ((CHANNEL) == DMA_CHANNEL_1) || \ + ((CHANNEL) == DMA_CHANNEL_2) || \ + ((CHANNEL) == DMA_CHANNEL_3) || \ + ((CHANNEL) == DMA_CHANNEL_4) || \ + ((CHANNEL) == DMA_CHANNEL_5) || \ + ((CHANNEL) == DMA_CHANNEL_6) || \ + ((CHANNEL) == DMA_CHANNEL_7)) + +#define IS_DMA_DIRECTION(DIRECTION) (((DIRECTION) == DMA_PERIPH_TO_MEMORY ) || \ + ((DIRECTION) == DMA_MEMORY_TO_PERIPH) || \ + ((DIRECTION) == DMA_MEMORY_TO_MEMORY)) + +#define IS_DMA_BUFFER_SIZE(SIZE) (((SIZE) >= 0x1) && ((SIZE) < 0x10000)) + +#define IS_DMA_PERIPHERAL_INC_STATE(STATE) (((STATE) == DMA_PINC_ENABLE) || \ + ((STATE) == DMA_PINC_DISABLE)) + +#define IS_DMA_MEMORY_INC_STATE(STATE) (((STATE) == DMA_MINC_ENABLE) || \ + ((STATE) == DMA_MINC_DISABLE)) + +#define IS_DMA_PERIPHERAL_DATA_SIZE(SIZE) (((SIZE) == DMA_PDATAALIGN_BYTE) || \ + ((SIZE) == DMA_PDATAALIGN_HALFWORD) || \ + ((SIZE) == DMA_PDATAALIGN_WORD)) + +#define IS_DMA_MEMORY_DATA_SIZE(SIZE) (((SIZE) == DMA_MDATAALIGN_BYTE) || \ + ((SIZE) == DMA_MDATAALIGN_HALFWORD) || \ + ((SIZE) == DMA_MDATAALIGN_WORD )) + +#define IS_DMA_MODE(MODE) (((MODE) == DMA_NORMAL ) || \ + ((MODE) == DMA_CIRCULAR) || \ + ((MODE) == DMA_PFCTRL)) + +#define IS_DMA_PRIORITY(PRIORITY) (((PRIORITY) == DMA_PRIORITY_LOW ) || \ + ((PRIORITY) == DMA_PRIORITY_MEDIUM) || \ + ((PRIORITY) == DMA_PRIORITY_HIGH) || \ + ((PRIORITY) == DMA_PRIORITY_VERY_HIGH)) + +#define IS_DMA_FIFO_MODE_STATE(STATE) (((STATE) == DMA_FIFOMODE_DISABLE ) || \ + ((STATE) == DMA_FIFOMODE_ENABLE)) + +#define IS_DMA_FIFO_THRESHOLD(THRESHOLD) (((THRESHOLD) == DMA_FIFO_THRESHOLD_1QUARTERFULL ) || \ + ((THRESHOLD) == DMA_FIFO_THRESHOLD_HALFFULL) || \ + ((THRESHOLD) == DMA_FIFO_THRESHOLD_3QUARTERSFULL) || \ + ((THRESHOLD) == DMA_FIFO_THRESHOLD_FULL)) + +#define IS_DMA_MEMORY_BURST(BURST) (((BURST) == DMA_MBURST_SINGLE) || \ + ((BURST) == DMA_MBURST_INC4) || \ + ((BURST) == DMA_MBURST_INC8) || \ + ((BURST) == DMA_MBURST_INC16)) + +#define IS_DMA_PERIPHERAL_BURST(BURST) (((BURST) == DMA_PBURST_SINGLE) || \ + ((BURST) == DMA_PBURST_INC4) || \ + ((BURST) == DMA_PBURST_INC8) || \ + ((BURST) == DMA_PBURST_INC16)) +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup DMA_Private_Functions DMA Private Functions + * @brief DMA private functions + * @{ + */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_DMA_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma2d.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma2d.h new file mode 100644 index 0000000..fc3ff1e --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma2d.h @@ -0,0 +1,554 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_dma2d.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of DMA2D HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_DMA2D_H +#define __STM32F4xx_HAL_DMA2D_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup DMA2D DMA2D + * @brief DMA2D HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup DMA2D_Exported_Types DMA2D Exported Types + * @{ + */ +#define MAX_DMA2D_LAYER 2 + +/** + * @brief DMA2D color Structure definition + */ +typedef struct +{ + uint32_t Blue; /*!< Configures the blue value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. */ + + uint32_t Green; /*!< Configures the green value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. */ + + uint32_t Red; /*!< Configures the red value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. */ +} DMA2D_ColorTypeDef; + +/** + * @brief DMA2D CLUT Structure definition + */ +typedef struct +{ + uint32_t *pCLUT; /*!< Configures the DMA2D CLUT memory address.*/ + + uint32_t CLUTColorMode; /*!< configures the DMA2D CLUT color mode. + This parameter can be one value of @ref DMA2D_CLUT_CM */ + + uint32_t Size; /*!< configures the DMA2D CLUT size. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF.*/ +} DMA2D_CLUTCfgTypeDef; + +/** + * @brief DMA2D Init structure definition + */ +typedef struct +{ + uint32_t Mode; /*!< configures the DMA2D transfer mode. + This parameter can be one value of @ref DMA2D_Mode */ + + uint32_t ColorMode; /*!< configures the color format of the output image. + This parameter can be one value of @ref DMA2D_Color_Mode */ + + uint32_t OutputOffset; /*!< Specifies the Offset value. + This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0x3FFF. */ +} DMA2D_InitTypeDef; + +/** + * @brief DMA2D Layer structure definition + */ +typedef struct +{ + uint32_t InputOffset; /*!< configures the DMA2D foreground offset. + This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0x3FFF. */ + + uint32_t InputColorMode; /*!< configures the DMA2D foreground color mode . + This parameter can be one value of @ref DMA2D_Input_Color_Mode */ + + uint32_t AlphaMode; /*!< configures the DMA2D foreground alpha mode. + This parameter can be one value of @ref DMA2D_ALPHA_MODE */ + + uint32_t InputAlpha; /*!< Specifies the DMA2D foreground alpha value and color value in case of A8 or A4 color mode. + This parameter must be a number between Min_Data = 0x00000000 and Max_Data = 0xFFFFFFFF + in case of A8 or A4 color mode (ARGB). + Otherwise, This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF.*/ + +} DMA2D_LayerCfgTypeDef; + +/** + * @brief HAL DMA2D State structures definition + */ +typedef enum +{ + HAL_DMA2D_STATE_RESET = 0x00, /*!< DMA2D not yet initialized or disabled */ + HAL_DMA2D_STATE_READY = 0x01, /*!< Peripheral Initialized and ready for use */ + HAL_DMA2D_STATE_BUSY = 0x02, /*!< an internal process is ongoing */ + HAL_DMA2D_STATE_TIMEOUT = 0x03, /*!< Timeout state */ + HAL_DMA2D_STATE_ERROR = 0x04, /*!< DMA2D state error */ + HAL_DMA2D_STATE_SUSPEND = 0x05 /*!< DMA2D process is suspended */ +}HAL_DMA2D_StateTypeDef; + +/** + * @brief DMA2D handle Structure definition + */ +typedef struct __DMA2D_HandleTypeDef +{ + DMA2D_TypeDef *Instance; /*!< DMA2D Register base address */ + + DMA2D_InitTypeDef Init; /*!< DMA2D communication parameters */ + + void (* XferCpltCallback)(struct __DMA2D_HandleTypeDef * hdma2d); /*!< DMA2D transfer complete callback */ + + void (* XferErrorCallback)(struct __DMA2D_HandleTypeDef * hdma2d); /*!< DMA2D transfer error callback */ + + DMA2D_LayerCfgTypeDef LayerCfg[MAX_DMA2D_LAYER]; /*!< DMA2D Layers parameters */ + + HAL_LockTypeDef Lock; /*!< DMA2D Lock */ + + __IO HAL_DMA2D_StateTypeDef State; /*!< DMA2D transfer state */ + + __IO uint32_t ErrorCode; /*!< DMA2D Error code */ +} DMA2D_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup DMA2D_Exported_Constants DMA2D Exported Constants + * @{ + */ + +/** @defgroup DMA2D_Error_Code DMA2D Error Code + * @{ + */ +#define HAL_DMA2D_ERROR_NONE ((uint32_t)0x00000000) /*!< No error */ +#define HAL_DMA2D_ERROR_TE ((uint32_t)0x00000001) /*!< Transfer error */ +#define HAL_DMA2D_ERROR_CE ((uint32_t)0x00000002) /*!< Configuration error */ +#define HAL_DMA2D_ERROR_TIMEOUT ((uint32_t)0x00000020) /*!< Timeout error */ +/** + * @} + */ + +/** @defgroup DMA2D_Mode DMA2D Mode + * @{ + */ +#define DMA2D_M2M ((uint32_t)0x00000000) /*!< DMA2D memory to memory transfer mode */ +#define DMA2D_M2M_PFC ((uint32_t)0x00010000) /*!< DMA2D memory to memory with pixel format conversion transfer mode */ +#define DMA2D_M2M_BLEND ((uint32_t)0x00020000) /*!< DMA2D memory to memory with blending transfer mode */ +#define DMA2D_R2M ((uint32_t)0x00030000) /*!< DMA2D register to memory transfer mode */ +/** + * @} + */ + +/** @defgroup DMA2D_Color_Mode DMA2D Color Mode + * @{ + */ +#define DMA2D_ARGB8888 ((uint32_t)0x00000000) /*!< ARGB8888 DMA2D color mode */ +#define DMA2D_RGB888 ((uint32_t)0x00000001) /*!< RGB888 DMA2D color mode */ +#define DMA2D_RGB565 ((uint32_t)0x00000002) /*!< RGB565 DMA2D color mode */ +#define DMA2D_ARGB1555 ((uint32_t)0x00000003) /*!< ARGB1555 DMA2D color mode */ +#define DMA2D_ARGB4444 ((uint32_t)0x00000004) /*!< ARGB4444 DMA2D color mode */ +/** + * @} + */ + +/** @defgroup DMA2D_COLOR_VALUE DMA2D COLOR VALUE + * @{ + */ +#define COLOR_VALUE ((uint32_t)0x000000FF) /*!< color value mask */ +/** + * @} + */ + +/** @defgroup DMA2D_SIZE DMA2D SIZE + * @{ + */ +#define DMA2D_PIXEL (DMA2D_NLR_PL >> 16) /*!< DMA2D pixel per line */ +#define DMA2D_LINE DMA2D_NLR_NL /*!< DMA2D number of line */ +/** + * @} + */ + +/** @defgroup DMA2D_Offset DMA2D Offset + * @{ + */ +#define DMA2D_OFFSET DMA2D_FGOR_LO /*!< Line Offset */ +/** + * @} + */ + +/** @defgroup DMA2D_Input_Color_Mode DMA2D Input Color Mode + * @{ + */ +#define CM_ARGB8888 ((uint32_t)0x00000000) /*!< ARGB8888 color mode */ +#define CM_RGB888 ((uint32_t)0x00000001) /*!< RGB888 color mode */ +#define CM_RGB565 ((uint32_t)0x00000002) /*!< RGB565 color mode */ +#define CM_ARGB1555 ((uint32_t)0x00000003) /*!< ARGB1555 color mode */ +#define CM_ARGB4444 ((uint32_t)0x00000004) /*!< ARGB4444 color mode */ +#define CM_L8 ((uint32_t)0x00000005) /*!< L8 color mode */ +#define CM_AL44 ((uint32_t)0x00000006) /*!< AL44 color mode */ +#define CM_AL88 ((uint32_t)0x00000007) /*!< AL88 color mode */ +#define CM_L4 ((uint32_t)0x00000008) /*!< L4 color mode */ +#define CM_A8 ((uint32_t)0x00000009) /*!< A8 color mode */ +#define CM_A4 ((uint32_t)0x0000000A) /*!< A4 color mode */ +/** + * @} + */ + +/** @defgroup DMA2D_ALPHA_MODE DMA2D ALPHA MODE + * @{ + */ +#define DMA2D_NO_MODIF_ALPHA ((uint32_t)0x00000000) /*!< No modification of the alpha channel value */ +#define DMA2D_REPLACE_ALPHA ((uint32_t)0x00000001) /*!< Replace original alpha channel value by programmed alpha value */ +#define DMA2D_COMBINE_ALPHA ((uint32_t)0x00000002) /*!< Replace original alpha channel value by programmed alpha value + with original alpha channel value */ +/** + * @} + */ + +/** @defgroup DMA2D_CLUT_CM DMA2D CLUT CM + * @{ + */ +#define DMA2D_CCM_ARGB8888 ((uint32_t)0x00000000) /*!< ARGB8888 DMA2D C-LUT color mode */ +#define DMA2D_CCM_RGB888 ((uint32_t)0x00000001) /*!< RGB888 DMA2D C-LUT color mode */ +/** + * @} + */ + +/** @defgroup DMA2D_Size_Clut DMA2D Size Clut + * @{ + */ +#define DMA2D_CLUT_SIZE (DMA2D_FGPFCCR_CS >> 8) /*!< DMA2D C-LUT size */ +/** + * @} + */ + +/** @defgroup DMA2D_DeadTime DMA2D DeadTime + * @{ + */ +#define LINE_WATERMARK DMA2D_LWR_LW +/** + * @} + */ + +/** @defgroup DMA2D_Interrupts DMA2D Interrupts + * @{ + */ +#define DMA2D_IT_CE DMA2D_CR_CEIE /*!< Configuration Error Interrupt */ +#define DMA2D_IT_CTC DMA2D_CR_CTCIE /*!< C-LUT Transfer Complete Interrupt */ +#define DMA2D_IT_CAE DMA2D_CR_CAEIE /*!< C-LUT Access Error Interrupt */ +#define DMA2D_IT_TW DMA2D_CR_TWIE /*!< Transfer Watermark Interrupt */ +#define DMA2D_IT_TC DMA2D_CR_TCIE /*!< Transfer Complete Interrupt */ +#define DMA2D_IT_TE DMA2D_CR_TEIE /*!< Transfer Error Interrupt */ +/** + * @} + */ + +/** @defgroup DMA2D_Flag DMA2D Flag + * @{ + */ +#define DMA2D_FLAG_CE DMA2D_ISR_CEIF /*!< Configuration Error Interrupt Flag */ +#define DMA2D_FLAG_CTC DMA2D_ISR_CTCIF /*!< C-LUT Transfer Complete Interrupt Flag */ +#define DMA2D_FLAG_CAE DMA2D_ISR_CAEIF /*!< C-LUT Access Error Interrupt Flag */ +#define DMA2D_FLAG_TW DMA2D_ISR_TWIF /*!< Transfer Watermark Interrupt Flag */ +#define DMA2D_FLAG_TC DMA2D_ISR_TCIF /*!< Transfer Complete Interrupt Flag */ +#define DMA2D_FLAG_TE DMA2D_ISR_TEIF /*!< Transfer Error Interrupt Flag */ +/** + * @} + */ + +/** + * @} + */ +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup DMA2D_Exported_Macros DMA2D Exported Macros + * @{ + */ + +/** @brief Reset DMA2D handle state + * @param __HANDLE__: specifies the DMA2D handle. + * @retval None + */ +#define __HAL_DMA2D_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_DMA2D_STATE_RESET) + +/** + * @brief Enable the DMA2D. + * @param __HANDLE__: DMA2D handle + * @retval None. + */ +#define __HAL_DMA2D_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= DMA2D_CR_START) + +/** + * @brief Disable the DMA2D. + * @param __HANDLE__: DMA2D handle + * @retval None. + */ +#define __HAL_DMA2D_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~DMA2D_CR_START) + +/* Interrupt & Flag management */ +/** + * @brief Get the DMA2D pending flags. + * @param __HANDLE__: DMA2D handle + * @param __FLAG__: Get the specified flag. + * This parameter can be any combination of the following values: + * @arg DMA2D_FLAG_CE: Configuration error flag + * @arg DMA2D_FLAG_CTC: C-LUT transfer complete flag + * @arg DMA2D_FLAG_CAE: C-LUT access error flag + * @arg DMA2D_FLAG_TW: Transfer Watermark flag + * @arg DMA2D_FLAG_TC: Transfer complete flag + * @arg DMA2D_FLAG_TE: Transfer error flag + * @retval The state of FLAG. + */ +#define __HAL_DMA2D_GET_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ISR & (__FLAG__)) + +/** + * @brief Clears the DMA2D pending flags. + * @param __HANDLE__: DMA2D handle + * @param __FLAG__: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg DMA2D_FLAG_CE: Configuration error flag + * @arg DMA2D_FLAG_CTC: C-LUT transfer complete flag + * @arg DMA2D_FLAG_CAE: C-LUT access error flag + * @arg DMA2D_FLAG_TW: Transfer Watermark flag + * @arg DMA2D_FLAG_TC: Transfer complete flag + * @arg DMA2D_FLAG_TE: Transfer error flag + * @retval None + */ +#define __HAL_DMA2D_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->IFCR = (__FLAG__)) + +/** + * @brief Enables the specified DMA2D interrupts. + * @param __HANDLE__: DMA2D handle + * @param __INTERRUPT__: specifies the DMA2D interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg DMA2D_IT_CE: Configuration error interrupt mask + * @arg DMA2D_IT_CTC: C-LUT transfer complete interrupt mask + * @arg DMA2D_IT_CAE: C-LUT access error interrupt mask + * @arg DMA2D_IT_TW: Transfer Watermark interrupt mask + * @arg DMA2D_IT_TC: Transfer complete interrupt mask + * @arg DMA2D_IT_TE: Transfer error interrupt mask + * @retval None + */ +#define __HAL_DMA2D_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR |= (__INTERRUPT__)) + +/** + * @brief Disables the specified DMA2D interrupts. + * @param __HANDLE__: DMA2D handle + * @param __INTERRUPT__: specifies the DMA2D interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg DMA2D_IT_CE: Configuration error interrupt mask + * @arg DMA2D_IT_CTC: C-LUT transfer complete interrupt mask + * @arg DMA2D_IT_CAE: C-LUT access error interrupt mask + * @arg DMA2D_IT_TW: Transfer Watermark interrupt mask + * @arg DMA2D_IT_TC: Transfer complete interrupt mask + * @arg DMA2D_IT_TE: Transfer error interrupt mask + * @retval None + */ +#define __HAL_DMA2D_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR &= ~(__INTERRUPT__)) + +/** + * @brief Checks whether the specified DMA2D interrupt has occurred or not. + * @param __HANDLE__: DMA2D handle + * @param __INTERRUPT__: specifies the DMA2D interrupt source to check. + * This parameter can be one of the following values: + * @arg DMA2D_IT_CE: Configuration error interrupt mask + * @arg DMA2D_IT_CTC: C-LUT transfer complete interrupt mask + * @arg DMA2D_IT_CAE: C-LUT access error interrupt mask + * @arg DMA2D_IT_TW: Transfer Watermark interrupt mask + * @arg DMA2D_IT_TC: Transfer complete interrupt mask + * @arg DMA2D_IT_TE: Transfer error interrupt mask + * @retval The state of INTERRUPT. + */ +#define __HAL_DMA2D_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR & (__INTERRUPT__)) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup DMA2D_Exported_Functions DMA2D Exported Functions + * @{ + */ +/* Initialization and de-initialization functions *******************************/ +HAL_StatusTypeDef HAL_DMA2D_Init(DMA2D_HandleTypeDef *hdma2d); +HAL_StatusTypeDef HAL_DMA2D_DeInit (DMA2D_HandleTypeDef *hdma2d); +void HAL_DMA2D_MspInit(DMA2D_HandleTypeDef* hdma2d); +void HAL_DMA2D_MspDeInit(DMA2D_HandleTypeDef* hdma2d); + +/* IO operation functions *******************************************************/ +HAL_StatusTypeDef HAL_DMA2D_Start(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width, uint32_t Height); +HAL_StatusTypeDef HAL_DMA2D_BlendingStart(DMA2D_HandleTypeDef *hdma2d, uint32_t SrcAddress1, uint32_t SrcAddress2, uint32_t DstAddress, uint32_t Width, uint32_t Height); +HAL_StatusTypeDef HAL_DMA2D_Start_IT(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width, uint32_t Height); +HAL_StatusTypeDef HAL_DMA2D_BlendingStart_IT(DMA2D_HandleTypeDef *hdma2d, uint32_t SrcAddress1, uint32_t SrcAddress2, uint32_t DstAddress, uint32_t Width, uint32_t Height); +HAL_StatusTypeDef HAL_DMA2D_Suspend(DMA2D_HandleTypeDef *hdma2d); +HAL_StatusTypeDef HAL_DMA2D_Resume(DMA2D_HandleTypeDef *hdma2d); +HAL_StatusTypeDef HAL_DMA2D_Abort(DMA2D_HandleTypeDef *hdma2d); +HAL_StatusTypeDef HAL_DMA2D_PollForTransfer(DMA2D_HandleTypeDef *hdma2d, uint32_t Timeout); +void HAL_DMA2D_IRQHandler(DMA2D_HandleTypeDef *hdma2d); + +/* Peripheral Control functions *************************************************/ +HAL_StatusTypeDef HAL_DMA2D_ConfigLayer(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_DMA2D_ConfigCLUT(DMA2D_HandleTypeDef *hdma2d, DMA2D_CLUTCfgTypeDef CLUTCfg, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_DMA2D_EnableCLUT(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_DMA2D_DisableCLUT(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_DMA2D_ProgramLineEvent(DMA2D_HandleTypeDef *hdma2d, uint32_t Line); + +/* Peripheral State functions ***************************************************/ +HAL_DMA2D_StateTypeDef HAL_DMA2D_GetState(DMA2D_HandleTypeDef *hdma2d); +uint32_t HAL_DMA2D_GetError(DMA2D_HandleTypeDef *hdma2d); +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/** @defgroup DMA2D_Private_Types DMA2D Private Types + * @{ + */ + +/** + * @} + */ + +/* Private defines -------------------------------------------------------------*/ +/** @defgroup DMA2D_Private_Defines DMA2D Private Defines + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup DMA2D_Private_Variables DMA2D Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup DMA2D_Private_Constants DMA2D Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup DMA2D_Private_Macros DMA2D Private Macros + * @{ + */ +#define IS_DMA2D_LAYER(LAYER) ((LAYER) <= MAX_DMA2D_LAYER) +#define IS_DMA2D_MODE(MODE) (((MODE) == DMA2D_M2M) || ((MODE) == DMA2D_M2M_PFC) || \ + ((MODE) == DMA2D_M2M_BLEND) || ((MODE) == DMA2D_R2M)) +#define IS_DMA2D_CMODE(MODE_ARGB) (((MODE_ARGB) == DMA2D_ARGB8888) || ((MODE_ARGB) == DMA2D_RGB888) || \ + ((MODE_ARGB) == DMA2D_RGB565) || ((MODE_ARGB) == DMA2D_ARGB1555) || \ + ((MODE_ARGB) == DMA2D_ARGB4444)) +#define IS_DMA2D_COLOR(COLOR) ((COLOR) <= COLOR_VALUE) +#define IS_DMA2D_LINE(LINE) ((LINE) <= DMA2D_LINE) +#define IS_DMA2D_PIXEL(PIXEL) ((PIXEL) <= DMA2D_PIXEL) +#define IS_DMA2D_OFFSET(OOFFSET) ((OOFFSET) <= DMA2D_OFFSET) +#define IS_DMA2D_INPUT_COLOR_MODE(INPUT_CM) (((INPUT_CM) == CM_ARGB8888) || ((INPUT_CM) == CM_RGB888) || \ + ((INPUT_CM) == CM_RGB565) || ((INPUT_CM) == CM_ARGB1555) || \ + ((INPUT_CM) == CM_ARGB4444) || ((INPUT_CM) == CM_L8) || \ + ((INPUT_CM) == CM_AL44) || ((INPUT_CM) == CM_AL88) || \ + ((INPUT_CM) == CM_L4) || ((INPUT_CM) == CM_A8) || \ + ((INPUT_CM) == CM_A4)) +#define IS_DMA2D_ALPHA_MODE(AlphaMode) (((AlphaMode) == DMA2D_NO_MODIF_ALPHA) || \ + ((AlphaMode) == DMA2D_REPLACE_ALPHA) || \ + ((AlphaMode) == DMA2D_COMBINE_ALPHA)) +#define IS_DMA2D_CLUT_CM(CLUT_CM) (((CLUT_CM) == DMA2D_CCM_ARGB8888) || ((CLUT_CM) == DMA2D_CCM_RGB888)) +#define IS_DMA2D_CLUT_SIZE(CLUT_SIZE) ((CLUT_SIZE) <= DMA2D_CLUT_SIZE) +#define IS_DMA2D_LineWatermark(LineWatermark) ((LineWatermark) <= LINE_WATERMARK) +/** + * @} + */ + +/* Private functions prototypes ---------------------------------------------------------*/ +/** @defgroup DMA2D_Private_Functions_Prototypes DMA2D Private Functions Prototypes + * @{ + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup DMA2D_Private_Functions DMA2D Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_DMA2D_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h new file mode 100644 index 0000000..9cf760b --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h @@ -0,0 +1,123 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_dma_ex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of DMA HAL extension module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_DMA_EX_H +#define __STM32F4xx_HAL_DMA_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup DMAEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup DMAEx_Exported_Types DMAEx Exported Types + * @brief DMAEx Exported types + * @{ + */ + +/** + * @brief HAL DMA Memory definition + */ +typedef enum +{ + MEMORY0 = 0x00, /*!< Memory 0 */ + MEMORY1 = 0x01, /*!< Memory 1 */ + +}HAL_DMA_MemoryTypeDef; + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup DMAEx_Exported_Functions DMAEx Exported Functions + * @brief DMAEx Exported functions + * @{ + */ + +/** @defgroup DMAEx_Exported_Functions_Group1 Extended features functions + * @brief Extended features functions + * @{ + */ + +/* IO operation functions *******************************************************/ +HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength); +HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength); +HAL_StatusTypeDef HAL_DMAEx_ChangeMemory(DMA_HandleTypeDef *hdma, uint32_t Address, HAL_DMA_MemoryTypeDef memory); + +/** + * @} + */ +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup DMAEx_Private_Functions DMAEx Private Functions + * @brief DMAEx Private functions + * @{ + */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32F4xx_HAL_DMA_EX_H*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_eth.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_eth.h new file mode 100644 index 0000000..79e936e --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_eth.h @@ -0,0 +1,2217 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_eth.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of ETH HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_ETH_H +#define __STM32F4xx_HAL_ETH_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup ETH + * @{ + */ + +/** @addtogroup ETH_Private_Macros + * @{ + */ +#define IS_ETH_PHY_ADDRESS(ADDRESS) ((ADDRESS) <= 0x20) +#define IS_ETH_AUTONEGOTIATION(CMD) (((CMD) == ETH_AUTONEGOTIATION_ENABLE) || \ + ((CMD) == ETH_AUTONEGOTIATION_DISABLE)) +#define IS_ETH_SPEED(SPEED) (((SPEED) == ETH_SPEED_10M) || \ + ((SPEED) == ETH_SPEED_100M)) +#define IS_ETH_DUPLEX_MODE(MODE) (((MODE) == ETH_MODE_FULLDUPLEX) || \ + ((MODE) == ETH_MODE_HALFDUPLEX)) +#define IS_ETH_RX_MODE(MODE) (((MODE) == ETH_RXPOLLING_MODE) || \ + ((MODE) == ETH_RXINTERRUPT_MODE)) +#define IS_ETH_CHECKSUM_MODE(MODE) (((MODE) == ETH_CHECKSUM_BY_HARDWARE) || \ + ((MODE) == ETH_CHECKSUM_BY_SOFTWARE)) +#define IS_ETH_MEDIA_INTERFACE(MODE) (((MODE) == ETH_MEDIA_INTERFACE_MII) || \ + ((MODE) == ETH_MEDIA_INTERFACE_RMII)) +#define IS_ETH_WATCHDOG(CMD) (((CMD) == ETH_WATCHDOG_ENABLE) || \ + ((CMD) == ETH_WATCHDOG_DISABLE)) +#define IS_ETH_JABBER(CMD) (((CMD) == ETH_JABBER_ENABLE) || \ + ((CMD) == ETH_JABBER_DISABLE)) +#define IS_ETH_INTER_FRAME_GAP(GAP) (((GAP) == ETH_INTERFRAMEGAP_96BIT) || \ + ((GAP) == ETH_INTERFRAMEGAP_88BIT) || \ + ((GAP) == ETH_INTERFRAMEGAP_80BIT) || \ + ((GAP) == ETH_INTERFRAMEGAP_72BIT) || \ + ((GAP) == ETH_INTERFRAMEGAP_64BIT) || \ + ((GAP) == ETH_INTERFRAMEGAP_56BIT) || \ + ((GAP) == ETH_INTERFRAMEGAP_48BIT) || \ + ((GAP) == ETH_INTERFRAMEGAP_40BIT)) +#define IS_ETH_CARRIER_SENSE(CMD) (((CMD) == ETH_CARRIERSENCE_ENABLE) || \ + ((CMD) == ETH_CARRIERSENCE_DISABLE)) +#define IS_ETH_RECEIVE_OWN(CMD) (((CMD) == ETH_RECEIVEOWN_ENABLE) || \ + ((CMD) == ETH_RECEIVEOWN_DISABLE)) +#define IS_ETH_LOOPBACK_MODE(CMD) (((CMD) == ETH_LOOPBACKMODE_ENABLE) || \ + ((CMD) == ETH_LOOPBACKMODE_DISABLE)) +#define IS_ETH_CHECKSUM_OFFLOAD(CMD) (((CMD) == ETH_CHECKSUMOFFLAOD_ENABLE) || \ + ((CMD) == ETH_CHECKSUMOFFLAOD_DISABLE)) +#define IS_ETH_RETRY_TRANSMISSION(CMD) (((CMD) == ETH_RETRYTRANSMISSION_ENABLE) || \ + ((CMD) == ETH_RETRYTRANSMISSION_DISABLE)) +#define IS_ETH_AUTOMATIC_PADCRC_STRIP(CMD) (((CMD) == ETH_AUTOMATICPADCRCSTRIP_ENABLE) || \ + ((CMD) == ETH_AUTOMATICPADCRCSTRIP_DISABLE)) +#define IS_ETH_BACKOFF_LIMIT(LIMIT) (((LIMIT) == ETH_BACKOFFLIMIT_10) || \ + ((LIMIT) == ETH_BACKOFFLIMIT_8) || \ + ((LIMIT) == ETH_BACKOFFLIMIT_4) || \ + ((LIMIT) == ETH_BACKOFFLIMIT_1)) +#define IS_ETH_DEFERRAL_CHECK(CMD) (((CMD) == ETH_DEFFERRALCHECK_ENABLE) || \ + ((CMD) == ETH_DEFFERRALCHECK_DISABLE)) +#define IS_ETH_RECEIVE_ALL(CMD) (((CMD) == ETH_RECEIVEALL_ENABLE) || \ + ((CMD) == ETH_RECEIVEAll_DISABLE)) +#define IS_ETH_SOURCE_ADDR_FILTER(CMD) (((CMD) == ETH_SOURCEADDRFILTER_NORMAL_ENABLE) || \ + ((CMD) == ETH_SOURCEADDRFILTER_INVERSE_ENABLE) || \ + ((CMD) == ETH_SOURCEADDRFILTER_DISABLE)) +#define IS_ETH_CONTROL_FRAMES(PASS) (((PASS) == ETH_PASSCONTROLFRAMES_BLOCKALL) || \ + ((PASS) == ETH_PASSCONTROLFRAMES_FORWARDALL) || \ + ((PASS) == ETH_PASSCONTROLFRAMES_FORWARDPASSEDADDRFILTER)) +#define IS_ETH_BROADCAST_FRAMES_RECEPTION(CMD) (((CMD) == ETH_BROADCASTFRAMESRECEPTION_ENABLE) || \ + ((CMD) == ETH_BROADCASTFRAMESRECEPTION_DISABLE)) +#define IS_ETH_DESTINATION_ADDR_FILTER(FILTER) (((FILTER) == ETH_DESTINATIONADDRFILTER_NORMAL) || \ + ((FILTER) == ETH_DESTINATIONADDRFILTER_INVERSE)) +#define IS_ETH_PROMISCUOUS_MODE(CMD) (((CMD) == ETH_PROMISCUOUS_MODE_ENABLE) || \ + ((CMD) == ETH_PROMISCUOUS_MODE_DISABLE)) +#define IS_ETH_MULTICAST_FRAMES_FILTER(FILTER) (((FILTER) == ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE) || \ + ((FILTER) == ETH_MULTICASTFRAMESFILTER_HASHTABLE) || \ + ((FILTER) == ETH_MULTICASTFRAMESFILTER_PERFECT) || \ + ((FILTER) == ETH_MULTICASTFRAMESFILTER_NONE)) +#define IS_ETH_UNICAST_FRAMES_FILTER(FILTER) (((FILTER) == ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE) || \ + ((FILTER) == ETH_UNICASTFRAMESFILTER_HASHTABLE) || \ + ((FILTER) == ETH_UNICASTFRAMESFILTER_PERFECT)) +#define IS_ETH_PAUSE_TIME(TIME) ((TIME) <= 0xFFFF) +#define IS_ETH_ZEROQUANTA_PAUSE(CMD) (((CMD) == ETH_ZEROQUANTAPAUSE_ENABLE) || \ + ((CMD) == ETH_ZEROQUANTAPAUSE_DISABLE)) +#define IS_ETH_PAUSE_LOW_THRESHOLD(THRESHOLD) (((THRESHOLD) == ETH_PAUSELOWTHRESHOLD_MINUS4) || \ + ((THRESHOLD) == ETH_PAUSELOWTHRESHOLD_MINUS28) || \ + ((THRESHOLD) == ETH_PAUSELOWTHRESHOLD_MINUS144) || \ + ((THRESHOLD) == ETH_PAUSELOWTHRESHOLD_MINUS256)) +#define IS_ETH_UNICAST_PAUSE_FRAME_DETECT(CMD) (((CMD) == ETH_UNICASTPAUSEFRAMEDETECT_ENABLE) || \ + ((CMD) == ETH_UNICASTPAUSEFRAMEDETECT_DISABLE)) +#define IS_ETH_RECEIVE_FLOWCONTROL(CMD) (((CMD) == ETH_RECEIVEFLOWCONTROL_ENABLE) || \ + ((CMD) == ETH_RECEIVEFLOWCONTROL_DISABLE)) +#define IS_ETH_TRANSMIT_FLOWCONTROL(CMD) (((CMD) == ETH_TRANSMITFLOWCONTROL_ENABLE) || \ + ((CMD) == ETH_TRANSMITFLOWCONTROL_DISABLE)) +#define IS_ETH_VLAN_TAG_COMPARISON(COMPARISON) (((COMPARISON) == ETH_VLANTAGCOMPARISON_12BIT) || \ + ((COMPARISON) == ETH_VLANTAGCOMPARISON_16BIT)) +#define IS_ETH_VLAN_TAG_IDENTIFIER(IDENTIFIER) ((IDENTIFIER) <= 0xFFFF) +#define IS_ETH_MAC_ADDRESS0123(ADDRESS) (((ADDRESS) == ETH_MAC_ADDRESS0) || \ + ((ADDRESS) == ETH_MAC_ADDRESS1) || \ + ((ADDRESS) == ETH_MAC_ADDRESS2) || \ + ((ADDRESS) == ETH_MAC_ADDRESS3)) +#define IS_ETH_MAC_ADDRESS123(ADDRESS) (((ADDRESS) == ETH_MAC_ADDRESS1) || \ + ((ADDRESS) == ETH_MAC_ADDRESS2) || \ + ((ADDRESS) == ETH_MAC_ADDRESS3)) +#define IS_ETH_MAC_ADDRESS_FILTER(FILTER) (((FILTER) == ETH_MAC_ADDRESSFILTER_SA) || \ + ((FILTER) == ETH_MAC_ADDRESSFILTER_DA)) +#define IS_ETH_MAC_ADDRESS_MASK(MASK) (((MASK) == ETH_MAC_ADDRESSMASK_BYTE6) || \ + ((MASK) == ETH_MAC_ADDRESSMASK_BYTE5) || \ + ((MASK) == ETH_MAC_ADDRESSMASK_BYTE4) || \ + ((MASK) == ETH_MAC_ADDRESSMASK_BYTE3) || \ + ((MASK) == ETH_MAC_ADDRESSMASK_BYTE2) || \ + ((MASK) == ETH_MAC_ADDRESSMASK_BYTE1)) +#define IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(CMD) (((CMD) == ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE) || \ + ((CMD) == ETH_DROPTCPIPCHECKSUMERRORFRAME_DISABLE)) +#define IS_ETH_RECEIVE_STORE_FORWARD(CMD) (((CMD) == ETH_RECEIVESTOREFORWARD_ENABLE) || \ + ((CMD) == ETH_RECEIVESTOREFORWARD_DISABLE)) +#define IS_ETH_FLUSH_RECEIVE_FRAME(CMD) (((CMD) == ETH_FLUSHRECEIVEDFRAME_ENABLE) || \ + ((CMD) == ETH_FLUSHRECEIVEDFRAME_DISABLE)) +#define IS_ETH_TRANSMIT_STORE_FORWARD(CMD) (((CMD) == ETH_TRANSMITSTOREFORWARD_ENABLE) || \ + ((CMD) == ETH_TRANSMITSTOREFORWARD_DISABLE)) +#define IS_ETH_TRANSMIT_THRESHOLD_CONTROL(THRESHOLD) (((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_64BYTES) || \ + ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_128BYTES) || \ + ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_192BYTES) || \ + ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_256BYTES) || \ + ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_40BYTES) || \ + ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_32BYTES) || \ + ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_24BYTES) || \ + ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_16BYTES)) +#define IS_ETH_FORWARD_ERROR_FRAMES(CMD) (((CMD) == ETH_FORWARDERRORFRAMES_ENABLE) || \ + ((CMD) == ETH_FORWARDERRORFRAMES_DISABLE)) +#define IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES(CMD) (((CMD) == ETH_FORWARDUNDERSIZEDGOODFRAMES_ENABLE) || \ + ((CMD) == ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE)) +#define IS_ETH_RECEIVE_THRESHOLD_CONTROL(THRESHOLD) (((THRESHOLD) == ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES) || \ + ((THRESHOLD) == ETH_RECEIVEDTHRESHOLDCONTROL_32BYTES) || \ + ((THRESHOLD) == ETH_RECEIVEDTHRESHOLDCONTROL_96BYTES) || \ + ((THRESHOLD) == ETH_RECEIVEDTHRESHOLDCONTROL_128BYTES)) +#define IS_ETH_SECOND_FRAME_OPERATE(CMD) (((CMD) == ETH_SECONDFRAMEOPERARTE_ENABLE) || \ + ((CMD) == ETH_SECONDFRAMEOPERARTE_DISABLE)) +#define IS_ETH_ADDRESS_ALIGNED_BEATS(CMD) (((CMD) == ETH_ADDRESSALIGNEDBEATS_ENABLE) || \ + ((CMD) == ETH_ADDRESSALIGNEDBEATS_DISABLE)) +#define IS_ETH_FIXED_BURST(CMD) (((CMD) == ETH_FIXEDBURST_ENABLE) || \ + ((CMD) == ETH_FIXEDBURST_DISABLE)) +#define IS_ETH_RXDMA_BURST_LENGTH(LENGTH) (((LENGTH) == ETH_RXDMABURSTLENGTH_1BEAT) || \ + ((LENGTH) == ETH_RXDMABURSTLENGTH_2BEAT) || \ + ((LENGTH) == ETH_RXDMABURSTLENGTH_4BEAT) || \ + ((LENGTH) == ETH_RXDMABURSTLENGTH_8BEAT) || \ + ((LENGTH) == ETH_RXDMABURSTLENGTH_16BEAT) || \ + ((LENGTH) == ETH_RXDMABURSTLENGTH_32BEAT) || \ + ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_4BEAT) || \ + ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_8BEAT) || \ + ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_16BEAT) || \ + ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_32BEAT) || \ + ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_64BEAT) || \ + ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_128BEAT)) +#define IS_ETH_TXDMA_BURST_LENGTH(LENGTH) (((LENGTH) == ETH_TXDMABURSTLENGTH_1BEAT) || \ + ((LENGTH) == ETH_TXDMABURSTLENGTH_2BEAT) || \ + ((LENGTH) == ETH_TXDMABURSTLENGTH_4BEAT) || \ + ((LENGTH) == ETH_TXDMABURSTLENGTH_8BEAT) || \ + ((LENGTH) == ETH_TXDMABURSTLENGTH_16BEAT) || \ + ((LENGTH) == ETH_TXDMABURSTLENGTH_32BEAT) || \ + ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_4BEAT) || \ + ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_8BEAT) || \ + ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_16BEAT) || \ + ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_32BEAT) || \ + ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_64BEAT) || \ + ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_128BEAT)) +#define IS_ETH_DMA_DESC_SKIP_LENGTH(LENGTH) ((LENGTH) <= 0x1F) +#define IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(RATIO) (((RATIO) == ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1) || \ + ((RATIO) == ETH_DMAARBITRATION_ROUNDROBIN_RXTX_2_1) || \ + ((RATIO) == ETH_DMAARBITRATION_ROUNDROBIN_RXTX_3_1) || \ + ((RATIO) == ETH_DMAARBITRATION_ROUNDROBIN_RXTX_4_1) || \ + ((RATIO) == ETH_DMAARBITRATION_RXPRIORTX)) +#define IS_ETH_DMATXDESC_GET_FLAG(FLAG) (((FLAG) == ETH_DMATXDESC_OWN) || \ + ((FLAG) == ETH_DMATXDESC_IC) || \ + ((FLAG) == ETH_DMATXDESC_LS) || \ + ((FLAG) == ETH_DMATXDESC_FS) || \ + ((FLAG) == ETH_DMATXDESC_DC) || \ + ((FLAG) == ETH_DMATXDESC_DP) || \ + ((FLAG) == ETH_DMATXDESC_TTSE) || \ + ((FLAG) == ETH_DMATXDESC_TER) || \ + ((FLAG) == ETH_DMATXDESC_TCH) || \ + ((FLAG) == ETH_DMATXDESC_TTSS) || \ + ((FLAG) == ETH_DMATXDESC_IHE) || \ + ((FLAG) == ETH_DMATXDESC_ES) || \ + ((FLAG) == ETH_DMATXDESC_JT) || \ + ((FLAG) == ETH_DMATXDESC_FF) || \ + ((FLAG) == ETH_DMATXDESC_PCE) || \ + ((FLAG) == ETH_DMATXDESC_LCA) || \ + ((FLAG) == ETH_DMATXDESC_NC) || \ + ((FLAG) == ETH_DMATXDESC_LCO) || \ + ((FLAG) == ETH_DMATXDESC_EC) || \ + ((FLAG) == ETH_DMATXDESC_VF) || \ + ((FLAG) == ETH_DMATXDESC_CC) || \ + ((FLAG) == ETH_DMATXDESC_ED) || \ + ((FLAG) == ETH_DMATXDESC_UF) || \ + ((FLAG) == ETH_DMATXDESC_DB)) +#define IS_ETH_DMA_TXDESC_SEGMENT(SEGMENT) (((SEGMENT) == ETH_DMATXDESC_LASTSEGMENTS) || \ + ((SEGMENT) == ETH_DMATXDESC_FIRSTSEGMENT)) +#define IS_ETH_DMA_TXDESC_CHECKSUM(CHECKSUM) (((CHECKSUM) == ETH_DMATXDESC_CHECKSUMBYPASS) || \ + ((CHECKSUM) == ETH_DMATXDESC_CHECKSUMIPV4HEADER) || \ + ((CHECKSUM) == ETH_DMATXDESC_CHECKSUMTCPUDPICMPSEGMENT) || \ + ((CHECKSUM) == ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL)) +#define IS_ETH_DMATXDESC_BUFFER_SIZE(SIZE) ((SIZE) <= 0x1FFF) +#define IS_ETH_DMARXDESC_GET_FLAG(FLAG) (((FLAG) == ETH_DMARXDESC_OWN) || \ + ((FLAG) == ETH_DMARXDESC_AFM) || \ + ((FLAG) == ETH_DMARXDESC_ES) || \ + ((FLAG) == ETH_DMARXDESC_DE) || \ + ((FLAG) == ETH_DMARXDESC_SAF) || \ + ((FLAG) == ETH_DMARXDESC_LE) || \ + ((FLAG) == ETH_DMARXDESC_OE) || \ + ((FLAG) == ETH_DMARXDESC_VLAN) || \ + ((FLAG) == ETH_DMARXDESC_FS) || \ + ((FLAG) == ETH_DMARXDESC_LS) || \ + ((FLAG) == ETH_DMARXDESC_IPV4HCE) || \ + ((FLAG) == ETH_DMARXDESC_LC) || \ + ((FLAG) == ETH_DMARXDESC_FT) || \ + ((FLAG) == ETH_DMARXDESC_RWT) || \ + ((FLAG) == ETH_DMARXDESC_RE) || \ + ((FLAG) == ETH_DMARXDESC_DBE) || \ + ((FLAG) == ETH_DMARXDESC_CE) || \ + ((FLAG) == ETH_DMARXDESC_MAMPCE)) +#define IS_ETH_DMA_RXDESC_BUFFER(BUFFER) (((BUFFER) == ETH_DMARXDESC_BUFFER1) || \ + ((BUFFER) == ETH_DMARXDESC_BUFFER2)) +#define IS_ETH_PMT_GET_FLAG(FLAG) (((FLAG) == ETH_PMT_FLAG_WUFR) || \ + ((FLAG) == ETH_PMT_FLAG_MPR)) +#define IS_ETH_DMA_FLAG(FLAG) ((((FLAG) & (uint32_t)0xC7FE1800) == 0x00) && ((FLAG) != 0x00)) +#define IS_ETH_DMA_GET_FLAG(FLAG) (((FLAG) == ETH_DMA_FLAG_TST) || ((FLAG) == ETH_DMA_FLAG_PMT) || \ + ((FLAG) == ETH_DMA_FLAG_MMC) || ((FLAG) == ETH_DMA_FLAG_DATATRANSFERERROR) || \ + ((FLAG) == ETH_DMA_FLAG_READWRITEERROR) || ((FLAG) == ETH_DMA_FLAG_ACCESSERROR) || \ + ((FLAG) == ETH_DMA_FLAG_NIS) || ((FLAG) == ETH_DMA_FLAG_AIS) || \ + ((FLAG) == ETH_DMA_FLAG_ER) || ((FLAG) == ETH_DMA_FLAG_FBE) || \ + ((FLAG) == ETH_DMA_FLAG_ET) || ((FLAG) == ETH_DMA_FLAG_RWT) || \ + ((FLAG) == ETH_DMA_FLAG_RPS) || ((FLAG) == ETH_DMA_FLAG_RBU) || \ + ((FLAG) == ETH_DMA_FLAG_R) || ((FLAG) == ETH_DMA_FLAG_TU) || \ + ((FLAG) == ETH_DMA_FLAG_RO) || ((FLAG) == ETH_DMA_FLAG_TJT) || \ + ((FLAG) == ETH_DMA_FLAG_TBU) || ((FLAG) == ETH_DMA_FLAG_TPS) || \ + ((FLAG) == ETH_DMA_FLAG_T)) +#define IS_ETH_MAC_IT(IT) ((((IT) & (uint32_t)0xFFFFFDF1) == 0x00) && ((IT) != 0x00)) +#define IS_ETH_MAC_GET_IT(IT) (((IT) == ETH_MAC_IT_TST) || ((IT) == ETH_MAC_IT_MMCT) || \ + ((IT) == ETH_MAC_IT_MMCR) || ((IT) == ETH_MAC_IT_MMC) || \ + ((IT) == ETH_MAC_IT_PMT)) +#define IS_ETH_MAC_GET_FLAG(FLAG) (((FLAG) == ETH_MAC_FLAG_TST) || ((FLAG) == ETH_MAC_FLAG_MMCT) || \ + ((FLAG) == ETH_MAC_FLAG_MMCR) || ((FLAG) == ETH_MAC_FLAG_MMC) || \ + ((FLAG) == ETH_MAC_FLAG_PMT)) +#define IS_ETH_DMA_IT(IT) ((((IT) & (uint32_t)0xC7FE1800) == 0x00) && ((IT) != 0x00)) +#define IS_ETH_DMA_GET_IT(IT) (((IT) == ETH_DMA_IT_TST) || ((IT) == ETH_DMA_IT_PMT) || \ + ((IT) == ETH_DMA_IT_MMC) || ((IT) == ETH_DMA_IT_NIS) || \ + ((IT) == ETH_DMA_IT_AIS) || ((IT) == ETH_DMA_IT_ER) || \ + ((IT) == ETH_DMA_IT_FBE) || ((IT) == ETH_DMA_IT_ET) || \ + ((IT) == ETH_DMA_IT_RWT) || ((IT) == ETH_DMA_IT_RPS) || \ + ((IT) == ETH_DMA_IT_RBU) || ((IT) == ETH_DMA_IT_R) || \ + ((IT) == ETH_DMA_IT_TU) || ((IT) == ETH_DMA_IT_RO) || \ + ((IT) == ETH_DMA_IT_TJT) || ((IT) == ETH_DMA_IT_TBU) || \ + ((IT) == ETH_DMA_IT_TPS) || ((IT) == ETH_DMA_IT_T)) +#define IS_ETH_DMA_GET_OVERFLOW(OVERFLOW) (((OVERFLOW) == ETH_DMA_OVERFLOW_RXFIFOCOUNTER) || \ + ((OVERFLOW) == ETH_DMA_OVERFLOW_MISSEDFRAMECOUNTER)) +#define IS_ETH_MMC_IT(IT) (((((IT) & (uint32_t)0xFFDF3FFF) == 0x00) || (((IT) & (uint32_t)0xEFFDFF9F) == 0x00)) && \ + ((IT) != 0x00)) +#define IS_ETH_MMC_GET_IT(IT) (((IT) == ETH_MMC_IT_TGF) || ((IT) == ETH_MMC_IT_TGFMSC) || \ + ((IT) == ETH_MMC_IT_TGFSC) || ((IT) == ETH_MMC_IT_RGUF) || \ + ((IT) == ETH_MMC_IT_RFAE) || ((IT) == ETH_MMC_IT_RFCE)) +#define IS_ETH_ENHANCED_DESCRIPTOR_FORMAT(CMD) (((CMD) == ETH_DMAENHANCEDDESCRIPTOR_ENABLE) || \ + ((CMD) == ETH_DMAENHANCEDDESCRIPTOR_DISABLE)) + + +/** + * @} + */ + +/** @addtogroup ETH_Private_Defines + * @{ + */ +/* Delay to wait when writing to some Ethernet registers */ +#define ETH_REG_WRITE_DELAY ((uint32_t)0x00000001) + +/* ETHERNET Errors */ +#define ETH_SUCCESS ((uint32_t)0) +#define ETH_ERROR ((uint32_t)1) + +/* ETHERNET DMA Tx descriptors Collision Count Shift */ +#define ETH_DMATXDESC_COLLISION_COUNTSHIFT ((uint32_t)3) + +/* ETHERNET DMA Tx descriptors Buffer2 Size Shift */ +#define ETH_DMATXDESC_BUFFER2_SIZESHIFT ((uint32_t)16) + +/* ETHERNET DMA Rx descriptors Frame Length Shift */ +#define ETH_DMARXDESC_FRAME_LENGTHSHIFT ((uint32_t)16) + +/* ETHERNET DMA Rx descriptors Buffer2 Size Shift */ +#define ETH_DMARXDESC_BUFFER2_SIZESHIFT ((uint32_t)16) + +/* ETHERNET DMA Rx descriptors Frame length Shift */ +#define ETH_DMARXDESC_FRAMELENGTHSHIFT ((uint32_t)16) + +/* ETHERNET MAC address offsets */ +#define ETH_MAC_ADDR_HBASE (uint32_t)(ETH_MAC_BASE + (uint32_t)0x40) /* ETHERNET MAC address high offset */ +#define ETH_MAC_ADDR_LBASE (uint32_t)(ETH_MAC_BASE + (uint32_t)0x44) /* ETHERNET MAC address low offset */ + +/* ETHERNET MACMIIAR register Mask */ +#define ETH_MACMIIAR_CR_MASK ((uint32_t)0xFFFFFFE3) + +/* ETHERNET MACCR register Mask */ +#define ETH_MACCR_CLEAR_MASK ((uint32_t)0xFF20810F) + +/* ETHERNET MACFCR register Mask */ +#define ETH_MACFCR_CLEAR_MASK ((uint32_t)0x0000FF41) + +/* ETHERNET DMAOMR register Mask */ +#define ETH_DMAOMR_CLEAR_MASK ((uint32_t)0xF8DE3F23) + +/* ETHERNET Remote Wake-up frame register length */ +#define ETH_WAKEUP_REGISTER_LENGTH 8 + +/* ETHERNET Missed frames counter Shift */ +#define ETH_DMA_RX_OVERFLOW_MISSEDFRAMES_COUNTERSHIFT 17 + /** + * @} + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup ETH_Exported_Types ETH Exported Types + * @{ + */ + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_ETH_STATE_RESET = 0x00, /*!< Peripheral not yet Initialized or disabled */ + HAL_ETH_STATE_READY = 0x01, /*!< Peripheral Initialized and ready for use */ + HAL_ETH_STATE_BUSY = 0x02, /*!< an internal process is ongoing */ + HAL_ETH_STATE_BUSY_TX = 0x12, /*!< Data Transmission process is ongoing */ + HAL_ETH_STATE_BUSY_RX = 0x22, /*!< Data Reception process is ongoing */ + HAL_ETH_STATE_BUSY_TX_RX = 0x32, /*!< Data Transmission and Reception process is ongoing */ + HAL_ETH_STATE_BUSY_WR = 0x42, /*!< Write process is ongoing */ + HAL_ETH_STATE_BUSY_RD = 0x82, /*!< Read process is ongoing */ + HAL_ETH_STATE_TIMEOUT = 0x03, /*!< Timeout state */ + HAL_ETH_STATE_ERROR = 0x04 /*!< Reception process is ongoing */ +}HAL_ETH_StateTypeDef; + +/** + * @brief ETH Init Structure definition + */ + +typedef struct +{ + uint32_t AutoNegotiation; /*!< Selects or not the AutoNegotiation mode for the external PHY + The AutoNegotiation allows an automatic setting of the Speed (10/100Mbps) + and the mode (half/full-duplex). + This parameter can be a value of @ref ETH_AutoNegotiation */ + + uint32_t Speed; /*!< Sets the Ethernet speed: 10/100 Mbps. + This parameter can be a value of @ref ETH_Speed */ + + uint32_t DuplexMode; /*!< Selects the MAC duplex mode: Half-Duplex or Full-Duplex mode + This parameter can be a value of @ref ETH_Duplex_Mode */ + + uint16_t PhyAddress; /*!< Ethernet PHY address. + This parameter must be a number between Min_Data = 0 and Max_Data = 32 */ + + uint8_t *MACAddr; /*!< MAC Address of used Hardware: must be pointer on an array of 6 bytes */ + + uint32_t RxMode; /*!< Selects the Ethernet Rx mode: Polling mode, Interrupt mode. + This parameter can be a value of @ref ETH_Rx_Mode */ + + uint32_t ChecksumMode; /*!< Selects if the checksum is check by hardware or by software. + This parameter can be a value of @ref ETH_Checksum_Mode */ + + uint32_t MediaInterface ; /*!< Selects the media-independent interface or the reduced media-independent interface. + This parameter can be a value of @ref ETH_Media_Interface */ + +} ETH_InitTypeDef; + + + /** + * @brief ETH MAC Configuration Structure definition + */ + +typedef struct +{ + uint32_t Watchdog; /*!< Selects or not the Watchdog timer + When enabled, the MAC allows no more then 2048 bytes to be received. + When disabled, the MAC can receive up to 16384 bytes. + This parameter can be a value of @ref ETH_Watchdog */ + + uint32_t Jabber; /*!< Selects or not Jabber timer + When enabled, the MAC allows no more then 2048 bytes to be sent. + When disabled, the MAC can send up to 16384 bytes. + This parameter can be a value of @ref ETH_Jabber */ + + uint32_t InterFrameGap; /*!< Selects the minimum IFG between frames during transmission. + This parameter can be a value of @ref ETH_Inter_Frame_Gap */ + + uint32_t CarrierSense; /*!< Selects or not the Carrier Sense. + This parameter can be a value of @ref ETH_Carrier_Sense */ + + uint32_t ReceiveOwn; /*!< Selects or not the ReceiveOwn, + ReceiveOwn allows the reception of frames when the TX_EN signal is asserted + in Half-Duplex mode. + This parameter can be a value of @ref ETH_Receive_Own */ + + uint32_t LoopbackMode; /*!< Selects or not the internal MAC MII Loopback mode. + This parameter can be a value of @ref ETH_Loop_Back_Mode */ + + uint32_t ChecksumOffload; /*!< Selects or not the IPv4 checksum checking for received frame payloads' TCP/UDP/ICMP headers. + This parameter can be a value of @ref ETH_Checksum_Offload */ + + uint32_t RetryTransmission; /*!< Selects or not the MAC attempt retries transmission, based on the settings of BL, + when a collision occurs (Half-Duplex mode). + This parameter can be a value of @ref ETH_Retry_Transmission */ + + uint32_t AutomaticPadCRCStrip; /*!< Selects or not the Automatic MAC Pad/CRC Stripping. + This parameter can be a value of @ref ETH_Automatic_Pad_CRC_Strip */ + + uint32_t BackOffLimit; /*!< Selects the BackOff limit value. + This parameter can be a value of @ref ETH_Back_Off_Limit */ + + uint32_t DeferralCheck; /*!< Selects or not the deferral check function (Half-Duplex mode). + This parameter can be a value of @ref ETH_Deferral_Check */ + + uint32_t ReceiveAll; /*!< Selects or not all frames reception by the MAC (No filtering). + This parameter can be a value of @ref ETH_Receive_All */ + + uint32_t SourceAddrFilter; /*!< Selects the Source Address Filter mode. + This parameter can be a value of @ref ETH_Source_Addr_Filter */ + + uint32_t PassControlFrames; /*!< Sets the forwarding mode of the control frames (including unicast and multicast PAUSE frames) + This parameter can be a value of @ref ETH_Pass_Control_Frames */ + + uint32_t BroadcastFramesReception; /*!< Selects or not the reception of Broadcast Frames. + This parameter can be a value of @ref ETH_Broadcast_Frames_Reception */ + + uint32_t DestinationAddrFilter; /*!< Sets the destination filter mode for both unicast and multicast frames. + This parameter can be a value of @ref ETH_Destination_Addr_Filter */ + + uint32_t PromiscuousMode; /*!< Selects or not the Promiscuous Mode + This parameter can be a value of @ref ETH_Promiscuous_Mode */ + + uint32_t MulticastFramesFilter; /*!< Selects the Multicast Frames filter mode: None/HashTableFilter/PerfectFilter/PerfectHashTableFilter. + This parameter can be a value of @ref ETH_Multicast_Frames_Filter */ + + uint32_t UnicastFramesFilter; /*!< Selects the Unicast Frames filter mode: HashTableFilter/PerfectFilter/PerfectHashTableFilter. + This parameter can be a value of @ref ETH_Unicast_Frames_Filter */ + + uint32_t HashTableHigh; /*!< This field holds the higher 32 bits of Hash table. + This parameter must be a number between Min_Data = 0x0 and Max_Data = 0xFFFFFFFF */ + + uint32_t HashTableLow; /*!< This field holds the lower 32 bits of Hash table. + This parameter must be a number between Min_Data = 0x0 and Max_Data = 0xFFFFFFFF */ + + uint32_t PauseTime; /*!< This field holds the value to be used in the Pause Time field in the transmit control frame. + This parameter must be a number between Min_Data = 0x0 and Max_Data = 0xFFFF */ + + uint32_t ZeroQuantaPause; /*!< Selects or not the automatic generation of Zero-Quanta Pause Control frames. + This parameter can be a value of @ref ETH_Zero_Quanta_Pause */ + + uint32_t PauseLowThreshold; /*!< This field configures the threshold of the PAUSE to be checked for + automatic retransmission of PAUSE Frame. + This parameter can be a value of @ref ETH_Pause_Low_Threshold */ + + uint32_t UnicastPauseFrameDetect; /*!< Selects or not the MAC detection of the Pause frames (with MAC Address0 + unicast address and unique multicast address). + This parameter can be a value of @ref ETH_Unicast_Pause_Frame_Detect */ + + uint32_t ReceiveFlowControl; /*!< Enables or disables the MAC to decode the received Pause frame and + disable its transmitter for a specified time (Pause Time) + This parameter can be a value of @ref ETH_Receive_Flow_Control */ + + uint32_t TransmitFlowControl; /*!< Enables or disables the MAC to transmit Pause frames (Full-Duplex mode) + or the MAC back-pressure operation (Half-Duplex mode) + This parameter can be a value of @ref ETH_Transmit_Flow_Control */ + + uint32_t VLANTagComparison; /*!< Selects the 12-bit VLAN identifier or the complete 16-bit VLAN tag for + comparison and filtering. + This parameter can be a value of @ref ETH_VLAN_Tag_Comparison */ + + uint32_t VLANTagIdentifier; /*!< Holds the VLAN tag identifier for receive frames */ + +} ETH_MACInitTypeDef; + + +/** + * @brief ETH DMA Configuration Structure definition + */ + +typedef struct +{ + uint32_t DropTCPIPChecksumErrorFrame; /*!< Selects or not the Dropping of TCP/IP Checksum Error Frames. + This parameter can be a value of @ref ETH_Drop_TCP_IP_Checksum_Error_Frame */ + + uint32_t ReceiveStoreForward; /*!< Enables or disables the Receive store and forward mode. + This parameter can be a value of @ref ETH_Receive_Store_Forward */ + + uint32_t FlushReceivedFrame; /*!< Enables or disables the flushing of received frames. + This parameter can be a value of @ref ETH_Flush_Received_Frame */ + + uint32_t TransmitStoreForward; /*!< Enables or disables Transmit store and forward mode. + This parameter can be a value of @ref ETH_Transmit_Store_Forward */ + + uint32_t TransmitThresholdControl; /*!< Selects or not the Transmit Threshold Control. + This parameter can be a value of @ref ETH_Transmit_Threshold_Control */ + + uint32_t ForwardErrorFrames; /*!< Selects or not the forward to the DMA of erroneous frames. + This parameter can be a value of @ref ETH_Forward_Error_Frames */ + + uint32_t ForwardUndersizedGoodFrames; /*!< Enables or disables the Rx FIFO to forward Undersized frames (frames with no Error + and length less than 64 bytes) including pad-bytes and CRC) + This parameter can be a value of @ref ETH_Forward_Undersized_Good_Frames */ + + uint32_t ReceiveThresholdControl; /*!< Selects the threshold level of the Receive FIFO. + This parameter can be a value of @ref ETH_Receive_Threshold_Control */ + + uint32_t SecondFrameOperate; /*!< Selects or not the Operate on second frame mode, which allows the DMA to process a second + frame of Transmit data even before obtaining the status for the first frame. + This parameter can be a value of @ref ETH_Second_Frame_Operate */ + + uint32_t AddressAlignedBeats; /*!< Enables or disables the Address Aligned Beats. + This parameter can be a value of @ref ETH_Address_Aligned_Beats */ + + uint32_t FixedBurst; /*!< Enables or disables the AHB Master interface fixed burst transfers. + This parameter can be a value of @ref ETH_Fixed_Burst */ + + uint32_t RxDMABurstLength; /*!< Indicates the maximum number of beats to be transferred in one Rx DMA transaction. + This parameter can be a value of @ref ETH_Rx_DMA_Burst_Length */ + + uint32_t TxDMABurstLength; /*!< Indicates the maximum number of beats to be transferred in one Tx DMA transaction. + This parameter can be a value of @ref ETH_Tx_DMA_Burst_Length */ + + uint32_t EnhancedDescriptorFormat; /*!< Enables the enhanced descriptor format. + This parameter can be a value of @ref ETH_DMA_Enhanced_descriptor_format */ + + uint32_t DescriptorSkipLength; /*!< Specifies the number of word to skip between two unchained descriptors (Ring mode) + This parameter must be a number between Min_Data = 0 and Max_Data = 32 */ + + uint32_t DMAArbitration; /*!< Selects the DMA Tx/Rx arbitration. + This parameter can be a value of @ref ETH_DMA_Arbitration */ +} ETH_DMAInitTypeDef; + + +/** + * @brief ETH DMA Descriptors data structure definition + */ + +typedef struct +{ + __IO uint32_t Status; /*!< Status */ + + uint32_t ControlBufferSize; /*!< Control and Buffer1, Buffer2 lengths */ + + uint32_t Buffer1Addr; /*!< Buffer1 address pointer */ + + uint32_t Buffer2NextDescAddr; /*!< Buffer2 or next descriptor address pointer */ + + /*!< Enhanced ETHERNET DMA PTP Descriptors */ + uint32_t ExtendedStatus; /*!< Extended status for PTP receive descriptor */ + + uint32_t Reserved1; /*!< Reserved */ + + uint32_t TimeStampLow; /*!< Time Stamp Low value for transmit and receive */ + + uint32_t TimeStampHigh; /*!< Time Stamp High value for transmit and receive */ + +} ETH_DMADescTypeDef; + + +/** + * @brief Received Frame Informations structure definition + */ +typedef struct +{ + ETH_DMADescTypeDef *FSRxDesc; /*!< First Segment Rx Desc */ + + ETH_DMADescTypeDef *LSRxDesc; /*!< Last Segment Rx Desc */ + + uint32_t SegCount; /*!< Segment count */ + + uint32_t length; /*!< Frame length */ + + uint32_t buffer; /*!< Frame buffer */ + +} ETH_DMARxFrameInfos; + + +/** + * @brief ETH Handle Structure definition + */ + +typedef struct +{ + ETH_TypeDef *Instance; /*!< Register base address */ + + ETH_InitTypeDef Init; /*!< Ethernet Init Configuration */ + + uint32_t LinkStatus; /*!< Ethernet link status */ + + ETH_DMADescTypeDef *RxDesc; /*!< Rx descriptor to Get */ + + ETH_DMADescTypeDef *TxDesc; /*!< Tx descriptor to Set */ + + ETH_DMARxFrameInfos RxFrameInfos; /*!< last Rx frame infos */ + + __IO HAL_ETH_StateTypeDef State; /*!< ETH communication state */ + + HAL_LockTypeDef Lock; /*!< ETH Lock */ + +} ETH_HandleTypeDef; + + /** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup ETH_Exported_Constants ETH Exported Constants + * @{ + */ + +/** @defgroup ETH_Buffers_setting ETH Buffers setting + * @{ + */ +#define ETH_MAX_PACKET_SIZE ((uint32_t)1524) /*!< ETH_HEADER + ETH_EXTRA + ETH_VLAN_TAG + ETH_MAX_ETH_PAYLOAD + ETH_CRC */ +#define ETH_HEADER ((uint32_t)14) /*!< 6 byte Dest addr, 6 byte Src addr, 2 byte length/type */ +#define ETH_CRC ((uint32_t)4) /*!< Ethernet CRC */ +#define ETH_EXTRA ((uint32_t)2) /*!< Extra bytes in some cases */ +#define ETH_VLAN_TAG ((uint32_t)4) /*!< optional 802.1q VLAN Tag */ +#define ETH_MIN_ETH_PAYLOAD ((uint32_t)46) /*!< Minimum Ethernet payload size */ +#define ETH_MAX_ETH_PAYLOAD ((uint32_t)1500) /*!< Maximum Ethernet payload size */ +#define ETH_JUMBO_FRAME_PAYLOAD ((uint32_t)9000) /*!< Jumbo frame payload size */ + + /* Ethernet driver receive buffers are organized in a chained linked-list, when + an ethernet packet is received, the Rx-DMA will transfer the packet from RxFIFO + to the driver receive buffers memory. + + Depending on the size of the received ethernet packet and the size of + each ethernet driver receive buffer, the received packet can take one or more + ethernet driver receive buffer. + + In below are defined the size of one ethernet driver receive buffer ETH_RX_BUF_SIZE + and the total count of the driver receive buffers ETH_RXBUFNB. + + The configured value for ETH_RX_BUF_SIZE and ETH_RXBUFNB are only provided as + example, they can be reconfigured in the application layer to fit the application + needs */ + +/* Here we configure each Ethernet driver receive buffer to fit the Max size Ethernet + packet */ +#ifndef ETH_RX_BUF_SIZE + #define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE +#endif + +/* 5 Ethernet driver receive buffers are used (in a chained linked list)*/ +#ifndef ETH_RXBUFNB + #define ETH_RXBUFNB ((uint32_t)5 /* 5 Rx buffers of size ETH_RX_BUF_SIZE */ +#endif + + + /* Ethernet driver transmit buffers are organized in a chained linked-list, when + an ethernet packet is transmitted, Tx-DMA will transfer the packet from the + driver transmit buffers memory to the TxFIFO. + + Depending on the size of the Ethernet packet to be transmitted and the size of + each ethernet driver transmit buffer, the packet to be transmitted can take + one or more ethernet driver transmit buffer. + + In below are defined the size of one ethernet driver transmit buffer ETH_TX_BUF_SIZE + and the total count of the driver transmit buffers ETH_TXBUFNB. + + The configured value for ETH_TX_BUF_SIZE and ETH_TXBUFNB are only provided as + example, they can be reconfigured in the application layer to fit the application + needs */ + +/* Here we configure each Ethernet driver transmit buffer to fit the Max size Ethernet + packet */ +#ifndef ETH_TX_BUF_SIZE + #define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE +#endif + +/* 5 ethernet driver transmit buffers are used (in a chained linked list)*/ +#ifndef ETH_TXBUFNB + #define ETH_TXBUFNB ((uint32_t)5 /* 5 Tx buffers of size ETH_TX_BUF_SIZE */ +#endif + + /** + * @} + */ + +/** @defgroup ETH_DMA_TX_Descriptor ETH DMA TX Descriptor + * @{ + */ + +/* + DMA Tx Descriptor + ----------------------------------------------------------------------------------------------- + TDES0 | OWN(31) | CTRL[30:26] | Reserved[25:24] | CTRL[23:20] | Reserved[19:17] | Status[16:0] | + ----------------------------------------------------------------------------------------------- + TDES1 | Reserved[31:29] | Buffer2 ByteCount[28:16] | Reserved[15:13] | Buffer1 ByteCount[12:0] | + ----------------------------------------------------------------------------------------------- + TDES2 | Buffer1 Address [31:0] | + ----------------------------------------------------------------------------------------------- + TDES3 | Buffer2 Address [31:0] / Next Descriptor Address [31:0] | + ----------------------------------------------------------------------------------------------- +*/ + +/** + * @brief Bit definition of TDES0 register: DMA Tx descriptor status register + */ +#define ETH_DMATXDESC_OWN ((uint32_t)0x80000000) /*!< OWN bit: descriptor is owned by DMA engine */ +#define ETH_DMATXDESC_IC ((uint32_t)0x40000000) /*!< Interrupt on Completion */ +#define ETH_DMATXDESC_LS ((uint32_t)0x20000000) /*!< Last Segment */ +#define ETH_DMATXDESC_FS ((uint32_t)0x10000000) /*!< First Segment */ +#define ETH_DMATXDESC_DC ((uint32_t)0x08000000) /*!< Disable CRC */ +#define ETH_DMATXDESC_DP ((uint32_t)0x04000000) /*!< Disable Padding */ +#define ETH_DMATXDESC_TTSE ((uint32_t)0x02000000) /*!< Transmit Time Stamp Enable */ +#define ETH_DMATXDESC_CIC ((uint32_t)0x00C00000) /*!< Checksum Insertion Control: 4 cases */ +#define ETH_DMATXDESC_CIC_BYPASS ((uint32_t)0x00000000) /*!< Do Nothing: Checksum Engine is bypassed */ +#define ETH_DMATXDESC_CIC_IPV4HEADER ((uint32_t)0x00400000) /*!< IPV4 header Checksum Insertion */ +#define ETH_DMATXDESC_CIC_TCPUDPICMP_SEGMENT ((uint32_t)0x00800000) /*!< TCP/UDP/ICMP Checksum Insertion calculated over segment only */ +#define ETH_DMATXDESC_CIC_TCPUDPICMP_FULL ((uint32_t)0x00C00000) /*!< TCP/UDP/ICMP Checksum Insertion fully calculated */ +#define ETH_DMATXDESC_TER ((uint32_t)0x00200000) /*!< Transmit End of Ring */ +#define ETH_DMATXDESC_TCH ((uint32_t)0x00100000) /*!< Second Address Chained */ +#define ETH_DMATXDESC_TTSS ((uint32_t)0x00020000) /*!< Tx Time Stamp Status */ +#define ETH_DMATXDESC_IHE ((uint32_t)0x00010000) /*!< IP Header Error */ +#define ETH_DMATXDESC_ES ((uint32_t)0x00008000) /*!< Error summary: OR of the following bits: UE || ED || EC || LCO || NC || LCA || FF || JT */ +#define ETH_DMATXDESC_JT ((uint32_t)0x00004000) /*!< Jabber Timeout */ +#define ETH_DMATXDESC_FF ((uint32_t)0x00002000) /*!< Frame Flushed: DMA/MTL flushed the frame due to SW flush */ +#define ETH_DMATXDESC_PCE ((uint32_t)0x00001000) /*!< Payload Checksum Error */ +#define ETH_DMATXDESC_LCA ((uint32_t)0x00000800) /*!< Loss of Carrier: carrier lost during transmission */ +#define ETH_DMATXDESC_NC ((uint32_t)0x00000400) /*!< No Carrier: no carrier signal from the transceiver */ +#define ETH_DMATXDESC_LCO ((uint32_t)0x00000200) /*!< Late Collision: transmission aborted due to collision */ +#define ETH_DMATXDESC_EC ((uint32_t)0x00000100) /*!< Excessive Collision: transmission aborted after 16 collisions */ +#define ETH_DMATXDESC_VF ((uint32_t)0x00000080) /*!< VLAN Frame */ +#define ETH_DMATXDESC_CC ((uint32_t)0x00000078) /*!< Collision Count */ +#define ETH_DMATXDESC_ED ((uint32_t)0x00000004) /*!< Excessive Deferral */ +#define ETH_DMATXDESC_UF ((uint32_t)0x00000002) /*!< Underflow Error: late data arrival from the memory */ +#define ETH_DMATXDESC_DB ((uint32_t)0x00000001) /*!< Deferred Bit */ + +/** + * @brief Bit definition of TDES1 register + */ +#define ETH_DMATXDESC_TBS2 ((uint32_t)0x1FFF0000) /*!< Transmit Buffer2 Size */ +#define ETH_DMATXDESC_TBS1 ((uint32_t)0x00001FFF) /*!< Transmit Buffer1 Size */ + +/** + * @brief Bit definition of TDES2 register + */ +#define ETH_DMATXDESC_B1AP ((uint32_t)0xFFFFFFFF) /*!< Buffer1 Address Pointer */ + +/** + * @brief Bit definition of TDES3 register + */ +#define ETH_DMATXDESC_B2AP ((uint32_t)0xFFFFFFFF) /*!< Buffer2 Address Pointer */ + + /*--------------------------------------------------------------------------------------------- + TDES6 | Transmit Time Stamp Low [31:0] | + ----------------------------------------------------------------------------------------------- + TDES7 | Transmit Time Stamp High [31:0] | + ----------------------------------------------------------------------------------------------*/ + +/* Bit definition of TDES6 register */ + #define ETH_DMAPTPTXDESC_TTSL ((uint32_t)0xFFFFFFFF) /* Transmit Time Stamp Low */ + +/* Bit definition of TDES7 register */ + #define ETH_DMAPTPTXDESC_TTSH ((uint32_t)0xFFFFFFFF) /* Transmit Time Stamp High */ + +/** + * @} + */ +/** @defgroup ETH_DMA_RX_Descriptor ETH DMA RX Descriptor + * @{ + */ + +/* + DMA Rx Descriptor + -------------------------------------------------------------------------------------------------------------------- + RDES0 | OWN(31) | Status [30:0] | + --------------------------------------------------------------------------------------------------------------------- + RDES1 | CTRL(31) | Reserved[30:29] | Buffer2 ByteCount[28:16] | CTRL[15:14] | Reserved(13) | Buffer1 ByteCount[12:0] | + --------------------------------------------------------------------------------------------------------------------- + RDES2 | Buffer1 Address [31:0] | + --------------------------------------------------------------------------------------------------------------------- + RDES3 | Buffer2 Address [31:0] / Next Descriptor Address [31:0] | + --------------------------------------------------------------------------------------------------------------------- +*/ + +/** + * @brief Bit definition of RDES0 register: DMA Rx descriptor status register + */ +#define ETH_DMARXDESC_OWN ((uint32_t)0x80000000) /*!< OWN bit: descriptor is owned by DMA engine */ +#define ETH_DMARXDESC_AFM ((uint32_t)0x40000000) /*!< DA Filter Fail for the rx frame */ +#define ETH_DMARXDESC_FL ((uint32_t)0x3FFF0000) /*!< Receive descriptor frame length */ +#define ETH_DMARXDESC_ES ((uint32_t)0x00008000) /*!< Error summary: OR of the following bits: DE || OE || IPC || LC || RWT || RE || CE */ +#define ETH_DMARXDESC_DE ((uint32_t)0x00004000) /*!< Descriptor error: no more descriptors for receive frame */ +#define ETH_DMARXDESC_SAF ((uint32_t)0x00002000) /*!< SA Filter Fail for the received frame */ +#define ETH_DMARXDESC_LE ((uint32_t)0x00001000) /*!< Frame size not matching with length field */ +#define ETH_DMARXDESC_OE ((uint32_t)0x00000800) /*!< Overflow Error: Frame was damaged due to buffer overflow */ +#define ETH_DMARXDESC_VLAN ((uint32_t)0x00000400) /*!< VLAN Tag: received frame is a VLAN frame */ +#define ETH_DMARXDESC_FS ((uint32_t)0x00000200) /*!< First descriptor of the frame */ +#define ETH_DMARXDESC_LS ((uint32_t)0x00000100) /*!< Last descriptor of the frame */ +#define ETH_DMARXDESC_IPV4HCE ((uint32_t)0x00000080) /*!< IPC Checksum Error: Rx Ipv4 header checksum error */ +#define ETH_DMARXDESC_LC ((uint32_t)0x00000040) /*!< Late collision occurred during reception */ +#define ETH_DMARXDESC_FT ((uint32_t)0x00000020) /*!< Frame type - Ethernet, otherwise 802.3 */ +#define ETH_DMARXDESC_RWT ((uint32_t)0x00000010) /*!< Receive Watchdog Timeout: watchdog timer expired during reception */ +#define ETH_DMARXDESC_RE ((uint32_t)0x00000008) /*!< Receive error: error reported by MII interface */ +#define ETH_DMARXDESC_DBE ((uint32_t)0x00000004) /*!< Dribble bit error: frame contains non int multiple of 8 bits */ +#define ETH_DMARXDESC_CE ((uint32_t)0x00000002) /*!< CRC error */ +#define ETH_DMARXDESC_MAMPCE ((uint32_t)0x00000001) /*!< Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error */ + +/** + * @brief Bit definition of RDES1 register + */ +#define ETH_DMARXDESC_DIC ((uint32_t)0x80000000) /*!< Disable Interrupt on Completion */ +#define ETH_DMARXDESC_RBS2 ((uint32_t)0x1FFF0000) /*!< Receive Buffer2 Size */ +#define ETH_DMARXDESC_RER ((uint32_t)0x00008000) /*!< Receive End of Ring */ +#define ETH_DMARXDESC_RCH ((uint32_t)0x00004000) /*!< Second Address Chained */ +#define ETH_DMARXDESC_RBS1 ((uint32_t)0x00001FFF) /*!< Receive Buffer1 Size */ + +/** + * @brief Bit definition of RDES2 register + */ +#define ETH_DMARXDESC_B1AP ((uint32_t)0xFFFFFFFF) /*!< Buffer1 Address Pointer */ + +/** + * @brief Bit definition of RDES3 register + */ +#define ETH_DMARXDESC_B2AP ((uint32_t)0xFFFFFFFF) /*!< Buffer2 Address Pointer */ + +/*--------------------------------------------------------------------------------------------------------------------- + RDES4 | Reserved[31:15] | Extended Status [14:0] | + --------------------------------------------------------------------------------------------------------------------- + RDES5 | Reserved[31:0] | + --------------------------------------------------------------------------------------------------------------------- + RDES6 | Receive Time Stamp Low [31:0] | + --------------------------------------------------------------------------------------------------------------------- + RDES7 | Receive Time Stamp High [31:0] | + --------------------------------------------------------------------------------------------------------------------*/ + +/* Bit definition of RDES4 register */ +#define ETH_DMAPTPRXDESC_PTPV ((uint32_t)0x00002000) /* PTP Version */ +#define ETH_DMAPTPRXDESC_PTPFT ((uint32_t)0x00001000) /* PTP Frame Type */ +#define ETH_DMAPTPRXDESC_PTPMT ((uint32_t)0x00000F00) /* PTP Message Type */ + #define ETH_DMAPTPRXDESC_PTPMT_SYNC ((uint32_t)0x00000100) /* SYNC message (all clock types) */ + #define ETH_DMAPTPRXDESC_PTPMT_FOLLOWUP ((uint32_t)0x00000200) /* FollowUp message (all clock types) */ + #define ETH_DMAPTPRXDESC_PTPMT_DELAYREQ ((uint32_t)0x00000300) /* DelayReq message (all clock types) */ + #define ETH_DMAPTPRXDESC_PTPMT_DELAYRESP ((uint32_t)0x00000400) /* DelayResp message (all clock types) */ + #define ETH_DMAPTPRXDESC_PTPMT_PDELAYREQ_ANNOUNCE ((uint32_t)0x00000500) /* PdelayReq message (peer-to-peer transparent clock) or Announce message (Ordinary or Boundary clock) */ + #define ETH_DMAPTPRXDESC_PTPMT_PDELAYRESP_MANAG ((uint32_t)0x00000600) /* PdelayResp message (peer-to-peer transparent clock) or Management message (Ordinary or Boundary clock) */ + #define ETH_DMAPTPRXDESC_PTPMT_PDELAYRESPFOLLOWUP_SIGNAL ((uint32_t)0x00000700) /* PdelayRespFollowUp message (peer-to-peer transparent clock) or Signaling message (Ordinary or Boundary clock) */ +#define ETH_DMAPTPRXDESC_IPV6PR ((uint32_t)0x00000080) /* IPv6 Packet Received */ +#define ETH_DMAPTPRXDESC_IPV4PR ((uint32_t)0x00000040) /* IPv4 Packet Received */ +#define ETH_DMAPTPRXDESC_IPCB ((uint32_t)0x00000020) /* IP Checksum Bypassed */ +#define ETH_DMAPTPRXDESC_IPPE ((uint32_t)0x00000010) /* IP Payload Error */ +#define ETH_DMAPTPRXDESC_IPHE ((uint32_t)0x00000008) /* IP Header Error */ +#define ETH_DMAPTPRXDESC_IPPT ((uint32_t)0x00000007) /* IP Payload Type */ + #define ETH_DMAPTPRXDESC_IPPT_UDP ((uint32_t)0x00000001) /* UDP payload encapsulated in the IP datagram */ + #define ETH_DMAPTPRXDESC_IPPT_TCP ((uint32_t)0x00000002) /* TCP payload encapsulated in the IP datagram */ + #define ETH_DMAPTPRXDESC_IPPT_ICMP ((uint32_t)0x00000003) /* ICMP payload encapsulated in the IP datagram */ + +/* Bit definition of RDES6 register */ +#define ETH_DMAPTPRXDESC_RTSL ((uint32_t)0xFFFFFFFF) /* Receive Time Stamp Low */ + +/* Bit definition of RDES7 register */ +#define ETH_DMAPTPRXDESC_RTSH ((uint32_t)0xFFFFFFFF) /* Receive Time Stamp High */ +/** + * @} + */ + /** @defgroup ETH_AutoNegotiation ETH AutoNegotiation + * @{ + */ +#define ETH_AUTONEGOTIATION_ENABLE ((uint32_t)0x00000001) +#define ETH_AUTONEGOTIATION_DISABLE ((uint32_t)0x00000000) + +/** + * @} + */ +/** @defgroup ETH_Speed ETH Speed + * @{ + */ +#define ETH_SPEED_10M ((uint32_t)0x00000000) +#define ETH_SPEED_100M ((uint32_t)0x00004000) + +/** + * @} + */ +/** @defgroup ETH_Duplex_Mode ETH Duplex Mode + * @{ + */ +#define ETH_MODE_FULLDUPLEX ((uint32_t)0x00000800) +#define ETH_MODE_HALFDUPLEX ((uint32_t)0x00000000) +/** + * @} + */ +/** @defgroup ETH_Rx_Mode ETH Rx Mode + * @{ + */ +#define ETH_RXPOLLING_MODE ((uint32_t)0x00000000) +#define ETH_RXINTERRUPT_MODE ((uint32_t)0x00000001) +/** + * @} + */ + +/** @defgroup ETH_Checksum_Mode ETH Checksum Mode + * @{ + */ +#define ETH_CHECKSUM_BY_HARDWARE ((uint32_t)0x00000000) +#define ETH_CHECKSUM_BY_SOFTWARE ((uint32_t)0x00000001) +/** + * @} + */ + +/** @defgroup ETH_Media_Interface ETH Media Interface + * @{ + */ +#define ETH_MEDIA_INTERFACE_MII ((uint32_t)0x00000000) +#define ETH_MEDIA_INTERFACE_RMII ((uint32_t)SYSCFG_PMC_MII_RMII_SEL) +/** + * @} + */ + +/** @defgroup ETH_Watchdog ETH Watchdog + * @{ + */ +#define ETH_WATCHDOG_ENABLE ((uint32_t)0x00000000) +#define ETH_WATCHDOG_DISABLE ((uint32_t)0x00800000) +/** + * @} + */ + +/** @defgroup ETH_Jabber ETH Jabber + * @{ + */ +#define ETH_JABBER_ENABLE ((uint32_t)0x00000000) +#define ETH_JABBER_DISABLE ((uint32_t)0x00400000) +/** + * @} + */ + +/** @defgroup ETH_Inter_Frame_Gap ETH Inter Frame Gap + * @{ + */ +#define ETH_INTERFRAMEGAP_96BIT ((uint32_t)0x00000000) /*!< minimum IFG between frames during transmission is 96Bit */ +#define ETH_INTERFRAMEGAP_88BIT ((uint32_t)0x00020000) /*!< minimum IFG between frames during transmission is 88Bit */ +#define ETH_INTERFRAMEGAP_80BIT ((uint32_t)0x00040000) /*!< minimum IFG between frames during transmission is 80Bit */ +#define ETH_INTERFRAMEGAP_72BIT ((uint32_t)0x00060000) /*!< minimum IFG between frames during transmission is 72Bit */ +#define ETH_INTERFRAMEGAP_64BIT ((uint32_t)0x00080000) /*!< minimum IFG between frames during transmission is 64Bit */ +#define ETH_INTERFRAMEGAP_56BIT ((uint32_t)0x000A0000) /*!< minimum IFG between frames during transmission is 56Bit */ +#define ETH_INTERFRAMEGAP_48BIT ((uint32_t)0x000C0000) /*!< minimum IFG between frames during transmission is 48Bit */ +#define ETH_INTERFRAMEGAP_40BIT ((uint32_t)0x000E0000) /*!< minimum IFG between frames during transmission is 40Bit */ +/** + * @} + */ + +/** @defgroup ETH_Carrier_Sense ETH Carrier Sense + * @{ + */ +#define ETH_CARRIERSENCE_ENABLE ((uint32_t)0x00000000) +#define ETH_CARRIERSENCE_DISABLE ((uint32_t)0x00010000) +/** + * @} + */ + +/** @defgroup ETH_Receive_Own ETH Receive Own + * @{ + */ +#define ETH_RECEIVEOWN_ENABLE ((uint32_t)0x00000000) +#define ETH_RECEIVEOWN_DISABLE ((uint32_t)0x00002000) +/** + * @} + */ + +/** @defgroup ETH_Loop_Back_Mode ETH Loop Back Mode + * @{ + */ +#define ETH_LOOPBACKMODE_ENABLE ((uint32_t)0x00001000) +#define ETH_LOOPBACKMODE_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Checksum_Offload ETH Checksum Offload + * @{ + */ +#define ETH_CHECKSUMOFFLAOD_ENABLE ((uint32_t)0x00000400) +#define ETH_CHECKSUMOFFLAOD_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Retry_Transmission ETH Retry Transmission + * @{ + */ +#define ETH_RETRYTRANSMISSION_ENABLE ((uint32_t)0x00000000) +#define ETH_RETRYTRANSMISSION_DISABLE ((uint32_t)0x00000200) +/** + * @} + */ + +/** @defgroup ETH_Automatic_Pad_CRC_Strip ETH Automatic Pad CRC Strip + * @{ + */ +#define ETH_AUTOMATICPADCRCSTRIP_ENABLE ((uint32_t)0x00000080) +#define ETH_AUTOMATICPADCRCSTRIP_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Back_Off_Limit ETH Back Off Limit + * @{ + */ +#define ETH_BACKOFFLIMIT_10 ((uint32_t)0x00000000) +#define ETH_BACKOFFLIMIT_8 ((uint32_t)0x00000020) +#define ETH_BACKOFFLIMIT_4 ((uint32_t)0x00000040) +#define ETH_BACKOFFLIMIT_1 ((uint32_t)0x00000060) +/** + * @} + */ + +/** @defgroup ETH_Deferral_Check ETH Deferral Check + * @{ + */ +#define ETH_DEFFERRALCHECK_ENABLE ((uint32_t)0x00000010) +#define ETH_DEFFERRALCHECK_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Receive_All ETH Receive All + * @{ + */ +#define ETH_RECEIVEALL_ENABLE ((uint32_t)0x80000000) +#define ETH_RECEIVEAll_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Source_Addr_Filter ETH Source Addr Filter + * @{ + */ +#define ETH_SOURCEADDRFILTER_NORMAL_ENABLE ((uint32_t)0x00000200) +#define ETH_SOURCEADDRFILTER_INVERSE_ENABLE ((uint32_t)0x00000300) +#define ETH_SOURCEADDRFILTER_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Pass_Control_Frames ETH Pass Control Frames + * @{ + */ +#define ETH_PASSCONTROLFRAMES_BLOCKALL ((uint32_t)0x00000040) /*!< MAC filters all control frames from reaching the application */ +#define ETH_PASSCONTROLFRAMES_FORWARDALL ((uint32_t)0x00000080) /*!< MAC forwards all control frames to application even if they fail the Address Filter */ +#define ETH_PASSCONTROLFRAMES_FORWARDPASSEDADDRFILTER ((uint32_t)0x000000C0) /*!< MAC forwards control frames that pass the Address Filter. */ +/** + * @} + */ + +/** @defgroup ETH_Broadcast_Frames_Reception ETH Broadcast Frames Reception + * @{ + */ +#define ETH_BROADCASTFRAMESRECEPTION_ENABLE ((uint32_t)0x00000000) +#define ETH_BROADCASTFRAMESRECEPTION_DISABLE ((uint32_t)0x00000020) +/** + * @} + */ + +/** @defgroup ETH_Destination_Addr_Filter ETH Destination Addr Filter + * @{ + */ +#define ETH_DESTINATIONADDRFILTER_NORMAL ((uint32_t)0x00000000) +#define ETH_DESTINATIONADDRFILTER_INVERSE ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup ETH_Promiscuous_Mode ETH Promiscuous Mode + * @{ + */ +#define ETH_PROMISCUOUS_MODE_ENABLE ((uint32_t)0x00000001) +#define ETH_PROMISCUOUS_MODE_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Multicast_Frames_Filter ETH Multicast Frames Filter + * @{ + */ +#define ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE ((uint32_t)0x00000404) +#define ETH_MULTICASTFRAMESFILTER_HASHTABLE ((uint32_t)0x00000004) +#define ETH_MULTICASTFRAMESFILTER_PERFECT ((uint32_t)0x00000000) +#define ETH_MULTICASTFRAMESFILTER_NONE ((uint32_t)0x00000010) +/** + * @} + */ + +/** @defgroup ETH_Unicast_Frames_Filter ETH Unicast Frames Filter + * @{ + */ +#define ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE ((uint32_t)0x00000402) +#define ETH_UNICASTFRAMESFILTER_HASHTABLE ((uint32_t)0x00000002) +#define ETH_UNICASTFRAMESFILTER_PERFECT ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Zero_Quanta_Pause ETH Zero Quanta Pause + * @{ + */ +#define ETH_ZEROQUANTAPAUSE_ENABLE ((uint32_t)0x00000000) +#define ETH_ZEROQUANTAPAUSE_DISABLE ((uint32_t)0x00000080) +/** + * @} + */ + +/** @defgroup ETH_Pause_Low_Threshold ETH Pause Low Threshold + * @{ + */ +#define ETH_PAUSELOWTHRESHOLD_MINUS4 ((uint32_t)0x00000000) /*!< Pause time minus 4 slot times */ +#define ETH_PAUSELOWTHRESHOLD_MINUS28 ((uint32_t)0x00000010) /*!< Pause time minus 28 slot times */ +#define ETH_PAUSELOWTHRESHOLD_MINUS144 ((uint32_t)0x00000020) /*!< Pause time minus 144 slot times */ +#define ETH_PAUSELOWTHRESHOLD_MINUS256 ((uint32_t)0x00000030) /*!< Pause time minus 256 slot times */ +/** + * @} + */ + +/** @defgroup ETH_Unicast_Pause_Frame_Detect ETH Unicast Pause Frame Detect + * @{ + */ +#define ETH_UNICASTPAUSEFRAMEDETECT_ENABLE ((uint32_t)0x00000008) +#define ETH_UNICASTPAUSEFRAMEDETECT_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Receive_Flow_Control ETH Receive Flow Control + * @{ + */ +#define ETH_RECEIVEFLOWCONTROL_ENABLE ((uint32_t)0x00000004) +#define ETH_RECEIVEFLOWCONTROL_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Transmit_Flow_Control ETH Transmit Flow Control + * @{ + */ +#define ETH_TRANSMITFLOWCONTROL_ENABLE ((uint32_t)0x00000002) +#define ETH_TRANSMITFLOWCONTROL_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_VLAN_Tag_Comparison ETH VLAN Tag Comparison + * @{ + */ +#define ETH_VLANTAGCOMPARISON_12BIT ((uint32_t)0x00010000) +#define ETH_VLANTAGCOMPARISON_16BIT ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_MAC_addresses ETH MAC addresses + * @{ + */ +#define ETH_MAC_ADDRESS0 ((uint32_t)0x00000000) +#define ETH_MAC_ADDRESS1 ((uint32_t)0x00000008) +#define ETH_MAC_ADDRESS2 ((uint32_t)0x00000010) +#define ETH_MAC_ADDRESS3 ((uint32_t)0x00000018) +/** + * @} + */ + +/** @defgroup ETH_MAC_addresses_filter_SA_DA ETH MAC addresses filter SA DA + * @{ + */ +#define ETH_MAC_ADDRESSFILTER_SA ((uint32_t)0x00000000) +#define ETH_MAC_ADDRESSFILTER_DA ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup ETH_MAC_addresses_filter_Mask_bytes ETH MAC addresses filter Mask bytes + * @{ + */ +#define ETH_MAC_ADDRESSMASK_BYTE6 ((uint32_t)0x20000000) /*!< Mask MAC Address high reg bits [15:8] */ +#define ETH_MAC_ADDRESSMASK_BYTE5 ((uint32_t)0x10000000) /*!< Mask MAC Address high reg bits [7:0] */ +#define ETH_MAC_ADDRESSMASK_BYTE4 ((uint32_t)0x08000000) /*!< Mask MAC Address low reg bits [31:24] */ +#define ETH_MAC_ADDRESSMASK_BYTE3 ((uint32_t)0x04000000) /*!< Mask MAC Address low reg bits [23:16] */ +#define ETH_MAC_ADDRESSMASK_BYTE2 ((uint32_t)0x02000000) /*!< Mask MAC Address low reg bits [15:8] */ +#define ETH_MAC_ADDRESSMASK_BYTE1 ((uint32_t)0x01000000) /*!< Mask MAC Address low reg bits [70] */ +/** + * @} + */ + +/** @defgroup ETH_MAC_Debug_flags ETH MAC Debug flags + * @{ + */ +#define ETH_MAC_TXFIFO_FULL ((uint32_t)0x02000000) /* Tx FIFO full */ +#define ETH_MAC_TXFIFONOT_EMPTY ((uint32_t)0x01000000) /* Tx FIFO not empty */ +#define ETH_MAC_TXFIFO_WRITE_ACTIVE ((uint32_t)0x00400000) /* Tx FIFO write active */ +#define ETH_MAC_TXFIFO_IDLE ((uint32_t)0x00000000) /* Tx FIFO read status: Idle */ +#define ETH_MAC_TXFIFO_READ ((uint32_t)0x00100000) /* Tx FIFO read status: Read (transferring data to the MAC transmitter) */ +#define ETH_MAC_TXFIFO_WAITING ((uint32_t)0x00200000) /* Tx FIFO read status: Waiting for TxStatus from MAC transmitter */ +#define ETH_MAC_TXFIFO_WRITING ((uint32_t)0x00300000) /* Tx FIFO read status: Writing the received TxStatus or flushing the TxFIFO */ +#define ETH_MAC_TRANSMISSION_PAUSE ((uint32_t)0x00080000) /* MAC transmitter in pause */ +#define ETH_MAC_TRANSMITFRAMECONTROLLER_IDLE ((uint32_t)0x00000000) /* MAC transmit frame controller: Idle */ +#define ETH_MAC_TRANSMITFRAMECONTROLLER_WAITING ((uint32_t)0x00020000) /* MAC transmit frame controller: Waiting for Status of previous frame or IFG/backoff period to be over */ +#define ETH_MAC_TRANSMITFRAMECONTROLLER_GENRATING_PCF ((uint32_t)0x00040000) /* MAC transmit frame controller: Generating and transmitting a Pause control frame (in full duplex mode) */ +#define ETH_MAC_TRANSMITFRAMECONTROLLER_TRANSFERRING ((uint32_t)0x00060000) /* MAC transmit frame controller: Transferring input frame for transmission */ +#define ETH_MAC_MII_TRANSMIT_ACTIVE ((uint32_t)0x00010000) /* MAC MII transmit engine active */ +#define ETH_MAC_RXFIFO_EMPTY ((uint32_t)0x00000000) /* Rx FIFO fill level: empty */ +#define ETH_MAC_RXFIFO_BELOW_THRESHOLD ((uint32_t)0x00000100) /* Rx FIFO fill level: fill-level below flow-control de-activate threshold */ +#define ETH_MAC_RXFIFO_ABOVE_THRESHOLD ((uint32_t)0x00000200) /* Rx FIFO fill level: fill-level above flow-control activate threshold */ +#define ETH_MAC_RXFIFO_FULL ((uint32_t)0x00000300) /* Rx FIFO fill level: full */ +#define ETH_MAC_READCONTROLLER_IDLE ((uint32_t)0x00000000) /* Rx FIFO read controller IDLE state */ +#define ETH_MAC_READCONTROLLER_READING_DATA ((uint32_t)0x00000020) /* Rx FIFO read controller Reading frame data */ +#define ETH_MAC_READCONTROLLER_READING_STATUS ((uint32_t)0x00000040) /* Rx FIFO read controller Reading frame status (or time-stamp) */ +#define ETH_MAC_READCONTROLLER_FLUSHING ((uint32_t)0x00000060) /* Rx FIFO read controller Flushing the frame data and status */ +#define ETH_MAC_RXFIFO_WRITE_ACTIVE ((uint32_t)0x00000010) /* Rx FIFO write controller active */ +#define ETH_MAC_SMALL_FIFO_NOTACTIVE ((uint32_t)0x00000000) /* MAC small FIFO read / write controllers not active */ +#define ETH_MAC_SMALL_FIFO_READ_ACTIVE ((uint32_t)0x00000002) /* MAC small FIFO read controller active */ +#define ETH_MAC_SMALL_FIFO_WRITE_ACTIVE ((uint32_t)0x00000004) /* MAC small FIFO write controller active */ +#define ETH_MAC_SMALL_FIFO_RW_ACTIVE ((uint32_t)0x00000006) /* MAC small FIFO read / write controllers active */ +#define ETH_MAC_MII_RECEIVE_PROTOCOL_ACTIVE ((uint32_t)0x00000001) /* MAC MII receive protocol engine active */ +/** + * @} + */ + +/** @defgroup ETH_Drop_TCP_IP_Checksum_Error_Frame ETH Drop TCP IP Checksum Error Frame + * @{ + */ +#define ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE ((uint32_t)0x00000000) +#define ETH_DROPTCPIPCHECKSUMERRORFRAME_DISABLE ((uint32_t)0x04000000) +/** + * @} + */ + +/** @defgroup ETH_Receive_Store_Forward ETH Receive Store Forward + * @{ + */ +#define ETH_RECEIVESTOREFORWARD_ENABLE ((uint32_t)0x02000000) +#define ETH_RECEIVESTOREFORWARD_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Flush_Received_Frame ETH Flush Received Frame + * @{ + */ +#define ETH_FLUSHRECEIVEDFRAME_ENABLE ((uint32_t)0x00000000) +#define ETH_FLUSHRECEIVEDFRAME_DISABLE ((uint32_t)0x01000000) +/** + * @} + */ + +/** @defgroup ETH_Transmit_Store_Forward ETH Transmit Store Forward + * @{ + */ +#define ETH_TRANSMITSTOREFORWARD_ENABLE ((uint32_t)0x00200000) +#define ETH_TRANSMITSTOREFORWARD_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Transmit_Threshold_Control ETH Transmit Threshold Control + * @{ + */ +#define ETH_TRANSMITTHRESHOLDCONTROL_64BYTES ((uint32_t)0x00000000) /*!< threshold level of the MTL Transmit FIFO is 64 Bytes */ +#define ETH_TRANSMITTHRESHOLDCONTROL_128BYTES ((uint32_t)0x00004000) /*!< threshold level of the MTL Transmit FIFO is 128 Bytes */ +#define ETH_TRANSMITTHRESHOLDCONTROL_192BYTES ((uint32_t)0x00008000) /*!< threshold level of the MTL Transmit FIFO is 192 Bytes */ +#define ETH_TRANSMITTHRESHOLDCONTROL_256BYTES ((uint32_t)0x0000C000) /*!< threshold level of the MTL Transmit FIFO is 256 Bytes */ +#define ETH_TRANSMITTHRESHOLDCONTROL_40BYTES ((uint32_t)0x00010000) /*!< threshold level of the MTL Transmit FIFO is 40 Bytes */ +#define ETH_TRANSMITTHRESHOLDCONTROL_32BYTES ((uint32_t)0x00014000) /*!< threshold level of the MTL Transmit FIFO is 32 Bytes */ +#define ETH_TRANSMITTHRESHOLDCONTROL_24BYTES ((uint32_t)0x00018000) /*!< threshold level of the MTL Transmit FIFO is 24 Bytes */ +#define ETH_TRANSMITTHRESHOLDCONTROL_16BYTES ((uint32_t)0x0001C000) /*!< threshold level of the MTL Transmit FIFO is 16 Bytes */ +/** + * @} + */ + +/** @defgroup ETH_Forward_Error_Frames ETH Forward Error Frames + * @{ + */ +#define ETH_FORWARDERRORFRAMES_ENABLE ((uint32_t)0x00000080) +#define ETH_FORWARDERRORFRAMES_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Forward_Undersized_Good_Frames ETH Forward Undersized Good Frames + * @{ + */ +#define ETH_FORWARDUNDERSIZEDGOODFRAMES_ENABLE ((uint32_t)0x00000040) +#define ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Receive_Threshold_Control ETH Receive Threshold Control + * @{ + */ +#define ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES ((uint32_t)0x00000000) /*!< threshold level of the MTL Receive FIFO is 64 Bytes */ +#define ETH_RECEIVEDTHRESHOLDCONTROL_32BYTES ((uint32_t)0x00000008) /*!< threshold level of the MTL Receive FIFO is 32 Bytes */ +#define ETH_RECEIVEDTHRESHOLDCONTROL_96BYTES ((uint32_t)0x00000010) /*!< threshold level of the MTL Receive FIFO is 96 Bytes */ +#define ETH_RECEIVEDTHRESHOLDCONTROL_128BYTES ((uint32_t)0x00000018) /*!< threshold level of the MTL Receive FIFO is 128 Bytes */ +/** + * @} + */ + +/** @defgroup ETH_Second_Frame_Operate ETH Second Frame Operate + * @{ + */ +#define ETH_SECONDFRAMEOPERARTE_ENABLE ((uint32_t)0x00000004) +#define ETH_SECONDFRAMEOPERARTE_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Address_Aligned_Beats ETH Address Aligned Beats + * @{ + */ +#define ETH_ADDRESSALIGNEDBEATS_ENABLE ((uint32_t)0x02000000) +#define ETH_ADDRESSALIGNEDBEATS_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Fixed_Burst ETH Fixed Burst + * @{ + */ +#define ETH_FIXEDBURST_ENABLE ((uint32_t)0x00010000) +#define ETH_FIXEDBURST_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_Rx_DMA_Burst_Length ETH Rx DMA Burst Length + * @{ + */ +#define ETH_RXDMABURSTLENGTH_1BEAT ((uint32_t)0x00020000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 1 */ +#define ETH_RXDMABURSTLENGTH_2BEAT ((uint32_t)0x00040000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 2 */ +#define ETH_RXDMABURSTLENGTH_4BEAT ((uint32_t)0x00080000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 4 */ +#define ETH_RXDMABURSTLENGTH_8BEAT ((uint32_t)0x00100000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 8 */ +#define ETH_RXDMABURSTLENGTH_16BEAT ((uint32_t)0x00200000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 16 */ +#define ETH_RXDMABURSTLENGTH_32BEAT ((uint32_t)0x00400000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 32 */ +#define ETH_RXDMABURSTLENGTH_4XPBL_4BEAT ((uint32_t)0x01020000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 4 */ +#define ETH_RXDMABURSTLENGTH_4XPBL_8BEAT ((uint32_t)0x01040000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 8 */ +#define ETH_RXDMABURSTLENGTH_4XPBL_16BEAT ((uint32_t)0x01080000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 16 */ +#define ETH_RXDMABURSTLENGTH_4XPBL_32BEAT ((uint32_t)0x01100000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 32 */ +#define ETH_RXDMABURSTLENGTH_4XPBL_64BEAT ((uint32_t)0x01200000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 64 */ +#define ETH_RXDMABURSTLENGTH_4XPBL_128BEAT ((uint32_t)0x01400000) /*!< maximum number of beats to be transferred in one RxDMA transaction is 128 */ +/** + * @} + */ + +/** @defgroup ETH_Tx_DMA_Burst_Length ETH Tx DMA Burst Length + * @{ + */ +#define ETH_TXDMABURSTLENGTH_1BEAT ((uint32_t)0x00000100) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 1 */ +#define ETH_TXDMABURSTLENGTH_2BEAT ((uint32_t)0x00000200) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 2 */ +#define ETH_TXDMABURSTLENGTH_4BEAT ((uint32_t)0x00000400) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */ +#define ETH_TXDMABURSTLENGTH_8BEAT ((uint32_t)0x00000800) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */ +#define ETH_TXDMABURSTLENGTH_16BEAT ((uint32_t)0x00001000) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */ +#define ETH_TXDMABURSTLENGTH_32BEAT ((uint32_t)0x00002000) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */ +#define ETH_TXDMABURSTLENGTH_4XPBL_4BEAT ((uint32_t)0x01000100) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */ +#define ETH_TXDMABURSTLENGTH_4XPBL_8BEAT ((uint32_t)0x01000200) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */ +#define ETH_TXDMABURSTLENGTH_4XPBL_16BEAT ((uint32_t)0x01000400) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */ +#define ETH_TXDMABURSTLENGTH_4XPBL_32BEAT ((uint32_t)0x01000800) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */ +#define ETH_TXDMABURSTLENGTH_4XPBL_64BEAT ((uint32_t)0x01001000) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 64 */ +#define ETH_TXDMABURSTLENGTH_4XPBL_128BEAT ((uint32_t)0x01002000) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 128 */ +/** + * @} + */ + +/** @defgroup ETH_DMA_Enhanced_descriptor_format ETH DMA Enhanced descriptor format + * @{ + */ +#define ETH_DMAENHANCEDDESCRIPTOR_ENABLE ((uint32_t)0x00000080) +#define ETH_DMAENHANCEDDESCRIPTOR_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup ETH_DMA_Arbitration ETH DMA Arbitration + * @{ + */ +#define ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1 ((uint32_t)0x00000000) +#define ETH_DMAARBITRATION_ROUNDROBIN_RXTX_2_1 ((uint32_t)0x00004000) +#define ETH_DMAARBITRATION_ROUNDROBIN_RXTX_3_1 ((uint32_t)0x00008000) +#define ETH_DMAARBITRATION_ROUNDROBIN_RXTX_4_1 ((uint32_t)0x0000C000) +#define ETH_DMAARBITRATION_RXPRIORTX ((uint32_t)0x00000002) +/** + * @} + */ + +/** @defgroup ETH_DMA_Tx_descriptor_segment ETH DMA Tx descriptor segment + * @{ + */ +#define ETH_DMATXDESC_LASTSEGMENTS ((uint32_t)0x40000000) /*!< Last Segment */ +#define ETH_DMATXDESC_FIRSTSEGMENT ((uint32_t)0x20000000) /*!< First Segment */ +/** + * @} + */ + +/** @defgroup ETH_DMA_Tx_descriptor_Checksum_Insertion_Control ETH DMA Tx descriptor Checksum Insertion Control + * @{ + */ +#define ETH_DMATXDESC_CHECKSUMBYPASS ((uint32_t)0x00000000) /*!< Checksum engine bypass */ +#define ETH_DMATXDESC_CHECKSUMIPV4HEADER ((uint32_t)0x00400000) /*!< IPv4 header checksum insertion */ +#define ETH_DMATXDESC_CHECKSUMTCPUDPICMPSEGMENT ((uint32_t)0x00800000) /*!< TCP/UDP/ICMP checksum insertion. Pseudo header checksum is assumed to be present */ +#define ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL ((uint32_t)0x00C00000) /*!< TCP/UDP/ICMP checksum fully in hardware including pseudo header */ +/** + * @} + */ + +/** @defgroup ETH_DMA_Rx_descriptor_buffers ETH DMA Rx descriptor buffers + * @{ + */ +#define ETH_DMARXDESC_BUFFER1 ((uint32_t)0x00000000) /*!< DMA Rx Desc Buffer1 */ +#define ETH_DMARXDESC_BUFFER2 ((uint32_t)0x00000001) /*!< DMA Rx Desc Buffer2 */ +/** + * @} + */ + +/** @defgroup ETH_PMT_Flags ETH PMT Flags + * @{ + */ +#define ETH_PMT_FLAG_WUFFRPR ((uint32_t)0x80000000) /*!< Wake-Up Frame Filter Register Pointer Reset */ +#define ETH_PMT_FLAG_WUFR ((uint32_t)0x00000040) /*!< Wake-Up Frame Received */ +#define ETH_PMT_FLAG_MPR ((uint32_t)0x00000020) /*!< Magic Packet Received */ +/** + * @} + */ + +/** @defgroup ETH_MMC_Tx_Interrupts ETH MMC Tx Interrupts + * @{ + */ +#define ETH_MMC_IT_TGF ((uint32_t)0x00200000) /*!< When Tx good frame counter reaches half the maximum value */ +#define ETH_MMC_IT_TGFMSC ((uint32_t)0x00008000) /*!< When Tx good multi col counter reaches half the maximum value */ +#define ETH_MMC_IT_TGFSC ((uint32_t)0x00004000) /*!< When Tx good single col counter reaches half the maximum value */ +/** + * @} + */ + +/** @defgroup ETH_MMC_Rx_Interrupts ETH MMC Rx Interrupts + * @{ + */ +#define ETH_MMC_IT_RGUF ((uint32_t)0x10020000) /*!< When Rx good unicast frames counter reaches half the maximum value */ +#define ETH_MMC_IT_RFAE ((uint32_t)0x10000040) /*!< When Rx alignment error counter reaches half the maximum value */ +#define ETH_MMC_IT_RFCE ((uint32_t)0x10000020) /*!< When Rx crc error counter reaches half the maximum value */ +/** + * @} + */ + +/** @defgroup ETH_MAC_Flags ETH MAC Flags + * @{ + */ +#define ETH_MAC_FLAG_TST ((uint32_t)0x00000200) /*!< Time stamp trigger flag (on MAC) */ +#define ETH_MAC_FLAG_MMCT ((uint32_t)0x00000040) /*!< MMC transmit flag */ +#define ETH_MAC_FLAG_MMCR ((uint32_t)0x00000020) /*!< MMC receive flag */ +#define ETH_MAC_FLAG_MMC ((uint32_t)0x00000010) /*!< MMC flag (on MAC) */ +#define ETH_MAC_FLAG_PMT ((uint32_t)0x00000008) /*!< PMT flag (on MAC) */ +/** + * @} + */ + +/** @defgroup ETH_DMA_Flags ETH DMA Flags + * @{ + */ +#define ETH_DMA_FLAG_TST ((uint32_t)0x20000000) /*!< Time-stamp trigger interrupt (on DMA) */ +#define ETH_DMA_FLAG_PMT ((uint32_t)0x10000000) /*!< PMT interrupt (on DMA) */ +#define ETH_DMA_FLAG_MMC ((uint32_t)0x08000000) /*!< MMC interrupt (on DMA) */ +#define ETH_DMA_FLAG_DATATRANSFERERROR ((uint32_t)0x00800000) /*!< Error bits 0-Rx DMA, 1-Tx DMA */ +#define ETH_DMA_FLAG_READWRITEERROR ((uint32_t)0x01000000) /*!< Error bits 0-write transfer, 1-read transfer */ +#define ETH_DMA_FLAG_ACCESSERROR ((uint32_t)0x02000000) /*!< Error bits 0-data buffer, 1-desc. access */ +#define ETH_DMA_FLAG_NIS ((uint32_t)0x00010000) /*!< Normal interrupt summary flag */ +#define ETH_DMA_FLAG_AIS ((uint32_t)0x00008000) /*!< Abnormal interrupt summary flag */ +#define ETH_DMA_FLAG_ER ((uint32_t)0x00004000) /*!< Early receive flag */ +#define ETH_DMA_FLAG_FBE ((uint32_t)0x00002000) /*!< Fatal bus error flag */ +#define ETH_DMA_FLAG_ET ((uint32_t)0x00000400) /*!< Early transmit flag */ +#define ETH_DMA_FLAG_RWT ((uint32_t)0x00000200) /*!< Receive watchdog timeout flag */ +#define ETH_DMA_FLAG_RPS ((uint32_t)0x00000100) /*!< Receive process stopped flag */ +#define ETH_DMA_FLAG_RBU ((uint32_t)0x00000080) /*!< Receive buffer unavailable flag */ +#define ETH_DMA_FLAG_R ((uint32_t)0x00000040) /*!< Receive flag */ +#define ETH_DMA_FLAG_TU ((uint32_t)0x00000020) /*!< Underflow flag */ +#define ETH_DMA_FLAG_RO ((uint32_t)0x00000010) /*!< Overflow flag */ +#define ETH_DMA_FLAG_TJT ((uint32_t)0x00000008) /*!< Transmit jabber timeout flag */ +#define ETH_DMA_FLAG_TBU ((uint32_t)0x00000004) /*!< Transmit buffer unavailable flag */ +#define ETH_DMA_FLAG_TPS ((uint32_t)0x00000002) /*!< Transmit process stopped flag */ +#define ETH_DMA_FLAG_T ((uint32_t)0x00000001) /*!< Transmit flag */ +/** + * @} + */ + +/** @defgroup ETH_MAC_Interrupts ETH MAC Interrupts + * @{ + */ +#define ETH_MAC_IT_TST ((uint32_t)0x00000200) /*!< Time stamp trigger interrupt (on MAC) */ +#define ETH_MAC_IT_MMCT ((uint32_t)0x00000040) /*!< MMC transmit interrupt */ +#define ETH_MAC_IT_MMCR ((uint32_t)0x00000020) /*!< MMC receive interrupt */ +#define ETH_MAC_IT_MMC ((uint32_t)0x00000010) /*!< MMC interrupt (on MAC) */ +#define ETH_MAC_IT_PMT ((uint32_t)0x00000008) /*!< PMT interrupt (on MAC) */ +/** + * @} + */ + +/** @defgroup ETH_DMA_Interrupts ETH DMA Interrupts + * @{ + */ +#define ETH_DMA_IT_TST ((uint32_t)0x20000000) /*!< Time-stamp trigger interrupt (on DMA) */ +#define ETH_DMA_IT_PMT ((uint32_t)0x10000000) /*!< PMT interrupt (on DMA) */ +#define ETH_DMA_IT_MMC ((uint32_t)0x08000000) /*!< MMC interrupt (on DMA) */ +#define ETH_DMA_IT_NIS ((uint32_t)0x00010000) /*!< Normal interrupt summary */ +#define ETH_DMA_IT_AIS ((uint32_t)0x00008000) /*!< Abnormal interrupt summary */ +#define ETH_DMA_IT_ER ((uint32_t)0x00004000) /*!< Early receive interrupt */ +#define ETH_DMA_IT_FBE ((uint32_t)0x00002000) /*!< Fatal bus error interrupt */ +#define ETH_DMA_IT_ET ((uint32_t)0x00000400) /*!< Early transmit interrupt */ +#define ETH_DMA_IT_RWT ((uint32_t)0x00000200) /*!< Receive watchdog timeout interrupt */ +#define ETH_DMA_IT_RPS ((uint32_t)0x00000100) /*!< Receive process stopped interrupt */ +#define ETH_DMA_IT_RBU ((uint32_t)0x00000080) /*!< Receive buffer unavailable interrupt */ +#define ETH_DMA_IT_R ((uint32_t)0x00000040) /*!< Receive interrupt */ +#define ETH_DMA_IT_TU ((uint32_t)0x00000020) /*!< Underflow interrupt */ +#define ETH_DMA_IT_RO ((uint32_t)0x00000010) /*!< Overflow interrupt */ +#define ETH_DMA_IT_TJT ((uint32_t)0x00000008) /*!< Transmit jabber timeout interrupt */ +#define ETH_DMA_IT_TBU ((uint32_t)0x00000004) /*!< Transmit buffer unavailable interrupt */ +#define ETH_DMA_IT_TPS ((uint32_t)0x00000002) /*!< Transmit process stopped interrupt */ +#define ETH_DMA_IT_T ((uint32_t)0x00000001) /*!< Transmit interrupt */ +/** + * @} + */ + +/** @defgroup ETH_DMA_transmit_process_state ETH DMA transmit process state + * @{ + */ +#define ETH_DMA_TRANSMITPROCESS_STOPPED ((uint32_t)0x00000000) /*!< Stopped - Reset or Stop Tx Command issued */ +#define ETH_DMA_TRANSMITPROCESS_FETCHING ((uint32_t)0x00100000) /*!< Running - fetching the Tx descriptor */ +#define ETH_DMA_TRANSMITPROCESS_WAITING ((uint32_t)0x00200000) /*!< Running - waiting for status */ +#define ETH_DMA_TRANSMITPROCESS_READING ((uint32_t)0x00300000) /*!< Running - reading the data from host memory */ +#define ETH_DMA_TRANSMITPROCESS_SUSPENDED ((uint32_t)0x00600000) /*!< Suspended - Tx Descriptor unavailable */ +#define ETH_DMA_TRANSMITPROCESS_CLOSING ((uint32_t)0x00700000) /*!< Running - closing Rx descriptor */ + +/** + * @} + */ + + +/** @defgroup ETH_DMA_receive_process_state ETH DMA receive process state + * @{ + */ +#define ETH_DMA_RECEIVEPROCESS_STOPPED ((uint32_t)0x00000000) /*!< Stopped - Reset or Stop Rx Command issued */ +#define ETH_DMA_RECEIVEPROCESS_FETCHING ((uint32_t)0x00020000) /*!< Running - fetching the Rx descriptor */ +#define ETH_DMA_RECEIVEPROCESS_WAITING ((uint32_t)0x00060000) /*!< Running - waiting for packet */ +#define ETH_DMA_RECEIVEPROCESS_SUSPENDED ((uint32_t)0x00080000) /*!< Suspended - Rx Descriptor unavailable */ +#define ETH_DMA_RECEIVEPROCESS_CLOSING ((uint32_t)0x000A0000) /*!< Running - closing descriptor */ +#define ETH_DMA_RECEIVEPROCESS_QUEUING ((uint32_t)0x000E0000) /*!< Running - queuing the receive frame into host memory */ + +/** + * @} + */ + +/** @defgroup ETH_DMA_overflow ETH DMA overflow + * @{ + */ +#define ETH_DMA_OVERFLOW_RXFIFOCOUNTER ((uint32_t)0x10000000) /*!< Overflow bit for FIFO overflow counter */ +#define ETH_DMA_OVERFLOW_MISSEDFRAMECOUNTER ((uint32_t)0x00010000) /*!< Overflow bit for missed frame counter */ +/** + * @} + */ + +/** @defgroup ETH_EXTI_LINE_WAKEUP ETH EXTI LINE WAKEUP + * @{ + */ +#define ETH_EXTI_LINE_WAKEUP ((uint32_t)0x00080000) /*!< External interrupt line 19 Connected to the ETH EXTI Line */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup ETH_Exported_Macros ETH Exported Macros + * @brief macros to handle interrupts and specific clock configurations + * @{ + */ + +/** @brief Reset ETH handle state + * @param __HANDLE__: specifies the ETH handle. + * @retval None + */ +#define __HAL_ETH_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_ETH_STATE_RESET) + +/** + * @brief Checks whether the specified ETHERNET DMA Tx Desc flag is set or not. + * @param __HANDLE__: ETH Handle + * @param __FLAG__: specifies the flag of TDES0 to check. + * @retval the ETH_DMATxDescFlag (SET or RESET). + */ +#define __HAL_ETH_DMATXDESC_GET_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->TxDesc->Status & (__FLAG__) == (__FLAG__)) + +/** + * @brief Checks whether the specified ETHERNET DMA Rx Desc flag is set or not. + * @param __HANDLE__: ETH Handle + * @param __FLAG__: specifies the flag of RDES0 to check. + * @retval the ETH_DMATxDescFlag (SET or RESET). + */ +#define __HAL_ETH_DMARXDESC_GET_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->RxDesc->Status & (__FLAG__) == (__FLAG__)) + +/** + * @brief Enables the specified DMA Rx Desc receive interrupt. + * @param __HANDLE__: ETH Handle + * @retval None + */ +#define __HAL_ETH_DMARXDESC_ENABLE_IT(__HANDLE__) ((__HANDLE__)->RxDesc->ControlBufferSize &=(~(uint32_t)ETH_DMARXDESC_DIC)) + +/** + * @brief Disables the specified DMA Rx Desc receive interrupt. + * @param __HANDLE__: ETH Handle + * @retval None + */ +#define __HAL_ETH_DMARXDESC_DISABLE_IT(__HANDLE__) ((__HANDLE__)->RxDesc->ControlBufferSize |= ETH_DMARXDESC_DIC) + +/** + * @brief Set the specified DMA Rx Desc Own bit. + * @param __HANDLE__: ETH Handle + * @retval None + */ +#define __HAL_ETH_DMARXDESC_SET_OWN_BIT(__HANDLE__) ((__HANDLE__)->RxDesc->Status |= ETH_DMARXDESC_OWN) + +/** + * @brief Returns the specified ETHERNET DMA Tx Desc collision count. + * @param __HANDLE__: ETH Handle + * @retval The Transmit descriptor collision counter value. + */ +#define __HAL_ETH_DMATXDESC_GET_COLLISION_COUNT(__HANDLE__) (((__HANDLE__)->TxDesc->Status & ETH_DMATXDESC_CC) >> ETH_DMATXDESC_COLLISION_COUNTSHIFT) + +/** + * @brief Set the specified DMA Tx Desc Own bit. + * @param __HANDLE__: ETH Handle + * @retval None + */ +#define __HAL_ETH_DMATXDESC_SET_OWN_BIT(__HANDLE__) ((__HANDLE__)->TxDesc->Status |= ETH_DMATXDESC_OWN) + +/** + * @brief Enables the specified DMA Tx Desc Transmit interrupt. + * @param __HANDLE__: ETH Handle + * @retval None + */ +#define __HAL_ETH_DMATXDESC_ENABLE_IT(__HANDLE__) ((__HANDLE__)->TxDesc->Status |= ETH_DMATXDESC_IC) + +/** + * @brief Disables the specified DMA Tx Desc Transmit interrupt. + * @param __HANDLE__: ETH Handle + * @retval None + */ +#define __HAL_ETH_DMATXDESC_DISABLE_IT(__HANDLE__) ((__HANDLE__)->TxDesc->Status &= ~ETH_DMATXDESC_IC) + +/** + * @brief Selects the specified ETHERNET DMA Tx Desc Checksum Insertion. + * @param __HANDLE__: ETH Handle + * @param __CHECKSUM__: specifies is the DMA Tx desc checksum insertion. + * This parameter can be one of the following values: + * @arg ETH_DMATXDESC_CHECKSUMBYPASS : Checksum bypass + * @arg ETH_DMATXDESC_CHECKSUMIPV4HEADER : IPv4 header checksum + * @arg ETH_DMATXDESC_CHECKSUMTCPUDPICMPSEGMENT : TCP/UDP/ICMP checksum. Pseudo header checksum is assumed to be present + * @arg ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL : TCP/UDP/ICMP checksum fully in hardware including pseudo header + * @retval None + */ +#define __HAL_ETH_DMATXDESC_CHECKSUM_INSERTION(__HANDLE__, __CHECKSUM__) ((__HANDLE__)->TxDesc->Status |= (__CHECKSUM__)) + +/** + * @brief Enables the DMA Tx Desc CRC. + * @param __HANDLE__: ETH Handle + * @retval None + */ +#define __HAL_ETH_DMATXDESC_CRC_ENABLE(__HANDLE__) ((__HANDLE__)->TxDesc->Status &= ~ETH_DMATXDESC_DC) + +/** + * @brief Disables the DMA Tx Desc CRC. + * @param __HANDLE__: ETH Handle + * @retval None + */ +#define __HAL_ETH_DMATXDESC_CRC_DISABLE(__HANDLE__) ((__HANDLE__)->TxDesc->Status |= ETH_DMATXDESC_DC) + +/** + * @brief Enables the DMA Tx Desc padding for frame shorter than 64 bytes. + * @param __HANDLE__: ETH Handle + * @retval None + */ +#define __HAL_ETH_DMATXDESC_SHORT_FRAME_PADDING_ENABLE(__HANDLE__) ((__HANDLE__)->TxDesc->Status &= ~ETH_DMATXDESC_DP) + +/** + * @brief Disables the DMA Tx Desc padding for frame shorter than 64 bytes. + * @param __HANDLE__: ETH Handle + * @retval None + */ +#define __HAL_ETH_DMATXDESC_SHORT_FRAME_PADDING_DISABLE(__HANDLE__) ((__HANDLE__)->TxDesc->Status |= ETH_DMATXDESC_DP) + +/** + * @brief Enables the specified ETHERNET MAC interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET MAC interrupt sources to be + * enabled or disabled. + * This parameter can be any combination of the following values: + * @arg ETH_MAC_IT_TST : Time stamp trigger interrupt + * @arg ETH_MAC_IT_PMT : PMT interrupt + * @retval None + */ +#define __HAL_ETH_MAC_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MACIMR |= (__INTERRUPT__)) + +/** + * @brief Disables the specified ETHERNET MAC interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET MAC interrupt sources to be + * enabled or disabled. + * This parameter can be any combination of the following values: + * @arg ETH_MAC_IT_TST : Time stamp trigger interrupt + * @arg ETH_MAC_IT_PMT : PMT interrupt + * @retval None + */ +#define __HAL_ETH_MAC_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MACIMR &= ~(__INTERRUPT__)) + +/** + * @brief Initiate a Pause Control Frame (Full-duplex only). + * @param __HANDLE__: ETH Handle + * @retval None + */ +#define __HAL_ETH_INITIATE_PAUSE_CONTROL_FRAME(__HANDLE__) ((__HANDLE__)->Instance->MACFCR |= ETH_MACFCR_FCBBPA) + +/** + * @brief Checks whether the ETHERNET flow control busy bit is set or not. + * @param __HANDLE__: ETH Handle + * @retval The new state of flow control busy status bit (SET or RESET). + */ +#define __HAL_ETH_GET_FLOW_CONTROL_BUSY_STATUS(__HANDLE__) (((__HANDLE__)->Instance->MACFCR & ETH_MACFCR_FCBBPA) == ETH_MACFCR_FCBBPA) + +/** + * @brief Enables the MAC Back Pressure operation activation (Half-duplex only). + * @param __HANDLE__: ETH Handle + * @retval None + */ +#define __HAL_ETH_BACK_PRESSURE_ACTIVATION_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MACFCR |= ETH_MACFCR_FCBBPA) + +/** + * @brief Disables the MAC BackPressure operation activation (Half-duplex only). + * @param __HANDLE__: ETH Handle + * @retval None + */ +#define __HAL_ETH_BACK_PRESSURE_ACTIVATION_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MACFCR &= ~ETH_MACFCR_FCBBPA) + +/** + * @brief Checks whether the specified ETHERNET MAC flag is set or not. + * @param __HANDLE__: ETH Handle + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg ETH_MAC_FLAG_TST : Time stamp trigger flag + * @arg ETH_MAC_FLAG_MMCT : MMC transmit flag + * @arg ETH_MAC_FLAG_MMCR : MMC receive flag + * @arg ETH_MAC_FLAG_MMC : MMC flag + * @arg ETH_MAC_FLAG_PMT : PMT flag + * @retval The state of ETHERNET MAC flag. + */ +#define __HAL_ETH_MAC_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->MACSR &( __FLAG__)) == ( __FLAG__)) + +/** + * @brief Enables the specified ETHERNET DMA interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be + * enabled @ref ETH_DMA_Interrupts + * @retval None + */ +#define __HAL_ETH_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMAIER |= (__INTERRUPT__)) + +/** + * @brief Disables the specified ETHERNET DMA interrupts. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the ETHERNET DMA interrupt sources to be + * disabled. @ref ETH_DMA_Interrupts + * @retval None + */ +#define __HAL_ETH_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMAIER &= ~(__INTERRUPT__)) + +/** + * @brief Clears the ETHERNET DMA IT pending bit. + * @param __HANDLE__ : ETH Handle + * @param __INTERRUPT__: specifies the interrupt pending bit to clear. @ref ETH_DMA_Interrupts + * @retval None + */ +#define __HAL_ETH_DMA_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMASR =(__INTERRUPT__)) + +/** + * @brief Checks whether the specified ETHERNET DMA flag is set or not. +* @param __HANDLE__: ETH Handle + * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Flags + * @retval The new state of ETH_DMA_FLAG (SET or RESET). + */ +#define __HAL_ETH_DMA_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->DMASR &( __FLAG__)) == ( __FLAG__)) + +/** + * @brief Checks whether the specified ETHERNET DMA flag is set or not. + * @param __HANDLE__: ETH Handle + * @param __FLAG__: specifies the flag to clear. @ref ETH_DMA_Flags + * @retval The new state of ETH_DMA_FLAG (SET or RESET). + */ +#define __HAL_ETH_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->DMASR = (__FLAG__)) + +/** + * @brief Checks whether the specified ETHERNET DMA overflow flag is set or not. + * @param __HANDLE__: ETH Handle + * @param __OVERFLOW__: specifies the DMA overflow flag to check. + * This parameter can be one of the following values: + * @arg ETH_DMA_OVERFLOW_RXFIFOCOUNTER : Overflow for FIFO Overflows Counter + * @arg ETH_DMA_OVERFLOW_MISSEDFRAMECOUNTER : Overflow for Buffer Unavailable Missed Frame Counter + * @retval The state of ETHERNET DMA overflow Flag (SET or RESET). + */ +#define __HAL_ETH_GET_DMA_OVERFLOW_STATUS(__HANDLE__, __OVERFLOW__) (((__HANDLE__)->Instance->DMAMFBOCR & (__OVERFLOW__)) == (__OVERFLOW__)) + +/** + * @brief Set the DMA Receive status watchdog timer register value + * @param __HANDLE__: ETH Handle + * @param __VALUE__: DMA Receive status watchdog timer register value + * @retval None + */ +#define __HAL_ETH_SET_RECEIVE_WATCHDOG_TIMER(__HANDLE__, __VALUE__) ((__HANDLE__)->Instance->DMARSWTR = (__VALUE__)) + +/** + * @brief Enables any unicast packet filtered by the MAC address + * recognition to be a wake-up frame. + * @param __HANDLE__: ETH Handle. + * @retval None + */ +#define __HAL_ETH_GLOBAL_UNICAST_WAKEUP_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR |= ETH_MACPMTCSR_GU) + +/** + * @brief Disables any unicast packet filtered by the MAC address + * recognition to be a wake-up frame. + * @param __HANDLE__: ETH Handle. + * @retval None + */ +#define __HAL_ETH_GLOBAL_UNICAST_WAKEUP_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR &= ~ETH_MACPMTCSR_GU) + +/** + * @brief Enables the MAC Wake-Up Frame Detection. + * @param __HANDLE__: ETH Handle. + * @retval None + */ +#define __HAL_ETH_WAKEUP_FRAME_DETECTION_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR |= ETH_MACPMTCSR_WFE) + +/** + * @brief Disables the MAC Wake-Up Frame Detection. + * @param __HANDLE__: ETH Handle. + * @retval None + */ +#define __HAL_ETH_WAKEUP_FRAME_DETECTION_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR &= ~ETH_MACPMTCSR_WFE) + +/** + * @brief Enables the MAC Magic Packet Detection. + * @param __HANDLE__: ETH Handle. + * @retval None + */ +#define __HAL_ETH_MAGIC_PACKET_DETECTION_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR |= ETH_MACPMTCSR_MPE) + +/** + * @brief Disables the MAC Magic Packet Detection. + * @param __HANDLE__: ETH Handle. + * @retval None + */ +#define __HAL_ETH_MAGIC_PACKET_DETECTION_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR &= ~ETH_MACPMTCSR_WFE) + +/** + * @brief Enables the MAC Power Down. + * @param __HANDLE__: ETH Handle + * @retval None + */ +#define __HAL_ETH_POWER_DOWN_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR |= ETH_MACPMTCSR_PD) + +/** + * @brief Disables the MAC Power Down. + * @param __HANDLE__: ETH Handle + * @retval None + */ +#define __HAL_ETH_POWER_DOWN_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR &= ~ETH_MACPMTCSR_PD) + +/** + * @brief Checks whether the specified ETHERNET PMT flag is set or not. + * @param __HANDLE__: ETH Handle. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg ETH_PMT_FLAG_WUFFRPR : Wake-Up Frame Filter Register Pointer Reset + * @arg ETH_PMT_FLAG_WUFR : Wake-Up Frame Received + * @arg ETH_PMT_FLAG_MPR : Magic Packet Received + * @retval The new state of ETHERNET PMT Flag (SET or RESET). + */ +#define __HAL_ETH_GET_PMT_FLAG_STATUS(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->MACPMTCSR &( __FLAG__)) == ( __FLAG__)) + +/** + * @brief Preset and Initialize the MMC counters to almost-full value: 0xFFFF_FFF0 (full - 16) + * @param __HANDLE__: ETH Handle. + * @retval None + */ +#define __HAL_ETH_MMC_COUNTER_FULL_PRESET(__HANDLE__) ((__HANDLE__)->Instance->MMCCR |= (ETH_MMCCR_MCFHP | ETH_MMCCR_MCP)) + +/** + * @brief Preset and Initialize the MMC counters to almost-half value: 0x7FFF_FFF0 (half - 16) + * @param __HANDLE__: ETH Handle. + * @retval None + */ +#define __HAL_ETH_MMC_COUNTER_HALF_PRESET(__HANDLE__) do{(__HANDLE__)->Instance->MMCCR &= ~ETH_MMCCR_MCFHP;\ + (__HANDLE__)->Instance->MMCCR |= ETH_MMCCR_MCP;} while (0) + +/** + * @brief Enables the MMC Counter Freeze. + * @param __HANDLE__: ETH Handle. + * @retval None + */ +#define __HAL_ETH_MMC_COUNTER_FREEZE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR |= ETH_MMCCR_MCF) + +/** + * @brief Disables the MMC Counter Freeze. + * @param __HANDLE__: ETH Handle. + * @retval None + */ +#define __HAL_ETH_MMC_COUNTER_FREEZE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR &= ~ETH_MMCCR_MCF) + +/** + * @brief Enables the MMC Reset On Read. + * @param __HANDLE__: ETH Handle. + * @retval None + */ +#define __HAL_ETH_ETH_MMC_RESET_ONREAD_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR |= ETH_MMCCR_ROR) + +/** + * @brief Disables the MMC Reset On Read. + * @param __HANDLE__: ETH Handle. + * @retval None + */ +#define __HAL_ETH_ETH_MMC_RESET_ONREAD_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR &= ~ETH_MMCCR_ROR) + +/** + * @brief Enables the MMC Counter Stop Rollover. + * @param __HANDLE__: ETH Handle. + * @retval None + */ +#define __HAL_ETH_ETH_MMC_COUNTER_ROLLOVER_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR &= ~ETH_MMCCR_CSR) + +/** + * @brief Disables the MMC Counter Stop Rollover. + * @param __HANDLE__: ETH Handle. + * @retval None + */ +#define __HAL_ETH_ETH_MMC_COUNTER_ROLLOVER_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR |= ETH_MMCCR_CSR) + +/** + * @brief Resets the MMC Counters. + * @param __HANDLE__: ETH Handle. + * @retval None + */ +#define __HAL_ETH_MMC_COUNTERS_RESET(__HANDLE__) ((__HANDLE__)->Instance->MMCCR |= ETH_MMCCR_CR) + +/** + * @brief Enables the specified ETHERNET MMC Rx interrupts. + * @param __HANDLE__: ETH Handle. + * @param __INTERRUPT__: specifies the ETHERNET MMC interrupt sources to be enabled or disabled. + * This parameter can be one of the following values: + * @arg ETH_MMC_IT_RGUF : When Rx good unicast frames counter reaches half the maximum value + * @arg ETH_MMC_IT_RFAE : When Rx alignment error counter reaches half the maximum value + * @arg ETH_MMC_IT_RFCE : When Rx crc error counter reaches half the maximum value + * @retval None + */ +#define __HAL_ETH_MMC_RX_IT_ENABLE(__HANDLE__, __INTERRUPT__) (__HANDLE__)->Instance->MMCRIMR &= ~((__INTERRUPT__) & 0xEFFFFFFF) +/** + * @brief Disables the specified ETHERNET MMC Rx interrupts. + * @param __HANDLE__: ETH Handle. + * @param __INTERRUPT__: specifies the ETHERNET MMC interrupt sources to be enabled or disabled. + * This parameter can be one of the following values: + * @arg ETH_MMC_IT_RGUF : When Rx good unicast frames counter reaches half the maximum value + * @arg ETH_MMC_IT_RFAE : When Rx alignment error counter reaches half the maximum value + * @arg ETH_MMC_IT_RFCE : When Rx crc error counter reaches half the maximum value + * @retval None + */ +#define __HAL_ETH_MMC_RX_IT_DISABLE(__HANDLE__, __INTERRUPT__) (__HANDLE__)->Instance->MMCRIMR |= ((__INTERRUPT__) & 0xEFFFFFFF) +/** + * @brief Enables the specified ETHERNET MMC Tx interrupts. + * @param __HANDLE__: ETH Handle. + * @param __INTERRUPT__: specifies the ETHERNET MMC interrupt sources to be enabled or disabled. + * This parameter can be one of the following values: + * @arg ETH_MMC_IT_TGF : When Tx good frame counter reaches half the maximum value + * @arg ETH_MMC_IT_TGFMSC: When Tx good multi col counter reaches half the maximum value + * @arg ETH_MMC_IT_TGFSC : When Tx good single col counter reaches half the maximum value + * @retval None + */ +#define __HAL_ETH_MMC_TX_IT_ENABLE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MMCRIMR &= ~ (__INTERRUPT__)) + +/** + * @brief Disables the specified ETHERNET MMC Tx interrupts. + * @param __HANDLE__: ETH Handle. + * @param __INTERRUPT__: specifies the ETHERNET MMC interrupt sources to be enabled or disabled. + * This parameter can be one of the following values: + * @arg ETH_MMC_IT_TGF : When Tx good frame counter reaches half the maximum value + * @arg ETH_MMC_IT_TGFMSC: When Tx good multi col counter reaches half the maximum value + * @arg ETH_MMC_IT_TGFSC : When Tx good single col counter reaches half the maximum value + * @retval None + */ +#define __HAL_ETH_MMC_TX_IT_DISABLE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MMCRIMR |= (__INTERRUPT__)) + +/** + * @brief Enables the ETH External interrupt line. + * @retval None + */ +#define __HAL_ETH_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= (ETH_EXTI_LINE_WAKEUP) + +/** + * @brief Disables the ETH External interrupt line. + * @retval None + */ +#define __HAL_ETH_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(ETH_EXTI_LINE_WAKEUP) + +/** + * @brief Enable event on ETH External event line. + * @retval None. + */ +#define __HAL_ETH_WAKEUP_EXTI_ENABLE_EVENT() EXTI->EMR |= (ETH_EXTI_LINE_WAKEUP) + +/** + * @brief Disable event on ETH External event line + * @retval None. + */ +#define __HAL_ETH_WAKEUP_EXTI_DISABLE_EVENT() EXTI->EMR &= ~(ETH_EXTI_LINE_WAKEUP) + +/** + * @brief Get flag of the ETH External interrupt line. + * @retval None + */ +#define __HAL_ETH_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (ETH_EXTI_LINE_WAKEUP) + +/** + * @brief Clear flag of the ETH External interrupt line. + * @retval None + */ +#define __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = (ETH_EXTI_LINE_WAKEUP) + +/** + * @brief Enables rising edge trigger to the ETH External interrupt line. + * @retval None + */ +#define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE_TRIGGER() EXTI->RTSR |= ETH_EXTI_LINE_WAKEUP + +/** + * @brief Disables the rising edge trigger to the ETH External interrupt line. + * @retval None + */ +#define __HAL_ETH_WAKEUP_EXTI_DISABLE_RISING_EDGE_TRIGGER() EXTI->RTSR &= ~(ETH_EXTI_LINE_WAKEUP) + +/** + * @brief Enables falling edge trigger to the ETH External interrupt line. + * @retval None + */ +#define __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE_TRIGGER() EXTI->FTSR |= (ETH_EXTI_LINE_WAKEUP) + +/** + * @brief Disables falling edge trigger to the ETH External interrupt line. + * @retval None + */ +#define __HAL_ETH_WAKEUP_EXTI_DISABLE_FALLING_EDGE_TRIGGER() EXTI->FTSR &= ~(ETH_EXTI_LINE_WAKEUP) + +/** + * @brief Enables rising/falling edge trigger to the ETH External interrupt line. + * @retval None + */ +#define __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLINGRISING_TRIGGER() EXTI->RTSR |= ETH_EXTI_LINE_WAKEUP;\ + EXTI->FTSR |= ETH_EXTI_LINE_WAKEUP + +/** + * @brief Disables rising/falling edge trigger to the ETH External interrupt line. + * @retval None + */ +#define __HAL_ETH_WAKEUP_EXTI_DISABLE_FALLINGRISING_TRIGGER() EXTI->RTSR &= ~(ETH_EXTI_LINE_WAKEUP);\ + EXTI->FTSR &= ~(ETH_EXTI_LINE_WAKEUP) + +/** + * @brief Generate a Software interrupt on selected EXTI line. + * @retval None. + */ +#define __HAL_ETH_WAKEUP_EXTI_GENERATE_SWIT() EXTI->SWIER|= ETH_EXTI_LINE_WAKEUP + +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup ETH_Exported_Functions + * @{ + */ + +/* Initialization and de-initialization functions ****************************/ + +/** @addtogroup ETH_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth); +HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth); +void HAL_ETH_MspInit(ETH_HandleTypeDef *heth); +void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth); +HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMATxDescTab, uint8_t* TxBuff, uint32_t TxBuffCount); +HAL_StatusTypeDef HAL_ETH_DMARxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount); + +/** + * @} + */ +/* IO operation functions ****************************************************/ + +/** @addtogroup ETH_Exported_Functions_Group2 + * @{ + */ +HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength); +HAL_StatusTypeDef HAL_ETH_GetReceivedFrame(ETH_HandleTypeDef *heth); +/* Communication with PHY functions*/ +HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t *RegValue); +HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef *heth); +void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth); +/* Callback in non blocking modes (Interrupt) */ +void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth); +void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth); +void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth); +/** + * @} + */ + +/* Peripheral Control functions **********************************************/ + +/** @addtogroup ETH_Exported_Functions_Group3 + * @{ + */ + +HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth); +HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth); +HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef *macconf); +HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef *dmaconf); +/** + * @} + */ + +/* Peripheral State functions ************************************************/ + +/** @addtogroup ETH_Exported_Functions_Group4 + * @{ + */ +HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_ETH_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h new file mode 100644 index 0000000..1060645 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h @@ -0,0 +1,442 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_flash.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of FLASH HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_FLASH_H +#define __STM32F4xx_HAL_FLASH_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup FLASH + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup FLASH_Exported_Types FLASH Exported Types + * @{ + */ + +/** + * @brief FLASH Procedure structure definition + */ +typedef enum +{ + FLASH_PROC_NONE = 0, + FLASH_PROC_SECTERASE, + FLASH_PROC_MASSERASE, + FLASH_PROC_PROGRAM +} FLASH_ProcedureTypeDef; + +/** + * @brief FLASH handle Structure definition + */ +typedef struct +{ + __IO FLASH_ProcedureTypeDef ProcedureOnGoing; /*Internal variable to indicate which procedure is ongoing or not in IT context*/ + + __IO uint32_t NbSectorsToErase; /*Internal variable to save the remaining sectors to erase in IT context*/ + + __IO uint8_t VoltageForErase; /*Internal variable to provide voltage range selected by user in IT context*/ + + __IO uint32_t Sector; /*Internal variable to define the current sector which is erasing*/ + + __IO uint32_t Bank; /*Internal variable to save current bank selected during mass erase*/ + + __IO uint32_t Address; /*Internal variable to save address selected for program*/ + + HAL_LockTypeDef Lock; /* FLASH locking object */ + + __IO uint32_t ErrorCode; /* FLASH error code */ + +}FLASH_ProcessTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup FLASH_Exported_Constants FLASH Exported Constants + * @{ + */ +/** @defgroup FLASH_Error_Code FLASH Error Code + * @brief FLASH Error Code + * @{ + */ +#define HAL_FLASH_ERROR_NONE ((uint32_t)0x00000000) /*!< No error */ +#define HAL_FLASH_ERROR_RD ((uint32_t)0x00000001) /*!< Read Protection error */ +#define HAL_FLASH_ERROR_PGS ((uint32_t)0x00000002) /*!< Programming Sequence error */ +#define HAL_FLASH_ERROR_PGP ((uint32_t)0x00000004) /*!< Programming Parallelism error */ +#define HAL_FLASH_ERROR_PGA ((uint32_t)0x00000008) /*!< Programming Alignment error */ +#define HAL_FLASH_ERROR_WRP ((uint32_t)0x00000010) /*!< Write protection error */ +#define HAL_FLASH_ERROR_OPERATION ((uint32_t)0x00000020) /*!< Operation Error */ +/** + * @} + */ + +/** @defgroup FLASH_Type_Program FLASH Type Program + * @{ + */ +#define FLASH_TYPEPROGRAM_BYTE ((uint32_t)0x00) /*!< Program byte (8-bit) at a specified address */ +#define FLASH_TYPEPROGRAM_HALFWORD ((uint32_t)0x01) /*!< Program a half-word (16-bit) at a specified address */ +#define FLASH_TYPEPROGRAM_WORD ((uint32_t)0x02) /*!< Program a word (32-bit) at a specified address */ +#define FLASH_TYPEPROGRAM_DOUBLEWORD ((uint32_t)0x03) /*!< Program a double word (64-bit) at a specified address */ +/** + * @} + */ + +/** @defgroup FLASH_Flag_definition FLASH Flag definition + * @brief Flag definition + * @{ + */ +#define FLASH_FLAG_EOP FLASH_SR_EOP /*!< FLASH End of Operation flag */ +#define FLASH_FLAG_OPERR FLASH_SR_SOP /*!< FLASH operation Error flag */ +#define FLASH_FLAG_WRPERR FLASH_SR_WRPERR /*!< FLASH Write protected error flag */ +#define FLASH_FLAG_PGAERR FLASH_SR_PGAERR /*!< FLASH Programming Alignment error flag */ +#define FLASH_FLAG_PGPERR FLASH_SR_PGPERR /*!< FLASH Programming Parallelism error flag */ +#define FLASH_FLAG_PGSERR FLASH_SR_PGSERR /*!< FLASH Programming Sequence error flag */ +#define FLASH_FLAG_RDERR ((uint32_t)0x00000100) /*!< Read Protection error flag (PCROP) */ +#define FLASH_FLAG_BSY FLASH_SR_BSY /*!< FLASH Busy flag */ +/** + * @} + */ + +/** @defgroup FLASH_Interrupt_definition FLASH Interrupt definition + * @brief FLASH Interrupt definition + * @{ + */ +#define FLASH_IT_EOP FLASH_CR_EOPIE /*!< End of FLASH Operation Interrupt source */ +#define FLASH_IT_ERR ((uint32_t)0x02000000) /*!< Error Interrupt source */ +/** + * @} + */ + +/** @defgroup FLASH_Program_Parallelism FLASH Program Parallelism + * @{ + */ +#define FLASH_PSIZE_BYTE ((uint32_t)0x00000000) +#define FLASH_PSIZE_HALF_WORD ((uint32_t)0x00000100) +#define FLASH_PSIZE_WORD ((uint32_t)0x00000200) +#define FLASH_PSIZE_DOUBLE_WORD ((uint32_t)0x00000300) +#define CR_PSIZE_MASK ((uint32_t)0xFFFFFCFF) +/** + * @} + */ + +/** @defgroup FLASH_Keys FLASH Keys + * @{ + */ +#define RDP_KEY ((uint16_t)0x00A5) +#define FLASH_KEY1 ((uint32_t)0x45670123) +#define FLASH_KEY2 ((uint32_t)0xCDEF89AB) +#define FLASH_OPT_KEY1 ((uint32_t)0x08192A3B) +#define FLASH_OPT_KEY2 ((uint32_t)0x4C5D6E7F) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup FLASH_Exported_Macros FLASH Exported Macros + * @{ + */ +/** + * @brief Set the FLASH Latency. + * @param __LATENCY__: FLASH Latency + * The value of this parameter depend on device used within the same series + * @retval none + */ +#define __HAL_FLASH_SET_LATENCY(__LATENCY__) (*(__IO uint8_t *)ACR_BYTE0_ADDRESS = (uint8_t)(__LATENCY__)) + +/** + * @brief Get the FLASH Latency. + * @retval FLASH Latency + * The value of this parameter depend on device used within the same series + */ +#define __HAL_FLASH_GET_LATENCY() (READ_BIT((FLASH->ACR), FLASH_ACR_LATENCY)) + +/** + * @brief Enable the FLASH prefetch buffer. + * @retval none + */ +#define __HAL_FLASH_PREFETCH_BUFFER_ENABLE() (FLASH->ACR |= FLASH_ACR_PRFTEN) + +/** + * @brief Disable the FLASH prefetch buffer. + * @retval none + */ +#define __HAL_FLASH_PREFETCH_BUFFER_DISABLE() (FLASH->ACR &= (~FLASH_ACR_PRFTEN)) + +/** + * @brief Enable the FLASH instruction cache. + * @retval none + */ +#define __HAL_FLASH_INSTRUCTION_CACHE_ENABLE() (FLASH->ACR |= FLASH_ACR_ICEN) + +/** + * @brief Disable the FLASH instruction cache. + * @retval none + */ +#define __HAL_FLASH_INSTRUCTION_CACHE_DISABLE() (FLASH->ACR &= (~FLASH_ACR_ICEN)) + +/** + * @brief Enable the FLASH data cache. + * @retval none + */ +#define __HAL_FLASH_DATA_CACHE_ENABLE() (FLASH->ACR |= FLASH_ACR_DCEN) + +/** + * @brief Disable the FLASH data cache. + * @retval none + */ +#define __HAL_FLASH_DATA_CACHE_DISABLE() (FLASH->ACR &= (~FLASH_ACR_DCEN)) + +/** + * @brief Resets the FLASH instruction Cache. + * @note This function must be used only when the Instruction Cache is disabled. + * @retval None + */ +#define __HAL_FLASH_INSTRUCTION_CACHE_RESET() do {FLASH->ACR |= FLASH_ACR_ICRST; \ + FLASH->ACR &= ~FLASH_ACR_ICRST; \ + }while(0) + +/** + * @brief Resets the FLASH data Cache. + * @note This function must be used only when the data Cache is disabled. + * @retval None + */ +#define __HAL_FLASH_DATA_CACHE_RESET() do {FLASH->ACR |= FLASH_ACR_DCRST; \ + FLASH->ACR &= ~FLASH_ACR_DCRST; \ + }while(0) +/** + * @brief Enable the specified FLASH interrupt. + * @param __INTERRUPT__ : FLASH interrupt + * This parameter can be any combination of the following values: + * @arg FLASH_IT_EOP: End of FLASH Operation Interrupt + * @arg FLASH_IT_ERR: Error Interrupt + * @retval none + */ +#define __HAL_FLASH_ENABLE_IT(__INTERRUPT__) (FLASH->CR |= (__INTERRUPT__)) + +/** + * @brief Disable the specified FLASH interrupt. + * @param __INTERRUPT__ : FLASH interrupt + * This parameter can be any combination of the following values: + * @arg FLASH_IT_EOP: End of FLASH Operation Interrupt + * @arg FLASH_IT_ERR: Error Interrupt + * @retval none + */ +#define __HAL_FLASH_DISABLE_IT(__INTERRUPT__) (FLASH->CR &= ~(uint32_t)(__INTERRUPT__)) + +/** + * @brief Get the specified FLASH flag status. + * @param __FLAG__: specifies the FLASH flag to check. + * This parameter can be one of the following values: + * @arg FLASH_FLAG_EOP : FLASH End of Operation flag + * @arg FLASH_FLAG_OPERR : FLASH operation Error flag + * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag + * @arg FLASH_FLAG_PGAERR: FLASH Programming Alignment error flag + * @arg FLASH_FLAG_PGPERR: FLASH Programming Parallelism error flag + * @arg FLASH_FLAG_PGSERR: FLASH Programming Sequence error flag + * @arg FLASH_FLAG_RDERR : FLASH Read Protection error flag (PCROP) + * @arg FLASH_FLAG_BSY : FLASH Busy flag + * @retval The new state of __FLAG__ (SET or RESET). + */ +#define __HAL_FLASH_GET_FLAG(__FLAG__) ((FLASH->SR & (__FLAG__))) + +/** + * @brief Clear the specified FLASH flag. + * @param __FLAG__: specifies the FLASH flags to clear. + * This parameter can be any combination of the following values: + * @arg FLASH_FLAG_EOP : FLASH End of Operation flag + * @arg FLASH_FLAG_OPERR : FLASH operation Error flag + * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag + * @arg FLASH_FLAG_PGAERR: FLASH Programming Alignment error flag + * @arg FLASH_FLAG_PGPERR: FLASH Programming Parallelism error flag + * @arg FLASH_FLAG_PGSERR: FLASH Programming Sequence error flag + * @arg FLASH_FLAG_RDERR : FLASH Read Protection error flag (PCROP) + * @retval none + */ +#define __HAL_FLASH_CLEAR_FLAG(__FLAG__) (FLASH->SR = (__FLAG__)) +/** + * @} + */ + +/* Include FLASH HAL Extension module */ +#include "stm32f4xx_hal_flash_ex.h" +#include "stm32f4xx_hal_flash_ramfunc.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup FLASH_Exported_Functions + * @{ + */ +/** @addtogroup FLASH_Exported_Functions_Group1 + * @{ + */ +/* Program operation functions ***********************************************/ +HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data); +HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data); +/* FLASH IRQ handler method */ +void HAL_FLASH_IRQHandler(void); +/* Callbacks in non blocking modes */ +void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue); +void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue); +/** + * @} + */ + +/** @addtogroup FLASH_Exported_Functions_Group2 + * @{ + */ +/* Peripheral Control functions **********************************************/ +HAL_StatusTypeDef HAL_FLASH_Unlock(void); +HAL_StatusTypeDef HAL_FLASH_Lock(void); +HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void); +HAL_StatusTypeDef HAL_FLASH_OB_Lock(void); +/* Option bytes control */ +HAL_StatusTypeDef HAL_FLASH_OB_Launch(void); +/** + * @} + */ + +/** @addtogroup FLASH_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State functions ************************************************/ +uint32_t HAL_FLASH_GetError(void); +HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @defgroup FLASH_Private_Variables FLASH Private Variables + * @{ + */ + +/** + * @} + */ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup FLASH_Private_Constants FLASH Private Constants + * @{ + */ + +/** + * @brief ACR register byte 0 (Bits[7:0]) base address + */ +#define ACR_BYTE0_ADDRESS ((uint32_t)0x40023C00) +/** + * @brief OPTCR register byte 0 (Bits[7:0]) base address + */ +#define OPTCR_BYTE0_ADDRESS ((uint32_t)0x40023C14) +/** + * @brief OPTCR register byte 1 (Bits[15:8]) base address + */ +#define OPTCR_BYTE1_ADDRESS ((uint32_t)0x40023C15) +/** + * @brief OPTCR register byte 2 (Bits[23:16]) base address + */ +#define OPTCR_BYTE2_ADDRESS ((uint32_t)0x40023C16) +/** + * @brief OPTCR register byte 3 (Bits[31:24]) base address + */ +#define OPTCR_BYTE3_ADDRESS ((uint32_t)0x40023C17) + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup FLASH_Private_Macros FLASH Private Macros + * @{ + */ + +/** @defgroup FLASH_IS_FLASH_Definitions FLASH Private macros to check input parameters + * @{ + */ +#define IS_FLASH_TYPEPROGRAM(VALUE)(((VALUE) == FLASH_TYPEPROGRAM_BYTE) || \ + ((VALUE) == FLASH_TYPEPROGRAM_HALFWORD) || \ + ((VALUE) == FLASH_TYPEPROGRAM_WORD) || \ + ((VALUE) == FLASH_TYPEPROGRAM_DOUBLEWORD)) +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup FLASH_Private_Functions FLASH Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_FLASH_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h new file mode 100644 index 0000000..a917577 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ex.h @@ -0,0 +1,866 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_flash_ex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of FLASH HAL Extension module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_FLASH_EX_H +#define __STM32F4xx_HAL_FLASH_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup FLASHEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup FLASHEx_Exported_Types FLASH Exported Types + * @{ + */ + +/** + * @brief FLASH Erase structure definition + */ +typedef struct +{ + uint32_t TypeErase; /*!< Mass erase or sector Erase. + This parameter can be a value of @ref FLASHEx_Type_Erase */ + + uint32_t Banks; /*!< Select banks to erase when Mass erase is enabled. + This parameter must be a value of @ref FLASHEx_Banks */ + + uint32_t Sector; /*!< Initial FLASH sector to erase when Mass erase is disabled + This parameter must be a value of @ref FLASHEx_Sectors */ + + uint32_t NbSectors; /*!< Number of sectors to be erased. + This parameter must be a value between 1 and (max number of sectors - value of Initial sector)*/ + + uint32_t VoltageRange;/*!< The device voltage range which defines the erase parallelism + This parameter must be a value of @ref FLASHEx_Voltage_Range */ + +} FLASH_EraseInitTypeDef; + +/** + * @brief FLASH Option Bytes Program structure definition + */ +typedef struct +{ + uint32_t OptionType; /*!< Option byte to be configured. + This parameter can be a value of @ref FLASHEx_Option_Type */ + + uint32_t WRPState; /*!< Write protection activation or deactivation. + This parameter can be a value of @ref FLASHEx_WRP_State */ + + uint32_t WRPSector; /*!< Specifies the sector(s) to be write protected. + The value of this parameter depend on device used within the same series */ + + uint32_t Banks; /*!< Select banks for WRP activation/deactivation of all sectors. + This parameter must be a value of @ref FLASHEx_Banks */ + + uint32_t RDPLevel; /*!< Set the read protection level. + This parameter can be a value of @ref FLASHEx_Option_Bytes_Read_Protection */ + + uint32_t BORLevel; /*!< Set the BOR Level. + This parameter can be a value of @ref FLASHEx_BOR_Reset_Level */ + + uint8_t USERConfig; /*!< Program the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY. */ + +} FLASH_OBProgramInitTypeDef; + +/** + * @brief FLASH Advanced Option Bytes Program structure definition + */ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) +typedef struct +{ + uint32_t OptionType; /*!< Option byte to be configured for extension. + This parameter can be a value of @ref FLASHEx_Advanced_Option_Type */ + + uint32_t PCROPState; /*!< PCROP activation or deactivation. + This parameter can be a value of @ref FLASHEx_PCROP_State */ + +#if defined (STM32F401xC) || defined (STM32F401xE) || defined (STM32F411xE) || defined (STM32F446xx) + uint16_t Sectors; /*!< specifies the sector(s) set for PCROP. + This parameter can be a value of @ref FLASHEx_Option_Bytes_PC_ReadWrite_Protection */ +#endif /* STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + uint32_t Banks; /*!< Select banks for PCROP activation/deactivation of all sectors. + This parameter must be a value of @ref FLASHEx_Banks */ + + uint16_t SectorsBank1; /*!< Specifies the sector(s) set for PCROP for Bank1. + This parameter can be a value of @ref FLASHEx_Option_Bytes_PC_ReadWrite_Protection */ + + uint16_t SectorsBank2; /*!< Specifies the sector(s) set for PCROP for Bank2. + This parameter can be a value of @ref FLASHEx_Option_Bytes_PC_ReadWrite_Protection */ + + uint8_t BootConfig; /*!< Specifies Option bytes for boot config. + This parameter can be a value of @ref FLASHEx_Dual_Boot */ + +#endif /*STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +} FLASH_AdvOBProgramInitTypeDef; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup FLASHEx_Exported_Constants FLASH Exported Constants + * @{ + */ + +/** @defgroup FLASHEx_Type_Erase FLASH Type Erase + * @{ + */ +#define FLASH_TYPEERASE_SECTORS ((uint32_t)0x00) /*!< Sectors erase only */ +#define FLASH_TYPEERASE_MASSERASE ((uint32_t)0x01) /*!< Flash Mass erase activation */ +/** + * @} + */ + +/** @defgroup FLASHEx_Voltage_Range FLASH Voltage Range + * @{ + */ +#define FLASH_VOLTAGE_RANGE_1 ((uint32_t)0x00) /*!< Device operating range: 1.8V to 2.1V */ +#define FLASH_VOLTAGE_RANGE_2 ((uint32_t)0x01) /*!< Device operating range: 2.1V to 2.7V */ +#define FLASH_VOLTAGE_RANGE_3 ((uint32_t)0x02) /*!< Device operating range: 2.7V to 3.6V */ +#define FLASH_VOLTAGE_RANGE_4 ((uint32_t)0x03) /*!< Device operating range: 2.7V to 3.6V + External Vpp */ +/** + * @} + */ + +/** @defgroup FLASHEx_WRP_State FLASH WRP State + * @{ + */ +#define OB_WRPSTATE_DISABLE ((uint32_t)0x00) /*!< Disable the write protection of the desired bank 1 sectors */ +#define OB_WRPSTATE_ENABLE ((uint32_t)0x01) /*!< Enable the write protection of the desired bank 1 sectors */ +/** + * @} + */ + +/** @defgroup FLASHEx_Option_Type FLASH Option Type + * @{ + */ +#define OPTIONBYTE_WRP ((uint32_t)0x01) /*!< WRP option byte configuration */ +#define OPTIONBYTE_RDP ((uint32_t)0x02) /*!< RDP option byte configuration */ +#define OPTIONBYTE_USER ((uint32_t)0x04) /*!< USER option byte configuration */ +#define OPTIONBYTE_BOR ((uint32_t)0x08) /*!< BOR option byte configuration */ +/** + * @} + */ + +/** @defgroup FLASHEx_Option_Bytes_Read_Protection FLASH Option Bytes Read Protection + * @{ + */ +#define OB_RDP_LEVEL_0 ((uint8_t)0xAA) +#define OB_RDP_LEVEL_1 ((uint8_t)0x55) +#define OB_RDP_LEVEL_2 ((uint8_t)0xCC) /*!< Warning: When enabling read protection level 2 + it s no more possible to go back to level 1 or 0 */ +/** + * @} + */ + +/** @defgroup FLASHEx_Option_Bytes_IWatchdog FLASH Option Bytes IWatchdog + * @{ + */ +#define OB_IWDG_SW ((uint8_t)0x20) /*!< Software IWDG selected */ +#define OB_IWDG_HW ((uint8_t)0x00) /*!< Hardware IWDG selected */ +/** + * @} + */ + +/** @defgroup FLASHEx_Option_Bytes_nRST_STOP FLASH Option Bytes nRST_STOP + * @{ + */ +#define OB_STOP_NO_RST ((uint8_t)0x40) /*!< No reset generated when entering in STOP */ +#define OB_STOP_RST ((uint8_t)0x00) /*!< Reset generated when entering in STOP */ +/** + * @} + */ + + +/** @defgroup FLASHEx_Option_Bytes_nRST_STDBY FLASH Option Bytes nRST_STDBY + * @{ + */ +#define OB_STDBY_NO_RST ((uint8_t)0x80) /*!< No reset generated when entering in STANDBY */ +#define OB_STDBY_RST ((uint8_t)0x00) /*!< Reset generated when entering in STANDBY */ +/** + * @} + */ + +/** @defgroup FLASHEx_BOR_Reset_Level FLASH BOR Reset Level + * @{ + */ +#define OB_BOR_LEVEL3 ((uint8_t)0x00) /*!< Supply voltage ranges from 2.70 to 3.60 V */ +#define OB_BOR_LEVEL2 ((uint8_t)0x04) /*!< Supply voltage ranges from 2.40 to 2.70 V */ +#define OB_BOR_LEVEL1 ((uint8_t)0x08) /*!< Supply voltage ranges from 2.10 to 2.40 V */ +#define OB_BOR_OFF ((uint8_t)0x0C) /*!< Supply voltage ranges from 1.62 to 2.10 V */ +/** + * @} + */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) +/** @defgroup FLASHEx_PCROP_State FLASH PCROP State + * @{ + */ +#define OB_PCROP_STATE_DISABLE ((uint32_t)0x00) /*!< Disable PCROP */ +#define OB_PCROP_STATE_ENABLE ((uint32_t)0x01) /*!< Enable PCROP */ +/** + * @} + */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F401xC || STM32F401xE || STM32F411xE */ + +/** @defgroup FLASHEx_Advanced_Option_Type FLASH Advanced Option Type + * @{ + */ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) +#define OPTIONBYTE_PCROP ((uint32_t)0x01) /*!< PCROP option byte configuration */ +#define OPTIONBYTE_BOOTCONFIG ((uint32_t)0x02) /*!< BOOTConfig option byte configuration */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +#if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) +#define OPTIONBYTE_PCROP ((uint32_t)0x01) /*!= FLASH_BASE) && ((ADDRESS) <= FLASH_END)) +#define IS_FLASH_NBSECTORS(NBSECTORS) (((NBSECTORS) != 0) && ((NBSECTORS) <= FLASH_SECTOR_TOTAL)) + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) +#define IS_OB_WRP_SECTOR(SECTOR)((((SECTOR) & (uint32_t)0xFF000000) == 0x00000000) && ((SECTOR) != 0x00000000)) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx|| STM32F439xx */ + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) +#define IS_OB_WRP_SECTOR(SECTOR)((((SECTOR) & (uint32_t)0xFFFFF000) == 0x00000000) && ((SECTOR) != 0x00000000)) +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */ + +#if defined(STM32F401xC) +#define IS_OB_WRP_SECTOR(SECTOR)((((SECTOR) & (uint32_t)0xFFFFF000) == 0x00000000) && ((SECTOR) != 0x00000000)) +#endif /* STM32F401xC */ + +#if defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) +#define IS_OB_WRP_SECTOR(SECTOR)((((SECTOR) & (uint32_t)0xFFFFF000) == 0x00000000) && ((SECTOR) != 0x00000000)) +#endif /* STM32F401xE || STM32F411xE || STM32F446xx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) +#define IS_OB_PCROP(SECTOR)((((SECTOR) & (uint32_t)0xFFFFF000) == 0x00000000) && ((SECTOR) != 0x00000000)) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx|| STM32F439xx */ + +#if defined(STM32F401xC) +#define IS_OB_PCROP(SECTOR)((((SECTOR) & (uint32_t)0xFFFFF000) == 0x00000000) && ((SECTOR) != 0x00000000)) +#endif /* STM32F401xC */ + +#if defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) +#define IS_OB_PCROP(SECTOR)((((SECTOR) & (uint32_t)0xFFFFF000) == 0x00000000) && ((SECTOR) != 0x00000000)) +#endif /* STM32F401xE || STM32F411xE || STM32F446xx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) +#define IS_OB_BOOT(BOOT) (((BOOT) == OB_DUAL_BOOT_ENABLE) || ((BOOT) == OB_DUAL_BOOT_DISABLE)) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx|| STM32F439xx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) +#define IS_OB_PCROP_SELECT(PCROP) (((PCROP) == OB_PCROP_SELECTED) || ((PCROP) == OB_PCROP_DESELECTED)) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx */ +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup FLASHEx_Private_Functions FLASH Private Functions + * @{ + */ +void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_FLASH_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h new file mode 100644 index 0000000..db308ac --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h @@ -0,0 +1,97 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_flash_ramfunc.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of FLASH RAMFUNC driver. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_FLASH_RAMFUNC_H +#define __STM32F4xx_FLASH_RAMFUNC_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F411xE) || defined(STM32F446xx) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup FLASHRAMFUNC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup FLASHRAMFUNC_Exported_Functions + * @{ + */ + +/** @addtogroup FLASHRAMFUNC_Exported_Functions_Group1 + * @{ + */ +__RAM_FUNC HAL_FLASHEx_StopFlashInterfaceClk(void); +__RAM_FUNC HAL_FLASHEx_StartFlashInterfaceClk(void); +__RAM_FUNC HAL_FLASHEx_EnableFlashSleepMode(void); +__RAM_FUNC HAL_FLASHEx_DisableFlashSleepMode(void); +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F411xE */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F4xx_FLASH_RAMFUNC_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_fmpi2c.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_fmpi2c.h new file mode 100644 index 0000000..dff8815 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_fmpi2c.h @@ -0,0 +1,577 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_fmpi2c.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of FMPI2C HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_FMPI2C_H +#define __STM32F4xx_HAL_FMPI2C_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F446xx) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup FMPI2C + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup FMPI2C_Exported_Types FMPI2C Exported Types + * @{ + */ + +/** + * @brief FMPI2C Configuration Structure definition + */ +typedef struct +{ + uint32_t Timing; /*!< Specifies the FMPI2C_TIMINGR_register value. + This parameter calculated by referring to FMPI2C initialization + section in Reference manual */ + + uint32_t OwnAddress1; /*!< Specifies the first device own address. + This parameter can be a 7-bit or 10-bit address. */ + + uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected. + This parameter can be a value of @ref FMPI2C_addressing_mode */ + + uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected. + This parameter can be a value of @ref FMPI2C_dual_addressing_mode */ + + uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected + This parameter can be a 7-bit address. */ + + uint32_t OwnAddress2Masks; /*!< Specifies the acknoledge mask address second device own address if dual addressing mode is selected + This parameter can be a value of @ref FMPI2C_own_address2_masks */ + + uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected. + This parameter can be a value of @ref FMPI2C_general_call_addressing_mode */ + + uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected. + This parameter can be a value of @ref FMPI2C_nostretch_mode */ + +}FMPI2C_InitTypeDef; + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_FMPI2C_STATE_RESET = 0x00, /*!< FMPI2C not yet initialized or disabled */ + HAL_FMPI2C_STATE_READY = 0x01, /*!< FMPI2C initialized and ready for use */ + HAL_FMPI2C_STATE_BUSY = 0x02, /*!< FMPI2C internal process is ongoing */ + HAL_FMPI2C_STATE_MASTER_BUSY_TX = 0x12, /*!< Master Data Transmission process is ongoing */ + HAL_FMPI2C_STATE_MASTER_BUSY_RX = 0x22, /*!< Master Data Reception process is ongoing */ + HAL_FMPI2C_STATE_SLAVE_BUSY_TX = 0x32, /*!< Slave Data Transmission process is ongoing */ + HAL_FMPI2C_STATE_SLAVE_BUSY_RX = 0x42, /*!< Slave Data Reception process is ongoing */ + HAL_FMPI2C_STATE_MEM_BUSY_TX = 0x52, /*!< Memory Data Transmission process is ongoing */ + HAL_FMPI2C_STATE_MEM_BUSY_RX = 0x62, /*!< Memory Data Reception process is ongoing */ + HAL_FMPI2C_STATE_TIMEOUT = 0x03, /*!< Timeout state */ + HAL_FMPI2C_STATE_ERROR = 0x04 /*!< Reception process is ongoing */ +}HAL_FMPI2C_StateTypeDef; + +/** + * @brief HAL FMPI2C Error Code structure definition + */ +typedef enum +{ + HAL_FMPI2C_ERROR_NONE = 0x00, /*!< No error */ + HAL_FMPI2C_ERROR_BERR = 0x01, /*!< BERR error */ + HAL_FMPI2C_ERROR_ARLO = 0x02, /*!< ARLO error */ + HAL_FMPI2C_ERROR_AF = 0x04, /*!< ACKF error */ + HAL_FMPI2C_ERROR_OVR = 0x08, /*!< OVR error */ + HAL_FMPI2C_ERROR_DMA = 0x10, /*!< DMA transfer error */ + HAL_FMPI2C_ERROR_TIMEOUT = 0x20, /*!< Timeout error */ + HAL_FMPI2C_ERROR_SIZE = 0x40 /*!< Size Management error */ +}HAL_FMPI2C_ErrorTypeDef; + +/** + * @brief FMPI2C handle Structure definition + */ +typedef struct +{ + FMPI2C_TypeDef *Instance; /*!< FMPI2C registers base address */ + + FMPI2C_InitTypeDef Init; /*!< FMPI2C communication parameters */ + + uint8_t *pBuffPtr; /*!< Pointer to FMPI2C transfer buffer */ + + uint16_t XferSize; /*!< FMPI2C transfer size */ + + __IO uint16_t XferCount; /*!< FMPI2C transfer counter */ + + DMA_HandleTypeDef *hdmatx; /*!< FMPI2C Tx DMA handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< FMPI2C Rx DMA handle parameters */ + + HAL_LockTypeDef Lock; /*!< FMPI2C locking object */ + + __IO HAL_FMPI2C_StateTypeDef State; /*!< FMPI2C communication state */ + + __IO HAL_FMPI2C_ErrorTypeDef ErrorCode; /* FMPI2C Error code */ + +}FMPI2C_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup FMPI2C_Exported_Constants FMPI2C Exported Constants + * @{ + */ + +/** @defgroup FMPI2C_addressing_mode FMPI2C addressing mode + * @{ + */ +#define FMPI2C_ADDRESSINGMODE_7BIT ((uint32_t)0x00000001) +#define FMPI2C_ADDRESSINGMODE_10BIT ((uint32_t)0x00000002) + +/** + * @} + */ + +/** @defgroup FMPI2C_dual_addressing_mode FMPI2C dual addressing mode + * @{ + */ + +#define FMPI2C_DUALADDRESS_DISABLE ((uint32_t)0x00000000) +#define FMPI2C_DUALADDRESS_ENABLE FMPI2C_OAR2_OA2EN + +/** + * @} + */ + +/** @defgroup FMPI2C_own_address2_masks FMPI2C own address2 masks + * @{ + */ + +#define FMPI2C_OA2_NOMASK ((uint8_t)0x00) +#define FMPI2C_OA2_MASK01 ((uint8_t)0x01) +#define FMPI2C_OA2_MASK02 ((uint8_t)0x02) +#define FMPI2C_OA2_MASK03 ((uint8_t)0x03) +#define FMPI2C_OA2_MASK04 ((uint8_t)0x04) +#define FMPI2C_OA2_MASK05 ((uint8_t)0x05) +#define FMPI2C_OA2_MASK06 ((uint8_t)0x06) +#define FMPI2C_OA2_MASK07 ((uint8_t)0x07) + +/** + * @} + */ + +/** @defgroup FMPI2C_general_call_addressing_mode FMPI2C general call addressing mode + * @{ + */ +#define FMPI2C_GENERALCALL_DISABLE ((uint32_t)0x00000000) +#define FMPI2C_GENERALCALL_ENABLE FMPI2C_CR1_GCEN + +/** + * @} + */ + +/** @defgroup FMPI2C_nostretch_mode FMPI2C nostretch mode + * @{ + */ +#define FMPI2C_NOSTRETCH_DISABLE ((uint32_t)0x00000000) +#define FMPI2C_NOSTRETCH_ENABLE FMPI2C_CR1_NOSTRETCH + +/** + * @} + */ + +/** @defgroup FMPI2C_Memory_Address_Size FMPI2C Memory Address Size + * @{ + */ +#define FMPI2C_MEMADD_SIZE_8BIT ((uint32_t)0x00000001) +#define FMPI2C_MEMADD_SIZE_16BIT ((uint32_t)0x00000002) + +/** + * @} + */ + +/** @defgroup FMPI2C_ReloadEndMode_definition FMPI2C ReloadEndMode definition + * @{ + */ + +#define FMPI2C_RELOAD_MODE FMPI2C_CR2_RELOAD +#define FMPI2C_AUTOEND_MODE FMPI2C_CR2_AUTOEND +#define FMPI2C_SOFTEND_MODE ((uint32_t)0x00000000) + +/** + * @} + */ + +/** @defgroup FMPI2C_StartStopMode_definition FMPI2C StartStopMode definition + * @{ + */ + +#define FMPI2C_NO_STARTSTOP ((uint32_t)0x00000000) +#define FMPI2C_GENERATE_STOP FMPI2C_CR2_STOP +#define FMPI2C_GENERATE_START_READ (uint32_t)(FMPI2C_CR2_START | FMPI2C_CR2_RD_WRN) +#define FMPI2C_GENERATE_START_WRITE FMPI2C_CR2_START + +/** + * @} + */ + +/** @defgroup FMPI2C_Interrupt_configuration_definition FMPI2C Interrupt configuration definition + * @brief FMPI2C Interrupt definition + * Elements values convention: 0xXXXXXXXX + * - XXXXXXXX : Interrupt control mask + * @{ + */ +#define FMPI2C_IT_ERRI FMPI2C_CR1_ERRIE +#define FMPI2C_IT_TCI FMPI2C_CR1_TCIE +#define FMPI2C_IT_STOPI FMPI2C_CR1_STOPIE +#define FMPI2C_IT_NACKI FMPI2C_CR1_NACKIE +#define FMPI2C_IT_ADDRI FMPI2C_CR1_ADDRIE +#define FMPI2C_IT_RXI FMPI2C_CR1_RXIE +#define FMPI2C_IT_TXI FMPI2C_CR1_TXIE + +/** + * @} + */ + + +/** @defgroup FMPI2C_Flag_definition FMPI2C Flag definition + * @{ + */ + +#define FMPI2C_FLAG_TXE FMPI2C_ISR_TXE +#define FMPI2C_FLAG_TXIS FMPI2C_ISR_TXIS +#define FMPI2C_FLAG_RXNE FMPI2C_ISR_RXNE +#define FMPI2C_FLAG_ADDR FMPI2C_ISR_ADDR +#define FMPI2C_FLAG_AF FMPI2C_ISR_NACKF +#define FMPI2C_FLAG_STOPF FMPI2C_ISR_STOPF +#define FMPI2C_FLAG_TC FMPI2C_ISR_TC +#define FMPI2C_FLAG_TCR FMPI2C_ISR_TCR +#define FMPI2C_FLAG_BERR FMPI2C_ISR_BERR +#define FMPI2C_FLAG_ARLO FMPI2C_ISR_ARLO +#define FMPI2C_FLAG_OVR FMPI2C_ISR_OVR +#define FMPI2C_FLAG_PECERR FMPI2C_ISR_PECERR +#define FMPI2C_FLAG_TIMEOUT FMPI2C_ISR_TIMEOUT +#define FMPI2C_FLAG_ALERT FMPI2C_ISR_ALERT +#define FMPI2C_FLAG_BUSY FMPI2C_ISR_BUSY +#define FMPI2C_FLAG_DIR FMPI2C_ISR_DIR + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup FMPI2C_Exported_Macros FMPI2C Exported Macros + * @{ + */ + +/** @brief Reset FMPI2C handle state + * @param __HANDLE__: specifies the FMPI2C Handle. + * This parameter can be FMPI2C where x: 1 or 2 to select the FMPI2C peripheral. + * @retval None + */ +#define __HAL_FMPI2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_FMPI2C_STATE_RESET) + +/** @brief Enables or disables the specified FMPI2C interrupts. + * @param __HANDLE__: specifies the FMPI2C Handle. + * This parameter can be FMPI2C where x: 1 or 2 to select the FMPI2C peripheral. + * @param __INTERRUPT__: specifies the interrupt source to enable or disable. + * This parameter can be one of the following values: + * @arg FMPI2C_IT_ERRI: Errors interrupt enable + * @arg FMPI2C_IT_TCI: Transfer complete interrupt enable + * @arg FMPI2C_IT_STOPI: STOP detection interrupt enable + * @arg FMPI2C_IT_NACKI: NACK received interrupt enable + * @arg FMPI2C_IT_ADDRI: Address match interrupt enable + * @arg FMPI2C_IT_RXI: RX interrupt enable + * @arg FMPI2C_IT_TXI: TX interrupt enable + * + * @retval None + */ + +#define __HAL_FMPI2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR1 |= (__INTERRUPT__)) +#define __HAL_FMPI2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR1 &= (~(__INTERRUPT__))) + +/** @brief Checks if the specified FMPI2C interrupt source is enabled or disabled. + * @param __HANDLE__: specifies the FMPI2C Handle. + * This parameter can be FMPI2C where x: 1 or 2 to select the FMPI2C peripheral. + * @param __INTERRUPT__: specifies the FMPI2C interrupt source to check. + * This parameter can be one of the following values: + * @arg FMPI2C_IT_ERRI: Errors interrupt enable + * @arg FMPI2C_IT_TCI: Transfer complete interrupt enable + * @arg FMPI2C_IT_STOPI: STOP detection interrupt enable + * @arg FMPI2C_IT_NACKI: NACK received interrupt enable + * @arg FMPI2C_IT_ADDRI: Address match interrupt enable + * @arg FMPI2C_IT_RXI: RX interrupt enable + * @arg FMPI2C_IT_TXI: TX interrupt enable + * + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_FMPI2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR1 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Checks whether the specified FMPI2C flag is set or not. + * @param __HANDLE__: specifies the FMPI2C Handle. + * This parameter can be FMPI2C where x: 1 or 2 to select the FMPI2C peripheral. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg FMPI2C_FLAG_TXE: Transmit data register empty + * @arg FMPI2C_FLAG_TXIS: Transmit interrupt status + * @arg FMPI2C_FLAG_RXNE: Receive data register not empty + * @arg FMPI2C_FLAG_ADDR: Address matched (slave mode) + * @arg FMPI2C_FLAG_AF: Acknowledge failure received flag + * @arg FMPI2C_FLAG_STOPF: STOP detection flag + * @arg FMPI2C_FLAG_TC: Transfer complete (master mode) + * @arg FMPI2C_FLAG_TCR: Transfer complete reload + * @arg FMPI2C_FLAG_BERR: Bus error + * @arg FMPI2C_FLAG_ARLO: Arbitration lost + * @arg FMPI2C_FLAG_OVR: Overrun/Underrun + * @arg FMPI2C_FLAG_PECERR: PEC error in reception + * @arg FMPI2C_FLAG_TIMEOUT: Timeout or Tlow detection flag + * @arg FMPI2C_FLAG_ALERT: SMBus alert + * @arg FMPI2C_FLAG_BUSY: Bus busy + * @arg FMPI2C_FLAG_DIR: Transfer direction (slave mode) + * + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_FMPI2C_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->ISR) & ((__FLAG__) & FMPI2C_FLAG_MASK)) == ((__FLAG__) & FMPI2C_FLAG_MASK))) + +/** @brief Clears the FMPI2C pending flags which are cleared by writing 1 in a specific bit. + * @param __HANDLE__: specifies the FMPI2C Handle. + * This parameter can be FMPI2C where x: 1 or 2 to select the FMPI2C peripheral. + * @param __FLAG__: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg FMPI2C_FLAG_ADDR: Address matched (slave mode) + * @arg FMPI2C_FLAG_AF: Acknowledge failure received flag + * @arg FMPI2C_FLAG_STOPF: STOP detection flag + * @arg FMPI2C_FLAG_BERR: Bus error + * @arg FMPI2C_FLAG_ARLO: Arbitration lost + * @arg FMPI2C_FLAG_OVR: Overrun/Underrun + * @arg FMPI2C_FLAG_PECERR: PEC error in reception + * @arg FMPI2C_FLAG_TIMEOUT: Timeout or Tlow detection flag + * @arg FMPI2C_FLAG_ALERT: SMBus alert + * + * @retval None + */ +#define __HAL_FMPI2C_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = ((__FLAG__) & FMPI2C_FLAG_MASK)) + + +#define __HAL_FMPI2C_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= FMPI2C_CR1_PE) +#define __HAL_FMPI2C_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~FMPI2C_CR1_PE) + +#define __HAL_FMPI2C_RESET_CR2(__HANDLE__) ((__HANDLE__)->Instance->CR2 &= (uint32_t)~((uint32_t)(FMPI2C_CR2_SADD | FMPI2C_CR2_HEAD10R | FMPI2C_CR2_NBYTES | FMPI2C_CR2_RELOAD | FMPI2C_CR2_RD_WRN))) + +#define __HAL_FMPI2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0xFF00))) >> 8))) +#define __HAL_FMPI2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FF)))) + +#define __HAL_FMPI2C_GENERATE_START(__ADDMODE__,__ADDRESS__) (((__ADDMODE__) == FMPI2C_ADDRESSINGMODE_7BIT) ? (uint32_t)((((uint32_t)(__ADDRESS__) & (FMPI2C_CR2_SADD)) | (FMPI2C_CR2_START) | (FMPI2C_CR2_AUTOEND)) & (~FMPI2C_CR2_RD_WRN)) : \ + (uint32_t)((((uint32_t)(__ADDRESS__) & (FMPI2C_CR2_SADD)) | (FMPI2C_CR2_ADD10) | (FMPI2C_CR2_START)) & (~FMPI2C_CR2_RD_WRN))) + +#define IS_FMPI2C_OWN_ADDRESS1(ADDRESS1) ((ADDRESS1) <= (uint32_t)0x000003FF) +#define IS_FMPI2C_OWN_ADDRESS2(ADDRESS2) ((ADDRESS2) <= (uint16_t)0x00FF) + +/** + * @} + */ + +/* Include FMPI2C HAL Extension module */ +#include "stm32f4xx_hal_fmpi2c_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup FMPI2C_Exported_Functions + * @{ + */ + +/** @addtogroup FMPI2C_Exported_Functions_Group1 + * @{ + */ + +/* Initialization/de-initialization functions**********************************/ +HAL_StatusTypeDef HAL_FMPI2C_Init(FMPI2C_HandleTypeDef *hFMPI2C); +HAL_StatusTypeDef HAL_FMPI2C_DeInit (FMPI2C_HandleTypeDef *hFMPI2C); +void HAL_FMPI2C_MspInit(FMPI2C_HandleTypeDef *hFMPI2C); +void HAL_FMPI2C_MspDeInit(FMPI2C_HandleTypeDef *hFMPI2C); + +/** + * @} + */ + +/** @addtogroup FMPI2C_Exported_Functions_Group2 + * @{ + */ + +/* I/O operation functions ***************************************************/ + /******* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit(FMPI2C_HandleTypeDef *hFMPI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_FMPI2C_Master_Receive(FMPI2C_HandleTypeDef *hFMPI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit(FMPI2C_HandleTypeDef *hFMPI2C, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive(FMPI2C_HandleTypeDef *hFMPI2C, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_FMPI2C_Mem_Write(FMPI2C_HandleTypeDef *hFMPI2C, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_FMPI2C_Mem_Read(FMPI2C_HandleTypeDef *hFMPI2C, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_FMPI2C_IsDeviceReady(FMPI2C_HandleTypeDef *hFMPI2C, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout); + + /******* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_IT(FMPI2C_HandleTypeDef *hFMPI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_IT(FMPI2C_HandleTypeDef *hFMPI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_IT(FMPI2C_HandleTypeDef *hFMPI2C, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_IT(FMPI2C_HandleTypeDef *hFMPI2C, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_IT(FMPI2C_HandleTypeDef *hFMPI2C, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_IT(FMPI2C_HandleTypeDef *hFMPI2C, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); + + /******* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_DMA(FMPI2C_HandleTypeDef *hFMPI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_DMA(FMPI2C_HandleTypeDef *hFMPI2C, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_DMA(FMPI2C_HandleTypeDef *hFMPI2C, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_DMA(FMPI2C_HandleTypeDef *hFMPI2C, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_DMA(FMPI2C_HandleTypeDef *hFMPI2C, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_DMA(FMPI2C_HandleTypeDef *hFMPI2C, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); + + /******* FMPI2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */ +void HAL_FMPI2C_EV_IRQHandler(FMPI2C_HandleTypeDef *hFMPI2C); +void HAL_FMPI2C_ER_IRQHandler(FMPI2C_HandleTypeDef *hFMPI2C); +void HAL_FMPI2C_MasterTxCpltCallback(FMPI2C_HandleTypeDef *hFMPI2C); +void HAL_FMPI2C_MasterRxCpltCallback(FMPI2C_HandleTypeDef *hFMPI2C); +void HAL_FMPI2C_SlaveTxCpltCallback(FMPI2C_HandleTypeDef *hFMPI2C); +void HAL_FMPI2C_SlaveRxCpltCallback(FMPI2C_HandleTypeDef *hFMPI2C); +void HAL_FMPI2C_MemTxCpltCallback(FMPI2C_HandleTypeDef *hFMPI2C); +void HAL_FMPI2C_MemRxCpltCallback(FMPI2C_HandleTypeDef *hFMPI2C); +void HAL_FMPI2C_ErrorCallback(FMPI2C_HandleTypeDef *hFMPI2C); +/** + * @} + */ + +/** @addtogroup FMPI2C_Exported_Functions_Group3 + * @{ + */ + +/* Peripheral State functions ************************************************/ +HAL_FMPI2C_StateTypeDef HAL_FMPI2C_GetState(FMPI2C_HandleTypeDef *hFMPI2C); +uint32_t HAL_FMPI2C_GetError(FMPI2C_HandleTypeDef *hFMPI2C); + +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup FMPI2C_Private_Constants FMPI2C Private Constants + * @{ + */ +#define FMPI2C_FLAG_MASK ((uint32_t)0x0001FFFF) +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup FMPI2C_Private_Macros FMPI2C Private Macros + * @{ + */ + +#define IS_FMPI2C_ADDRESSING_MODE(MODE) (((MODE) == FMPI2C_ADDRESSINGMODE_7BIT) || \ + ((MODE) == FMPI2C_ADDRESSINGMODE_10BIT)) + +#define IS_FMPI2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == FMPI2C_DUALADDRESS_DISABLE) || \ + ((ADDRESS) == FMPI2C_DUALADDRESS_ENABLE)) + +#define IS_FMPI2C_OWN_ADDRESS2_MASK(MASK) (((MASK) == FMPI2C_OA2_NOMASK) || \ + ((MASK) == FMPI2C_OA2_MASK01) || \ + ((MASK) == FMPI2C_OA2_MASK02) || \ + ((MASK) == FMPI2C_OA2_MASK03) || \ + ((MASK) == FMPI2C_OA2_MASK04) || \ + ((MASK) == FMPI2C_OA2_MASK05) || \ + ((MASK) == FMPI2C_OA2_MASK06) || \ + ((MASK) == FMPI2C_OA2_MASK07)) + +#define IS_FMPI2C_GENERAL_CALL(CALL) (((CALL) == FMPI2C_GENERALCALL_DISABLE) || \ + ((CALL) == FMPI2C_GENERALCALL_ENABLE)) + +#define IS_FMPI2C_NO_STRETCH(STRETCH) (((STRETCH) == FMPI2C_NOSTRETCH_DISABLE) || \ + ((STRETCH) == FMPI2C_NOSTRETCH_ENABLE)) + +#define IS_FMPI2C_MEMADD_SIZE(SIZE) (((SIZE) == FMPI2C_MEMADD_SIZE_8BIT) || \ + ((SIZE) == FMPI2C_MEMADD_SIZE_16BIT)) + +#define IS_TRANSFER_MODE(MODE) (((MODE) == FMPI2C_RELOAD_MODE) || \ + ((MODE) == FMPI2C_AUTOEND_MODE) || \ + ((MODE) == FMPI2C_SOFTEND_MODE)) + +#define IS_TRANSFER_REQUEST(REQUEST) (((REQUEST) == FMPI2C_GENERATE_STOP) || \ + ((REQUEST) == FMPI2C_GENERATE_START_READ) || \ + ((REQUEST) == FMPI2C_GENERATE_START_WRITE) || \ + ((REQUEST) == FMPI2C_NO_STARTSTOP)) + +/** + * @} + */ +/* Private functions ---------------------------------------------------------*/ +/** @defgroup FMPI2C_Private_Functions FMPI2C Private Functions + * @brief FMPI2C private functions + * @{ + */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F446xx */ +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F4xx_HAL_FMPI2C_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_fmpi2c_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_fmpi2c_ex.h new file mode 100644 index 0000000..b485c97 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_fmpi2c_ex.h @@ -0,0 +1,151 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_fmpi2c_ex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of FMPI2C HAL Extension module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_FMPI2C_EX_H +#define __STM32F4xx_HAL_FMPI2C_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F446xx) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup FMPI2CEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup FMPI2CEx_Exported_Constants FMPI2C Exported Constants + * @{ + */ + +/** @defgroup FMPI2CEx_Analog_Filter FMPI2C Analog Filter + * @{ + */ +#define FMPI2C_ANALOGFILTER_ENABLE ((uint32_t)0x00000000) +#define FMPI2C_ANALOGFILTER_DISABLE FMPI2C_CR1_ANFOFF +/** + * @} + */ + +/** @defgroup FMPI2CEx_FastModePlus FMPI2C Fast Mode Plus + * @{ + */ +#define FMPI2C_FASTMODEPLUS_SCL SYSCFG_CFGR_FMPI2C1_SCL /*!< Enable Fast Mode Plus on FMPI2C1 SCL pins */ +#define FMPI2C_FASTMODEPLUS_SDA SYSCFG_CFGR_FMPI2C1_SDA /*!< Enable Fast Mode Plus on FMPI2C1 SDA pins */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup FMPI2CEx_Exported_Functions + * @{ + */ + +/** @addtogroup FMPI2CEx_Exported_Functions_Group1 + * @{ + */ +/* Peripheral Control functions ************************************************/ +HAL_StatusTypeDef HAL_FMPI2CEx_AnalogFilter_Config(FMPI2C_HandleTypeDef *hFMPI2C, uint32_t AnalogFilter); +HAL_StatusTypeDef HAL_FMPI2CEx_DigitalFilter_Config(FMPI2C_HandleTypeDef *hFMPI2C, uint32_t DigitalFilter); +HAL_StatusTypeDef HAL_FMPI2CEx_EnableWakeUp (FMPI2C_HandleTypeDef *hFMPI2C); +HAL_StatusTypeDef HAL_FMPI2CEx_DisableWakeUp (FMPI2C_HandleTypeDef *hFMPI2C); +void HAL_FMPI2CEx_EnableFastModePlus(uint32_t ConfigFastModePlus); +void HAL_FMPI2CEx_DisableFastModePlus(uint32_t ConfigFastModePlus); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2CEx_Private_Constants I2C Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2CEx_Private_Macros I2C Private Macros + * @{ + */ +#define IS_FMPI2C_ANALOG_FILTER(FILTER) (((FILTER) == FMPI2C_ANALOGFILTER_ENABLE) || \ + ((FILTER) == FMPI2C_ANALOGFILTER_DISABLE)) + +#define IS_FMPI2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000F) + +#define IS_FMPI2C_FASTMODEPLUS(__CONFIG__) ((((__CONFIG__) & (FMPI2C_FASTMODEPLUS_SCL)) == FMPI2C_FASTMODEPLUS_SCL) || \ + (((__CONFIG__) & (FMPI2C_FASTMODEPLUS_SDA)) == FMPI2C_FASTMODEPLUS_SDA)) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F446xx */ +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_FMPI2C_EX_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h new file mode 100644 index 0000000..f31c0ad --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h @@ -0,0 +1,327 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_gpio.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of GPIO HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_GPIO_H +#define __STM32F4xx_HAL_GPIO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup GPIO + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup GPIO_Exported_Types GPIO Exported Types + * @{ + */ + +/** + * @brief GPIO Init structure definition + */ +typedef struct +{ + uint32_t Pin; /*!< Specifies the GPIO pins to be configured. + This parameter can be any value of @ref GPIO_pins_define */ + + uint32_t Mode; /*!< Specifies the operating mode for the selected pins. + This parameter can be a value of @ref GPIO_mode_define */ + + uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected pins. + This parameter can be a value of @ref GPIO_pull_define */ + + uint32_t Speed; /*!< Specifies the speed for the selected pins. + This parameter can be a value of @ref GPIO_speed_define */ + + uint32_t Alternate; /*!< Peripheral to be connected to the selected pins. + This parameter can be a value of @ref GPIO_Alternate_function_selection */ +}GPIO_InitTypeDef; + +/** + * @brief GPIO Bit SET and Bit RESET enumeration + */ +typedef enum +{ + GPIO_PIN_RESET = 0, + GPIO_PIN_SET +}GPIO_PinState; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup GPIO_Exported_Constants GPIO Exported Constants + * @{ + */ + +/** @defgroup GPIO_pins_define GPIO pins define + * @{ + */ +#define GPIO_PIN_0 ((uint16_t)0x0001) /* Pin 0 selected */ +#define GPIO_PIN_1 ((uint16_t)0x0002) /* Pin 1 selected */ +#define GPIO_PIN_2 ((uint16_t)0x0004) /* Pin 2 selected */ +#define GPIO_PIN_3 ((uint16_t)0x0008) /* Pin 3 selected */ +#define GPIO_PIN_4 ((uint16_t)0x0010) /* Pin 4 selected */ +#define GPIO_PIN_5 ((uint16_t)0x0020) /* Pin 5 selected */ +#define GPIO_PIN_6 ((uint16_t)0x0040) /* Pin 6 selected */ +#define GPIO_PIN_7 ((uint16_t)0x0080) /* Pin 7 selected */ +#define GPIO_PIN_8 ((uint16_t)0x0100) /* Pin 8 selected */ +#define GPIO_PIN_9 ((uint16_t)0x0200) /* Pin 9 selected */ +#define GPIO_PIN_10 ((uint16_t)0x0400) /* Pin 10 selected */ +#define GPIO_PIN_11 ((uint16_t)0x0800) /* Pin 11 selected */ +#define GPIO_PIN_12 ((uint16_t)0x1000) /* Pin 12 selected */ +#define GPIO_PIN_13 ((uint16_t)0x2000) /* Pin 13 selected */ +#define GPIO_PIN_14 ((uint16_t)0x4000) /* Pin 14 selected */ +#define GPIO_PIN_15 ((uint16_t)0x8000) /* Pin 15 selected */ +#define GPIO_PIN_All ((uint16_t)0xFFFF) /* All pins selected */ + +#define GPIO_PIN_MASK ((uint32_t)0x0000FFFF) /* PIN mask for assert test */ +/** + * @} + */ + +/** @defgroup GPIO_mode_define GPIO mode define + * @brief GPIO Configuration Mode + * Elements values convention: 0xX0yz00YZ + * - X : GPIO mode or EXTI Mode + * - y : External IT or Event trigger detection + * - z : IO configuration on External IT or Event + * - Y : Output type (Push Pull or Open Drain) + * - Z : IO Direction mode (Input, Output, Alternate or Analog) + * @{ + */ +#define GPIO_MODE_INPUT ((uint32_t)0x00000000) /*!< Input Floating Mode */ +#define GPIO_MODE_OUTPUT_PP ((uint32_t)0x00000001) /*!< Output Push Pull Mode */ +#define GPIO_MODE_OUTPUT_OD ((uint32_t)0x00000011) /*!< Output Open Drain Mode */ +#define GPIO_MODE_AF_PP ((uint32_t)0x00000002) /*!< Alternate Function Push Pull Mode */ +#define GPIO_MODE_AF_OD ((uint32_t)0x00000012) /*!< Alternate Function Open Drain Mode */ + +#define GPIO_MODE_ANALOG ((uint32_t)0x00000003) /*!< Analog Mode */ + +#define GPIO_MODE_IT_RISING ((uint32_t)0x10110000) /*!< External Interrupt Mode with Rising edge trigger detection */ +#define GPIO_MODE_IT_FALLING ((uint32_t)0x10210000) /*!< External Interrupt Mode with Falling edge trigger detection */ +#define GPIO_MODE_IT_RISING_FALLING ((uint32_t)0x10310000) /*!< External Interrupt Mode with Rising/Falling edge trigger detection */ + +#define GPIO_MODE_EVT_RISING ((uint32_t)0x10120000) /*!< External Event Mode with Rising edge trigger detection */ +#define GPIO_MODE_EVT_FALLING ((uint32_t)0x10220000) /*!< External Event Mode with Falling edge trigger detection */ +#define GPIO_MODE_EVT_RISING_FALLING ((uint32_t)0x10320000) /*!< External Event Mode with Rising/Falling edge trigger detection */ +/** + * @} + */ + +/** @defgroup GPIO_speed_define GPIO speed define + * @brief GPIO Output Maximum frequency + * @{ + */ +#define GPIO_SPEED_LOW ((uint32_t)0x00000000) /*!< Low speed */ +#define GPIO_SPEED_MEDIUM ((uint32_t)0x00000001) /*!< Medium speed */ +#define GPIO_SPEED_FAST ((uint32_t)0x00000002) /*!< Fast speed */ +#define GPIO_SPEED_HIGH ((uint32_t)0x00000003) /*!< High speed */ +/** + * @} + */ + + /** @defgroup GPIO_pull_define GPIO pull define + * @brief GPIO Pull-Up or Pull-Down Activation + * @{ + */ +#define GPIO_NOPULL ((uint32_t)0x00000000) /*!< No Pull-up or Pull-down activation */ +#define GPIO_PULLUP ((uint32_t)0x00000001) /*!< Pull-up activation */ +#define GPIO_PULLDOWN ((uint32_t)0x00000002) /*!< Pull-down activation */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup GPIO_Exported_Macros GPIO Exported Macros + * @{ + */ + +/** + * @brief Checks whether the specified EXTI line flag is set or not. + * @param __EXTI_LINE__: specifies the EXTI line flag to check. + * This parameter can be GPIO_PIN_x where x can be(0..15) + * @retval The new state of __EXTI_LINE__ (SET or RESET). + */ +#define __HAL_GPIO_EXTI_GET_FLAG(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__)) + +/** + * @brief Clears the EXTI's line pending flags. + * @param __EXTI_LINE__: specifies the EXTI lines flags to clear. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_CLEAR_FLAG(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__)) + +/** + * @brief Checks whether the specified EXTI line is asserted or not. + * @param __EXTI_LINE__: specifies the EXTI line to check. + * This parameter can be GPIO_PIN_x where x can be(0..15) + * @retval The new state of __EXTI_LINE__ (SET or RESET). + */ +#define __HAL_GPIO_EXTI_GET_IT(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__)) + +/** + * @brief Clears the EXTI's line pending bits. + * @param __EXTI_LINE__: specifies the EXTI lines to clear. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_CLEAR_IT(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__)) + +/** + * @brief Generates a Software interrupt on selected EXTI line. + * @param __EXTI_LINE__: specifies the EXTI line to check. + * This parameter can be GPIO_PIN_x where x can be(0..15) + * @retval None + */ +#define __HAL_GPIO_EXTI_GENERATE_SWIT(__EXTI_LINE__) (EXTI->SWIER |= (__EXTI_LINE__)) +/** + * @} + */ + +/* Include GPIO HAL Extension module */ +#include "stm32f4xx_hal_gpio_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup GPIO_Exported_Functions + * @{ + */ + +/** @addtogroup GPIO_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions *****************************/ +void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init); +void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin); +/** + * @} + */ + +/** @addtogroup GPIO_Exported_Functions_Group2 + * @{ + */ +/* IO operation functions *****************************************************/ +GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState); +void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); +void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin); +void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin); + +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup GPIO_Private_Constants GPIO Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup GPIO_Private_Macros GPIO Private Macros + * @{ + */ +#define IS_GPIO_PIN_ACTION(ACTION) (((ACTION) == GPIO_PIN_RESET) || ((ACTION) == GPIO_PIN_SET)) +#define IS_GPIO_PIN(PIN) (((PIN) & GPIO_PIN_MASK ) != (uint32_t)0x00) +#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_MODE_INPUT) ||\ + ((MODE) == GPIO_MODE_OUTPUT_PP) ||\ + ((MODE) == GPIO_MODE_OUTPUT_OD) ||\ + ((MODE) == GPIO_MODE_AF_PP) ||\ + ((MODE) == GPIO_MODE_AF_OD) ||\ + ((MODE) == GPIO_MODE_IT_RISING) ||\ + ((MODE) == GPIO_MODE_IT_FALLING) ||\ + ((MODE) == GPIO_MODE_IT_RISING_FALLING) ||\ + ((MODE) == GPIO_MODE_EVT_RISING) ||\ + ((MODE) == GPIO_MODE_EVT_FALLING) ||\ + ((MODE) == GPIO_MODE_EVT_RISING_FALLING) ||\ + ((MODE) == GPIO_MODE_ANALOG)) +#define IS_GPIO_SPEED(SPEED) (((SPEED) == GPIO_SPEED_LOW) || ((SPEED) == GPIO_SPEED_MEDIUM) || \ + ((SPEED) == GPIO_SPEED_FAST) || ((SPEED) == GPIO_SPEED_HIGH)) +#define IS_GPIO_PULL(PULL) (((PULL) == GPIO_NOPULL) || ((PULL) == GPIO_PULLUP) || \ + ((PULL) == GPIO_PULLDOWN)) +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup GPIO_Private_Functions GPIO Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_GPIO_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h new file mode 100644 index 0000000..ddd191d --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio_ex.h @@ -0,0 +1,1100 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_gpio_ex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of GPIO HAL Extension module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_GPIO_EX_H +#define __STM32F4xx_HAL_GPIO_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup GPIOEx GPIOEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup GPIOEx_Exported_Constants GPIO Exported Constants + * @{ + */ + +/** @defgroup GPIO_Alternate_function_selection GPIO Alternate Function Selection + * @{ + */ + +/*------------------------------------------ STM32F429xx/STM32F439xx --------------------------------------*/ +#if defined (STM32F429xx) || defined (STM32F439xx) +/** + * @brief AF 0 selection + */ +#define GPIO_AF0_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */ +#define GPIO_AF0_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */ +#define GPIO_AF0_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */ +#define GPIO_AF0_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */ + +/** + * @brief AF 1 selection + */ +#define GPIO_AF1_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */ +#define GPIO_AF1_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */ + +/** + * @brief AF 2 selection + */ +#define GPIO_AF2_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */ +#define GPIO_AF2_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */ +#define GPIO_AF2_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */ + +/** + * @brief AF 3 selection + */ +#define GPIO_AF3_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */ +#define GPIO_AF3_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */ +#define GPIO_AF3_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */ +#define GPIO_AF3_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */ + +/** + * @brief AF 4 selection + */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */ +#define GPIO_AF4_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */ +#define GPIO_AF4_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */ + +/** + * @brief AF 5 selection + */ +#define GPIO_AF5_SPI1 ((uint8_t)0x05) /* SPI1 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF5_SPI3 ((uint8_t)0x05) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF5_SPI4 ((uint8_t)0x05) /* SPI4 Alternate Function mapping */ +#define GPIO_AF5_SPI5 ((uint8_t)0x05) /* SPI5 Alternate Function mapping */ +#define GPIO_AF5_SPI6 ((uint8_t)0x05) /* SPI6 Alternate Function mapping */ +#define GPIO_AF5_I2S3ext ((uint8_t)0x05) /* I2S3ext_SD Alternate Function mapping */ + +/** + * @brief AF 6 selection + */ +#define GPIO_AF6_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF6_I2S2ext ((uint8_t)0x06) /* I2S2ext_SD Alternate Function mapping */ +#define GPIO_AF6_SAI1 ((uint8_t)0x06) /* SAI1 Alternate Function mapping */ + +/** + * @brief AF 7 selection + */ +#define GPIO_AF7_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */ +#define GPIO_AF7_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */ +#define GPIO_AF7_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */ +#define GPIO_AF7_I2S3ext ((uint8_t)0x07) /* I2S3ext_SD Alternate Function mapping */ + +/** + * @brief AF 8 selection + */ +#define GPIO_AF8_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */ +#define GPIO_AF8_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */ +#define GPIO_AF8_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */ +#define GPIO_AF8_UART7 ((uint8_t)0x08) /* UART7 Alternate Function mapping */ +#define GPIO_AF8_UART8 ((uint8_t)0x08) /* UART8 Alternate Function mapping */ + +/** + * @brief AF 9 selection + */ +#define GPIO_AF9_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */ +#define GPIO_AF9_CAN2 ((uint8_t)0x09) /* CAN2 Alternate Function mapping */ +#define GPIO_AF9_TIM12 ((uint8_t)0x09) /* TIM12 Alternate Function mapping */ +#define GPIO_AF9_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */ +#define GPIO_AF9_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */ +#define GPIO_AF9_LTDC ((uint8_t)0x09) /* LCD-TFT Alternate Function mapping */ + +/** + * @brief AF 10 selection + */ +#define GPIO_AF10_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */ +#define GPIO_AF10_OTG_HS ((uint8_t)0xA) /* OTG_HS Alternate Function mapping */ + +/** + * @brief AF 11 selection + */ +#define GPIO_AF11_ETH ((uint8_t)0x0B) /* ETHERNET Alternate Function mapping */ + +/** + * @brief AF 12 selection + */ +#define GPIO_AF12_FMC ((uint8_t)0xC) /* FMC Alternate Function mapping */ +#define GPIO_AF12_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS, Alternate Function mapping */ +#define GPIO_AF12_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */ + +/** + * @brief AF 13 selection + */ +#define GPIO_AF13_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */ + +/** + * @brief AF 14 selection + */ +#define GPIO_AF14_LTDC ((uint8_t)0x0E) /* LCD-TFT Alternate Function mapping */ + +/** + * @brief AF 15 selection + */ +#define GPIO_AF15_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */ +#endif /* STM32F429xx || STM32F439xx */ +/*------------------------------------------------------------------------------------------*/ + +/*---------------------------------- STM32F427xx/STM32F437xx--------------------------------*/ +#if defined (STM32F427xx) || defined (STM32F437xx) +/** + * @brief AF 0 selection + */ +#define GPIO_AF0_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */ +#define GPIO_AF0_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */ +#define GPIO_AF0_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */ +#define GPIO_AF0_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */ + +/** + * @brief AF 1 selection + */ +#define GPIO_AF1_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */ +#define GPIO_AF1_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */ + +/** + * @brief AF 2 selection + */ +#define GPIO_AF2_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */ +#define GPIO_AF2_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */ +#define GPIO_AF2_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */ + +/** + * @brief AF 3 selection + */ +#define GPIO_AF3_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */ +#define GPIO_AF3_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */ +#define GPIO_AF3_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */ +#define GPIO_AF3_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */ + +/** + * @brief AF 4 selection + */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */ +#define GPIO_AF4_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */ +#define GPIO_AF4_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */ + +/** + * @brief AF 5 selection + */ +#define GPIO_AF5_SPI1 ((uint8_t)0x05) /* SPI1 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF5_SPI3 ((uint8_t)0x05) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF5_SPI4 ((uint8_t)0x05) /* SPI4 Alternate Function mapping */ +#define GPIO_AF5_SPI5 ((uint8_t)0x05) /* SPI5 Alternate Function mapping */ +#define GPIO_AF5_SPI6 ((uint8_t)0x05) /* SPI6 Alternate Function mapping */ +/** @brief GPIO_Legacy + */ +#define GPIO_AF5_I2S3ext GPIO_AF5_SPI3 /* I2S3ext_SD Alternate Function mapping */ + +/** + * @brief AF 6 selection + */ +#define GPIO_AF6_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF6_I2S2ext ((uint8_t)0x06) /* I2S2ext_SD Alternate Function mapping */ +#define GPIO_AF6_SAI1 ((uint8_t)0x06) /* SAI1 Alternate Function mapping */ + +/** + * @brief AF 7 selection + */ +#define GPIO_AF7_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */ +#define GPIO_AF7_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */ +#define GPIO_AF7_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */ +#define GPIO_AF7_I2S3ext ((uint8_t)0x07) /* I2S3ext_SD Alternate Function mapping */ + +/** + * @brief AF 8 selection + */ +#define GPIO_AF8_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */ +#define GPIO_AF8_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */ +#define GPIO_AF8_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */ +#define GPIO_AF8_UART7 ((uint8_t)0x08) /* UART7 Alternate Function mapping */ +#define GPIO_AF8_UART8 ((uint8_t)0x08) /* UART8 Alternate Function mapping */ + +/** + * @brief AF 9 selection + */ +#define GPIO_AF9_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */ +#define GPIO_AF9_CAN2 ((uint8_t)0x09) /* CAN2 Alternate Function mapping */ +#define GPIO_AF9_TIM12 ((uint8_t)0x09) /* TIM12 Alternate Function mapping */ +#define GPIO_AF9_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */ +#define GPIO_AF9_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */ + +/** + * @brief AF 10 selection + */ +#define GPIO_AF10_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */ +#define GPIO_AF10_OTG_HS ((uint8_t)0xA) /* OTG_HS Alternate Function mapping */ + +/** + * @brief AF 11 selection + */ +#define GPIO_AF11_ETH ((uint8_t)0x0B) /* ETHERNET Alternate Function mapping */ + +/** + * @brief AF 12 selection + */ +#define GPIO_AF12_FMC ((uint8_t)0xC) /* FMC Alternate Function mapping */ +#define GPIO_AF12_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS, Alternate Function mapping */ +#define GPIO_AF12_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */ + +/** + * @brief AF 13 selection + */ +#define GPIO_AF13_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */ + +/** + * @brief AF 15 selection + */ +#define GPIO_AF15_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */ +#endif /* STM32F427xx || STM32F437xx */ +/*------------------------------------------------------------------------------------------*/ + +/*---------------------------------- STM32F407xx/STM32F417xx--------------------------------*/ +#if defined (STM32F407xx) || defined (STM32F417xx) +/** + * @brief AF 0 selection + */ +#define GPIO_AF0_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */ +#define GPIO_AF0_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */ +#define GPIO_AF0_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */ +#define GPIO_AF0_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */ + +/** + * @brief AF 1 selection + */ +#define GPIO_AF1_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */ +#define GPIO_AF1_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */ + +/** + * @brief AF 2 selection + */ +#define GPIO_AF2_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */ +#define GPIO_AF2_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */ +#define GPIO_AF2_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */ + +/** + * @brief AF 3 selection + */ +#define GPIO_AF3_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */ +#define GPIO_AF3_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */ +#define GPIO_AF3_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */ +#define GPIO_AF3_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */ + +/** + * @brief AF 4 selection + */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */ +#define GPIO_AF4_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */ +#define GPIO_AF4_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */ + +/** + * @brief AF 5 selection + */ +#define GPIO_AF5_SPI1 ((uint8_t)0x05) /* SPI1 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF5_I2S3ext ((uint8_t)0x05) /* I2S3ext_SD Alternate Function mapping */ + +/** + * @brief AF 6 selection + */ +#define GPIO_AF6_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF6_I2S2ext ((uint8_t)0x06) /* I2S2ext_SD Alternate Function mapping */ + +/** + * @brief AF 7 selection + */ +#define GPIO_AF7_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */ +#define GPIO_AF7_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */ +#define GPIO_AF7_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */ +#define GPIO_AF7_I2S3ext ((uint8_t)0x07) /* I2S3ext_SD Alternate Function mapping */ + +/** + * @brief AF 8 selection + */ +#define GPIO_AF8_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */ +#define GPIO_AF8_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */ +#define GPIO_AF8_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */ + +/** + * @brief AF 9 selection + */ +#define GPIO_AF9_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */ +#define GPIO_AF9_CAN2 ((uint8_t)0x09) /* CAN2 Alternate Function mapping */ +#define GPIO_AF9_TIM12 ((uint8_t)0x09) /* TIM12 Alternate Function mapping */ +#define GPIO_AF9_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */ +#define GPIO_AF9_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */ + +/** + * @brief AF 10 selection + */ +#define GPIO_AF10_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */ +#define GPIO_AF10_OTG_HS ((uint8_t)0xA) /* OTG_HS Alternate Function mapping */ + +/** + * @brief AF 11 selection + */ +#define GPIO_AF11_ETH ((uint8_t)0x0B) /* ETHERNET Alternate Function mapping */ + +/** + * @brief AF 12 selection + */ +#define GPIO_AF12_FSMC ((uint8_t)0xC) /* FSMC Alternate Function mapping */ +#define GPIO_AF12_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS, Alternate Function mapping */ +#define GPIO_AF12_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */ + +/** + * @brief AF 13 selection + */ +#define GPIO_AF13_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */ + +/** + * @brief AF 15 selection + */ +#define GPIO_AF15_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */ +#endif /* STM32F407xx || STM32F417xx */ +/*------------------------------------------------------------------------------------------*/ + +/*---------------------------------- STM32F405xx/STM32F415xx--------------------------------*/ +#if defined (STM32F405xx) || defined (STM32F415xx) +/** + * @brief AF 0 selection + */ +#define GPIO_AF0_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */ +#define GPIO_AF0_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */ +#define GPIO_AF0_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */ +#define GPIO_AF0_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */ + +/** + * @brief AF 1 selection + */ +#define GPIO_AF1_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */ +#define GPIO_AF1_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */ + +/** + * @brief AF 2 selection + */ +#define GPIO_AF2_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */ +#define GPIO_AF2_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */ +#define GPIO_AF2_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */ + +/** + * @brief AF 3 selection + */ +#define GPIO_AF3_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */ +#define GPIO_AF3_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */ +#define GPIO_AF3_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */ +#define GPIO_AF3_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */ + +/** + * @brief AF 4 selection + */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */ +#define GPIO_AF4_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */ +#define GPIO_AF4_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */ + +/** + * @brief AF 5 selection + */ +#define GPIO_AF5_SPI1 ((uint8_t)0x05) /* SPI1 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF5_I2S3ext ((uint8_t)0x05) /* I2S3ext_SD Alternate Function mapping */ + +/** + * @brief AF 6 selection + */ +#define GPIO_AF6_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF6_I2S2ext ((uint8_t)0x06) /* I2S2ext_SD Alternate Function mapping */ + +/** + * @brief AF 7 selection + */ +#define GPIO_AF7_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */ +#define GPIO_AF7_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */ +#define GPIO_AF7_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */ +#define GPIO_AF7_I2S3ext ((uint8_t)0x07) /* I2S3ext_SD Alternate Function mapping */ + +/** + * @brief AF 8 selection + */ +#define GPIO_AF8_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */ +#define GPIO_AF8_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */ +#define GPIO_AF8_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */ + +/** + * @brief AF 9 selection + */ +#define GPIO_AF9_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */ +#define GPIO_AF9_CAN2 ((uint8_t)0x09) /* CAN2 Alternate Function mapping */ +#define GPIO_AF9_TIM12 ((uint8_t)0x09) /* TIM12 Alternate Function mapping */ +#define GPIO_AF9_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */ +#define GPIO_AF9_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */ + +/** + * @brief AF 10 selection + */ +#define GPIO_AF10_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */ +#define GPIO_AF10_OTG_HS ((uint8_t)0xA) /* OTG_HS Alternate Function mapping */ + +/** + * @brief AF 12 selection + */ +#define GPIO_AF12_FSMC ((uint8_t)0xC) /* FSMC Alternate Function mapping */ +#define GPIO_AF12_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS, Alternate Function mapping */ +#define GPIO_AF12_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */ + +/** + * @brief AF 15 selection + */ +#define GPIO_AF15_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */ +#endif /* STM32F405xx || STM32F415xx */ + +/*------------------------------------------------------------------------------------------*/ + +/*---------------------------------------- STM32F401xx--------------------------------------*/ +#if defined(STM32F401xC) || defined(STM32F401xE) +/** + * @brief AF 0 selection + */ +#define GPIO_AF0_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */ +#define GPIO_AF0_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */ +#define GPIO_AF0_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */ +#define GPIO_AF0_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */ + +/** + * @brief AF 1 selection + */ +#define GPIO_AF1_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */ +#define GPIO_AF1_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */ + +/** + * @brief AF 2 selection + */ +#define GPIO_AF2_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */ +#define GPIO_AF2_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */ +#define GPIO_AF2_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */ + +/** + * @brief AF 3 selection + */ +#define GPIO_AF3_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */ +#define GPIO_AF3_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */ +#define GPIO_AF3_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */ + +/** + * @brief AF 4 selection + */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */ +#define GPIO_AF4_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */ +#define GPIO_AF4_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */ + +/** + * @brief AF 5 selection + */ +#define GPIO_AF5_SPI1 ((uint8_t)0x05) /* SPI1 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF5_SPI4 ((uint8_t)0x05) /* SPI4 Alternate Function mapping */ +#define GPIO_AF5_I2S3ext ((uint8_t)0x05) /* I2S3ext_SD Alternate Function mapping */ + +/** + * @brief AF 6 selection + */ +#define GPIO_AF6_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF6_I2S2ext ((uint8_t)0x06) /* I2S2ext_SD Alternate Function mapping */ + +/** + * @brief AF 7 selection + */ +#define GPIO_AF7_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */ +#define GPIO_AF7_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */ +#define GPIO_AF7_I2S3ext ((uint8_t)0x07) /* I2S3ext_SD Alternate Function mapping */ + +/** + * @brief AF 8 selection + */ +#define GPIO_AF8_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */ + +/** + * @brief AF 9 selection + */ +#define GPIO_AF9_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */ +#define GPIO_AF9_I2C2 ((uint8_t)0x09) /* I2C2 Alternate Function mapping */ +#define GPIO_AF9_I2C3 ((uint8_t)0x09) /* I2C3 Alternate Function mapping */ + + +/** + * @brief AF 10 selection + */ +#define GPIO_AF10_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */ + +/** + * @brief AF 12 selection + */ +#define GPIO_AF12_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */ + +/** + * @brief AF 15 selection + */ +#define GPIO_AF15_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */ +#endif /* STM32F401xC || STM32F401xE */ +/*------------------------------------------------------------------------------------------*/ + +/*---------------------------------------- STM32F411xx--------------------------------------*/ +#if defined(STM32F411xE) +/** + * @brief AF 0 selection + */ +#define GPIO_AF0_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */ +#define GPIO_AF0_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */ +#define GPIO_AF0_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */ +#define GPIO_AF0_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */ + +/** + * @brief AF 1 selection + */ +#define GPIO_AF1_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */ +#define GPIO_AF1_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */ + +/** + * @brief AF 2 selection + */ +#define GPIO_AF2_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */ +#define GPIO_AF2_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */ +#define GPIO_AF2_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */ + +/** + * @brief AF 3 selection + */ +#define GPIO_AF3_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */ +#define GPIO_AF3_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */ +#define GPIO_AF3_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */ + +/** + * @brief AF 4 selection + */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */ +#define GPIO_AF4_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */ +#define GPIO_AF4_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */ + +/** + * @brief AF 5 selection + */ +#define GPIO_AF5_SPI1 ((uint8_t)0x05) /* SPI1/I2S1 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF5_SPI3 ((uint8_t)0x05) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF5_SPI4 ((uint8_t)0x05) /* SPI4 Alternate Function mapping */ +#define GPIO_AF5_I2S3ext ((uint8_t)0x05) /* I2S3ext_SD Alternate Function mapping */ + +/** + * @brief AF 6 selection + */ +#define GPIO_AF6_SPI2 ((uint8_t)0x06) /* I2S2 Alternate Function mapping */ +#define GPIO_AF6_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF6_SPI4 ((uint8_t)0x06) /* SPI4/I2S4 Alternate Function mapping */ +#define GPIO_AF6_SPI5 ((uint8_t)0x06) /* SPI5/I2S5 Alternate Function mapping */ +#define GPIO_AF6_I2S2ext ((uint8_t)0x06) /* I2S2ext_SD Alternate Function mapping */ +/** + * @brief AF 7 selection + */ +#define GPIO_AF7_SPI3 ((uint8_t)0x07) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF7_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */ +#define GPIO_AF7_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */ +#define GPIO_AF7_I2S3ext ((uint8_t)0x07) /* I2S3ext_SD Alternate Function mapping */ + +/** + * @brief AF 8 selection + */ +#define GPIO_AF8_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */ + +/** + * @brief AF 9 selection + */ +#define GPIO_AF9_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */ +#define GPIO_AF9_I2C2 ((uint8_t)0x09) /* I2C2 Alternate Function mapping */ +#define GPIO_AF9_I2C3 ((uint8_t)0x09) /* I2C3 Alternate Function mapping */ + + +/** + * @brief AF 10 selection + */ +#define GPIO_AF10_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */ + +/** + * @brief AF 12 selection + */ +#define GPIO_AF12_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */ + +/** + * @brief AF 15 selection + */ +#define GPIO_AF15_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */ +#endif /* STM32F411xE */ +/*---------------------------------------- STM32F446xx -------------------------------------------*/ +#if defined (STM32F446xx) +/** + * @brief AF 0 selection + */ +#define GPIO_AF0_RTC_50Hz ((uint8_t)0x00) /* RTC_50Hz Alternate Function mapping */ +#define GPIO_AF0_MCO ((uint8_t)0x00) /* MCO (MCO1 and MCO2) Alternate Function mapping */ +#define GPIO_AF0_TAMPER ((uint8_t)0x00) /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */ +#define GPIO_AF0_SWJ ((uint8_t)0x00) /* SWJ (SWD and JTAG) Alternate Function mapping */ +#define GPIO_AF0_TRACE ((uint8_t)0x00) /* TRACE Alternate Function mapping */ + +/** + * @brief AF 1 selection + */ +#define GPIO_AF1_TIM1 ((uint8_t)0x01) /* TIM1 Alternate Function mapping */ +#define GPIO_AF1_TIM2 ((uint8_t)0x01) /* TIM2 Alternate Function mapping */ + +/** + * @brief AF 2 selection + */ +#define GPIO_AF2_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */ +#define GPIO_AF2_TIM4 ((uint8_t)0x02) /* TIM4 Alternate Function mapping */ +#define GPIO_AF2_TIM5 ((uint8_t)0x02) /* TIM5 Alternate Function mapping */ + +/** + * @brief AF 3 selection + */ +#define GPIO_AF3_TIM8 ((uint8_t)0x03) /* TIM8 Alternate Function mapping */ +#define GPIO_AF3_TIM9 ((uint8_t)0x03) /* TIM9 Alternate Function mapping */ +#define GPIO_AF3_TIM10 ((uint8_t)0x03) /* TIM10 Alternate Function mapping */ +#define GPIO_AF3_TIM11 ((uint8_t)0x03) /* TIM11 Alternate Function mapping */ +#define GPIO_AF3_CEC ((uint8_t)0x03) /* CEC Alternate Function mapping */ + +/** + * @brief AF 4 selection + */ +#define GPIO_AF4_I2C1 ((uint8_t)0x04) /* I2C1 Alternate Function mapping */ +#define GPIO_AF4_I2C2 ((uint8_t)0x04) /* I2C2 Alternate Function mapping */ +#define GPIO_AF4_I2C3 ((uint8_t)0x04) /* I2C3 Alternate Function mapping */ +#define GPIO_AF4_FMPI2C1 ((uint8_t)0x04) /* FMPI2C1 Alternate Function mapping */ +#define GPIO_AF4_CEC ((uint8_t)0x04) /* CEC Alternate Function mapping */ + +/** + * @brief AF 5 selection + */ +#define GPIO_AF5_SPI1 ((uint8_t)0x05) /* SPI1/I2S1 Alternate Function mapping */ +#define GPIO_AF5_SPI2 ((uint8_t)0x05) /* SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF5_SPI3 ((uint8_t)0x05) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF5_SPI4 ((uint8_t)0x05) /* SPI4 Alternate Function mapping */ + +/** + * @brief AF 6 selection + */ +#define GPIO_AF6_SPI2 ((uint8_t)0x06) /* SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF6_SPI3 ((uint8_t)0x06) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF6_SPI4 ((uint8_t)0x06) /* SPI4 Alternate Function mapping */ +#define GPIO_AF6_SAI1 ((uint8_t)0x06) /* SAI1 Alternate Function mapping */ + +/** + * @brief AF 7 selection + */ +#define GPIO_AF7_USART1 ((uint8_t)0x07) /* USART1 Alternate Function mapping */ +#define GPIO_AF7_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */ +#define GPIO_AF7_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */ +#define GPIO_AF7_UART5 ((uint8_t)0x07) /* UART5 Alternate Function mapping */ +#define GPIO_AF7_SPI2 ((uint8_t)0x07) /* SPI2/I2S2 Alternate Function mapping */ +#define GPIO_AF7_SPI3 ((uint8_t)0x07) /* SPI3/I2S3 Alternate Function mapping */ +#define GPIO_AF7_SPDIFRX ((uint8_t)0x07) /* SPDIFRX Alternate Function mapping */ + +/** + * @brief AF 8 selection + */ +#define GPIO_AF8_UART4 ((uint8_t)0x08) /* UART4 Alternate Function mapping */ +#define GPIO_AF8_UART5 ((uint8_t)0x08) /* UART5 Alternate Function mapping */ +#define GPIO_AF8_USART6 ((uint8_t)0x08) /* USART6 Alternate Function mapping */ +#define GPIO_AF8_SPDIFRX ((uint8_t)0x08) /* SPDIFRX Alternate Function mapping */ +#define GPIO_AF8_SAI2 ((uint8_t)0x08) /* SAI2 Alternate Function mapping */ + +/** + * @brief AF 9 selection + */ +#define GPIO_AF9_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */ +#define GPIO_AF9_CAN2 ((uint8_t)0x09) /* CAN2 Alternate Function mapping */ +#define GPIO_AF9_TIM12 ((uint8_t)0x09) /* TIM12 Alternate Function mapping */ +#define GPIO_AF9_TIM13 ((uint8_t)0x09) /* TIM13 Alternate Function mapping */ +#define GPIO_AF9_TIM14 ((uint8_t)0x09) /* TIM14 Alternate Function mapping */ +#define GPIO_AF9_QSPI ((uint8_t)0x09) /* QSPI Alternate Function mapping */ + +/** + * @brief AF 10 selection + */ +#define GPIO_AF10_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */ +#define GPIO_AF10_OTG_HS ((uint8_t)0xA) /* OTG_HS Alternate Function mapping */ +#define GPIO_AF10_SAI2 ((uint8_t)0xA) /* SAI2 Alternate Function mapping */ +#define GPIO_AF10_QSPI ((uint8_t)0xA) /* QSPI Alternate Function mapping */ + +/** + * @brief AF 11 selection + */ +#define GPIO_AF11_ETH ((uint8_t)0x0B) /* ETHERNET Alternate Function mapping */ + +/** + * @brief AF 12 selection + */ +#define GPIO_AF12_FMC ((uint8_t)0xC) /* FMC Alternate Function mapping */ +#define GPIO_AF12_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS, Alternate Function mapping */ +#define GPIO_AF12_SDIO ((uint8_t)0xC) /* SDIO Alternate Function mapping */ + +/** + * @brief AF 13 selection + */ +#define GPIO_AF13_DCMI ((uint8_t)0x0D) /* DCMI Alternate Function mapping */ + +/** + * @brief AF 15 selection + */ +#define GPIO_AF15_EVENTOUT ((uint8_t)0x0F) /* EVENTOUT Alternate Function mapping */ + +#endif /* STM32F446xx */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup GPIOEx_Exported_Macros GPIO Exported Macros + * @{ + */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup GPIOEx_Exported_Functions GPIO Exported Functions + * @{ + */ +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup GPIOEx_Private_Constants GPIO Private Constants + * @{ + */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup GPIOEx_Private_Macros GPIO Private Macros + * @{ + */ +/** @defgroup GPIOEx_Get_Port_Index GPIO Get Port Index + * @{ + */ +#if defined (STM32F405xx) || defined (STM32F415xx) || defined (STM32F407xx) || defined (STM32F417xx) +#define GPIO_GET_INDEX(__GPIOx__) (uint8_t)(((__GPIOx__) == (GPIOA))? 0U :\ + ((__GPIOx__) == (GPIOB))? 1U :\ + ((__GPIOx__) == (GPIOC))? 2U :\ + ((__GPIOx__) == (GPIOD))? 3U :\ + ((__GPIOx__) == (GPIOE))? 4U :\ + ((__GPIOx__) == (GPIOF))? 5U :\ + ((__GPIOx__) == (GPIOG))? 6U :\ + ((__GPIOx__) == (GPIOH))? 7U :\ + ((__GPIOx__) == (GPIOI))? 8U : 9U) +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */ + +#if defined (STM32F427xx) || defined (STM32F437xx) || defined (STM32F429xx) || defined (STM32F439xx) +#define GPIO_GET_INDEX(__GPIOx__) (uint8_t)(((__GPIOx__) == (GPIOA))? 0U :\ + ((__GPIOx__) == (GPIOB))? 1U :\ + ((__GPIOx__) == (GPIOC))? 2U :\ + ((__GPIOx__) == (GPIOD))? 3U :\ + ((__GPIOx__) == (GPIOE))? 4U :\ + ((__GPIOx__) == (GPIOF))? 5U :\ + ((__GPIOx__) == (GPIOG))? 6U :\ + ((__GPIOx__) == (GPIOH))? 7U :\ + ((__GPIOx__) == (GPIOI))? 8U :\ + ((__GPIOx__) == (GPIOJ))? 9U : 10U) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +#if defined (STM32F401xC) || defined (STM32F401xE) || defined (STM32F411xE) +#define GPIO_GET_INDEX(__GPIOx__) (uint8_t)(((__GPIOx__) == (GPIOA))? 0U :\ + ((__GPIOx__) == (GPIOB))? 1U :\ + ((__GPIOx__) == (GPIOC))? 2U :\ + ((__GPIOx__) == (GPIOD))? 3U :\ + ((__GPIOx__) == (GPIOE))? 4U : 5U) +#endif /* STM32F401xC || STM32F401xE || STM32F411xE */ + +#if defined (STM32F446xx) +#define GPIO_GET_INDEX(__GPIOx__) (uint8_t)(((__GPIOx__) == (GPIOA))? 0U :\ + ((__GPIOx__) == (GPIOB))? 1U :\ + ((__GPIOx__) == (GPIOC))? 2U :\ + ((__GPIOx__) == (GPIOD))? 3U :\ + ((__GPIOx__) == (GPIOE))? 4U :\ + ((__GPIOx__) == (GPIOF))? 5U :\ + ((__GPIOx__) == (GPIOG))? 6U : 8U) +#endif /* STM32F446xx */ + +/** + * @} + */ + +/** @defgroup GPIOEx_IS_Alternat_function_selection GPIO Check Alternate Function + * @{ + */ +/*------------------------- STM32F429xx/STM32F439xx---------------------------*/ +#if defined (STM32F429xx) || defined (STM32F439xx) +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF9_TIM14) || \ + ((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF0_TAMPER) || \ + ((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \ + ((AF) == GPIO_AF1_TIM1) || ((AF) == GPIO_AF1_TIM2) || \ + ((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \ + ((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \ + ((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \ + ((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF5_SPI1) || \ + ((AF) == GPIO_AF5_SPI2) || ((AF) == GPIO_AF9_TIM13) || \ + ((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF9_TIM12) || \ + ((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \ + ((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF8_UART4) || \ + ((AF) == GPIO_AF8_UART5) || ((AF) == GPIO_AF8_USART6) || \ + ((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_CAN2) || \ + ((AF) == GPIO_AF10_OTG_FS) || ((AF) == GPIO_AF10_OTG_HS) || \ + ((AF) == GPIO_AF11_ETH) || ((AF) == GPIO_AF12_OTG_HS_FS) || \ + ((AF) == GPIO_AF12_SDIO) || ((AF) == GPIO_AF13_DCMI) || \ + ((AF) == GPIO_AF15_EVENTOUT) || ((AF) == GPIO_AF5_SPI4) || \ + ((AF) == GPIO_AF5_SPI5) || ((AF) == GPIO_AF5_SPI6) || \ + ((AF) == GPIO_AF8_UART7) || ((AF) == GPIO_AF8_UART8) || \ + ((AF) == GPIO_AF12_FMC) || ((AF) == GPIO_AF6_SAI1) || \ + ((AF) == GPIO_AF14_LTDC)) + +#endif /* STM32F429xx || STM32F439xx */ +/*------------------------------------------------------------------------------------------*/ + +/*---------------------------------- STM32F427xx/STM32F437xx--------------------------------*/ +#if defined (STM32F427xx) || defined (STM32F437xx) +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF9_TIM14) || \ + ((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF0_TAMPER) || \ + ((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \ + ((AF) == GPIO_AF1_TIM1) || ((AF) == GPIO_AF1_TIM2) || \ + ((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \ + ((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \ + ((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \ + ((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF5_SPI1) || \ + ((AF) == GPIO_AF5_SPI2) || ((AF) == GPIO_AF9_TIM13) || \ + ((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF9_TIM12) || \ + ((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \ + ((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF8_UART4) || \ + ((AF) == GPIO_AF8_UART5) || ((AF) == GPIO_AF8_USART6) || \ + ((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_CAN2) || \ + ((AF) == GPIO_AF10_OTG_FS) || ((AF) == GPIO_AF10_OTG_HS) || \ + ((AF) == GPIO_AF11_ETH) || ((AF) == GPIO_AF12_OTG_HS_FS) || \ + ((AF) == GPIO_AF12_SDIO) || ((AF) == GPIO_AF13_DCMI) || \ + ((AF) == GPIO_AF15_EVENTOUT) || ((AF) == GPIO_AF5_SPI4) || \ + ((AF) == GPIO_AF5_SPI5) || ((AF) == GPIO_AF5_SPI6) || \ + ((AF) == GPIO_AF8_UART7) || ((AF) == GPIO_AF8_UART8) || \ + ((AF) == GPIO_AF12_FMC) || ((AF) == GPIO_AF6_SAI1)) + +#endif /* STM32F427xx || STM32F437xx */ +/*------------------------------------------------------------------------------------------*/ + +/*---------------------------------- STM32F407xx/STM32F417xx--------------------------------*/ +#if defined (STM32F407xx) || defined (STM32F417xx) +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF9_TIM14) || \ + ((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF0_TAMPER) || \ + ((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \ + ((AF) == GPIO_AF1_TIM1) || ((AF) == GPIO_AF1_TIM2) || \ + ((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \ + ((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \ + ((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \ + ((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF5_SPI1) || \ + ((AF) == GPIO_AF5_SPI2) || ((AF) == GPIO_AF9_TIM13) || \ + ((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF9_TIM12) || \ + ((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \ + ((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF8_UART4) || \ + ((AF) == GPIO_AF8_UART5) || ((AF) == GPIO_AF8_USART6) || \ + ((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_CAN2) || \ + ((AF) == GPIO_AF10_OTG_FS) || ((AF) == GPIO_AF10_OTG_HS) || \ + ((AF) == GPIO_AF11_ETH) || ((AF) == GPIO_AF12_OTG_HS_FS) || \ + ((AF) == GPIO_AF12_SDIO) || ((AF) == GPIO_AF13_DCMI) || \ + ((AF) == GPIO_AF12_FSMC) || ((AF) == GPIO_AF15_EVENTOUT)) + +#endif /* STM32F407xx || STM32F417xx */ +/*------------------------------------------------------------------------------------------*/ + +/*---------------------------------- STM32F405xx/STM32F415xx--------------------------------*/ +#if defined (STM32F405xx) || defined (STM32F415xx) +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF9_TIM14) || \ + ((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF0_TAMPER) || \ + ((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \ + ((AF) == GPIO_AF1_TIM1) || ((AF) == GPIO_AF1_TIM2) || \ + ((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \ + ((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \ + ((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \ + ((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF5_SPI1) || \ + ((AF) == GPIO_AF5_SPI2) || ((AF) == GPIO_AF9_TIM13) || \ + ((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF9_TIM12) || \ + ((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \ + ((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF8_UART4) || \ + ((AF) == GPIO_AF8_UART5) || ((AF) == GPIO_AF8_USART6) || \ + ((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_CAN2) || \ + ((AF) == GPIO_AF10_OTG_FS) || ((AF) == GPIO_AF10_OTG_HS) || \ + ((AF) == GPIO_AF12_OTG_HS_FS) || ((AF) == GPIO_AF12_SDIO) || \ + ((AF) == GPIO_AF12_FSMC) || ((AF) == GPIO_AF15_EVENTOUT)) + +#endif /* STM32F405xx || STM32F415xx */ + +/*------------------------------------------------------------------------------------------*/ + +/*---------------------------------------- STM32F401xx--------------------------------------*/ +#if defined(STM32F401xC) || defined(STM32F401xE) +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF9_TIM14) || \ + ((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF0_TAMPER) || \ + ((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \ + ((AF) == GPIO_AF1_TIM1) || ((AF) == GPIO_AF1_TIM2) || \ + ((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \ + ((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF4_I2C1) || \ + ((AF) == GPIO_AF4_I2C2) || ((AF) == GPIO_AF4_I2C3) || \ + ((AF) == GPIO_AF5_SPI1) || ((AF) == GPIO_AF5_SPI2) || \ + ((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF5_SPI4) || \ + ((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \ + ((AF) == GPIO_AF8_USART6) || ((AF) == GPIO_AF10_OTG_FS) || \ + ((AF) == GPIO_AF9_I2C2) || ((AF) == GPIO_AF9_I2C3) || \ + ((AF) == GPIO_AF12_SDIO) || ((AF) == GPIO_AF15_EVENTOUT)) + +#endif /* STM32F401xC || STM32F401xE */ +/*------------------------------------------------------------------------------------------*/ + +/*---------------------------------------- STM32F411xx--------------------------------------*/ +#if defined(STM32F411xE) +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF9_TIM14) || \ + ((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF0_TAMPER) || \ + ((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \ + ((AF) == GPIO_AF1_TIM1) || ((AF) == GPIO_AF1_TIM2) || \ + ((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \ + ((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF4_I2C1) || \ + ((AF) == GPIO_AF4_I2C2) || ((AF) == GPIO_AF4_I2C3) || \ + ((AF) == GPIO_AF5_SPI1) || ((AF) == GPIO_AF5_SPI2) || \ + ((AF) == GPIO_AF5_SPI3) || ((AF) == GPIO_AF6_SPI4) || \ + ((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF5_SPI4) || \ + ((AF) == GPIO_AF6_SPI5) || ((AF) == GPIO_AF7_SPI3) || \ + ((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \ + ((AF) == GPIO_AF8_USART6) || ((AF) == GPIO_AF10_OTG_FS) || \ + ((AF) == GPIO_AF9_I2C2) || ((AF) == GPIO_AF9_I2C3) || \ + ((AF) == GPIO_AF12_SDIO) || ((AF) == GPIO_AF15_EVENTOUT)) + +#endif /* STM32F411xE */ +/*----------------------------------------------------------------------------------------------------*/ + +/*----------------------------------------------- STM32F446xx ----------------------------------------*/ +#if defined(STM32F446xx) +#define IS_GPIO_AF(AF) (((AF) == GPIO_AF0_RTC_50Hz) || ((AF) == GPIO_AF9_TIM14) || \ + ((AF) == GPIO_AF0_MCO) || ((AF) == GPIO_AF0_TAMPER) || \ + ((AF) == GPIO_AF0_SWJ) || ((AF) == GPIO_AF0_TRACE) || \ + ((AF) == GPIO_AF1_TIM1) || ((AF) == GPIO_AF1_TIM2) || \ + ((AF) == GPIO_AF2_TIM3) || ((AF) == GPIO_AF2_TIM4) || \ + ((AF) == GPIO_AF2_TIM5) || ((AF) == GPIO_AF3_TIM8) || \ + ((AF) == GPIO_AF4_I2C1) || ((AF) == GPIO_AF4_I2C2) || \ + ((AF) == GPIO_AF4_I2C3) || ((AF) == GPIO_AF5_SPI1) || \ + ((AF) == GPIO_AF5_SPI2) || ((AF) == GPIO_AF9_TIM13) || \ + ((AF) == GPIO_AF6_SPI3) || ((AF) == GPIO_AF9_TIM12) || \ + ((AF) == GPIO_AF7_USART1) || ((AF) == GPIO_AF7_USART2) || \ + ((AF) == GPIO_AF7_USART3) || ((AF) == GPIO_AF8_UART4) || \ + ((AF) == GPIO_AF8_UART5) || ((AF) == GPIO_AF8_USART6) || \ + ((AF) == GPIO_AF9_CAN1) || ((AF) == GPIO_AF9_CAN2) || \ + ((AF) == GPIO_AF10_OTG_FS) || ((AF) == GPIO_AF10_OTG_HS) || \ + ((AF) == GPIO_AF11_ETH) || ((AF) == GPIO_AF12_OTG_HS_FS) || \ + ((AF) == GPIO_AF12_SDIO) || ((AF) == GPIO_AF13_DCMI) || \ + ((AF) == GPIO_AF15_EVENTOUT) || ((AF) == GPIO_AF5_SPI4) || \ + ((AF) == GPIO_AF12_FMC) || ((AF) == GPIO_AF6_SAI1) || \ + ((AF) == GPIO_AF3_CEC) || ((AF) == GPIO_AF4_CEC) || \ + ((AF) == GPIO_AF5_SPI3) || ((AF) == GPIO_AF6_SPI2) || \ + ((AF) == GPIO_AF6_SPI4) || ((AF) == GPIO_AF7_UART5) || \ + ((AF) == GPIO_AF7_SPI2) || ((AF) == GPIO_AF7_SPI3) || \ + ((AF) == GPIO_AF7_SPDIFRX) || ((AF) == GPIO_AF8_SPDIFRX) || \ + ((AF) == GPIO_AF8_SAI2) || ((AF) == GPIO_AF9_QSPI) || \ + ((AF) == GPIO_AF10_SAI2) || ((AF) == GPIO_AF10_QSPI)) + +#endif /* STM32F446xx */ + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup GPIOEx_Private_Functions GPIO Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_GPIO_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_hash.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_hash.h new file mode 100644 index 0000000..fb39cdd --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_hash.h @@ -0,0 +1,450 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_hash.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of HASH HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_HASH_H +#define __STM32F4xx_HAL_HASH_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F415xx) || defined(STM32F417xx) || defined(STM32F437xx) || defined(STM32F439xx) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup HASH + * @brief HASH HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup HASH_Exported_Types HASH Exported Types + * @{ + */ + +/** @defgroup HASH_Exported_Types_Group1 HASH Configuration Structure definition + * @{ + */ + +typedef struct +{ + uint32_t DataType; /*!< 32-bit data, 16-bit data, 8-bit data or 1-bit string. + This parameter can be a value of @ref HASH DataType */ + + uint32_t KeySize; /*!< The key size is used only in HMAC operation */ + + uint8_t* pKey; /*!< The key is used only in HMAC operation */ +}HASH_InitTypeDef; + +/** + * @} + */ + +/** @defgroup HASH_Exported_Types_Group2 HASH State structures definition + * @{ + */ + +typedef enum +{ + HAL_HASH_STATE_RESET = 0x00, /*!< HASH not yet initialized or disabled */ + HAL_HASH_STATE_READY = 0x01, /*!< HASH initialized and ready for use */ + HAL_HASH_STATE_BUSY = 0x02, /*!< HASH internal process is ongoing */ + HAL_HASH_STATE_TIMEOUT = 0x03, /*!< HASH timeout state */ + HAL_HASH_STATE_ERROR = 0x04 /*!< HASH error state */ +}HAL_HASH_STATETypeDef; + +/** + * @} + */ + +/** @defgroup HASH_Exported_Types_Group3 HASH phase structures definition + * @{ + */ + +typedef enum +{ + HAL_HASH_PHASE_READY = 0x01, /*!< HASH peripheral is ready for initialization */ + HAL_HASH_PHASE_PROCESS = 0x02, /*!< HASH peripheral is in processing phase */ +}HAL_HASHPhaseTypeDef; + +/** + * @} + */ + +/** @defgroup HASH_Exported_Types_Group4 HASH Handle structures definition + * @{ + */ + +typedef struct +{ + HASH_InitTypeDef Init; /*!< HASH required parameters */ + + uint8_t *pHashInBuffPtr; /*!< Pointer to input buffer */ + + uint8_t *pHashOutBuffPtr; /*!< Pointer to input buffer */ + + __IO uint32_t HashBuffSize; /*!< Size of buffer to be processed */ + + __IO uint32_t HashInCount; /*!< Counter of inputed data */ + + __IO uint32_t HashITCounter; /*!< Counter of issued interrupts */ + + HAL_StatusTypeDef Status; /*!< HASH peripheral status */ + + HAL_HASHPhaseTypeDef Phase; /*!< HASH peripheral phase */ + + DMA_HandleTypeDef *hdmain; /*!< HASH In DMA handle parameters */ + + HAL_LockTypeDef Lock; /*!< HASH locking object */ + + __IO HAL_HASH_STATETypeDef State; /*!< HASH peripheral state */ +} HASH_HandleTypeDef; + +/** + * @} + */ + + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup HASH_Exported_Constants HASH Exported Constants + * @{ + */ + +/** @defgroup HASH_Exported_Constants_Group1 HASH Algorithm Selection + * @{ + */ +#define HASH_ALGOSELECTION_SHA1 ((uint32_t)0x0000) /*!< HASH function is SHA1 */ +#define HASH_ALGOSELECTION_SHA224 HASH_CR_ALGO_1 /*!< HASH function is SHA224 */ +#define HASH_ALGOSELECTION_SHA256 HASH_CR_ALGO /*!< HASH function is SHA256 */ +#define HASH_ALGOSELECTION_MD5 HASH_CR_ALGO_0 /*!< HASH function is MD5 */ +/** + * @} + */ + +/** @defgroup HASH_Exported_Constants_Group2 HASH Algorithm Mode + * @{ + */ +#define HASH_ALGOMODE_HASH ((uint32_t)0x00000000) /*!< Algorithm is HASH */ +#define HASH_ALGOMODE_HMAC HASH_CR_MODE /*!< Algorithm is HMAC */ +/** + * @} + */ + +/** @defgroup HASH_Exported_Constants_Group3 HASH DataType + * @{ + */ +#define HASH_DATATYPE_32B ((uint32_t)0x0000) /*!< 32-bit data. No swapping */ +#define HASH_DATATYPE_16B HASH_CR_DATATYPE_0 /*!< 16-bit data. Each half word is swapped */ +#define HASH_DATATYPE_8B HASH_CR_DATATYPE_1 /*!< 8-bit data. All bytes are swapped */ +#define HASH_DATATYPE_1B HASH_CR_DATATYPE /*!< 1-bit data. In the word all bits are swapped */ +/** + * @} + */ + +/** @defgroup HASH_Exported_Constants_Group4 HASH HMAC Long key + * @brief HASH HMAC Long key used only for HMAC mode + * @{ + */ +#define HASH_HMAC_KEYTYPE_SHORTKEY ((uint32_t)0x00000000) /*!< HMAC Key is <= 64 bytes */ +#define HASH_HMAC_KEYTYPE_LONGKEY HASH_CR_LKEY /*!< HMAC Key is > 64 bytes */ +/** + * @} + */ + +/** @defgroup HASH_Exported_Constants_Group5 HASH Flags definition + * @{ + */ +#define HASH_FLAG_DINIS HASH_SR_DINIS /*!< 16 locations are free in the DIN : A new block can be entered into the input buffer */ +#define HASH_FLAG_DCIS HASH_SR_DCIS /*!< Digest calculation complete */ +#define HASH_FLAG_DMAS HASH_SR_DMAS /*!< DMA interface is enabled (DMAE=1) or a transfer is ongoing */ +#define HASH_FLAG_BUSY HASH_SR_BUSY /*!< The hash core is Busy : processing a block of data */ +#define HASH_FLAG_DINNE HASH_CR_DINNE /*!< DIN not empty : The input buffer contains at least one word of data */ +/** + * @} + */ + +/** @defgroup HASH_Exported_Constants_Group6 HASH Interrupts definition + * @{ + */ +#define HASH_IT_DINI HASH_IMR_DINIE /*!< A new block can be entered into the input buffer (DIN) */ +#define HASH_IT_DCI HASH_IMR_DCIE /*!< Digest calculation complete */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup HASH_Exported_Macros HASH Exported Macros + * @{ + */ + +/** @brief Reset HASH handle state + * @param __HANDLE__: specifies the HASH handle. + * @retval None + */ +#define __HAL_HASH_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_HASH_STATE_RESET) + +/** @brief Check whether the specified HASH flag is set or not. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg HASH_FLAG_DINIS: A new block can be entered into the input buffer. + * @arg HASH_FLAG_DCIS: Digest calculation complete + * @arg HASH_FLAG_DMAS: DMA interface is enabled (DMAE=1) or a transfer is ongoing + * @arg HASH_FLAG_BUSY: The hash core is Busy : processing a block of data + * @arg HASH_FLAG_DINNE: DIN not empty : The input buffer contains at least one word of data + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_HASH_GET_FLAG(__FLAG__) (((__FLAG__) > 8U) ? ((HASH->CR & (__FLAG__)) == (__FLAG__)) :\ + ((HASH->SR & (__FLAG__)) == (__FLAG__))) +/** + * @brief Enable the multiple DMA mode. + * This feature is available only in STM32F429x and STM32F439x devices. + * @retval None + */ +#define __HAL_HASH_SET_MDMAT() HASH->CR |= HASH_CR_MDMAT + +/** + * @brief Disable the multiple DMA mode. + * @retval None + */ +#define __HAL_HASH_RESET_MDMAT() HASH->CR &= (uint32_t)(~HASH_CR_MDMAT) + +/** + * @brief Start the digest computation + * @retval None + */ +#define __HAL_HASH_START_DIGEST() HASH->STR |= HASH_STR_DCAL + +/** + * @brief Set the number of valid bits in last word written in Data register + * @param SIZE: size in byte of last data written in Data register. + * @retval None +*/ +#define __HAL_HASH_SET_NBVALIDBITS(SIZE) do{HASH->STR &= ~(HASH_STR_NBLW);\ + HASH->STR |= 8 * ((SIZE) % 4);\ + }while(0) + +/** + * @} + */ + +/* Include HASH HAL Extension module */ +#include "stm32f4xx_hal_hash_ex.h" +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup HASH_Exported_Functions HASH Exported Functions + * @{ + */ + +/** @addtogroup HASH_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_HASH_Init(HASH_HandleTypeDef *hhash); +HAL_StatusTypeDef HAL_HASH_DeInit(HASH_HandleTypeDef *hhash); +/** + * @} + */ + +/** @addtogroup HASH_Exported_Functions_Group2 + * @{ + */ +HAL_StatusTypeDef HAL_HASH_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout); +HAL_StatusTypeDef HAL_HASH_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout); +HAL_StatusTypeDef HAL_HASH_MD5_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size); +HAL_StatusTypeDef HAL_HASH_SHA1_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size); +/** + * @} + */ + +/** @addtogroup HASH_Exported_Functions_Group3 + * @{ + */ +HAL_StatusTypeDef HAL_HMAC_SHA1_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout); +HAL_StatusTypeDef HAL_HMAC_MD5_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout); +/** + * @} + */ + +/** @addtogroup HASH_Exported_Functions_Group4 + * @{ + */ +HAL_StatusTypeDef HAL_HASH_SHA1_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer); +HAL_StatusTypeDef HAL_HASH_MD5_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer); +/** + * @} + */ + +/** @addtogroup HASH_Exported_Functions_Group5 + * @{ + */ +HAL_StatusTypeDef HAL_HASH_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size); +HAL_StatusTypeDef HAL_HASH_SHA1_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout); +HAL_StatusTypeDef HAL_HASH_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size); +HAL_StatusTypeDef HAL_HASH_MD5_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout); +/** + * @} + */ + +/** @addtogroup HASH_Exported_Functions_Group6 + * @{ + */ +HAL_StatusTypeDef HAL_HMAC_SHA1_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size); +HAL_StatusTypeDef HAL_HMAC_MD5_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size); +/** + * @} + */ + +/** @addtogroup HASH_Exported_Functions_Group7 + * @{ + */ +void HAL_HASH_IRQHandler(HASH_HandleTypeDef *hhash); +/** + * @} + */ + +/** @addtogroup HASH_Exported_Functions_Group8 + * @{ + */ +HAL_HASH_STATETypeDef HAL_HASH_GetState(HASH_HandleTypeDef *hhash); +void HAL_HASH_MspInit(HASH_HandleTypeDef *hhash); +void HAL_HASH_MspDeInit(HASH_HandleTypeDef *hhash); +void HAL_HASH_InCpltCallback(HASH_HandleTypeDef *hhash); +void HAL_HASH_DgstCpltCallback(HASH_HandleTypeDef *hhash); +void HAL_HASH_ErrorCallback(HASH_HandleTypeDef *hhash); +/** + * @} + */ + + /** + * @} + */ + + /* Private types -------------------------------------------------------------*/ +/** @defgroup HASH_Private_Types HASH Private Types + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup HASH_Private_Variables HASH Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup HASH_Private_Constants HASH Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup HASH_Private_Macros HASH Private Macros + * @{ + */ +#define IS_HASH_ALGOSELECTION(__ALGOSELECTION__) (((__ALGOSELECTION__) == HASH_ALGOSELECTION_SHA1) || \ + ((__ALGOSELECTION__) == HASH_ALGOSELECTION_SHA224) || \ + ((__ALGOSELECTION__) == HASH_ALGOSELECTION_SHA256) || \ + ((__ALGOSELECTION__) == HASH_ALGOSELECTION_MD5)) + + +#define IS_HASH_ALGOMODE(__ALGOMODE__) (((__ALGOMODE__) == HASH_ALGOMODE_HASH) || \ + ((__ALGOMODE__) == HASH_ALGOMODE_HMAC)) + + +#define IS_HASH_DATATYPE(__DATATYPE__) (((__DATATYPE__) == HASH_DATATYPE_32B)|| \ + ((__DATATYPE__) == HASH_DATATYPE_16B)|| \ + ((__DATATYPE__) == HASH_DATATYPE_8B) || \ + ((__DATATYPE__) == HASH_DATATYPE_1B)) + + +#define IS_HASH_HMAC_KEYTYPE(__KEYTYPE__) (((__KEYTYPE__) == HASH_HMAC_KEYTYPE_SHORTKEY) || \ + ((__KEYTYPE__) == HASH_HMAC_KEYTYPE_LONGKEY)) + +#define IS_HASH_SHA1_BUFFER_SIZE(__SIZE__) ((((__SIZE__)%4) != 0)? 0U: 1U) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup HASH_Private_Functions HASH Private Functions + * @{ + */ + +/** + * @} + */ + +#endif /* STM32F415xx || STM32F417xx || STM32F437xx || STM32F439xx */ +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F4xx_HAL_HASH_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_hash_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_hash_ex.h new file mode 100644 index 0000000..b4d2625 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_hash_ex.h @@ -0,0 +1,200 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_hash_ex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of HASH HAL Extension module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_HASH_EX_H +#define __STM32F4xx_HAL_HASH_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F437xx) || defined(STM32F439xx) +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup HASHEx + * @brief HASHEx HAL Extension module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup HASHEx_Exported_Functions HASHEx Exported Functions + * @{ + */ + +/** @defgroup HASHEx_Exported_Functions_Group1 HASHEx processing using polling functions + * @{ + */ + +HAL_StatusTypeDef HAL_HASHEx_SHA224_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout); +HAL_StatusTypeDef HAL_HASHEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout); +HAL_StatusTypeDef HAL_HASHEx_SHA224_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size); +HAL_StatusTypeDef HAL_HASHEx_SHA256_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size); + +/** + * @} + */ + +/** @defgroup HASHEx_Exported_Functions_Group2 HMAC processing using polling functions + * @{ + */ + +HAL_StatusTypeDef HAL_HMACEx_SHA224_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout); +HAL_StatusTypeDef HAL_HMACEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout); + +/** + * @} + */ + +/** @defgroup HASHEx_Exported_Functions_Group3 HASHEx processing using functions + * @{ + */ + +HAL_StatusTypeDef HAL_HASHEx_SHA224_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer); +HAL_StatusTypeDef HAL_HASHEx_SHA256_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer); + +/** + * @} + */ + +/** @defgroup HASHEx_Exported_Functions_Group4 HASHEx processing using DMA + * @{ + */ + +HAL_StatusTypeDef HAL_HASHEx_SHA224_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size); +HAL_StatusTypeDef HAL_HASHEx_SHA224_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout); +HAL_StatusTypeDef HAL_HASHEx_SHA256_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size); +HAL_StatusTypeDef HAL_HASHEx_SHA256_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout); + +/** + * @} + */ + +/** @defgroup HASHEx_Exported_Functions_Group5 HMAC processing using DMA + * @{ + */ + +HAL_StatusTypeDef HAL_HMACEx_SHA224_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size); +HAL_StatusTypeDef HAL_HMACEx_SHA256_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size); +/** + * @} + */ + +/** @defgroup HASHEx_Exported_Functions_Group6 HASHEx processing functions + * @{ + */ + +void HAL_HASHEx_IRQHandler(HASH_HandleTypeDef *hhash); + +/** + * @} + */ + +/** + * @} + */ + + /* Private types -------------------------------------------------------------*/ +/** @defgroup HASHEx_Private_Types HASHEx Private Types + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup HASHEx_Private_Variables HASHEx Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup HASHEx_Private_Constants HASHEx Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup HASHEx_Private_Macros HASHEx Private Macros + * @{ + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup HASHEx_Private_Functions HASHEx Private Functions + * @{ + */ + +/** + * @} + */ + +#endif /* STM32F437xx || STM32F439xx */ +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_HASH_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_hcd.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_hcd.h new file mode 100644 index 0000000..5bd40d6 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_hcd.h @@ -0,0 +1,273 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_hcd.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of HCD HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_HCD_H +#define __STM32F4xx_HAL_HCD_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_ll_usb.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup HCD + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup HCD_Exported_Types HCD Exported Types + * @{ + */ + +/** @defgroup HCD_Exported_Types_Group1 HCD State Structure definition + * @{ + */ +typedef enum +{ + HAL_HCD_STATE_RESET = 0x00, + HAL_HCD_STATE_READY = 0x01, + HAL_HCD_STATE_ERROR = 0x02, + HAL_HCD_STATE_BUSY = 0x03, + HAL_HCD_STATE_TIMEOUT = 0x04 +} HCD_StateTypeDef; + +typedef USB_OTG_GlobalTypeDef HCD_TypeDef; +typedef USB_OTG_CfgTypeDef HCD_InitTypeDef; +typedef USB_OTG_HCTypeDef HCD_HCTypeDef ; +typedef USB_OTG_URBStateTypeDef HCD_URBStateTypeDef ; +typedef USB_OTG_HCStateTypeDef HCD_HCStateTypeDef ; +/** + * @} + */ + +/** @defgroup HCD_Exported_Types_Group2 HCD Handle Structure definition + * @{ + */ + +#define HOST_CHANNEL_COUNT 15 + +typedef struct +{ + HCD_TypeDef *Instance; /*!< Register base address */ + HCD_InitTypeDef Init; /*!< HCD required parameters */ + HCD_HCTypeDef hc[HOST_CHANNEL_COUNT]; /*!< Host channels parameters */ + HAL_LockTypeDef Lock; /*!< HCD peripheral status */ + __IO HCD_StateTypeDef State; /*!< HCD communication state */ + void *pData; /*!< Pointer Stack Handler */ +} HCD_HandleTypeDef; +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup HCD_Exported_Constants HCD Exported Constants + * @{ + */ + +/** @defgroup HCD_Speed HCD Speed + * @{ + */ +#define HCD_SPEED_HIGH 0 +#define HCD_SPEED_LOW 2 +#define HCD_SPEED_FULL 3 +/** + * @} + */ + +/** @defgroup HCD_PHY_Module HCD PHY Module + * @{ + */ +#define HCD_PHY_ULPI 1 +#define HCD_PHY_EMBEDDED 2 +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup HCD_Exported_Macros HCD Exported Macros + * @brief macros to handle interrupts and specific clock configurations + * @{ + */ +#define __HAL_HCD_ENABLE(__HANDLE__) USB_EnableGlobalInt ((__HANDLE__)->Instance) +#define __HAL_HCD_DISABLE(__HANDLE__) USB_DisableGlobalInt ((__HANDLE__)->Instance) + +#define __HAL_HCD_GET_FLAG(__HANDLE__, __INTERRUPT__) ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__)) +#define __HAL_HCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->GINTSTS) = (__INTERRUPT__)) +#define __HAL_HCD_IS_INVALID_INTERRUPT(__HANDLE__) (USB_ReadInterrupts((__HANDLE__)->Instance) == 0) + +#define __HAL_HCD_CLEAR_HC_INT(chnum, __INTERRUPT__) (USBx_HC(chnum)->HCINT = (__INTERRUPT__)) +#define __HAL_HCD_MASK_HALT_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK &= ~USB_OTG_HCINTMSK_CHHM) +#define __HAL_HCD_UNMASK_HALT_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM) +#define __HAL_HCD_MASK_ACK_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK &= ~USB_OTG_HCINTMSK_ACKM) +#define __HAL_HCD_UNMASK_ACK_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK |= USB_OTG_HCINTMSK_ACKM) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HCD_Exported_Functions HCD Exported Functions + * @{ + */ + +/* Initialization/de-initialization functions ********************************/ +/** @addtogroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd); +HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd); +HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, + uint8_t ch_num, + uint8_t epnum, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps); + +HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num); + +void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd); +void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd); +/** + * @} + */ + +/* I/O operation functions ***************************************************/ +/** @addtogroup HCD_Exported_Functions_Group2 IO operation functions + * @{ + */ +HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, + uint8_t pipe, + uint8_t direction, + uint8_t ep_type, + uint8_t token, + uint8_t* pbuff, + uint16_t length, + uint8_t do_ping); + +/* Non-Blocking mode: Interrupt */ +void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd); +void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd); +void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd); +void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd); +HAL_StatusTypeDef HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd); +void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, + uint8_t chnum, + HCD_URBStateTypeDef urb_state); +/** + * @} + */ + +/* Peripheral Control functions **********************************************/ +/** @addtogroup HCD_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ +HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd); +HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd); +HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd); +/** + * @} + */ + +/* Peripheral State functions ************************************************/ +/** @addtogroup HCD_Exported_Functions_Group4 Peripheral State functions + * @{ + */ +HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd); +HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum); +uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum); +HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum); +uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd); +uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd); +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup HCD_Private_Macros HCD Private Macros + * @{ + */ +/** @defgroup HCD_Instance_definition HCD Instance definition + * @{ + */ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) ||\ + defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) + #define IS_HCD_ALL_INSTANCE(INSTANCE) (((INSTANCE) == USB_OTG_FS) || \ + ((INSTANCE) == USB_OTG_HS)) +#elif defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) + #define IS_HCD_ALL_INSTANCE(INSTANCE) (((INSTANCE) == USB_OTG_FS)) +#endif +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_HCD_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h new file mode 100644 index 0000000..dc58d5f --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h @@ -0,0 +1,535 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2c.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of I2C HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_I2C_H +#define __STM32F4xx_HAL_I2C_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup I2C + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup I2C_Exported_Types I2C Exported Types + * @{ + */ + +/** + * @brief I2C Configuration Structure definition + */ +typedef struct +{ + uint32_t ClockSpeed; /*!< Specifies the clock frequency. + This parameter must be set to a value lower than 400kHz */ + + uint32_t DutyCycle; /*!< Specifies the I2C fast mode duty cycle. + This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */ + + uint32_t OwnAddress1; /*!< Specifies the first device own address. + This parameter can be a 7-bit or 10-bit address. */ + + uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected. + This parameter can be a value of @ref I2C_addressing_mode */ + + uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected. + This parameter can be a value of @ref I2C_dual_addressing_mode */ + + uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected + This parameter can be a 7-bit address. */ + + uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected. + This parameter can be a value of @ref I2C_general_call_addressing_mode */ + + uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected. + This parameter can be a value of @ref I2C_nostretch_mode */ + +}I2C_InitTypeDef; + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_I2C_STATE_RESET = 0x00, /*!< I2C not yet initialized or disabled */ + HAL_I2C_STATE_READY = 0x01, /*!< I2C initialized and ready for use */ + HAL_I2C_STATE_BUSY = 0x02, /*!< I2C internal process is ongoing */ + HAL_I2C_STATE_BUSY_TX = 0x12, /*!< Data Transmission process is ongoing */ + HAL_I2C_STATE_BUSY_RX = 0x22, /*!< Data Reception process is ongoing */ + HAL_I2C_STATE_MEM_BUSY_TX = 0x32, /*!< Memory Data Transmission process is ongoing */ + HAL_I2C_STATE_MEM_BUSY_RX = 0x42, /*!< Memory Data Reception process is ongoing */ + HAL_I2C_STATE_TIMEOUT = 0x03, /*!< I2C timeout state */ + HAL_I2C_STATE_ERROR = 0x04 /*!< I2C error state */ + +}HAL_I2C_StateTypeDef; + +/** + * @brief I2C handle Structure definition + */ +typedef struct +{ + I2C_TypeDef *Instance; /*!< I2C registers base address */ + + I2C_InitTypeDef Init; /*!< I2C communication parameters */ + + uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */ + + uint16_t XferSize; /*!< I2C transfer size */ + + __IO uint16_t XferCount; /*!< I2C transfer counter */ + + DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */ + + HAL_LockTypeDef Lock; /*!< I2C locking object */ + + __IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */ + + __IO uint32_t ErrorCode; /*!< I2C Error code */ + +}I2C_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2C_Exported_Constants I2C Exported Constants + * @{ + */ + +/** @defgroup I2C_Error_Code I2C Error Code + * @brief I2C Error Code + * @{ + */ +#define HAL_I2C_ERROR_NONE ((uint32_t)0x00000000) /*!< No error */ +#define HAL_I2C_ERROR_BERR ((uint32_t)0x00000001) /*!< BERR error */ +#define HAL_I2C_ERROR_ARLO ((uint32_t)0x00000002) /*!< ARLO error */ +#define HAL_I2C_ERROR_AF ((uint32_t)0x00000004) /*!< AF error */ +#define HAL_I2C_ERROR_OVR ((uint32_t)0x00000008) /*!< OVR error */ +#define HAL_I2C_ERROR_DMA ((uint32_t)0x00000010) /*!< DMA transfer error */ +#define HAL_I2C_ERROR_TIMEOUT ((uint32_t)0x00000020) /*!< Timeout Error */ +/** + * @} + */ + +/** @defgroup I2C_duty_cycle_in_fast_mode I2C duty cycle in fast mode + * @{ + */ +#define I2C_DUTYCYCLE_2 ((uint32_t)0x00000000) +#define I2C_DUTYCYCLE_16_9 I2C_CCR_DUTY +/** + * @} + */ + +/** @defgroup I2C_addressing_mode I2C addressing mode + * @{ + */ +#define I2C_ADDRESSINGMODE_7BIT ((uint32_t)0x00004000) +#define I2C_ADDRESSINGMODE_10BIT (I2C_OAR1_ADDMODE | ((uint32_t)0x00004000)) +/** + * @} + */ + +/** @defgroup I2C_dual_addressing_mode I2C dual addressing mode + * @{ + */ +#define I2C_DUALADDRESS_DISABLE ((uint32_t)0x00000000) +#define I2C_DUALADDRESS_ENABLE I2C_OAR2_ENDUAL +/** + * @} + */ + +/** @defgroup I2C_general_call_addressing_mode I2C general call addressing mode + * @{ + */ +#define I2C_GENERALCALL_DISABLE ((uint32_t)0x00000000) +#define I2C_GENERALCALL_ENABLE I2C_CR1_ENGC +/** + * @} + */ + +/** @defgroup I2C_nostretch_mode I2C nostretch mode + * @{ + */ +#define I2C_NOSTRETCH_DISABLE ((uint32_t)0x00000000) +#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH +/** + * @} + */ + +/** @defgroup I2C_Memory_Address_Size I2C Memory Address Size + * @{ + */ +#define I2C_MEMADD_SIZE_8BIT ((uint32_t)0x00000001) +#define I2C_MEMADD_SIZE_16BIT ((uint32_t)0x00000010) +/** + * @} + */ + +/** @defgroup I2C_Interrupt_configuration_definition I2C Interrupt configuration definition + * @{ + */ +#define I2C_IT_BUF I2C_CR2_ITBUFEN +#define I2C_IT_EVT I2C_CR2_ITEVTEN +#define I2C_IT_ERR I2C_CR2_ITERREN +/** + * @} + */ + +/** @defgroup I2C_Flag_definition I2C Flag definition + * @{ + */ +#define I2C_FLAG_SMBALERT ((uint32_t)0x00018000) +#define I2C_FLAG_TIMEOUT ((uint32_t)0x00014000) +#define I2C_FLAG_PECERR ((uint32_t)0x00011000) +#define I2C_FLAG_OVR ((uint32_t)0x00010800) +#define I2C_FLAG_AF ((uint32_t)0x00010400) +#define I2C_FLAG_ARLO ((uint32_t)0x00010200) +#define I2C_FLAG_BERR ((uint32_t)0x00010100) +#define I2C_FLAG_TXE ((uint32_t)0x00010080) +#define I2C_FLAG_RXNE ((uint32_t)0x00010040) +#define I2C_FLAG_STOPF ((uint32_t)0x00010010) +#define I2C_FLAG_ADD10 ((uint32_t)0x00010008) +#define I2C_FLAG_BTF ((uint32_t)0x00010004) +#define I2C_FLAG_ADDR ((uint32_t)0x00010002) +#define I2C_FLAG_SB ((uint32_t)0x00010001) +#define I2C_FLAG_DUALF ((uint32_t)0x00100080) +#define I2C_FLAG_SMBHOST ((uint32_t)0x00100040) +#define I2C_FLAG_SMBDEFAULT ((uint32_t)0x00100020) +#define I2C_FLAG_GENCALL ((uint32_t)0x00100010) +#define I2C_FLAG_TRA ((uint32_t)0x00100004) +#define I2C_FLAG_BUSY ((uint32_t)0x00100002) +#define I2C_FLAG_MSL ((uint32_t)0x00100001) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup I2C_Exported_Macros I2C Exported Macros + * @{ + */ + +/** @brief Reset I2C handle state + * @param __HANDLE__: specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @retval None + */ +#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET) + +/** @brief Enable or disable the specified I2C interrupts. + * @param __HANDLE__: specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @param __INTERRUPT__: specifies the interrupt source to enable or disable. + * This parameter can be one of the following values: + * @arg I2C_IT_BUF: Buffer interrupt enable + * @arg I2C_IT_EVT: Event interrupt enable + * @arg I2C_IT_ERR: Error interrupt enable + * @retval None + */ +#define __HAL_I2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 |= (__INTERRUPT__)) +#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 &= (~(__INTERRUPT__))) + +/** @brief Checks if the specified I2C interrupt source is enabled or disabled. + * @param __HANDLE__: specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @param __INTERRUPT__: specifies the I2C interrupt source to check. + * This parameter can be one of the following values: + * @arg I2C_IT_BUF: Buffer interrupt enable + * @arg I2C_IT_EVT: Event interrupt enable + * @arg I2C_IT_ERR: Error interrupt enable + * @retval The new state of __INTERRUPT__ (TRUE or FALSE). + */ +#define __HAL_I2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Checks whether the specified I2C flag is set or not. + * @param __HANDLE__: specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg I2C_FLAG_SMBALERT: SMBus Alert flag + * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_FLAG_PECERR: PEC error in reception flag + * @arg I2C_FLAG_OVR: Overrun/Underrun flag + * @arg I2C_FLAG_AF: Acknowledge failure flag + * @arg I2C_FLAG_ARLO: Arbitration lost flag + * @arg I2C_FLAG_BERR: Bus error flag + * @arg I2C_FLAG_TXE: Data register empty flag + * @arg I2C_FLAG_RXNE: Data register not empty flag + * @arg I2C_FLAG_STOPF: Stop detection flag + * @arg I2C_FLAG_ADD10: 10-bit header sent flag + * @arg I2C_FLAG_BTF: Byte transfer finished flag + * @arg I2C_FLAG_ADDR: Address sent flag + * Address matched flag + * @arg I2C_FLAG_SB: Start bit flag + * @arg I2C_FLAG_DUALF: Dual flag + * @arg I2C_FLAG_SMBHOST: SMBus host header + * @arg I2C_FLAG_SMBDEFAULT: SMBus default header + * @arg I2C_FLAG_GENCALL: General call header flag + * @arg I2C_FLAG_TRA: Transmitter/Receiver flag + * @arg I2C_FLAG_BUSY: Bus busy flag + * @arg I2C_FLAG_MSL: Master/Slave flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_I2C_GET_FLAG(__HANDLE__, __FLAG__) ((((uint8_t)((__FLAG__) >> 16)) == 0x01)?((((__HANDLE__)->Instance->SR1) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)): \ + ((((__HANDLE__)->Instance->SR2) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK))) + +/** @brief Clears the I2C pending flags which are cleared by writing 0 in a specific bit. + * @param __HANDLE__: specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @param __FLAG__: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg I2C_FLAG_SMBALERT: SMBus Alert flag + * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_FLAG_PECERR: PEC error in reception flag + * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) + * @arg I2C_FLAG_AF: Acknowledge failure flag + * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) + * @arg I2C_FLAG_BERR: Bus error flag + * @retval None + */ +#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR1 = ~((__FLAG__) & I2C_FLAG_MASK)) + +/** @brief Clears the I2C ADDR pending flag. + * @param __HANDLE__: specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @retval None + */ +#define __HAL_I2C_CLEAR_ADDRFLAG(__HANDLE__) \ + do{ \ + __IO uint32_t tmpreg; \ + tmpreg = (__HANDLE__)->Instance->SR1; \ + tmpreg = (__HANDLE__)->Instance->SR2; \ + UNUSED(tmpreg); \ + } while(0) + +/** @brief Clears the I2C STOPF pending flag. + * @param __HANDLE__: specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @retval None + */ +#define __HAL_I2C_CLEAR_STOPFLAG(__HANDLE__) \ + do{ \ + __IO uint32_t tmpreg; \ + tmpreg = (__HANDLE__)->Instance->SR1; \ + (__HANDLE__)->Instance->CR1 |= I2C_CR1_PE; \ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_I2C_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= I2C_CR1_PE) +#define __HAL_I2C_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~I2C_CR1_PE) + +/** + * @} + */ + +/* Include I2C HAL Extension module */ +#include "stm32f4xx_hal_i2c_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup I2C_Exported_Functions + * @{ + */ + +/** @addtogroup I2C_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions **********************************/ +HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2C_DeInit (I2C_HandleTypeDef *hi2c); +void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c); +/** + * @} + */ + +/** @addtogroup I2C_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions *****************************************************/ +/******* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout); + +/******* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); + +/******* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); + +/******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */ +void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c); +void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c); +/** + * @} + */ + +/** @addtogroup I2C_Exported_Functions_Group3 + * @{ + */ +/* Peripheral Control and State functions **************************************/ +HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c); +uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c); + +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2C_Private_Constants I2C Private Constants + * @{ + */ +#define I2C_FLAG_MASK ((uint32_t)0x0000FFFF) +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2C_Private_Macros I2C Private Macros + * @{ + */ + +#define I2C_FREQRANGE(__PCLK__) ((__PCLK__)/1000000) +#define I2C_RISE_TIME(__FREQRANGE__, __SPEED__) (((__SPEED__) <= 100000) ? ((__FREQRANGE__) + 1) : ((((__FREQRANGE__) * 300) / 1000) + 1)) +#define I2C_SPEED_STANDARD(__PCLK__, __SPEED__) (((((__PCLK__)/((__SPEED__) << 1)) & I2C_CCR_CCR) < 4)? 4:((__PCLK__) / ((__SPEED__) << 1))) +#define I2C_SPEED_FAST(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__DUTYCYCLE__) == I2C_DUTYCYCLE_2)? ((__PCLK__) / ((__SPEED__) * 3)) : (((__PCLK__) / ((__SPEED__) * 25)) | I2C_DUTYCYCLE_16_9)) +#define I2C_SPEED(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__SPEED__) <= 100000)? (I2C_SPEED_STANDARD((__PCLK__), (__SPEED__))) : \ + ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__)) & I2C_CCR_CCR) == 0)? 1 : \ + ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__))) | I2C_CCR_FS)) + +#define I2C_7BIT_ADD_WRITE(__ADDRESS__) ((uint8_t)((__ADDRESS__) & (~I2C_OAR1_ADD0))) +#define I2C_7BIT_ADD_READ(__ADDRESS__) ((uint8_t)((__ADDRESS__) | I2C_OAR1_ADD0)) + +#define I2C_10BIT_ADDRESS(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FF)))) +#define I2C_10BIT_HEADER_WRITE(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0x0300))) >> 7) | (uint16_t)(0xF0)))) +#define I2C_10BIT_HEADER_READ(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0x0300))) >> 7) | (uint16_t)(0xF1)))) + +#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)(0xFF00))) >> 8))) +#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FF)))) + +/** @defgroup I2C_IS_RTC_Definitions I2C Private macros to check input parameters + * @{ + */ +#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DUTYCYCLE_2) || \ + ((CYCLE) == I2C_DUTYCYCLE_16_9)) +#define IS_I2C_ADDRESSING_MODE(ADDRESS) (((ADDRESS) == I2C_ADDRESSINGMODE_7BIT) || \ + ((ADDRESS) == I2C_ADDRESSINGMODE_10BIT)) +#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || \ + ((ADDRESS) == I2C_DUALADDRESS_ENABLE)) +#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \ + ((CALL) == I2C_GENERALCALL_ENABLE)) +#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \ + ((STRETCH) == I2C_NOSTRETCH_ENABLE)) +#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || \ + ((SIZE) == I2C_MEMADD_SIZE_16BIT)) +#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) > 0) && ((SPEED) <= 400000)) +#define IS_I2C_OWN_ADDRESS1(ADDRESS1) (((ADDRESS1) & (uint32_t)(0xFFFFFC00)) == 0) +#define IS_I2C_OWN_ADDRESS2(ADDRESS2) (((ADDRESS2) & (uint32_t)(0xFFFFFF01)) == 0) +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup I2C_Private_Functions I2C Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F4xx_HAL_I2C_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h new file mode 100644 index 0000000..b364620 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h @@ -0,0 +1,136 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2c_ex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of I2C HAL Extension module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_I2C_EX_H +#define __STM32F4xx_HAL_I2C_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup I2CEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2CEx_Exported_Constants I2C Exported Constants + * @{ + */ + +/** @defgroup I2CEx_Analog_Filter I2C Analog Filter + * @{ + */ +#define I2C_ANALOGFILTER_ENABLE ((uint32_t)0x00000000) +#define I2C_ANALOGFILTER_DISABLE I2C_FLTR_ANOFF +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup I2CEx_Exported_Functions + * @{ + */ + +/** @addtogroup I2CEx_Exported_Functions_Group1 + * @{ + */ +/* Peripheral Control functions ************************************************/ +HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter); +HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2CEx_Private_Constants I2C Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2CEx_Private_Macros I2C Private Macros + * @{ + */ +#define IS_I2C_ANALOG_FILTER(FILTER) (((FILTER) == I2C_ANALOGFILTER_ENABLE) || \ + ((FILTER) == I2C_ANALOGFILTER_DISABLE)) +#define IS_I2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000F) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_I2C_EX_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2s.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2s.h new file mode 100644 index 0000000..18e6c2d --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2s.h @@ -0,0 +1,511 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2s.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of I2S HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_I2S_H +#define __STM32F4xx_HAL_I2S_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup I2S + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup I2S_Exported_Types I2S Exported Types + * @{ + */ + +/** + * @brief I2S Init structure definition + */ +typedef struct +{ + uint32_t Mode; /*!< Specifies the I2S operating mode. + This parameter can be a value of @ref I2S_Mode */ + + uint32_t Standard; /*!< Specifies the standard used for the I2S communication. + This parameter can be a value of @ref I2S_Standard */ + + uint32_t DataFormat; /*!< Specifies the data format for the I2S communication. + This parameter can be a value of @ref I2S_Data_Format */ + + uint32_t MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not. + This parameter can be a value of @ref I2S_MCLK_Output */ + + uint32_t AudioFreq; /*!< Specifies the frequency selected for the I2S communication. + This parameter can be a value of @ref I2S_Audio_Frequency */ + + uint32_t CPOL; /*!< Specifies the idle state of the I2S clock. + This parameter can be a value of @ref I2S_Clock_Polarity */ + + uint32_t ClockSource; /*!< Specifies the I2S Clock Source. + This parameter can be a value of @ref I2S_Clock_Source */ + + uint32_t FullDuplexMode; /*!< Specifies the I2S FullDuplex mode. + This parameter can be a value of @ref I2S_FullDuplex_Mode */ + +}I2S_InitTypeDef; + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_I2S_STATE_RESET = 0x00, /*!< I2S not yet initialized or disabled */ + HAL_I2S_STATE_READY = 0x01, /*!< I2S initialized and ready for use */ + HAL_I2S_STATE_BUSY = 0x02, /*!< I2S internal process is ongoing */ + HAL_I2S_STATE_BUSY_TX = 0x12, /*!< Data Transmission process is ongoing */ + HAL_I2S_STATE_BUSY_RX = 0x22, /*!< Data Reception process is ongoing */ + HAL_I2S_STATE_BUSY_TX_RX = 0x32, /*!< Data Transmission and Reception process is ongoing */ + HAL_I2S_STATE_TIMEOUT = 0x03, /*!< I2S timeout state */ + HAL_I2S_STATE_ERROR = 0x04 /*!< I2S error state */ + +}HAL_I2S_StateTypeDef; + +/** + * @brief I2S handle Structure definition + */ +typedef struct +{ + SPI_TypeDef *Instance; /* I2S registers base address */ + + I2S_InitTypeDef Init; /* I2S communication parameters */ + + uint16_t *pTxBuffPtr; /* Pointer to I2S Tx transfer buffer */ + + __IO uint16_t TxXferSize; /* I2S Tx transfer size */ + + __IO uint16_t TxXferCount; /* I2S Tx transfer Counter */ + + uint16_t *pRxBuffPtr; /* Pointer to I2S Rx transfer buffer */ + + __IO uint16_t RxXferSize; /* I2S Rx transfer size */ + + __IO uint16_t RxXferCount; /* I2S Rx transfer counter */ + + DMA_HandleTypeDef *hdmatx; /* I2S Tx DMA handle parameters */ + + DMA_HandleTypeDef *hdmarx; /* I2S Rx DMA handle parameters */ + + __IO HAL_LockTypeDef Lock; /* I2S locking object */ + + __IO HAL_I2S_StateTypeDef State; /* I2S communication state */ + + __IO uint32_t ErrorCode; /* I2S Error code */ + +}I2S_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2S_Exported_Constants I2S Exported Constants + * @{ + */ + +/** @defgroup I2S_Error_Code I2S Error Code + * @brief I2S Error Code + * @{ + */ +#define HAL_I2S_ERROR_NONE ((uint32_t)0x00000000) /*!< No error */ +#define HAL_I2S_ERROR_UDR ((uint32_t)0x00000001) /*!< I2S Underrun error */ +#define HAL_I2S_ERROR_OVR ((uint32_t)0x00000002) /*!< I2S Overrun error */ +#define HAL_I2SEX_ERROR_UDR ((uint32_t)0x00000004) /*!< I2S extended Underrun error */ +#define HAL_I2SEX_ERROR_OVR ((uint32_t)0x00000008) /*!< I2S extended Overrun error */ +#define HAL_I2S_ERROR_FRE ((uint32_t)0x00000010) /*!< I2S Frame format error */ +#define HAL_I2S_ERROR_DMA ((uint32_t)0x00000020) /*!< DMA transfer error */ +/** + * @} + */ + +/** @defgroup I2S_Clock_Source I2S Clock Source + * @{ + */ +#define I2S_CLOCK_PLL ((uint32_t)0x00000000) +#define I2S_CLOCK_EXTERNAL ((uint32_t)0x00000001) +#define I2S_CLOCK_PLLR ((uint32_t)0x00000002) +#define I2S_CLOCK_PLLSRC ((uint32_t)0x00000003) +/** + * @} + */ + +/** @defgroup I2S_Mode I2S Mode + * @{ + */ +#define I2S_MODE_SLAVE_TX ((uint32_t)0x00000000) +#define I2S_MODE_SLAVE_RX ((uint32_t)0x00000100) +#define I2S_MODE_MASTER_TX ((uint32_t)0x00000200) +#define I2S_MODE_MASTER_RX ((uint32_t)0x00000300) +/** + * @} + */ + +/** @defgroup I2S_Standard I2S Standard + * @{ + */ +#define I2S_STANDARD_PHILIPS ((uint32_t)0x00000000) +#define I2S_STANDARD_MSB ((uint32_t)0x00000010) +#define I2S_STANDARD_LSB ((uint32_t)0x00000020) +#define I2S_STANDARD_PCM_SHORT ((uint32_t)0x00000030) +#define I2S_STANDARD_PCM_LONG ((uint32_t)0x000000B0) +/** + * @} + */ + +/** @defgroup I2S_Data_Format I2S Data Format + * @{ + */ +#define I2S_DATAFORMAT_16B ((uint32_t)0x00000000) +#define I2S_DATAFORMAT_16B_EXTENDED ((uint32_t)0x00000001) +#define I2S_DATAFORMAT_24B ((uint32_t)0x00000003) +#define I2S_DATAFORMAT_32B ((uint32_t)0x00000005) +/** + * @} + */ + +/** @defgroup I2S_MCLK_Output I2S Mclk Output + * @{ + */ +#define I2S_MCLKOUTPUT_ENABLE ((uint32_t)SPI_I2SPR_MCKOE) +#define I2S_MCLKOUTPUT_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup I2S_Audio_Frequency I2S Audio Frequency + * @{ + */ +#define I2S_AUDIOFREQ_192K ((uint32_t)192000) +#define I2S_AUDIOFREQ_96K ((uint32_t)96000) +#define I2S_AUDIOFREQ_48K ((uint32_t)48000) +#define I2S_AUDIOFREQ_44K ((uint32_t)44100) +#define I2S_AUDIOFREQ_32K ((uint32_t)32000) +#define I2S_AUDIOFREQ_22K ((uint32_t)22050) +#define I2S_AUDIOFREQ_16K ((uint32_t)16000) +#define I2S_AUDIOFREQ_11K ((uint32_t)11025) +#define I2S_AUDIOFREQ_8K ((uint32_t)8000) +#define I2S_AUDIOFREQ_DEFAULT ((uint32_t)2) +/** + * @} + */ + +/** @defgroup I2S_FullDuplex_Mode I2S FullDuplex Mode + * @{ + */ +#define I2S_FULLDUPLEXMODE_DISABLE ((uint32_t)0x00000000) +#define I2S_FULLDUPLEXMODE_ENABLE ((uint32_t)0x00000001) +/** + * @} + */ + +/** @defgroup I2S_Clock_Polarity I2S Clock Polarity + * @{ + */ +#define I2S_CPOL_LOW ((uint32_t)0x00000000) +#define I2S_CPOL_HIGH ((uint32_t)SPI_I2SCFGR_CKPOL) +/** + * @} + */ + +/** @defgroup I2S_Interrupts_Definition I2S Interrupts Definition + * @{ + */ +#define I2S_IT_TXE SPI_CR2_TXEIE +#define I2S_IT_RXNE SPI_CR2_RXNEIE +#define I2S_IT_ERR SPI_CR2_ERRIE +/** + * @} + */ + +/** @defgroup I2S_Flags_Definition I2S Flags Definition + * @{ + */ +#define I2S_FLAG_TXE SPI_SR_TXE +#define I2S_FLAG_RXNE SPI_SR_RXNE + +#define I2S_FLAG_UDR SPI_SR_UDR +#define I2S_FLAG_OVR SPI_SR_OVR +#define I2S_FLAG_FRE SPI_SR_FRE + +#define I2S_FLAG_CHSIDE SPI_SR_CHSIDE +#define I2S_FLAG_BSY SPI_SR_BSY +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup I2S_Exported_Macros I2S Exported Macros + * @{ + */ + +/** @brief Reset I2S handle state + * @param __HANDLE__: specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2S_STATE_RESET) + +/** @brief Enable or disable the specified SPI peripheral (in I2S mode). + * @param __HANDLE__: specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->I2SCFGR |= SPI_I2SCFGR_I2SE) +#define __HAL_I2S_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->I2SCFGR &= ~SPI_I2SCFGR_I2SE) + +/** @brief Enable or disable the specified I2S interrupts. + * @param __HANDLE__: specifies the I2S Handle. + * @param __INTERRUPT__: specifies the interrupt source to enable or disable. + * This parameter can be one of the following values: + * @arg I2S_IT_TXE: Tx buffer empty interrupt enable + * @arg I2S_IT_RXNE: RX buffer not empty interrupt enable + * @arg I2S_IT_ERR: Error interrupt enable + * @retval None + */ +#define __HAL_I2S_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 |= (__INTERRUPT__)) +#define __HAL_I2S_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 &= ~(__INTERRUPT__)) + +/** @brief Checks if the specified I2S interrupt source is enabled or disabled. + * @param __HANDLE__: specifies the I2S Handle. + * This parameter can be I2S where x: 1, 2, or 3 to select the I2S peripheral. + * @param __INTERRUPT__: specifies the I2S interrupt source to check. + * This parameter can be one of the following values: + * @arg I2S_IT_TXE: Tx buffer empty interrupt enable + * @arg I2S_IT_RXNE: RX buffer not empty interrupt enable + * @arg I2S_IT_ERR: Error interrupt enable + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_I2S_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Checks whether the specified I2S flag is set or not. + * @param __HANDLE__: specifies the I2S Handle. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg I2S_FLAG_RXNE: Receive buffer not empty flag + * @arg I2S_FLAG_TXE: Transmit buffer empty flag + * @arg I2S_FLAG_UDR: Underrun flag + * @arg I2S_FLAG_OVR: Overrun flag + * @arg I2S_FLAG_FRE: Frame error flag + * @arg I2S_FLAG_CHSIDE: Channel Side flag + * @arg I2S_FLAG_BSY: Busy flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_I2S_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__)) + +/** @brief Clears the I2S OVR pending flag. + * @param __HANDLE__: specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_CLEAR_OVRFLAG(__HANDLE__) \ + do{ \ + __IO uint32_t tmpreg; \ + tmpreg = (__HANDLE__)->Instance->DR; \ + tmpreg = (__HANDLE__)->Instance->SR; \ + UNUSED(tmpreg); \ + } while(0) + +/** @brief Clears the I2S UDR pending flag. + * @param __HANDLE__: specifies the I2S Handle. + * @retval None + */ +#define __HAL_I2S_CLEAR_UDRFLAG(__HANDLE__) \ + do{ \ + __IO uint32_t tmpreg; \ + tmpreg = (__HANDLE__)->Instance->SR; \ + UNUSED(tmpreg); \ + } while(0) +/** + * @} + */ + +/* Include I2S Extension module */ +#include "stm32f4xx_hal_i2s_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup I2S_Exported_Functions + * @{ + */ + +/** @addtogroup I2S_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions **********************************/ +HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s); +HAL_StatusTypeDef HAL_I2S_DeInit (I2S_HandleTypeDef *hi2s); +void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s); +void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s); +/** + * @} + */ + +/** @addtogroup I2S_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions *****************************************************/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout); + + /* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size); +void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s); + +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size); + +HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s); +HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s); +HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s); + +/* Peripheral Control and State functions **************************************/ +HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s); +uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s); + +/* Callbacks used in non blocking modes (Interrupt and DMA) *******************/ +void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s); +void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s); +void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s); +void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s); +void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2S_Private_Constants I2S Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2S_Private_Macros I2S Private Macros + * @{ + */ +#define IS_I2S_CLOCKSOURCE(CLOCK) (((CLOCK) == I2S_CLOCK_EXTERNAL) || \ + ((CLOCK) == I2S_CLOCK_PLLR) ||\ + ((CLOCK) == I2S_CLOCK_PLLSRC) ||\ + ((CLOCK) == I2S_CLOCK_PLL)) + +#define IS_I2S_MODE(MODE) (((MODE) == I2S_MODE_SLAVE_TX) || \ + ((MODE) == I2S_MODE_SLAVE_RX) || \ + ((MODE) == I2S_MODE_MASTER_TX) || \ + ((MODE) == I2S_MODE_MASTER_RX)) + +#define IS_I2S_STANDARD(STANDARD) (((STANDARD) == I2S_STANDARD_PHILIPS) || \ + ((STANDARD) == I2S_STANDARD_MSB) || \ + ((STANDARD) == I2S_STANDARD_LSB) || \ + ((STANDARD) == I2S_STANDARD_PCM_SHORT) || \ + ((STANDARD) == I2S_STANDARD_PCM_LONG)) + +#define IS_I2S_DATA_FORMAT(FORMAT) (((FORMAT) == I2S_DATAFORMAT_16B) || \ + ((FORMAT) == I2S_DATAFORMAT_16B_EXTENDED) || \ + ((FORMAT) == I2S_DATAFORMAT_24B) || \ + ((FORMAT) == I2S_DATAFORMAT_32B)) + +#define IS_I2S_MCLK_OUTPUT(OUTPUT) (((OUTPUT) == I2S_MCLKOUTPUT_ENABLE) || \ + ((OUTPUT) == I2S_MCLKOUTPUT_DISABLE)) + +#define IS_I2S_AUDIO_FREQ(FREQ) ((((FREQ) >= I2S_AUDIOFREQ_8K) && \ + ((FREQ) <= I2S_AUDIOFREQ_192K)) || \ + ((FREQ) == I2S_AUDIOFREQ_DEFAULT)) + +#define IS_I2S_FULLDUPLEX_MODE(MODE) (((MODE) == I2S_FULLDUPLEXMODE_DISABLE) || \ + ((MODE) == I2S_FULLDUPLEXMODE_ENABLE)) + +#define IS_I2S_CPOL(CPOL) (((CPOL) == I2S_CPOL_LOW) || \ + ((CPOL) == I2S_CPOL_HIGH)) + +#define I2SxEXT(__INSTANCE__) ((__INSTANCE__) == (SPI2)? (SPI_TypeDef *)(I2S2ext_BASE): (SPI_TypeDef *)(I2S3ext_BASE)) +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup I2S_Private_Functions I2S Private Functions + * @{ + */ +void I2S_DMATxCplt(DMA_HandleTypeDef *hdma); +void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma); +void I2S_DMARxCplt(DMA_HandleTypeDef *hdma); +void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma); +void I2S_DMAError(DMA_HandleTypeDef *hdma); +HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, uint32_t Status, uint32_t Timeout); +HAL_StatusTypeDef I2S_Transmit_IT(I2S_HandleTypeDef *hi2s); +HAL_StatusTypeDef I2S_Receive_IT(I2S_HandleTypeDef *hi2s); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F4xx_HAL_I2S_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2s_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2s_ex.h new file mode 100644 index 0000000..81cdc62 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2s_ex.h @@ -0,0 +1,148 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2s_ex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of I2S HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_I2S_EX_H +#define __STM32F4xx_HAL_I2S_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup I2SEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup I2SEx_Exported_Types I2S Exported Types + * @{ + */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2SEx_Exported_Constants I2S Exported Constants + * @{ + */ +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup I2SEx_Exported_Macros I2S Exported Macros + * @{ + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup I2SEx_Exported_Functions + * @{ + */ + +/** @addtogroup I2SEx_Exported_Functions_Group1 + * @{ + */ + +/* Extended features functions **************************************************/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size, uint32_t Timeout); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2SEx_Private_Constants I2S Private Constants + * @{ + */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2SEx_Private_Macros I2S Private Macros + * @{ + */ +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup I2SEx_Private_Functions I2S Private Functions + * @{ + */ +HAL_StatusTypeDef I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s); +uint32_t I2S_GetInputClock(I2S_HandleTypeDef *hi2s); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F4xx_HAL_I2S_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_irda.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_irda.h new file mode 100644 index 0000000..2516f7c --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_irda.h @@ -0,0 +1,538 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_irda.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of IRDA HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_IRDA_H +#define __STM32F4xx_HAL_IRDA_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup IRDA + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup IRDA_Exported_Types IRDA Exported Types + * @{ + */ +/** + * @brief IRDA Init Structure definition + */ +typedef struct +{ + uint32_t BaudRate; /*!< This member configures the IRDA communication baud rate. + The baud rate is computed using the following formula: + - IntegerDivider = ((PCLKx) / (8 * (hirda->Init.BaudRate))) + - FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 8) + 0.5 */ + + uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref IRDA_Word_Length */ + + + uint32_t Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref IRDA_Parity + @note When parity is enabled, the computed parity is inserted + at the MSB position of the transmitted data (9th bit when + the word length is set to 9 data bits; 8th bit when the + word length is set to 8 data bits). */ + + uint32_t Mode; /*!< Specifies wether the Receive or Transmit mode is enabled or disabled. + This parameter can be a value of @ref IRDA_Mode */ + + uint8_t Prescaler; /*!< Specifies the Prescaler */ + + uint32_t IrDAMode; /*!< Specifies the IrDA mode + This parameter can be a value of @ref IRDA_Low_Power */ +}IRDA_InitTypeDef; + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_IRDA_STATE_RESET = 0x00, /*!< Peripheral is not yet Initialized */ + HAL_IRDA_STATE_READY = 0x01, /*!< Peripheral Initialized and ready for use */ + HAL_IRDA_STATE_BUSY = 0x02, /*!< An internal process is ongoing */ + HAL_IRDA_STATE_BUSY_TX = 0x12, /*!< Data Transmission process is ongoing */ + HAL_IRDA_STATE_BUSY_RX = 0x22, /*!< Data Reception process is ongoing */ + HAL_IRDA_STATE_BUSY_TX_RX = 0x32, /*!< Data Transmission and Reception process is ongoing */ + HAL_IRDA_STATE_TIMEOUT = 0x03, /*!< Timeout state */ + HAL_IRDA_STATE_ERROR = 0x04 /*!< Error */ +}HAL_IRDA_StateTypeDef; + +/** + * @brief IRDA handle Structure definition + */ +typedef struct +{ + USART_TypeDef *Instance; /* USART registers base address */ + + IRDA_InitTypeDef Init; /* IRDA communication parameters */ + + uint8_t *pTxBuffPtr; /* Pointer to IRDA Tx transfer Buffer */ + + uint16_t TxXferSize; /* IRDA Tx Transfer size */ + + uint16_t TxXferCount; /* IRDA Tx Transfer Counter */ + + uint8_t *pRxBuffPtr; /* Pointer to IRDA Rx transfer Buffer */ + + uint16_t RxXferSize; /* IRDA Rx Transfer size */ + + uint16_t RxXferCount; /* IRDA Rx Transfer Counter */ + + DMA_HandleTypeDef *hdmatx; /* IRDA Tx DMA Handle parameters */ + + DMA_HandleTypeDef *hdmarx; /* IRDA Rx DMA Handle parameters */ + + HAL_LockTypeDef Lock; /* Locking object */ + + __IO HAL_IRDA_StateTypeDef State; /* IRDA communication state */ + + __IO uint32_t ErrorCode; /* IRDA Error code */ + +}IRDA_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup IRDA_Exported_Constants IRDA Exported constants + * @{ + */ +/** @defgroup IRDA_Error_Code IRDA Error Code + * @brief IRDA Error Code + * @{ + */ +#define HAL_IRDA_ERROR_NONE ((uint32_t)0x00000000) /*!< No error */ +#define HAL_IRDA_ERROR_PE ((uint32_t)0x00000001) /*!< Parity error */ +#define HAL_IRDA_ERROR_NE ((uint32_t)0x00000002) /*!< Noise error */ +#define HAL_IRDA_ERROR_FE ((uint32_t)0x00000004) /*!< Frame error */ +#define HAL_IRDA_ERROR_ORE ((uint32_t)0x00000008) /*!< Overrun error */ +#define HAL_IRDA_ERROR_DMA ((uint32_t)0x00000010) /*!< DMA transfer error */ +/** + * @} + */ + +/** @defgroup IRDA_Word_Length IRDA Word Length + * @{ + */ +#define IRDA_WORDLENGTH_8B ((uint32_t)0x00000000) +#define IRDA_WORDLENGTH_9B ((uint32_t)USART_CR1_M) +/** + * @} + */ + +/** @defgroup IRDA_Parity IRDA Parity + * @{ + */ +#define IRDA_PARITY_NONE ((uint32_t)0x00000000) +#define IRDA_PARITY_EVEN ((uint32_t)USART_CR1_PCE) +#define IRDA_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS)) +/** + * @} + */ + +/** @defgroup IRDA_Mode IRDA Transfer Mode + * @{ + */ +#define IRDA_MODE_RX ((uint32_t)USART_CR1_RE) +#define IRDA_MODE_TX ((uint32_t)USART_CR1_TE) +#define IRDA_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE)) +/** + * @} + */ + +/** @defgroup IRDA_Low_Power IRDA Low Power + * @{ + */ +#define IRDA_POWERMODE_LOWPOWER ((uint32_t)USART_CR3_IRLP) +#define IRDA_POWERMODE_NORMAL ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup IRDA_Flags IRDA Flags + * Elements values convention: 0xXXXX + * - 0xXXXX : Flag mask in the SR register + * @{ + */ +#define IRDA_FLAG_TXE ((uint32_t)0x00000080) +#define IRDA_FLAG_TC ((uint32_t)0x00000040) +#define IRDA_FLAG_RXNE ((uint32_t)0x00000020) +#define IRDA_FLAG_IDLE ((uint32_t)0x00000010) +#define IRDA_FLAG_ORE ((uint32_t)0x00000008) +#define IRDA_FLAG_NE ((uint32_t)0x00000004) +#define IRDA_FLAG_FE ((uint32_t)0x00000002) +#define IRDA_FLAG_PE ((uint32_t)0x00000001) +/** + * @} + */ + +/** @defgroup IRDA_Interrupt_definition IRDA Interrupt Definitions + * Elements values convention: 0xY000XXXX + * - XXXX : Interrupt mask in the XX register + * - Y : Interrupt source register (2bits) + * - 01: CR1 register + * - 10: CR2 register + * - 11: CR3 register + * @{ + */ +#define IRDA_IT_PE ((uint32_t)(IRDA_CR1_REG_INDEX << 28 | USART_CR1_PEIE)) +#define IRDA_IT_TXE ((uint32_t)(IRDA_CR1_REG_INDEX << 28 | USART_CR1_TXEIE)) +#define IRDA_IT_TC ((uint32_t)(IRDA_CR1_REG_INDEX << 28 | USART_CR1_TCIE)) +#define IRDA_IT_RXNE ((uint32_t)(IRDA_CR1_REG_INDEX << 28 | USART_CR1_RXNEIE)) +#define IRDA_IT_IDLE ((uint32_t)(IRDA_CR1_REG_INDEX << 28 | USART_CR1_IDLEIE)) + +#define IRDA_IT_LBD ((uint32_t)(IRDA_CR2_REG_INDEX << 28 | USART_CR2_LBDIE)) + +#define IRDA_IT_CTS ((uint32_t)(IRDA_CR3_REG_INDEX << 28 | USART_CR3_CTSIE)) +#define IRDA_IT_ERR ((uint32_t)(IRDA_CR3_REG_INDEX << 28 | USART_CR3_EIE)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup IRDA_Exported_Macros IRDA Exported Macros + * @{ + */ + +/** @brief Reset IRDA handle state + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_IRDA_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_IRDA_STATE_RESET) + +/** @brief Flushs the IRDA DR register + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + */ +#define __HAL_IRDA_FLUSH_DRREGISTER(__HANDLE__) ((__HANDLE__)->Instance->DR) + +/** @brief Checks whether the specified IRDA flag is set or not. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg IRDA_FLAG_TXE: Transmit data register empty flag + * @arg IRDA_FLAG_TC: Transmission Complete flag + * @arg IRDA_FLAG_RXNE: Receive data register not empty flag + * @arg IRDA_FLAG_IDLE: Idle Line detection flag + * @arg IRDA_FLAG_ORE: OverRun Error flag + * @arg IRDA_FLAG_NE: Noise Error flag + * @arg IRDA_FLAG_FE: Framing Error flag + * @arg IRDA_FLAG_PE: Parity Error flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_IRDA_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__)) + +/** @brief Clears the specified IRDA pending flag. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @param __FLAG__: specifies the flag to check. + * This parameter can be any combination of the following values: + * @arg IRDA_FLAG_TC: Transmission Complete flag. + * @arg IRDA_FLAG_RXNE: Receive data register not empty flag. + * + * @note PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun + * error) and IDLE (Idle line detected) flags are cleared by software + * sequence: a read operation to USART_SR register followed by a read + * operation to USART_DR register. + * @note RXNE flag can be also cleared by a read to the USART_DR register. + * @note TC flag can be also cleared by software sequence: a read operation to + * USART_SR register followed by a write operation to USART_DR register. + * @note TXE flag is cleared only by a write to the USART_DR register. + * + * @retval None + */ +#define __HAL_IRDA_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__)) + +/** @brief Clear the IRDA PE pending flag. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__) \ + do{ \ + __IO uint32_t tmpreg; \ + tmpreg = (__HANDLE__)->Instance->SR; \ + UNUSED(tmpreg); \ + } while(0) + +/** @brief Clear the IRDA FE pending flag. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_IRDA_CLEAR_FEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__) + +/** @brief Clear the IRDA NE pending flag. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_IRDA_CLEAR_NEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__) + +/** @brief Clear the IRDA ORE pending flag. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_IRDA_CLEAR_OREFLAG(__HANDLE__) __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__) + +/** @brief Clear the IRDA IDLE pending flag. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_IRDA_CLEAR_IDLEFLAG(__HANDLE__) __HAL_IRDA_CLEAR_PEFLAG(__HANDLE__) + +/** @brief Enables or disables the specified IRDA interrupt. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @param __INTERRUPT__: specifies the IRDA interrupt source to check. + * This parameter can be one of the following values: + * @arg IRDA_IT_TXE: Transmit Data Register empty interrupt + * @arg IRDA_IT_TC: Transmission complete interrupt + * @arg IRDA_IT_RXNE: Receive Data register not empty interrupt + * @arg IRDA_IT_IDLE: Idle line detection interrupt + * @arg IRDA_IT_PE: Parity Error interrupt + * @arg IRDA_IT_ERR: Error interrupt(Frame error, noise error, overrun error) + * @retval None + */ +#define __HAL_IRDA_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28) == 1)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & IRDA_IT_MASK)): \ + (((__INTERRUPT__) >> 28) == 2)? ((__HANDLE__)->Instance->CR2 |= ((__INTERRUPT__) & IRDA_IT_MASK)): \ + ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & IRDA_IT_MASK))) +#define __HAL_IRDA_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28) == 1)? ((__HANDLE__)->Instance->CR1 &= ~((__INTERRUPT__) & IRDA_IT_MASK)): \ + (((__INTERRUPT__) >> 28) == 2)? ((__HANDLE__)->Instance->CR2 &= ~((__INTERRUPT__) & IRDA_IT_MASK)): \ + ((__HANDLE__)->Instance->CR3 &= ~ ((__INTERRUPT__) & IRDA_IT_MASK))) + +/** @brief Checks whether the specified IRDA interrupt has occurred or not. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @param __IT__: specifies the IRDA interrupt source to check. + * This parameter can be one of the following values: + * @arg IRDA_IT_TXE: Transmit Data Register empty interrupt + * @arg IRDA_IT_TC: Transmission complete interrupt + * @arg IRDA_IT_RXNE: Receive Data register not empty interrupt + * @arg IRDA_IT_IDLE: Idle line detection interrupt + * @arg USART_IT_ERR: Error interrupt + * @arg IRDA_IT_PE: Parity Error interrupt + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_IRDA_GET_IT_SOURCE(__HANDLE__, __IT__) (((((__IT__) >> 28) == 1)? (__HANDLE__)->Instance->CR1:(((((uint32_t)(__IT__)) >> 28) == 2)? \ + (__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & (((uint32_t)(__IT__)) & IRDA_IT_MASK)) + +/** @brief Macro to enable the IRDA's one bit sample method + * @param __HANDLE__: specifies the IRDA Handle. + * @retval None + */ +#define __HAL_IRDA_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT) + +/** @brief Macro to disable the IRDA's one bit sample method + * @param __HANDLE__: specifies the IRDA Handle. + * @retval None + */ +#define __HAL_IRDA_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_ONEBIT)) + +/** @brief Enable UART/USART associated to IRDA Handle + * @param __HANDLE__: specifies the IRDA Handle. + * IRDA Handle selects the USARTx or UARTy peripheral + * (USART,UART availability and x,y values depending on device). + * @retval None + */ +#define __HAL_IRDA_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE) + +/** @brief Disable UART/USART associated to IRDA Handle + * @param __HANDLE__: specifies the IRDA Handle. + * IRDA Handle selects the USARTx or UARTy peripheral + * (USART,UART availability and x,y values depending on device). + * @retval None + */ +#define __HAL_IRDA_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup IRDA_Exported_Functions + * @{ + */ + +/** @addtogroup IRDA_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions **********************************/ +HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda); +/** + * @} + */ + +/** @addtogroup IRDA_Exported_Functions_Group2 + * @{ + */ +/* IO operation functions *******************************************************/ +HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda); +HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda); +void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda); +/** + * @} + */ + +/** @addtogroup IRDA_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State functions **************************************************/ +HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda); +uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup IRDA_Private_Constants IRDA Private Constants + * @{ + */ + +/** @brief IRDA interruptions flag mask + * + */ +#define IRDA_IT_MASK ((uint32_t) USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE | USART_CR1_RXNEIE | \ + USART_CR1_IDLEIE | USART_CR2_LBDIE | USART_CR3_CTSIE | USART_CR3_EIE ) + + +#define IRDA_CR1_REG_INDEX 1 +#define IRDA_CR2_REG_INDEX 2 +#define IRDA_CR3_REG_INDEX 3 +/** + * @} + */ + +/* Private macros --------------------------------------------------------*/ +/** @defgroup IRDA_Private_Macros IRDA Private Macros + * @{ + */ +#define IS_IRDA_WORD_LENGTH(LENGTH) (((LENGTH) == IRDA_WORDLENGTH_8B) || \ + ((LENGTH) == IRDA_WORDLENGTH_9B)) +#define IS_IRDA_PARITY(PARITY) (((PARITY) == IRDA_PARITY_NONE) || \ + ((PARITY) == IRDA_PARITY_EVEN) || \ + ((PARITY) == IRDA_PARITY_ODD)) +#define IS_IRDA_MODE(MODE) ((((MODE) & (uint32_t)0x0000FFF3) == 0x00) && ((MODE) != (uint32_t)0x000000)) +#define IS_IRDA_POWERMODE(MODE) (((MODE) == IRDA_POWERMODE_LOWPOWER) || \ + ((MODE) == IRDA_POWERMODE_NORMAL)) +#define IS_IRDA_BAUDRATE(BAUDRATE) ((BAUDRATE) < 115201) + +#define IRDA_DIV(_PCLK_, _BAUD_) (((_PCLK_)*25)/(4*(_BAUD_))) +#define IRDA_DIVMANT(_PCLK_, _BAUD_) (IRDA_DIV((_PCLK_), (_BAUD_))/100) +#define IRDA_DIVFRAQ(_PCLK_, _BAUD_) (((IRDA_DIV((_PCLK_), (_BAUD_)) - (IRDA_DIVMANT((_PCLK_), (_BAUD_)) * 100)) * 16 + 50) / 100) +#define IRDA_BRR(_PCLK_, _BAUD_) ((IRDA_DIVMANT((_PCLK_), (_BAUD_)) << 4)|(IRDA_DIVFRAQ((_PCLK_), (_BAUD_)) & 0x0F)) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup IRDA_Private_Functions IRDA Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_IRDA_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h new file mode 100644 index 0000000..f711957 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h @@ -0,0 +1,288 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_iwdg.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of IWDG HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_IWDG_H +#define __STM32F4xx_HAL_IWDG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup IWDG + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup IWDG_Exported_Types IWDG Exported Types + * @{ + */ + +/** + * @brief IWDG HAL State Structure definition + */ +typedef enum +{ + HAL_IWDG_STATE_RESET = 0x00, /*!< IWDG not yet initialized or disabled */ + HAL_IWDG_STATE_READY = 0x01, /*!< IWDG initialized and ready for use */ + HAL_IWDG_STATE_BUSY = 0x02, /*!< IWDG internal process is ongoing */ + HAL_IWDG_STATE_TIMEOUT = 0x03, /*!< IWDG timeout state */ + HAL_IWDG_STATE_ERROR = 0x04 /*!< IWDG error state */ +}HAL_IWDG_StateTypeDef; + +/** + * @brief IWDG Init structure definition + */ +typedef struct +{ + uint32_t Prescaler; /*!< Select the prescaler of the IWDG. + This parameter can be a value of @ref IWDG_Prescaler */ + + uint32_t Reload; /*!< Specifies the IWDG down-counter reload value. + This parameter must be a number between Min_Data = 0 and Max_Data = 0x0FFF */ +}IWDG_InitTypeDef; + +/** + * @brief IWDG Handle Structure definition + */ +typedef struct +{ + IWDG_TypeDef *Instance; /*!< Register base address */ + + IWDG_InitTypeDef Init; /*!< IWDG required parameters */ + + HAL_LockTypeDef Lock; /*!< IWDG Locking object */ + + __IO HAL_IWDG_StateTypeDef State; /*!< IWDG communication state */ +}IWDG_HandleTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup IWDG_Exported_Constants IWDG Exported Constants + * @{ + */ + +/** @defgroup IWDG_Registers_BitMask IWDG Registers BitMask + * @brief IWDG registers bit mask + * @{ + */ +/* --- KR Register ---*/ +/* KR register bit mask */ +#define IWDG_KEY_RELOAD ((uint32_t)0xAAAA) /*!< IWDG Reload Counter Enable */ +#define IWDG_KEY_ENABLE ((uint32_t)0xCCCC) /*!< IWDG Peripheral Enable */ +#define IWDG_KEY_WRITE_ACCESS_ENABLE ((uint32_t)0x5555) /*!< IWDG KR Write Access Enable */ +#define IWDG_KEY_WRITE_ACCESS_DISABLE ((uint32_t)0x0000) /*!< IWDG KR Write Access Disable */ +/** + * @} + */ + +/** @defgroup IWDG_Flag_definition IWDG Flag definition + * @{ + */ +#define IWDG_FLAG_PVU ((uint32_t)IWDG_SR_PVU) /*!< Watchdog counter prescaler value update Flag */ +#define IWDG_FLAG_RVU ((uint32_t)IWDG_SR_RVU) /*!< Watchdog counter reload value update Flag */ +/** + * @} + */ + +/** @defgroup IWDG_Prescaler IWDG Prescaler + * @{ + */ +#define IWDG_PRESCALER_4 ((uint8_t)0x00) /*!< IWDG prescaler set to 4 */ +#define IWDG_PRESCALER_8 ((uint8_t)(IWDG_PR_PR_0)) /*!< IWDG prescaler set to 8 */ +#define IWDG_PRESCALER_16 ((uint8_t)(IWDG_PR_PR_1)) /*!< IWDG prescaler set to 16 */ +#define IWDG_PRESCALER_32 ((uint8_t)(IWDG_PR_PR_1 | IWDG_PR_PR_0)) /*!< IWDG prescaler set to 32 */ +#define IWDG_PRESCALER_64 ((uint8_t)(IWDG_PR_PR_2)) /*!< IWDG prescaler set to 64 */ +#define IWDG_PRESCALER_128 ((uint8_t)(IWDG_PR_PR_2 | IWDG_PR_PR_0)) /*!< IWDG prescaler set to 128 */ +#define IWDG_PRESCALER_256 ((uint8_t)(IWDG_PR_PR_2 | IWDG_PR_PR_1)) /*!< IWDG prescaler set to 256 */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup IWDG_Exported_Macros IWDG Exported Macros + * @{ + */ + +/** @brief Reset IWDG handle state + * @param __HANDLE__: IWDG handle. + * @retval None + */ +#define __HAL_IWDG_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_IWDG_STATE_RESET) + +/** + * @brief Enables the IWDG peripheral. + * @param __HANDLE__: IWDG handle + * @retval None + */ +#define __HAL_IWDG_START(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_ENABLE) + +/** + * @brief Reloads IWDG counter with value defined in the reload register + * (write access to IWDG_PR and IWDG_RLR registers disabled). + * @param __HANDLE__: IWDG handle + * @retval None + */ +#define __HAL_IWDG_RELOAD_COUNTER(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_RELOAD) + +/** + * @brief Gets the selected IWDG's flag status. + * @param __HANDLE__: IWDG handle + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg IWDG_FLAG_PVU: Watchdog counter reload value update flag + * @arg IWDG_FLAG_RVU: Watchdog counter prescaler value flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_IWDG_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup IWDG_Exported_Functions + * @{ + */ + +/** @addtogroup IWDG_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions ********************************/ +HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg); +void HAL_IWDG_MspInit(IWDG_HandleTypeDef *hiwdg); +/** + * @} + */ + +/** @addtogroup IWDG_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions ****************************************************/ +HAL_StatusTypeDef HAL_IWDG_Start(IWDG_HandleTypeDef *hiwdg); +HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg); +/** + * @} + */ + +/** @addtogroup IWDG_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State functions ************************************************/ +HAL_IWDG_StateTypeDef HAL_IWDG_GetState(IWDG_HandleTypeDef *hiwdg); + +/** + * @} + */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup IWDG_Private_Macros IWDG Private Macros + * @{ + */ + +/** + * @brief Enables write access to IWDG_PR and IWDG_RLR registers. + * @param __HANDLE__: IWDG handle + * @retval None + */ +#define IWDG_ENABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_WRITE_ACCESS_ENABLE) + +/** + * @brief Disables write access to IWDG_PR and IWDG_RLR registers. + * @param __HANDLE__: IWDG handle + * @retval None + */ +#define IWDG_DISABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_WRITE_ACCESS_DISABLE) + + +#define IS_IWDG_PRESCALER(__PRESCALER__) (((__PRESCALER__) == IWDG_PRESCALER_4) || \ + ((__PRESCALER__) == IWDG_PRESCALER_8) || \ + ((__PRESCALER__) == IWDG_PRESCALER_16) || \ + ((__PRESCALER__) == IWDG_PRESCALER_32) || \ + ((__PRESCALER__) == IWDG_PRESCALER_64) || \ + ((__PRESCALER__) == IWDG_PRESCALER_128)|| \ + ((__PRESCALER__) == IWDG_PRESCALER_256)) + + +#define IS_IWDG_RELOAD(__RELOAD__) ((__RELOAD__) <= 0xFFF) + +/** + * @} + */ + +/* Private define ------------------------------------------------------------*/ + /** @defgroup IWDG_Private_Constants IWDG Private Constants + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_IWDG_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_ltdc.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_ltdc.h new file mode 100644 index 0000000..096364c --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_ltdc.h @@ -0,0 +1,631 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_ltdc.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of LTDC HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_LTDC_H +#define __STM32F4xx_HAL_LTDC_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F429xx) || defined(STM32F439xx) +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup LTDC LTDC + * @brief LTDC HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup LTDC_Exported_Types LTDC Exported Types + * @{ + */ +#define MAX_LAYER 2 + +/** + * @brief LTDC color structure definition + */ +typedef struct +{ + uint8_t Blue; /*!< Configures the blue value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. */ + + uint8_t Green; /*!< Configures the green value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. */ + + uint8_t Red; /*!< Configures the red value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. */ + + uint8_t Reserved; /*!< Reserved 0xFF */ +} LTDC_ColorTypeDef; + +/** + * @brief LTDC Init structure definition + */ +typedef struct +{ + uint32_t HSPolarity; /*!< configures the horizontal synchronization polarity. + This parameter can be one value of @ref LTDC_HS_POLARITY */ + + uint32_t VSPolarity; /*!< configures the vertical synchronization polarity. + This parameter can be one value of @ref LTDC_VS_POLARITY */ + + uint32_t DEPolarity; /*!< configures the data enable polarity. + This parameter can be one of value of @ref LTDC_DE_POLARITY */ + + uint32_t PCPolarity; /*!< configures the pixel clock polarity. + This parameter can be one of value of @ref LTDC_PC_POLARITY */ + + uint32_t HorizontalSync; /*!< configures the number of Horizontal synchronization width. + This parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF. */ + + uint32_t VerticalSync; /*!< configures the number of Vertical synchronization height. + This parameter must be a number between Min_Data = 0x000 and Max_Data = 0x7FF. */ + + uint32_t AccumulatedHBP; /*!< configures the accumulated horizontal back porch width. + This parameter must be a number between Min_Data = LTDC_HorizontalSync and Max_Data = 0xFFF. */ + + uint32_t AccumulatedVBP; /*!< configures the accumulated vertical back porch height. + This parameter must be a number between Min_Data = LTDC_VerticalSync and Max_Data = 0x7FF. */ + + uint32_t AccumulatedActiveW; /*!< configures the accumulated active width. + This parameter must be a number between Min_Data = LTDC_AccumulatedHBP and Max_Data = 0xFFF. */ + + uint32_t AccumulatedActiveH; /*!< configures the accumulated active height. + This parameter must be a number between Min_Data = LTDC_AccumulatedVBP and Max_Data = 0x7FF. */ + + uint32_t TotalWidth; /*!< configures the total width. + This parameter must be a number between Min_Data = LTDC_AccumulatedActiveW and Max_Data = 0xFFF. */ + + uint32_t TotalHeigh; /*!< configures the total height. + This parameter must be a number between Min_Data = LTDC_AccumulatedActiveH and Max_Data = 0x7FF. */ + + LTDC_ColorTypeDef Backcolor; /*!< Configures the background color. */ +} LTDC_InitTypeDef; + +/** + * @brief LTDC Layer structure definition + */ +typedef struct +{ + uint32_t WindowX0; /*!< Configures the Window Horizontal Start Position. + This parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF. */ + + uint32_t WindowX1; /*!< Configures the Window Horizontal Stop Position. + This parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF. */ + + uint32_t WindowY0; /*!< Configures the Window vertical Start Position. + This parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF. */ + + uint32_t WindowY1; /*!< Configures the Window vertical Stop Position. + This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */ + + uint32_t PixelFormat; /*!< Specifies the pixel format. + This parameter can be one of value of @ref LTDC_Pixelformat */ + + uint32_t Alpha; /*!< Specifies the constant alpha used for blending. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. */ + + uint32_t Alpha0; /*!< Configures the default alpha value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. */ + + uint32_t BlendingFactor1; /*!< Select the blending factor 1. + This parameter can be one of value of @ref LTDC_BlendingFactor1 */ + + uint32_t BlendingFactor2; /*!< Select the blending factor 2. + This parameter can be one of value of @ref LTDC_BlendingFactor2 */ + + uint32_t FBStartAdress; /*!< Configures the color frame buffer address */ + + uint32_t ImageWidth; /*!< Configures the color frame buffer line length. + This parameter must be a number between Min_Data = 0x0000 and Max_Data = 0x1FFF. */ + + uint32_t ImageHeight; /*!< Specifies the number of line in frame buffer. + This parameter must be a number between Min_Data = 0x000 and Max_Data = 0x7FF. */ + + LTDC_ColorTypeDef Backcolor; /*!< Configures the layer background color. */ +} LTDC_LayerCfgTypeDef; + +/** + * @brief HAL LTDC State structures definition + */ +typedef enum +{ + HAL_LTDC_STATE_RESET = 0x00, /*!< LTDC not yet initialized or disabled */ + HAL_LTDC_STATE_READY = 0x01, /*!< LTDC initialized and ready for use */ + HAL_LTDC_STATE_BUSY = 0x02, /*!< LTDC internal process is ongoing */ + HAL_LTDC_STATE_TIMEOUT = 0x03, /*!< LTDC Timeout state */ + HAL_LTDC_STATE_ERROR = 0x04 /*!< LTDC state error */ +}HAL_LTDC_StateTypeDef; + +/** + * @brief LTDC handle Structure definition + */ +typedef struct +{ + LTDC_TypeDef *Instance; /*!< LTDC Register base address */ + + LTDC_InitTypeDef Init; /*!< LTDC parameters */ + + LTDC_LayerCfgTypeDef LayerCfg[MAX_LAYER]; /*!< LTDC Layers parameters */ + + HAL_LockTypeDef Lock; /*!< LTDC Lock */ + + __IO HAL_LTDC_StateTypeDef State; /*!< LTDC state */ + + __IO uint32_t ErrorCode; /*!< LTDC Error code */ + +} LTDC_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup LTDC_Exported_Constants LTDC Exported Constants + * @{ + */ + +/** @defgroup LTDC_Error_Code LTDC Error Code + * @{ + */ +#define HAL_LTDC_ERROR_NONE ((uint32_t)0x00000000) /*!< LTDC No error */ +#define HAL_LTDC_ERROR_TE ((uint32_t)0x00000001) /*!< LTDC Transfer error */ +#define HAL_LTDC_ERROR_FU ((uint32_t)0x00000002) /*!< LTDC FIFO Underrun */ +#define HAL_LTDC_ERROR_TIMEOUT ((uint32_t)0x00000020) /*!< LTDC Timeout error */ +/** + * @} + */ + +/** @defgroup LTDC_HS_POLARITY LTDC HS POLARITY + * @{ + */ +#define LTDC_HSPOLARITY_AL ((uint32_t)0x00000000) /*!< Horizontal Synchronization is active low. */ +#define LTDC_HSPOLARITY_AH LTDC_GCR_HSPOL /*!< Horizontal Synchronization is active high. */ +/** + * @} + */ + +/** @defgroup LTDC_VS_POLARITY LTDC VS POLARITY + * @{ + */ +#define LTDC_VSPOLARITY_AL ((uint32_t)0x00000000) /*!< Vertical Synchronization is active low. */ +#define LTDC_VSPOLARITY_AH LTDC_GCR_VSPOL /*!< Vertical Synchronization is active high. */ +/** + * @} + */ + +/** @defgroup LTDC_DE_POLARITY LTDC DE POLARITY + * @{ + */ +#define LTDC_DEPOLARITY_AL ((uint32_t)0x00000000) /*!< Data Enable, is active low. */ +#define LTDC_DEPOLARITY_AH LTDC_GCR_DEPOL /*!< Data Enable, is active high. */ +/** + * @} + */ + +/** @defgroup LTDC_PC_POLARITY LTDC PC POLARITY + * @{ + */ +#define LTDC_PCPOLARITY_IPC ((uint32_t)0x00000000) /*!< input pixel clock. */ +#define LTDC_PCPOLARITY_IIPC LTDC_GCR_PCPOL /*!< inverted input pixel clock. */ +/** + * @} + */ + +/** @defgroup LTDC_SYNC LTDC SYNC + * @{ + */ +#define LTDC_HORIZONTALSYNC (LTDC_SSCR_HSW >> 16) /*!< Horizontal synchronization width. */ +#define LTDC_VERTICALSYNC LTDC_SSCR_VSH /*!< Vertical synchronization height. */ +/** + * @} + */ + +/** @defgroup LTDC_BACK_COLOR LTDC BACK COLOR + * @{ + */ +#define LTDC_COLOR ((uint32_t)0x000000FF) /*!< Color mask */ +/** + * @} + */ + +/** @defgroup LTDC_BlendingFactor1 LTDC Blending Factor1 + * @{ + */ +#define LTDC_BLENDING_FACTOR1_CA ((uint32_t)0x00000400) /*!< Blending factor : Cte Alpha */ +#define LTDC_BLENDING_FACTOR1_PAxCA ((uint32_t)0x00000600) /*!< Blending factor : Cte Alpha x Pixel Alpha*/ +/** + * @} + */ + +/** @defgroup LTDC_BlendingFactor2 LTDC Blending Factor2 + * @{ + */ +#define LTDC_BLENDING_FACTOR2_CA ((uint32_t)0x00000005) /*!< Blending factor : Cte Alpha */ +#define LTDC_BLENDING_FACTOR2_PAxCA ((uint32_t)0x00000007) /*!< Blending factor : Cte Alpha x Pixel Alpha*/ +/** + * @} + */ + +/** @defgroup LTDC_Pixelformat LTDC Pixel format + * @{ + */ +#define LTDC_PIXEL_FORMAT_ARGB8888 ((uint32_t)0x00000000) /*!< ARGB8888 LTDC pixel format */ +#define LTDC_PIXEL_FORMAT_RGB888 ((uint32_t)0x00000001) /*!< RGB888 LTDC pixel format */ +#define LTDC_PIXEL_FORMAT_RGB565 ((uint32_t)0x00000002) /*!< RGB565 LTDC pixel format */ +#define LTDC_PIXEL_FORMAT_ARGB1555 ((uint32_t)0x00000003) /*!< ARGB1555 LTDC pixel format */ +#define LTDC_PIXEL_FORMAT_ARGB4444 ((uint32_t)0x00000004) /*!< ARGB4444 LTDC pixel format */ +#define LTDC_PIXEL_FORMAT_L8 ((uint32_t)0x00000005) /*!< L8 LTDC pixel format */ +#define LTDC_PIXEL_FORMAT_AL44 ((uint32_t)0x00000006) /*!< AL44 LTDC pixel format */ +#define LTDC_PIXEL_FORMAT_AL88 ((uint32_t)0x00000007) /*!< AL88 LTDC pixel format */ +/** + * @} + */ + +/** @defgroup LTDC_Alpha LTDC Alpha + * @{ + */ +#define LTDC_ALPHA LTDC_LxCACR_CONSTA /*!< LTDC Cte Alpha mask */ +/** + * @} + */ + +/** @defgroup LTDC_LAYER_Config LTDC LAYER Config + * @{ + */ +#define LTDC_STOPPOSITION (LTDC_LxWHPCR_WHSPPOS >> 16) /*!< LTDC Layer stop position */ +#define LTDC_STARTPOSITION LTDC_LxWHPCR_WHSTPOS /*!< LTDC Layer start position */ + +#define LTDC_COLOR_FRAME_BUFFER LTDC_LxCFBLR_CFBLL /*!< LTDC Layer Line length */ +#define LTDC_LINE_NUMBER LTDC_LxCFBLNR_CFBLNBR /*!< LTDC Layer Line number */ +/** + * @} + */ + +/** @defgroup LTDC_Interrupts LTDC Interrupts + * @{ + */ +#define LTDC_IT_LI LTDC_IER_LIE +#define LTDC_IT_FU LTDC_IER_FUIE +#define LTDC_IT_TE LTDC_IER_TERRIE +#define LTDC_IT_RR LTDC_IER_RRIE +/** + * @} + */ + +/** @defgroup LTDC_Flag LTDC Flag + * @{ + */ +#define LTDC_FLAG_LI LTDC_ISR_LIF +#define LTDC_FLAG_FU LTDC_ISR_FUIF +#define LTDC_FLAG_TE LTDC_ISR_TERRIF +#define LTDC_FLAG_RR LTDC_ISR_RRIF +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup LTDC_Exported_Macros LTDC Exported Macros + * @{ + */ + +/** @brief Reset LTDC handle state + * @param __HANDLE__: specifies the LTDC handle. + * @retval None + */ +#define __HAL_LTDC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_LTDC_STATE_RESET) + +/** + * @brief Enable the LTDC. + * @param __HANDLE__: LTDC handle + * @retval None. + */ +#define __HAL_LTDC_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->GCR |= LTDC_GCR_LTDCEN) + +/** + * @brief Disable the LTDC. + * @param __HANDLE__: LTDC handle + * @retval None. + */ +#define __HAL_LTDC_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->GCR &= ~(LTDC_GCR_LTDCEN)) + +/** + * @brief Enable the LTDC Layer. + * @param __HANDLE__: LTDC handle + * @param __LAYER__: Specify the layer to be enabled + * This parameter can be 0 or 1 + * @retval None. + */ +#define __HAL_LTDC_LAYER_ENABLE(__HANDLE__, __LAYER__) ((LTDC_LAYER((__HANDLE__), (__LAYER__)))->CR |= (uint32_t)LTDC_LxCR_LEN) + +/** + * @brief Disable the LTDC Layer. + * @param __HANDLE__: LTDC handle + * @param __LAYER__: Specify the layer to be disabled + * This parameter can be 0 or 1 + * @retval None. + */ +#define __HAL_LTDC_LAYER_DISABLE(__HANDLE__, __LAYER__) ((LTDC_LAYER((__HANDLE__), (__LAYER__)))->CR &= ~(uint32_t)LTDC_LxCR_LEN) + +/** + * @brief Reload Layer Configuration. + * @param __HANDLE__: LTDC handle + * @retval None. + */ +#define __HAL_LTDC_RELOAD_CONFIG(__HANDLE__) ((__HANDLE__)->Instance->SRCR |= LTDC_SRCR_IMR) + +/* Interrupt & Flag management */ +/** + * @brief Get the LTDC pending flags. + * @param __HANDLE__: LTDC handle + * @param __FLAG__: Get the specified flag. + * This parameter can be any combination of the following values: + * @arg LTDC_FLAG_LI: Line Interrupt flag + * @arg LTDC_FLAG_FU: FIFO Underrun Interrupt flag + * @arg LTDC_FLAG_TE: Transfer Error interrupt flag + * @arg LTDC_FLAG_RR: Register Reload Interrupt Flag + * @retval The state of FLAG (SET or RESET). + */ +#define __HAL_LTDC_GET_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ISR & (__FLAG__)) + +/** + * @brief Clears the LTDC pending flags. + * @param __HANDLE__: LTDC handle + * @param __FLAG__: specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg LTDC_FLAG_LI: Line Interrupt flag + * @arg LTDC_FLAG_FU: FIFO Underrun Interrupt flag + * @arg LTDC_FLAG_TE: Transfer Error interrupt flag + * @arg LTDC_FLAG_RR: Register Reload Interrupt Flag + * @retval None + */ +#define __HAL_LTDC_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__)) + +/** + * @brief Enables the specified LTDC interrupts. + * @param __HANDLE__: LTDC handle + * @param __INTERRUPT__: specifies the LTDC interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg LTDC_IT_LI: Line Interrupt flag + * @arg LTDC_IT_FU: FIFO Underrun Interrupt flag + * @arg LTDC_IT_TE: Transfer Error interrupt flag + * @arg LTDC_IT_RR: Register Reload Interrupt Flag + * @retval None + */ +#define __HAL_LTDC_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER |= (__INTERRUPT__)) + +/** + * @brief Disables the specified LTDC interrupts. + * @param __HANDLE__: LTDC handle + * @param __INTERRUPT__: specifies the LTDC interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg LTDC_IT_LI: Line Interrupt flag + * @arg LTDC_IT_FU: FIFO Underrun Interrupt flag + * @arg LTDC_IT_TE: Transfer Error interrupt flag + * @arg LTDC_IT_RR: Register Reload Interrupt Flag + * @retval None + */ +#define __HAL_LTDC_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER &= ~(__INTERRUPT__)) + +/** + * @brief Checks whether the specified LTDC interrupt has occurred or not. + * @param __HANDLE__: LTDC handle + * @param __INTERRUPT__: specifies the LTDC interrupt source to check. + * This parameter can be one of the following values: + * @arg LTDC_IT_LI: Line Interrupt flag + * @arg LTDC_IT_FU: FIFO Underrun Interrupt flag + * @arg LTDC_IT_TE: Transfer Error interrupt flag + * @arg LTDC_IT_RR: Register Reload Interrupt Flag + * @retval The state of INTERRUPT (SET or RESET). + */ +#define __HAL_LTDC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->ISR & (__INTERRUPT__)) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup LTDC_Exported_Functions + * @{ + */ +/** @addtogroup LTDC_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions *****************************/ +HAL_StatusTypeDef HAL_LTDC_Init(LTDC_HandleTypeDef *hltdc); +HAL_StatusTypeDef HAL_LTDC_DeInit(LTDC_HandleTypeDef *hltdc); +void HAL_LTDC_MspInit(LTDC_HandleTypeDef* hltdc); +void HAL_LTDC_MspDeInit(LTDC_HandleTypeDef* hltdc); +void HAL_LTDC_ErrorCallback(LTDC_HandleTypeDef *hltdc); +void HAL_LTDC_LineEvenCallback(LTDC_HandleTypeDef *hltdc); +/** + * @} + */ + +/** @addtogroup LTDC_Exported_Functions_Group2 + * @{ + */ +/* IO operation functions *****************************************************/ +void HAL_LTDC_IRQHandler(LTDC_HandleTypeDef *hltdc); +/** + * @} + */ + +/** @addtogroup LTDC_Exported_Functions_Group3 + * @{ + */ +/* Peripheral Control functions ***********************************************/ +HAL_StatusTypeDef HAL_LTDC_ConfigLayer(LTDC_HandleTypeDef *hltdc, LTDC_LayerCfgTypeDef *pLayerCfg, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetWindowSize(LTDC_HandleTypeDef *hltdc, uint32_t XSize, uint32_t YSize, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetWindowPosition(LTDC_HandleTypeDef *hltdc, uint32_t X0, uint32_t Y0, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetPixelFormat(LTDC_HandleTypeDef *hltdc, uint32_t Pixelformat, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetAlpha(LTDC_HandleTypeDef *hltdc, uint32_t Alpha, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_SetAddress(LTDC_HandleTypeDef *hltdc, uint32_t Address, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_ConfigColorKeying(LTDC_HandleTypeDef *hltdc, uint32_t RGBValue, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_ConfigCLUT(LTDC_HandleTypeDef *hltdc, uint32_t *pCLUT, uint32_t CLUTSize, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_EnableColorKeying(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_DisableColorKeying(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_EnableCLUT(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_DisableCLUT(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx); +HAL_StatusTypeDef HAL_LTDC_ProgramLineEvent(LTDC_HandleTypeDef *hltdc, uint32_t Line); +HAL_StatusTypeDef HAL_LTDC_EnableDither(LTDC_HandleTypeDef *hltdc); +HAL_StatusTypeDef HAL_LTDC_DisableDither(LTDC_HandleTypeDef *hltdc); +/** + * @} + */ + +/** @addtogroup LTDC_Exported_Functions_Group4 + * @{ + */ +/* Peripheral State functions *************************************************/ +HAL_LTDC_StateTypeDef HAL_LTDC_GetState(LTDC_HandleTypeDef *hltdc); +uint32_t HAL_LTDC_GetError(LTDC_HandleTypeDef *hltdc); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/** @defgroup LTDC_Private_Types LTDC Private Types + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup LTDC_Private_Variables LTDC Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup LTDC_Private_Constants LTDC Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup LTDC_Private_Macros LTDC Private Macros + * @{ + */ +#define LTDC_LAYER(__HANDLE__, __LAYER__) ((LTDC_Layer_TypeDef *)((uint32_t)(((uint32_t)((__HANDLE__)->Instance)) + 0x84 + (0x80*(__LAYER__))))) +#define IS_LTDC_LAYER(LAYER) ((LAYER) <= MAX_LAYER) +#define IS_LTDC_HSPOL(HSPOL) (((HSPOL) == LTDC_HSPOLARITY_AL) || \ + ((HSPOL) == LTDC_HSPOLARITY_AH)) +#define IS_LTDC_VSPOL(VSPOL) (((VSPOL) == LTDC_VSPOLARITY_AL) || \ + ((VSPOL) == LTDC_VSPOLARITY_AH)) +#define IS_LTDC_DEPOL(DEPOL) (((DEPOL) == LTDC_DEPOLARITY_AL) || \ + ((DEPOL) == LTDC_DEPOLARITY_AH)) +#define IS_LTDC_PCPOL(PCPOL) (((PCPOL) == LTDC_PCPOLARITY_IPC) || \ + ((PCPOL) == LTDC_PCPOLARITY_IIPC)) +#define IS_LTDC_HSYNC(HSYNC) ((HSYNC) <= LTDC_HORIZONTALSYNC) +#define IS_LTDC_VSYNC(VSYNC) ((VSYNC) <= LTDC_VERTICALSYNC) +#define IS_LTDC_AHBP(AHBP) ((AHBP) <= LTDC_HORIZONTALSYNC) +#define IS_LTDC_AVBP(AVBP) ((AVBP) <= LTDC_VERTICALSYNC) +#define IS_LTDC_AAW(AAW) ((AAW) <= LTDC_HORIZONTALSYNC) +#define IS_LTDC_AAH(AAH) ((AAH) <= LTDC_VERTICALSYNC) +#define IS_LTDC_TOTALW(TOTALW) ((TOTALW) <= LTDC_HORIZONTALSYNC) +#define IS_LTDC_TOTALH(TOTALH) ((TOTALH) <= LTDC_VERTICALSYNC) +#define IS_LTDC_BLUEVALUE(BBLUE) ((BBLUE) <= LTDC_COLOR) +#define IS_LTDC_GREENVALUE(BGREEN) ((BGREEN) <= LTDC_COLOR) +#define IS_LTDC_REDVALUE(BRED) ((BRED) <= LTDC_COLOR) +#define IS_LTDC_BLENDING_FACTOR1(BlendingFactor1) (((BlendingFactor1) == LTDC_BLENDING_FACTOR1_CA) || \ + ((BlendingFactor1) == LTDC_BLENDING_FACTOR1_PAxCA)) +#define IS_LTDC_BLENDING_FACTOR2(BlendingFactor2) (((BlendingFactor2) == LTDC_BLENDING_FACTOR2_CA) || \ + ((BlendingFactor2) == LTDC_BLENDING_FACTOR2_PAxCA)) +#define IS_LTDC_PIXEL_FORMAT(Pixelformat) (((Pixelformat) == LTDC_PIXEL_FORMAT_ARGB8888) || ((Pixelformat) == LTDC_PIXEL_FORMAT_RGB888) || \ + ((Pixelformat) == LTDC_PIXEL_FORMAT_RGB565) || ((Pixelformat) == LTDC_PIXEL_FORMAT_ARGB1555) || \ + ((Pixelformat) == LTDC_PIXEL_FORMAT_ARGB4444) || ((Pixelformat) == LTDC_PIXEL_FORMAT_L8) || \ + ((Pixelformat) == LTDC_PIXEL_FORMAT_AL44) || ((Pixelformat) == LTDC_PIXEL_FORMAT_AL88)) +#define IS_LTDC_ALPHA(ALPHA) ((ALPHA) <= LTDC_ALPHA) +#define IS_LTDC_HCONFIGST(HCONFIGST) ((HCONFIGST) <= LTDC_STARTPOSITION) +#define IS_LTDC_HCONFIGSP(HCONFIGSP) ((HCONFIGSP) <= LTDC_STOPPOSITION) +#define IS_LTDC_VCONFIGST(VCONFIGST) ((VCONFIGST) <= LTDC_STARTPOSITION) +#define IS_LTDC_VCONFIGSP(VCONFIGSP) ((VCONFIGSP) <= LTDC_STOPPOSITION) +#define IS_LTDC_CFBP(CFBP) ((CFBP) <= LTDC_COLOR_FRAME_BUFFER) +#define IS_LTDC_CFBLL(CFBLL) ((CFBLL) <= LTDC_COLOR_FRAME_BUFFER) +#define IS_LTDC_CFBLNBR(CFBLNBR) ((CFBLNBR) <= LTDC_LINE_NUMBER) +#define IS_LTDC_LIPOS(LIPOS) ((LIPOS) <= 0x7FF) +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup LTDC_Private_Functions LTDC Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* STM32F429xx || STM32F439xx */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_LTDC_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_nand.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_nand.h new file mode 100644 index 0000000..6cf3ae3 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_nand.h @@ -0,0 +1,316 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_nand.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of NAND HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_NAND_H +#define __STM32F4xx_HAL_NAND_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) + #include "stm32f4xx_ll_fsmc.h" +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) + #include "stm32f4xx_ll_fmc.h" +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup NAND + * @{ + */ + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F446xx) + +/* Exported typedef ----------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/** @defgroup NAND_Exported_Types NAND Exported Types + * @{ + */ + +/** + * @brief HAL NAND State structures definition + */ +typedef enum +{ + HAL_NAND_STATE_RESET = 0x00, /*!< NAND not yet initialized or disabled */ + HAL_NAND_STATE_READY = 0x01, /*!< NAND initialized and ready for use */ + HAL_NAND_STATE_BUSY = 0x02, /*!< NAND internal process is ongoing */ + HAL_NAND_STATE_ERROR = 0x03 /*!< NAND error state */ +}HAL_NAND_StateTypeDef; + +/** + * @brief NAND Memory electronic signature Structure definition + */ +typedef struct +{ + /*State = HAL_NAND_STATE_RESET) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup NAND_Exported_Functions NAND Exported Functions + * @{ + */ + +/** @addtogroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ + +/* Initialization/de-initialization functions ********************************/ +HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing); +HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand); +void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand); +void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand); +void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand); +void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand); + +/** + * @} + */ + +/** @addtogroup NAND_Exported_Functions_Group2 Input and Output functions + * @{ + */ + +/* IO operation functions ****************************************************/ +HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID); +HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand); +HAL_StatusTypeDef HAL_NAND_Read_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead); +HAL_StatusTypeDef HAL_NAND_Write_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite); +HAL_StatusTypeDef HAL_NAND_Read_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead); +HAL_StatusTypeDef HAL_NAND_Write_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite); +HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress); +uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand); +uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress); + +/** + * @} + */ + +/** @addtogroup NAND_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ + +/* NAND Control functions ****************************************************/ +HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand); +HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand); +HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout); + +/** + * @} + */ + +/** @addtogroup NAND_Exported_Functions_Group4 Peripheral State functions + * @{ + */ +/* NAND State functions *******************************************************/ +HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand); +uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup NAND_Private_Constants NAND Private Constants + * @{ + */ +#define NAND_DEVICE1 ((uint32_t)0x70000000) +#define NAND_DEVICE2 ((uint32_t)0x80000000) +#define NAND_WRITE_TIMEOUT ((uint32_t)0x01000000) + +#define CMD_AREA ((uint32_t)(1<<16)) /* A16 = CLE high */ +#define ADDR_AREA ((uint32_t)(1<<17)) /* A17 = ALE high */ + +#define NAND_CMD_AREA_A ((uint8_t)0x00) +#define NAND_CMD_AREA_B ((uint8_t)0x01) +#define NAND_CMD_AREA_C ((uint8_t)0x50) +#define NAND_CMD_AREA_TRUE1 ((uint8_t)0x30) + +#define NAND_CMD_WRITE0 ((uint8_t)0x80) +#define NAND_CMD_WRITE_TRUE1 ((uint8_t)0x10) +#define NAND_CMD_ERASE0 ((uint8_t)0x60) +#define NAND_CMD_ERASE1 ((uint8_t)0xD0) +#define NAND_CMD_READID ((uint8_t)0x90) +#define NAND_CMD_STATUS ((uint8_t)0x70) +#define NAND_CMD_LOCK_STATUS ((uint8_t)0x7A) +#define NAND_CMD_RESET ((uint8_t)0xFF) + +/* NAND memory status */ +#define NAND_VALID_ADDRESS ((uint32_t)0x00000100) +#define NAND_INVALID_ADDRESS ((uint32_t)0x00000200) +#define NAND_TIMEOUT_ERROR ((uint32_t)0x00000400) +#define NAND_BUSY ((uint32_t)0x00000000) +#define NAND_ERROR ((uint32_t)0x00000001) +#define NAND_READY ((uint32_t)0x00000040) +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup NAND_Private_Macros NAND Private Macros + * @{ + */ + +/** + * @brief NAND memory address computation. + * @param __ADDRESS__: NAND memory address. + * @param __HANDLE__ : NAND handle. + * @retval NAND Raw address value + */ +#define ARRAY_ADDRESS(__ADDRESS__ , __HANDLE__) ((__ADDRESS__)->Page + \ + (((__ADDRESS__)->Block + (((__ADDRESS__)->Zone) * ((__HANDLE__)->Info.ZoneSize)))* ((__HANDLE__)->Info.BlockSize))) + +/** + * @brief NAND memory address cycling. + * @param __ADDRESS__: NAND memory address. + * @retval NAND address cycling value. + */ +#define ADDR_1ST_CYCLE(__ADDRESS__) (uint8_t)(__ADDRESS__) /* 1st addressing cycle */ +#define ADDR_2ND_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 8) /* 2nd addressing cycle */ +#define ADDR_3RD_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 16) /* 3rd addressing cycle */ +#define ADDR_4TH_CYCLE(__ADDRESS__) (uint8_t)((__ADDRESS__) >> 24) /* 4th addressing cycle */ +/** + * @} + */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx ||\ + STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||\ + STM32F446xx */ + +/** + * @} + */ +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_NAND_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_nor.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_nor.h new file mode 100644 index 0000000..55f8690 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_nor.h @@ -0,0 +1,301 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_nor.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of NOR HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_NOR_H +#define __STM32F4xx_HAL_NOR_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) + #include "stm32f4xx_ll_fsmc.h" +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) + #include "stm32f4xx_ll_fmc.h" +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup NOR + * @{ + */ + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F446xx) + +/* Exported typedef ----------------------------------------------------------*/ +/** @defgroup NOR_Exported_Types NOR Exported Types + * @{ + */ + +/** + * @brief HAL SRAM State structures definition + */ +typedef enum +{ + HAL_NOR_STATE_RESET = 0x00, /*!< NOR not yet initialized or disabled */ + HAL_NOR_STATE_READY = 0x01, /*!< NOR initialized and ready for use */ + HAL_NOR_STATE_BUSY = 0x02, /*!< NOR internal processing is ongoing */ + HAL_NOR_STATE_ERROR = 0x03, /*!< NOR error state */ + HAL_NOR_STATE_PROTECTED = 0x04 /*!< NOR NORSRAM device write protected */ +}HAL_NOR_StateTypeDef; + +/** + * @brief FMC NOR Status typedef + */ +typedef enum +{ + HAL_NOR_STATUS_SUCCESS = 0, + HAL_NOR_STATUS_ONGOING, + HAL_NOR_STATUS_ERROR, + HAL_NOR_STATUS_TIMEOUT +}HAL_NOR_StatusTypeDef; + +/** + * @brief FMC NOR ID typedef + */ +typedef struct +{ + uint16_t Manufacturer_Code; /*!< Defines the device's manufacturer code used to identify the memory */ + + uint16_t Device_Code1; + + uint16_t Device_Code2; + + uint16_t Device_Code3; /*!< Defines the device's codes used to identify the memory. + These codes can be accessed by performing read operations with specific + control signals and addresses set.They can also be accessed by issuing + an Auto Select command */ +}NOR_IDTypeDef; + +/** + * @brief FMC NOR CFI typedef + */ +typedef struct +{ + /*!< Defines the information stored in the memory's Common flash interface + which contains a description of various electrical and timing parameters, + density information and functions supported by the memory */ + + uint16_t CFI_1; + + uint16_t CFI_2; + + uint16_t CFI_3; + + uint16_t CFI_4; +}NOR_CFITypeDef; + +/** + * @brief NOR handle Structure definition + */ +typedef struct +{ + FMC_NORSRAM_TypeDef *Instance; /*!< Register base address */ + + FMC_NORSRAM_EXTENDED_TypeDef *Extended; /*!< Extended mode register base address */ + + FMC_NORSRAM_InitTypeDef Init; /*!< NOR device control configuration parameters */ + + HAL_LockTypeDef Lock; /*!< NOR locking object */ + + __IO HAL_NOR_StateTypeDef State; /*!< NOR device access state */ + +}NOR_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/* Exported macros ------------------------------------------------------------*/ +/** @defgroup NOR_Exported_Macros NOR Exported Macros + * @{ + */ +/** @brief Reset NOR handle state + * @param __HANDLE__: specifies the NOR handle. + * @retval None + */ +#define __HAL_NOR_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_NOR_STATE_RESET) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup NOR_Exported_Functions + * @{ + */ + +/** @addtogroup NOR_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions ********************************/ +HAL_StatusTypeDef HAL_NOR_Init(NOR_HandleTypeDef *hnor, FMC_NORSRAM_TimingTypeDef *Timing, FMC_NORSRAM_TimingTypeDef *ExtTiming); +HAL_StatusTypeDef HAL_NOR_DeInit(NOR_HandleTypeDef *hnor); +void HAL_NOR_MspInit(NOR_HandleTypeDef *hnor); +void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor); +void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout); +/** + * @} + */ + +/** @addtogroup NOR_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions ***************************************************/ +HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID); +HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor); +HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData); +HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData); + +HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize); +HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize); + +HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address); +HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address); +HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI); +/** + * @} + */ + +/** @addtogroup NOR_Exported_Functions_Group3 + * @{ + */ +/* NOR Control functions *****************************************************/ +HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor); +HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor); +/** + * @} + */ + +/** @addtogroup NOR_Exported_Functions_Group4 + * @{ + */ +/* NOR State functions ********************************************************/ +HAL_NOR_StateTypeDef HAL_NOR_GetState(NOR_HandleTypeDef *hnor); +HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup NOR_Private_Constants NOR Private Constants + * @{ + */ +/* NOR device IDs addresses */ +#define MC_ADDRESS ((uint16_t)0x0000) +#define DEVICE_CODE1_ADDR ((uint16_t)0x0001) +#define DEVICE_CODE2_ADDR ((uint16_t)0x000E) +#define DEVICE_CODE3_ADDR ((uint16_t)0x000F) + +/* NOR CFI IDs addresses */ +#define CFI1_ADDRESS ((uint16_t)0x61) +#define CFI2_ADDRESS ((uint16_t)0x62) +#define CFI3_ADDRESS ((uint16_t)0x63) +#define CFI4_ADDRESS ((uint16_t)0x64) + +/* NOR operation wait timeout */ +#define NOR_TMEOUT ((uint16_t)0xFFFF) + +/* NOR memory data width */ +#define NOR_MEMORY_8B ((uint8_t)0x0) +#define NOR_MEMORY_16B ((uint8_t)0x1) + +/* NOR memory device read/write start address */ +#define NOR_MEMORY_ADRESS1 ((uint32_t)0x60000000) +#define NOR_MEMORY_ADRESS2 ((uint32_t)0x64000000) +#define NOR_MEMORY_ADRESS3 ((uint32_t)0x68000000) +#define NOR_MEMORY_ADRESS4 ((uint32_t)0x6C000000) +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup NOR_Private_Macros NOR Private Macros + * @{ + */ +/** + * @brief NOR memory address shifting. + * @param __NOR_ADDRESS__: NOR base address + * @param NOR_MEMORY_WIDTH: NOR memory width + * @param ADDRESS: NOR memory address + * @retval NOR shifted address value + */ +#define NOR_ADDR_SHIFT(__NOR_ADDRESS__, NOR_MEMORY_WIDTH, ADDRESS) (uint32_t)(((NOR_MEMORY_WIDTH) == NOR_MEMORY_8B)? ((uint32_t)((__NOR_ADDRESS__) + (2 * (ADDRESS)))):\ + ((uint32_t)((__NOR_ADDRESS__) + (ADDRESS)))) + +/** + * @brief NOR memory write data to specified address. + * @param ADDRESS: NOR memory address + * @param DATA: Data to write + * @retval None + */ +#define NOR_WRITE(ADDRESS, DATA) (*(__IO uint16_t *)((uint32_t)(ADDRESS)) = (DATA)) + +/** + * @} + */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx ||\ + STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||\ + STM32F446xx */ +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_NOR_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pccard.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pccard.h new file mode 100644 index 0000000..a67f54f --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pccard.h @@ -0,0 +1,267 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_pccard.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of PCCARD HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_PCCARD_H +#define __STM32F4xx_HAL_PCCARD_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) + #include "stm32f4xx_ll_fsmc.h" +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + #include "stm32f4xx_ll_fmc.h" +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + +/** @addtogroup PCCARD + * @{ + */ + +/* Exported typedef ----------------------------------------------------------*/ +/** @defgroup PCCARD_Exported_Types PCCARD Exported Types + * @{ + */ + +/** + * @brief HAL PCCARD State structures definition + */ +typedef enum +{ + HAL_PCCARD_STATE_RESET = 0x00, /*!< PCCARD peripheral not yet initialized or disabled */ + HAL_PCCARD_STATE_READY = 0x01, /*!< PCCARD peripheral ready */ + HAL_PCCARD_STATE_BUSY = 0x02, /*!< PCCARD peripheral busy */ + HAL_PCCARD_STATE_ERROR = 0x04 /*!< PCCARD peripheral error */ +}HAL_PCCARD_StateTypeDef; + +typedef enum +{ + HAL_PCCARD_STATUS_SUCCESS = 0, + HAL_PCCARD_STATUS_ONGOING, + HAL_PCCARD_STATUS_ERROR, + HAL_PCCARD_STATUS_TIMEOUT +}HAL_PCCARD_StatusTypeDef; + +/** + * @brief FMC_PCCARD handle Structure definition + */ +typedef struct +{ + FMC_PCCARD_TypeDef *Instance; /*!< Register base address for PCCARD device */ + + FMC_PCCARD_InitTypeDef Init; /*!< PCCARD device control configuration parameters */ + + __IO HAL_PCCARD_StateTypeDef State; /*!< PCCARD device access state */ + + HAL_LockTypeDef Lock; /*!< PCCARD Lock */ + +}PCCARD_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup PCCARD_Exported_Macros PCCARD Exported Macros + * @{ + */ +/** @brief Reset PCCARD handle state + * @param __HANDLE__: specifies the PCCARD handle. + * @retval None + */ +#define __HAL_PCCARD_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_PCCARD_STATE_RESET) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup PCCARD_Exported_Functions + * @{ + */ + +/** @addtogroup PCCARD_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions **********************************/ +HAL_StatusTypeDef HAL_PCCARD_Init(PCCARD_HandleTypeDef *hpccard, FMC_NAND_PCC_TimingTypeDef *ComSpaceTiming, FMC_NAND_PCC_TimingTypeDef *AttSpaceTiming, FMC_NAND_PCC_TimingTypeDef *IOSpaceTiming); +HAL_StatusTypeDef HAL_PCCARD_DeInit(PCCARD_HandleTypeDef *hpccard); +void HAL_PCCARD_MspInit(PCCARD_HandleTypeDef *hpccard); +void HAL_PCCARD_MspDeInit(PCCARD_HandleTypeDef *hpccard); +/** + * @} + */ + +/** @addtogroup PCCARD_Exported_Functions_Group2 + * @{ + */ +/* IO operation functions *****************************************************/ +HAL_StatusTypeDef HAL_PCCARD_Read_ID(PCCARD_HandleTypeDef *hpccard, uint8_t CompactFlash_ID[], uint8_t *pStatus); +HAL_StatusTypeDef HAL_PCCARD_Write_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress, uint8_t *pStatus); +HAL_StatusTypeDef HAL_PCCARD_Read_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress, uint8_t *pStatus); +HAL_StatusTypeDef HAL_PCCARD_Erase_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t SectorAddress, uint8_t *pStatus); +HAL_StatusTypeDef HAL_PCCARD_Reset(PCCARD_HandleTypeDef *hpccard); +void HAL_PCCARD_IRQHandler(PCCARD_HandleTypeDef *hpccard); +void HAL_PCCARD_ITCallback(PCCARD_HandleTypeDef *hpccard); + +/** + * @} + */ + +/** @addtogroup PCCARD_Exported_Functions_Group3 + * @{ + */ +/* PCCARD State functions *******************************************************/ +HAL_PCCARD_StateTypeDef HAL_PCCARD_GetState(PCCARD_HandleTypeDef *hpccard); +HAL_PCCARD_StatusTypeDef HAL_PCCARD_GetStatus(PCCARD_HandleTypeDef *hpccard); +HAL_PCCARD_StatusTypeDef HAL_PCCARD_ReadStatus(PCCARD_HandleTypeDef *hpccard); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup PCCARD_Private_Constants PCCARD Private Constants + * @{ + */ +#define PCCARD_DEVICE_ADDRESS ((uint32_t)0x90000000) +#define PCCARD_ATTRIBUTE_SPACE_ADDRESS ((uint32_t)0x98000000) /* Attribute space size to @0x9BFF FFFF */ +#define PCCARD_COMMON_SPACE_ADDRESS PCCARD_DEVICE_ADDRESS /* Common space size to @0x93FF FFFF */ +#define PCCARD_IO_SPACE_ADDRESS ((uint32_t)0x9C000000) /* IO space size to @0x9FFF FFFF */ +#define PCCARD_IO_SPACE_PRIMARY_ADDR ((uint32_t)0x9C0001F0) /* IO space size to @0x9FFF FFFF */ + +/* Flash-ATA registers description */ +#define ATA_DATA ((uint8_t)0x00) /* Data register */ +#define ATA_SECTOR_COUNT ((uint8_t)0x02) /* Sector Count register */ +#define ATA_SECTOR_NUMBER ((uint8_t)0x03) /* Sector Number register */ +#define ATA_CYLINDER_LOW ((uint8_t)0x04) /* Cylinder low register */ +#define ATA_CYLINDER_HIGH ((uint8_t)0x05) /* Cylinder high register */ +#define ATA_CARD_HEAD ((uint8_t)0x06) /* Card/Head register */ +#define ATA_STATUS_CMD ((uint8_t)0x07) /* Status(read)/Command(write) register */ +#define ATA_STATUS_CMD_ALTERNATE ((uint8_t)0x0E) /* Alternate Status(read)/Command(write) register */ +#define ATA_COMMON_DATA_AREA ((uint16_t)0x0400) /* Start of data area (for Common access only!) */ +#define ATA_CARD_CONFIGURATION ((uint16_t)0x0202) /* Card Configuration and Status Register */ + +/* Flash-ATA commands */ +#define ATA_READ_SECTOR_CMD ((uint8_t)0x20) +#define ATA_WRITE_SECTOR_CMD ((uint8_t)0x30) +#define ATA_ERASE_SECTOR_CMD ((uint8_t)0xC0) +#define ATA_IDENTIFY_CMD ((uint8_t)0xEC) + +/* PC Card/Compact Flash status */ +#define PCCARD_TIMEOUT_ERROR ((uint8_t)0x60) +#define PCCARD_BUSY ((uint8_t)0x80) +#define PCCARD_PROGR ((uint8_t)0x01) +#define PCCARD_READY ((uint8_t)0x40) + +#define PCCARD_SECTOR_SIZE ((uint32_t)255) /* In half words */ + +/** + * @} + */ +/* Compact Flash redefinition */ +#define HAL_CF_Init HAL_PCCARD_Init +#define HAL_CF_DeInit HAL_PCCARD_DeInit +#define HAL_CF_MspInit HAL_PCCARD_MspInit +#define HAL_CF_MspDeInit HAL_PCCARD_MspDeInit + +#define HAL_CF_Read_ID HAL_PCCARD_Read_ID +#define HAL_CF_Write_Sector HAL_PCCARD_Write_Sector +#define HAL_CF_Read_Sector HAL_PCCARD_Read_Sector +#define HAL_CF_Erase_Sector HAL_PCCARD_Erase_Sector +#define HAL_CF_Reset HAL_PCCARD_Reset +#define HAL_CF_IRQHandler HAL_PCCARD_IRQHandler +#define HAL_CF_ITCallback HAL_PCCARD_ITCallback + +#define HAL_CF_GetState HAL_PCCARD_GetState +#define HAL_CF_GetStatus HAL_PCCARD_GetStatus +#define HAL_CF_ReadStatus HAL_PCCARD_ReadStatus + +#define HAL_CF_STATUS_SUCCESS HAL_PCCARD_STATUS_SUCCESS +#define HAL_CF_STATUS_ONGOING HAL_PCCARD_STATUS_ONGOING +#define HAL_CF_STATUS_ERROR HAL_PCCARD_STATUS_ERROR +#define HAL_CF_STATUS_TIMEOUT HAL_PCCARD_STATUS_TIMEOUT +#define HAL_CF_StatusTypeDef HAL_PCCARD_StatusTypeDef + + +#define CF_DEVICE_ADDRESS PCCARD_DEVICE_ADDRESS +#define CF_ATTRIBUTE_SPACE_ADDRESS PCCARD_ATTRIBUTE_SPACE_ADDRESS +#define CF_COMMON_SPACE_ADDRESS PCCARD_COMMON_SPACE_ADDRESS +#define CF_IO_SPACE_ADDRESS PCCARD_IO_SPACE_ADDRESS +#define CF_IO_SPACE_PRIMARY_ADDR PCCARD_IO_SPACE_PRIMARY_ADDR + +#define CF_TIMEOUT_ERROR PCCARD_TIMEOUT_ERROR +#define CF_BUSY PCCARD_BUSY +#define CF_PROGR PCCARD_PROGR +#define CF_READY PCCARD_READY + +#define CF_SECTOR_SIZE PCCARD_SECTOR_SIZE + +/* Private macros ------------------------------------------------------------*/ +/** + * @} + */ + +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx ||\ + STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_PCCARD_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd.h new file mode 100644 index 0000000..ad6ae87 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd.h @@ -0,0 +1,341 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_pcd.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of PCD HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_PCD_H +#define __STM32F4xx_HAL_PCD_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_ll_usb.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup PCD + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup PCD_Exported_Types PCD Exported Types + * @{ + */ + +/** + * @brief PCD State structure definition + */ +typedef enum +{ + HAL_PCD_STATE_RESET = 0x00, + HAL_PCD_STATE_READY = 0x01, + HAL_PCD_STATE_ERROR = 0x02, + HAL_PCD_STATE_BUSY = 0x03, + HAL_PCD_STATE_TIMEOUT = 0x04 +} PCD_StateTypeDef; + +#ifdef USB_OTG_GLPMCFG_LPMEN +/* Device LPM suspend state */ +typedef enum +{ + LPM_L0 = 0x00, /* on */ + LPM_L1 = 0x01, /* LPM L1 sleep */ + LPM_L2 = 0x02, /* suspend */ + LPM_L3 = 0x03, /* off */ +}PCD_LPM_StateTypeDef; +#endif /* USB_OTG_GLPMCFG_LPMEN */ + +typedef USB_OTG_GlobalTypeDef PCD_TypeDef; +typedef USB_OTG_CfgTypeDef PCD_InitTypeDef; +typedef USB_OTG_EPTypeDef PCD_EPTypeDef ; + +/** + * @brief PCD Handle Structure definition + */ +typedef struct +{ + PCD_TypeDef *Instance; /*!< Register base address */ + PCD_InitTypeDef Init; /*!< PCD required parameters */ + PCD_EPTypeDef IN_ep[15]; /*!< IN endpoint parameters */ + PCD_EPTypeDef OUT_ep[15]; /*!< OUT endpoint parameters */ + HAL_LockTypeDef Lock; /*!< PCD peripheral status */ + __IO PCD_StateTypeDef State; /*!< PCD communication state */ + uint32_t Setup[12]; /*!< Setup packet buffer */ +#ifdef USB_OTG_GLPMCFG_LPMEN + PCD_LPM_StateTypeDef LPM_State; /*!< LPM State */ + uint32_t BESL; + uint32_t lpm_active; /*!< Enable or disable the Link Power Management . + This parameter can be set to ENABLE or DISABLE */ +#endif /* USB_OTG_GLPMCFG_LPMEN */ + void *pData; /*!< Pointer to upper stack Handler */ +} PCD_HandleTypeDef; + +/** + * @} + */ + +/* Include PCD HAL Extension module */ +#include "stm32f4xx_hal_pcd_ex.h" + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PCD_Exported_Constants PCD Exported Constants + * @{ + */ + +/** @defgroup PCD_Speed PCD Speed + * @{ + */ +#define PCD_SPEED_HIGH 0 +#define PCD_SPEED_HIGH_IN_FULL 1 +#define PCD_SPEED_FULL 2 +/** + * @} + */ + +/** @defgroup PCD_PHY_Module PCD PHY Module + * @{ + */ +#define PCD_PHY_ULPI 1 +#define PCD_PHY_EMBEDDED 2 +/** + * @} + */ + +/** @defgroup PCD_Turnaround_Timeout Turnaround Timeout Value + * @{ + */ +#ifndef USBD_HS_TRDT_VALUE + #define USBD_HS_TRDT_VALUE 9 +#endif /* USBD_HS_TRDT_VALUE */ +#ifndef USBD_FS_TRDT_VALUE + #define USBD_FS_TRDT_VALUE 5 +#endif /* USBD_FS_TRDT_VALUE */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup PCD_Exported_Macros PCD Exported Macros + * @brief macros to handle interrupts and specific clock configurations + * @{ + */ +#define __HAL_PCD_ENABLE(__HANDLE__) USB_EnableGlobalInt ((__HANDLE__)->Instance) +#define __HAL_PCD_DISABLE(__HANDLE__) USB_DisableGlobalInt ((__HANDLE__)->Instance) + +#define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__)) +#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->GINTSTS) = (__INTERRUPT__)) +#define __HAL_PCD_IS_INVALID_INTERRUPT(__HANDLE__) (USB_ReadInterrupts((__HANDLE__)->Instance) == 0) + + +#define __HAL_PCD_UNGATE_PHYCLOCK(__HANDLE__) *(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) &= \ + ~(USB_OTG_PCGCCTL_STOPCLK) + +#define __HAL_PCD_GATE_PHYCLOCK(__HANDLE__) *(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) |= USB_OTG_PCGCCTL_STOPCLK + +#define __HAL_PCD_IS_PHY_SUSPENDED(__HANDLE__) ((*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE))&0x10) + +#define USB_OTG_FS_WAKEUP_EXTI_RISING_EDGE ((uint32_t)0x08) +#define USB_OTG_FS_WAKEUP_EXTI_FALLING_EDGE ((uint32_t)0x0C) +#define USB_OTG_FS_WAKEUP_EXTI_RISING_FALLING_EDGE ((uint32_t)0x10) + +#define USB_OTG_HS_WAKEUP_EXTI_RISING_EDGE ((uint32_t)0x08) +#define USB_OTG_HS_WAKEUP_EXTI_FALLING_EDGE ((uint32_t)0x0C) +#define USB_OTG_HS_WAKEUP_EXTI_RISING_FALLING_EDGE ((uint32_t)0x10) + +#define USB_OTG_HS_WAKEUP_EXTI_LINE ((uint32_t)0x00100000) /*!< External interrupt line 20 Connected to the USB HS EXTI Line */ +#define USB_OTG_FS_WAKEUP_EXTI_LINE ((uint32_t)0x00040000) /*!< External interrupt line 18 Connected to the USB FS EXTI Line */ + +#define __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= (USB_OTG_HS_WAKEUP_EXTI_LINE) +#define __HAL_USB_OTG_HS_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_OTG_HS_WAKEUP_EXTI_LINE) +#define __HAL_USB_OTG_HS_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (USB_OTG_HS_WAKEUP_EXTI_LINE) +#define __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = (USB_OTG_HS_WAKEUP_EXTI_LINE) + +#define __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_EDGE() EXTI->FTSR &= ~(USB_OTG_HS_WAKEUP_EXTI_LINE);\ + EXTI->RTSR |= USB_OTG_HS_WAKEUP_EXTI_LINE + +#define __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_FALLING_EDGE() EXTI->FTSR |= (USB_OTG_HS_WAKEUP_EXTI_LINE);\ + EXTI->RTSR &= ~(USB_OTG_HS_WAKEUP_EXTI_LINE) + +#define __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE() EXTI->RTSR &= ~(USB_OTG_HS_WAKEUP_EXTI_LINE);\ + EXTI->FTSR &= ~(USB_OTG_HS_WAKEUP_EXTI_LINE;)\ + EXTI->RTSR |= USB_OTG_HS_WAKEUP_EXTI_LINE;\ + EXTI->FTSR |= USB_OTG_HS_WAKEUP_EXTI_LINE + +#define __HAL_USB_OTG_HS_WAKEUP_EXTI_GENERATE_SWIT() (EXTI->SWIER |= USB_OTG_FS_WAKEUP_EXTI_LINE) + +#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= USB_OTG_FS_WAKEUP_EXTI_LINE +#define __HAL_USB_OTG_FS_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE) +#define __HAL_USB_OTG_FS_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (USB_OTG_FS_WAKEUP_EXTI_LINE) +#define __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = USB_OTG_FS_WAKEUP_EXTI_LINE + +#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE() EXTI->FTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE);\ + EXTI->RTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE + + +#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_FALLING_EDGE() EXTI->FTSR |= (USB_OTG_FS_WAKEUP_EXTI_LINE);\ + EXTI->RTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE) + +#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_FALLING_EDGE() EXTI->RTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE);\ + EXTI->FTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE);\ + EXTI->RTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE;\ + EXTI->FTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE + +#define __HAL_USB_OTG_FS_WAKEUP_EXTI_GENERATE_SWIT() (EXTI->SWIER |= USB_OTG_FS_WAKEUP_EXTI_LINE) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup PCD_Exported_Functions PCD Exported Functions + * @{ + */ + +/* Initialization/de-initialization functions ********************************/ +/** @addtogroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd); +void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd); +void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd); +/** + * @} + */ + +/* I/O operation functions ***************************************************/ +/* Non-Blocking mode: Interrupt */ +/** @addtogroup PCD_Exported_Functions_Group2 IO operation functions + * @{ + */ +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd); +void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd); + +void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); +void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); +void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); +void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); +void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd); +/** + * @} + */ + +/* Peripheral Control functions **********************************************/ +/** @addtogroup PCD_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ +HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address); +HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type); +HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); +HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); +uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd); +/** + * @} + */ + +/* Peripheral State functions ************************************************/ +/** @addtogroup PCD_Exported_Functions_Group4 Peripheral State functions + * @{ + */ +PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd); +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PCD_Private_Macros PCD Private Macros + * @{ + */ +/** @defgroup PCD_Instance_definition PCD Instance definition + * @{ + */ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) ||\ + defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) + #define IS_PCD_ALL_INSTANCE(INSTANCE) (((INSTANCE) == USB_OTG_FS) || \ + ((INSTANCE) == USB_OTG_HS)) +#elif defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) + #define IS_PCD_ALL_INSTANCE(INSTANCE) (((INSTANCE) == USB_OTG_FS)) +#endif +/** + * @} + */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F4xx_HAL_PCD_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd_ex.h new file mode 100644 index 0000000..7d4b0c3 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pcd_ex.h @@ -0,0 +1,105 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_pcd_ex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of PCD HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_PCD_EX_H +#define __STM32F4xx_HAL_PCD_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup PCDEx + * @{ + */ +/* Exported types ------------------------------------------------------------*/ +#if defined(STM32F446xx) +typedef enum +{ + PCD_LPM_L0_ACTIVE = 0x00, /* on */ + PCD_LPM_L1_ACTIVE = 0x01, /* LPM L1 sleep */ +}PCD_LPM_MsgTypeDef; +#endif /* STM32F446xx */ + +/* Exported constants --------------------------------------------------------*/ +/* Exported macros -----------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup PCDEx_Exported_Functions PCDEx Exported Functions + * @{ + */ +/** @addtogroup PCDEx_Exported_Functions_Group1 Peripheral Control functions + * @{ + */ +HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size); +HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size); +#if defined(STM32F446xx) +HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd); +void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); +#endif /* STM32F446xx */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F4xx_HAL_PCD_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h new file mode 100644 index 0000000..0532721 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h @@ -0,0 +1,484 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_pwr.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of PWR HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_PWR_H +#define __STM32F4xx_HAL_PWR_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup PWR + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup PWR_Exported_Types PWR Exported Types + * @{ + */ + +/** + * @brief PWR PVD configuration structure definition + */ +typedef struct +{ + uint32_t PVDLevel; /*!< PVDLevel: Specifies the PVD detection level. + This parameter can be a value of @ref PWR_PVD_detection_level */ + + uint32_t Mode; /*!< Mode: Specifies the operating mode for the selected pins. + This parameter can be a value of @ref PWR_PVD_Mode */ +}PWR_PVDTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PWR_Exported_Constants PWR Exported Constants + * @{ + */ + +/** @defgroup PWR_WakeUp_Pins PWR WakeUp Pins + * @{ + */ +#define PWR_WAKEUP_PIN1 ((uint32_t)0x00000100) +#define PWR_WAKEUP_PIN2 ((uint32_t)0x00000080) +/** + * @} + */ + +/** @defgroup PWR_PVD_detection_level PWR PVD detection level + * @{ + */ +#define PWR_PVDLEVEL_0 PWR_CR_PLS_LEV0 +#define PWR_PVDLEVEL_1 PWR_CR_PLS_LEV1 +#define PWR_PVDLEVEL_2 PWR_CR_PLS_LEV2 +#define PWR_PVDLEVEL_3 PWR_CR_PLS_LEV3 +#define PWR_PVDLEVEL_4 PWR_CR_PLS_LEV4 +#define PWR_PVDLEVEL_5 PWR_CR_PLS_LEV5 +#define PWR_PVDLEVEL_6 PWR_CR_PLS_LEV6 +#define PWR_PVDLEVEL_7 PWR_CR_PLS_LEV7/* External input analog voltage + (Compare internally to VREFINT) */ +/** + * @} + */ + +/** @defgroup PWR_PVD_Mode PWR PVD Mode + * @{ + */ +#define PWR_PVD_MODE_NORMAL ((uint32_t)0x00000000) /*!< basic mode is used */ +#define PWR_PVD_MODE_IT_RISING ((uint32_t)0x00010001) /*!< External Interrupt Mode with Rising edge trigger detection */ +#define PWR_PVD_MODE_IT_FALLING ((uint32_t)0x00010002) /*!< External Interrupt Mode with Falling edge trigger detection */ +#define PWR_PVD_MODE_IT_RISING_FALLING ((uint32_t)0x00010003) /*!< External Interrupt Mode with Rising/Falling edge trigger detection */ +#define PWR_PVD_MODE_EVENT_RISING ((uint32_t)0x00020001) /*!< Event Mode with Rising edge trigger detection */ +#define PWR_PVD_MODE_EVENT_FALLING ((uint32_t)0x00020002) /*!< Event Mode with Falling edge trigger detection */ +#define PWR_PVD_MODE_EVENT_RISING_FALLING ((uint32_t)0x00020003) /*!< Event Mode with Rising/Falling edge trigger detection */ +/** + * @} + */ + + +/** @defgroup PWR_Regulator_state_in_STOP_mode PWR Regulator state in SLEEP/STOP mode + * @{ + */ +#define PWR_MAINREGULATOR_ON ((uint32_t)0x00000000) +#define PWR_LOWPOWERREGULATOR_ON PWR_CR_LPDS +/** + * @} + */ + +/** @defgroup PWR_SLEEP_mode_entry PWR SLEEP mode entry + * @{ + */ +#define PWR_SLEEPENTRY_WFI ((uint8_t)0x01) +#define PWR_SLEEPENTRY_WFE ((uint8_t)0x02) +/** + * @} + */ + +/** @defgroup PWR_STOP_mode_entry PWR STOP mode entry + * @{ + */ +#define PWR_STOPENTRY_WFI ((uint8_t)0x01) +#define PWR_STOPENTRY_WFE ((uint8_t)0x02) +/** + * @} + */ + +/** @defgroup PWR_Flag PWR Flag + * @{ + */ +#define PWR_FLAG_WU PWR_CSR_WUF +#define PWR_FLAG_SB PWR_CSR_SBF +#define PWR_FLAG_PVDO PWR_CSR_PVDO +#define PWR_FLAG_BRR PWR_CSR_BRR +#define PWR_FLAG_VOSRDY PWR_CSR_VOSRDY +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup PWR_Exported_Macro PWR Exported Macro + * @{ + */ + +#if defined(STM32F405xx) || defined(STM32F407xx) || defined(STM32F415xx) || defined(STM32F417xx) +/** @brief macros configure the main internal regulator output voltage. + * @param __REGULATOR__: specifies the regulator output voltage to achieve + * a tradeoff between performance and power consumption when the device does + * not operate at the maximum frequency (refer to the datasheets for more details). + * This parameter can be one of the following values: + * @arg PWR_REGULATOR_VOLTAGE_SCALE1: Regulator voltage output Scale 1 mode + * @arg PWR_REGULATOR_VOLTAGE_SCALE2: Regulator voltage output Scale 2 mode + * @retval None + */ +#define __HAL_PWR_VOLTAGESCALING_CONFIG(__REGULATOR__) do { \ + __IO uint32_t tmpreg; \ + MODIFY_REG(PWR->CR, PWR_CR_VOS, (__REGULATOR__)); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(PWR->CR, PWR_CR_VOS); \ + UNUSED(tmpreg); \ + } while(0) +#else +/** @brief macros configure the main internal regulator output voltage. + * @param __REGULATOR__: specifies the regulator output voltage to achieve + * a tradeoff between performance and power consumption when the device does + * not operate at the maximum frequency (refer to the datasheets for more details). + * This parameter can be one of the following values: + * @arg PWR_REGULATOR_VOLTAGE_SCALE1: Regulator voltage output Scale 1 mode + * @arg PWR_REGULATOR_VOLTAGE_SCALE2: Regulator voltage output Scale 2 mode + * @arg PWR_REGULATOR_VOLTAGE_SCALE3: Regulator voltage output Scale 3 mode + * @retval None + */ +#define __HAL_PWR_VOLTAGESCALING_CONFIG(__REGULATOR__) do { \ + __IO uint32_t tmpreg; \ + MODIFY_REG(PWR->CR, PWR_CR_VOS, (__REGULATOR__)); \ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(PWR->CR, PWR_CR_VOS); \ + UNUSED(tmpreg); \ + } while(0) +#endif /* STM32F405xx || STM32F407xx || STM32F415xx || STM32F417xx */ + +/** @brief Check PWR flag is set or not. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg PWR_FLAG_WU: Wake Up flag. This flag indicates that a wakeup event + * was received from the WKUP pin or from the RTC alarm (Alarm A + * or Alarm B), RTC Tamper event, RTC TimeStamp event or RTC Wakeup. + * An additional wakeup event is detected if the WKUP pin is enabled + * (by setting the EWUP bit) when the WKUP pin level is already high. + * @arg PWR_FLAG_SB: StandBy flag. This flag indicates that the system was + * resumed from StandBy mode. + * @arg PWR_FLAG_PVDO: PVD Output. This flag is valid only if PVD is enabled + * by the HAL_PWR_EnablePVD() function. The PVD is stopped by Standby mode + * For this reason, this bit is equal to 0 after Standby or reset + * until the PVDE bit is set. + * @arg PWR_FLAG_BRR: Backup regulator ready flag. This bit is not reset + * when the device wakes up from Standby mode or by a system reset + * or power reset. + * @arg PWR_FLAG_VOSRDY: This flag indicates that the Regulator voltage + * scaling output selection is ready. + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_PWR_GET_FLAG(__FLAG__) ((PWR->CSR & (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the PWR's pending flags. + * @param __FLAG__: specifies the flag to clear. + * This parameter can be one of the following values: + * @arg PWR_FLAG_WU: Wake Up flag + * @arg PWR_FLAG_SB: StandBy flag + */ +#define __HAL_PWR_CLEAR_FLAG(__FLAG__) (PWR->CR |= (__FLAG__) << 2) + +/** + * @brief Enable the PVD Exti Line 16. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_IT() (EXTI->IMR |= (PWR_EXTI_LINE_PVD)) + +/** + * @brief Disable the PVD EXTI Line 16. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_IT() (EXTI->IMR &= ~(PWR_EXTI_LINE_PVD)) + +/** + * @brief Enable event on PVD Exti Line 16. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_EVENT() (EXTI->EMR |= (PWR_EXTI_LINE_PVD)) + +/** + * @brief Disable event on PVD Exti Line 16. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_EVENT() (EXTI->EMR &= ~(PWR_EXTI_LINE_PVD)) + +/** + * @brief Enable the PVD Extended Interrupt Rising Trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE() SET_BIT(EXTI->RTSR, PWR_EXTI_LINE_PVD) + +/** + * @brief Disable the PVD Extended Interrupt Rising Trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE() CLEAR_BIT(EXTI->RTSR, PWR_EXTI_LINE_PVD) + +/** + * @brief Enable the PVD Extended Interrupt Falling Trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE() SET_BIT(EXTI->FTSR, PWR_EXTI_LINE_PVD) + + +/** + * @brief Disable the PVD Extended Interrupt Falling Trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE() CLEAR_BIT(EXTI->FTSR, PWR_EXTI_LINE_PVD) + + +/** + * @brief PVD EXTI line configuration: set rising & falling edge trigger. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_ENABLE_RISING_FALLING_EDGE() __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();__HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE(); + +/** + * @brief Disable the PVD Extended Interrupt Rising & Falling Trigger. + * This parameter can be: + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_DISABLE_RISING_FALLING_EDGE() __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();__HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE(); + +/** + * @brief checks whether the specified PVD Exti interrupt flag is set or not. + * @retval EXTI PVD Line Status. + */ +#define __HAL_PWR_PVD_EXTI_GET_FLAG() (EXTI->PR & (PWR_EXTI_LINE_PVD)) + +/** + * @brief Clear the PVD Exti flag. + * @retval None. + */ +#define __HAL_PWR_PVD_EXTI_CLEAR_FLAG() (EXTI->PR = (PWR_EXTI_LINE_PVD)) + +/** + * @brief Generates a Software interrupt on PVD EXTI line. + * @retval None + */ +#define __HAL_PWR_PVD_EXTI_GENERATE_SWIT() (EXTI->SWIER |= (PWR_EXTI_LINE_PVD)) + +/** + * @} + */ + +/* Include PWR HAL Extension module */ +#include "stm32f4xx_hal_pwr_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup PWR_Exported_Functions PWR Exported Functions + * @{ + */ + +/** @addtogroup PWR_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +/* Initialization and de-initialization functions *****************************/ +void HAL_PWR_DeInit(void); +void HAL_PWR_EnableBkUpAccess(void); +void HAL_PWR_DisableBkUpAccess(void); +/** + * @} + */ + +/** @addtogroup PWR_Exported_Functions_Group2 Peripheral Control functions + * @{ + */ +/* Peripheral Control functions **********************************************/ +/* PVD configuration */ +void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD); +void HAL_PWR_EnablePVD(void); +void HAL_PWR_DisablePVD(void); + +/* WakeUp pins configuration */ +void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx); +void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx); + +/* Low Power modes entry */ +void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry); +void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry); +void HAL_PWR_EnterSTANDBYMode(void); + +/* Power PVD IRQ Handler */ +void HAL_PWR_PVD_IRQHandler(void); +void HAL_PWR_PVDCallback(void); + +/* Cortex System Control functions *******************************************/ +void HAL_PWR_EnableSleepOnExit(void); +void HAL_PWR_DisableSleepOnExit(void); +void HAL_PWR_EnableSEVOnPend(void); +void HAL_PWR_DisableSEVOnPend(void); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup PWR_Private_Constants PWR Private Constants + * @{ + */ + +/** @defgroup PWR_PVD_EXTI_Line PWR PVD EXTI Line + * @{ + */ +#define PWR_EXTI_LINE_PVD ((uint32_t)EXTI_IMR_MR16) /*!< External interrupt line 16 Connected to the PVD EXTI Line */ +/** + * @} + */ + +/** @defgroup PWR_register_alias_address PWR Register alias address + * @{ + */ +/* ------------- PWR registers bit address in the alias region ---------------*/ +#define PWR_OFFSET (PWR_BASE - PERIPH_BASE) +#define PWR_CR_OFFSET 0x00 +#define PWR_CSR_OFFSET 0x04 +#define PWR_CR_OFFSET_BB (PWR_OFFSET + PWR_CR_OFFSET) +#define PWR_CSR_OFFSET_BB (PWR_OFFSET + PWR_CSR_OFFSET) +/** + * @} + */ + +/** @defgroup PWR_CR_register_alias PWR CR Register alias address + * @{ + */ +/* --- CR Register ---*/ +/* Alias word address of DBP bit */ +#define DBP_BIT_NUMBER POSITION_VAL(PWR_CR_DBP) +#define CR_DBP_BB (uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32) + (DBP_BIT_NUMBER * 4)) + +/* Alias word address of PVDE bit */ +#define PVDE_BIT_NUMBER POSITION_VAL(PWR_CR_PVDE) +#define CR_PVDE_BB (uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32) + (PVDE_BIT_NUMBER * 4)) + +/* Alias word address of PMODE bit */ +#define PMODE_BIT_NUMBER POSITION_VAL(PWR_CR_PMODE) +#define CR_PMODE_BB (uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32) + (PMODE_BIT_NUMBER * 4)) +/** + * @} + */ + +/** @defgroup PWR_CSR_register_alias PWR CSR Register alias address + * @{ + */ +/* --- CSR Register ---*/ +/* Alias word address of EWUP bit */ +#define EWUP_BIT_NUMBER POSITION_VAL(PWR_CSR_EWUP) +#define CSR_EWUP_BB (PERIPH_BB_BASE + (PWR_CSR_OFFSET_BB * 32) + (EWUP_BIT_NUMBER * 4)) +/** + * @} + */ + +/** + * @} + */ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PWR_Private_Macros PWR Private Macros + * @{ + */ + +/** @defgroup PWR_IS_PWR_Definitions PWR Private macros to check input parameters + * @{ + */ +#define IS_PWR_WAKEUP_PIN(PIN) (((PIN) == PWR_WAKEUP_PIN1) || ((PIN) == PWR_WAKEUP_PIN2)) +#define IS_PWR_PVD_LEVEL(LEVEL) (((LEVEL) == PWR_PVDLEVEL_0) || ((LEVEL) == PWR_PVDLEVEL_1)|| \ + ((LEVEL) == PWR_PVDLEVEL_2) || ((LEVEL) == PWR_PVDLEVEL_3)|| \ + ((LEVEL) == PWR_PVDLEVEL_4) || ((LEVEL) == PWR_PVDLEVEL_5)|| \ + ((LEVEL) == PWR_PVDLEVEL_6) || ((LEVEL) == PWR_PVDLEVEL_7)) +#define IS_PWR_PVD_MODE(MODE) (((MODE) == PWR_PVD_MODE_IT_RISING)|| ((MODE) == PWR_PVD_MODE_IT_FALLING) || \ + ((MODE) == PWR_PVD_MODE_IT_RISING_FALLING) || ((MODE) == PWR_PVD_MODE_EVENT_RISING) || \ + ((MODE) == PWR_PVD_MODE_EVENT_FALLING) || ((MODE) == PWR_PVD_MODE_EVENT_RISING_FALLING) || \ + ((MODE) == PWR_PVD_MODE_NORMAL)) +#define IS_PWR_REGULATOR(REGULATOR) (((REGULATOR) == PWR_MAINREGULATOR_ON) || \ + ((REGULATOR) == PWR_LOWPOWERREGULATOR_ON)) +#define IS_PWR_SLEEP_ENTRY(ENTRY) (((ENTRY) == PWR_SLEEPENTRY_WFI) || ((ENTRY) == PWR_SLEEPENTRY_WFE)) +#define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPENTRY_WFI) || ((ENTRY) == PWR_STOPENTRY_WFE)) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F4xx_HAL_PWR_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h new file mode 100644 index 0000000..17032d6 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr_ex.h @@ -0,0 +1,291 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_pwr_ex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of PWR HAL Extension module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_PWR_EX_H +#define __STM32F4xx_HAL_PWR_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup PWREx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PWREx_Exported_Constants PWREx Exported Constants + * @{ + */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) + +/** @defgroup PWREx_Regulator_state_in_UnderDrive_mode PWREx Regulator state in UnderDrive mode + * @{ + */ +#define PWR_MAINREGULATOR_UNDERDRIVE_ON PWR_CR_MRUDS +#define PWR_LOWPOWERREGULATOR_UNDERDRIVE_ON ((uint32_t)(PWR_CR_LPDS | PWR_CR_LPUDS)) +/** + * @} + */ + +/** @defgroup PWREx_Over_Under_Drive_Flag PWREx Over Under Drive Flag + * @{ + */ +#define PWR_FLAG_ODRDY PWR_CSR_ODRDY +#define PWR_FLAG_ODSWRDY PWR_CSR_ODSWRDY +#define PWR_FLAG_UDRDY PWR_CSR_UDSWRDY +/** + * @} + */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ + +/** @defgroup PWR_Regulator_Voltage_Scale PWR Regulator Voltage Scale + * @{ + */ +#if defined(STM32F405xx) || defined(STM32F407xx) || defined(STM32F415xx) || defined(STM32F417xx) +#define PWR_REGULATOR_VOLTAGE_SCALE1 PWR_CR_VOS /* Scale 1 mode(default value at reset): the maximum value of fHCLK = 168 MHz. */ +#define PWR_REGULATOR_VOLTAGE_SCALE2 ((uint32_t)0x00000000) /* Scale 2 mode: the maximum value of fHCLK = 144 MHz. */ +#else +#define PWR_REGULATOR_VOLTAGE_SCALE1 PWR_CR_VOS /* Scale 1 mode(default value at reset): the maximum value of fHCLK is 168 MHz. It can be extended to + 180 MHz by activating the over-drive mode. */ +#define PWR_REGULATOR_VOLTAGE_SCALE2 PWR_CR_VOS_1 /* Scale 2 mode: the maximum value of fHCLK is 144 MHz. It can be extended to + 168 MHz by activating the over-drive mode. */ +#define PWR_REGULATOR_VOLTAGE_SCALE3 PWR_CR_VOS_0 /* Scale 3 mode: the maximum value of fHCLK is 120 MHz. */ +#endif /* STM32F405xx || STM32F407xx || STM32F415xx || STM32F417xx */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup PWREx_Exported_Constants PWREx Exported Constants + * @{ + */ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) +/** @brief Macros to enable or disable the Over drive mode. + * @note These macros can be used only for STM32F42xx/STM3243xx devices. + */ +#define __HAL_PWR_OVERDRIVE_ENABLE() (*(__IO uint32_t *) CR_ODEN_BB = ENABLE) +#define __HAL_PWR_OVERDRIVE_DISABLE() (*(__IO uint32_t *) CR_ODEN_BB = DISABLE) + +/** @brief Macros to enable or disable the Over drive switching. + * @note These macros can be used only for STM32F42xx/STM3243xx devices. + */ +#define __HAL_PWR_OVERDRIVESWITCHING_ENABLE() (*(__IO uint32_t *) CR_ODSWEN_BB = ENABLE) +#define __HAL_PWR_OVERDRIVESWITCHING_DISABLE() (*(__IO uint32_t *) CR_ODSWEN_BB = DISABLE) + +/** @brief Macros to enable or disable the Under drive mode. + * @note This mode is enabled only with STOP low power mode. + * In this mode, the 1.2V domain is preserved in reduced leakage mode. This + * mode is only available when the main regulator or the low power regulator + * is in low voltage mode. + * @note If the Under-drive mode was enabled, it is automatically disabled after + * exiting Stop mode. + * When the voltage regulator operates in Under-drive mode, an additional + * startup delay is induced when waking up from Stop mode. + */ +#define __HAL_PWR_UNDERDRIVE_ENABLE() (PWR->CR |= (uint32_t)PWR_CR_UDEN) +#define __HAL_PWR_UNDERDRIVE_DISABLE() (PWR->CR &= (uint32_t)(~PWR_CR_UDEN)) + +/** @brief Check PWR flag is set or not. + * @note These macros can be used only for STM32F42xx/STM3243xx devices. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg PWR_FLAG_ODRDY: This flag indicates that the Over-drive mode + * is ready + * @arg PWR_FLAG_ODSWRDY: This flag indicates that the Over-drive mode + * switching is ready + * @arg PWR_FLAG_UDRDY: This flag indicates that the Under-drive mode + * is enabled in Stop mode + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_PWR_GET_ODRUDR_FLAG(__FLAG__) ((PWR->CSR & (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the Under-Drive Ready flag. + * @note These macros can be used only for STM32F42xx/STM3243xx devices. + */ +#define __HAL_PWR_CLEAR_ODRUDR_FLAG() (PWR->CSR |= PWR_FLAG_UDRDY) + +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup PWREx_Exported_Functions PWREx Exported Functions + * @{ + */ + +/** @addtogroup PWREx_Exported_Functions_Group1 + * @{ + */ +void HAL_PWREx_EnableFlashPowerDown(void); +void HAL_PWREx_DisableFlashPowerDown(void); +HAL_StatusTypeDef HAL_PWREx_EnableBkUpReg(void); +HAL_StatusTypeDef HAL_PWREx_DisableBkUpReg(void); +uint32_t HAL_PWREx_GetVoltageRange(void); +HAL_StatusTypeDef HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling); + +#if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) +void HAL_PWREx_EnableMainRegulatorLowVoltage(void); +void HAL_PWREx_DisableMainRegulatorLowVoltage(void); +void HAL_PWREx_EnableLowRegulatorLowVoltage(void); +void HAL_PWREx_DisableLowRegulatorLowVoltage(void); +#endif /* STM32F401xC || STM32F401xE || STM32F411xE */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) +HAL_StatusTypeDef HAL_PWREx_EnableOverDrive(void); +HAL_StatusTypeDef HAL_PWREx_DisableOverDrive(void); +HAL_StatusTypeDef HAL_PWREx_EnterUnderDriveSTOPMode(uint32_t Regulator, uint8_t STOPEntry); +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ + +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup PWREx_Private_Constants PWREx Private Constants + * @{ + */ + +/** @defgroup PWREx_register_alias_address PWREx Register alias address + * @{ + */ +/* ------------- PWR registers bit address in the alias region ---------------*/ +/* --- CR Register ---*/ +/* Alias word address of FPDS bit */ +#define FPDS_BIT_NUMBER POSITION_VAL(PWR_CR_FPDS) +#define CR_FPDS_BB (uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32) + (FPDS_BIT_NUMBER * 4)) + +/* Alias word address of ODEN bit */ +#define ODEN_BIT_NUMBER POSITION_VAL(PWR_CR_ODEN) +#define CR_ODEN_BB (uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32) + (ODEN_BIT_NUMBER * 4)) + +/* Alias word address of ODSWEN bit */ +#define ODSWEN_BIT_NUMBER POSITION_VAL(PWR_CR_ODSWEN) +#define CR_ODSWEN_BB (uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32) + (ODSWEN_BIT_NUMBER * 4)) + +/* Alias word address of MRLVDS bit */ +#define MRLVDS_BIT_NUMBER POSITION_VAL(PWR_CR_MRLVDS) +#define CR_MRLVDS_BB (uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32) + (MRLVDS_BIT_NUMBER * 4)) + +/* Alias word address of LPLVDS bit */ +#define LPLVDS_BIT_NUMBER POSITION_VAL(PWR_CR_LPLVDS) +#define CR_LPLVDS_BB (uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32) + (LPLVDS_BIT_NUMBER * 4)) + + /** + * @} + */ + +/** @defgroup PWREx_CSR_register_alias PWRx CSR Register alias address + * @{ + */ +/* --- CSR Register ---*/ +/* Alias word address of BRE bit */ +#define BRE_BIT_NUMBER POSITION_VAL(PWR_CSR_BRE) +#define CSR_BRE_BB (uint32_t)(PERIPH_BB_BASE + (PWR_CSR_OFFSET_BB * 32) + (BRE_BIT_NUMBER * 4)) +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PWREx_Private_Macros PWREx Private Macros + * @{ + */ + +/** @defgroup PWREx_IS_PWR_Definitions PWREx Private macros to check input parameters + * @{ + */ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) +#define IS_PWR_REGULATOR_UNDERDRIVE(REGULATOR) (((REGULATOR) == PWR_MAINREGULATOR_UNDERDRIVE_ON) || \ + ((REGULATOR) == PWR_LOWPOWERREGULATOR_UNDERDRIVE_ON)) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ + +#if defined(STM32F405xx) || defined(STM32F407xx) || defined(STM32F415xx) || defined(STM32F417xx) +#define IS_PWR_VOLTAGE_SCALING_RANGE(VOLTAGE) (((VOLTAGE) == PWR_REGULATOR_VOLTAGE_SCALE1) || \ + ((VOLTAGE) == PWR_REGULATOR_VOLTAGE_SCALE2)) +#else +#define IS_PWR_VOLTAGE_SCALING_RANGE(VOLTAGE) (((VOLTAGE) == PWR_REGULATOR_VOLTAGE_SCALE1) || \ + ((VOLTAGE) == PWR_REGULATOR_VOLTAGE_SCALE2) || \ + ((VOLTAGE) == PWR_REGULATOR_VOLTAGE_SCALE3)) +#endif /* STM32F405xx || STM32F407xx || STM32F415xx || STM32F417xx */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F4xx_HAL_PWR_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_qspi.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_qspi.h new file mode 100644 index 0000000..bd76eeb --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_qspi.h @@ -0,0 +1,788 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_qspi.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of QSPI HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_QSPI_H +#define __STM32F4xx_HAL_QSPI_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F446xx) +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup QSPI + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup QSPI_Exported_Types QSPI Exported Types + * @{ + */ + +/** + * @brief QSPI Init structure definition + */ + +typedef struct +{ + uint32_t ClockPrescaler; /* Specifies the prescaler factor for generating clock based on the AHB clock. + This parameter can be a number between 0 and 255 */ + + uint32_t FifoThreshold; /* Specifies the threshold number of bytes in the FIFO (used only in indirect mode) + This parameter can be a value between 1 and 32 */ + + uint32_t SampleShifting; /* Specifies the Sample Shift. The data is sampled 1/2 clock cycle delay later to + take in account external signal delays. (It should be QSPI_SAMPLE_SHIFTING_NONE in DDR mode) + This parameter can be a value of @ref QSPI_SampleShifting */ + + uint32_t FlashSize; /* Specifies the Flash Size. FlashSize+1 is effectively the number of address bits + required to address the flash memory. The flash capacity can be up to 4GB + (addressed using 32 bits) in indirect mode, but the addressable space in + memory-mapped mode is limited to 256MB + This parameter can be a number between 0 and 31 */ + + uint32_t ChipSelectHighTime; /* Specifies the Chip Select High Time. ChipSelectHighTime+1 defines the minimum number + of clock cycles which the chip select must remain high between commands. + This parameter can be a value of @ref QSPI_ChipSelectHighTime */ + + uint32_t ClockMode; /* Specifies the Clock Mode. It indicates the level that clock takes between commands. + This parameter can be a value of @ref QSPI_ClockMode */ + + uint32_t FlashID; /* Specifies the Flash which will be used, + This parameter can be a value of @ref QSPI_Flash_Select */ + + uint32_t DualFlash; /* Specifies the Dual Flash Mode State + This parameter can be a value of @ref QSPI_DualFlash_Mode */ +}QSPI_InitTypeDef; + +/** + * @brief HAL QSPI State structures definition + */ +typedef enum +{ + HAL_QSPI_STATE_RESET = 0x00, /*!< Peripheral not initialized */ + HAL_QSPI_STATE_READY = 0x01, /*!< Peripheral initialized and ready for use */ + HAL_QSPI_STATE_BUSY = 0x02, /*!< Peripheral in indirect mode and busy */ + HAL_QSPI_STATE_BUSY_INDIRECT_TX = 0x12, /*!< Peripheral in indirect mode with transmission ongoing */ + HAL_QSPI_STATE_BUSY_INDIRECT_RX = 0x22, /*!< Peripheral in indirect mode with reception ongoing */ + HAL_QSPI_STATE_BUSY_AUTO_POLLING = 0x42, /*!< Peripheral in auto polling mode ongoing */ + HAL_QSPI_STATE_BUSY_MEM_MAPPED = 0x82, /*!< Peripheral in memory mapped mode ongoing */ + HAL_QSPI_STATE_ERROR = 0x04 /*!< Peripheral in error */ +}HAL_QSPI_StateTypeDef; + +/** + * @brief QSPI Handle Structure definition + */ +typedef struct +{ + QUADSPI_TypeDef *Instance; /* QSPI registers base address */ + QSPI_InitTypeDef Init; /* QSPI communication parameters */ + uint8_t *pTxBuffPtr; /* Pointer to QSPI Tx transfer Buffer */ + __IO uint16_t TxXferSize; /* QSPI Tx Transfer size */ + __IO uint16_t TxXferCount; /* QSPI Tx Transfer Counter */ + uint8_t *pRxBuffPtr; /* Pointer to QSPI Rx transfer Buffer */ + __IO uint16_t RxXferSize; /* QSPI Rx Transfer size */ + __IO uint16_t RxXferCount; /* QSPI Rx Transfer Counter */ + DMA_HandleTypeDef *hdma; /* QSPI Rx/Tx DMA Handle parameters */ + __IO HAL_LockTypeDef Lock; /* Locking object */ + __IO HAL_QSPI_StateTypeDef State; /* QSPI communication state */ + __IO uint32_t ErrorCode; /* QSPI Error code */ + uint32_t Timeout; /* Timeout for the QSPI memory access */ +}QSPI_HandleTypeDef; + +/** + * @brief QSPI Command structure definition + */ +typedef struct +{ + uint32_t Instruction; /* Specifies the Instruction to be sent + This parameter can be a value (8-bit) between 0x00 and 0xFF */ + uint32_t Address; /* Specifies the Address to be sent (Size from 1 to 4 bytes according AddressSize) + This parameter can be a value (32-bits) between 0x0 and 0xFFFFFFFF */ + uint32_t AlternateBytes; /* Specifies the Alternate Bytes to be sent (Size from 1 to 4 bytes according AlternateBytesSize) + This parameter can be a value (32-bits) between 0x0 and 0xFFFFFFFF */ + uint32_t AddressSize; /* Specifies the Address Size + This parameter can be a value of @ref QSPI_AddressSize */ + uint32_t AlternateBytesSize; /* Specifies the Alternate Bytes Size + This parameter can be a value of @ref QSPI_AlternateBytesSize */ + uint32_t DummyCycles; /* Specifies the Number of Dummy Cycles. + This parameter can be a number between 0 and 31 */ + uint32_t InstructionMode; /* Specifies the Instruction Mode + This parameter can be a value of @ref QSPI_InstructionMode */ + uint32_t AddressMode; /* Specifies the Address Mode + This parameter can be a value of @ref QSPI_AddressMode */ + uint32_t AlternateByteMode; /* Specifies the Alternate Bytes Mode + This parameter can be a value of @ref QSPI_AlternateBytesMode */ + uint32_t DataMode; /* Specifies the Data Mode (used for dummy cycles and data phases) + This parameter can be a value of @ref QSPI_DataMode */ + uint32_t NbData; /* Specifies the number of data to transfer. + This parameter can be any value between 0 and 0xFFFFFFFF (0 means undefined length + until end of memory)*/ + uint32_t DdrMode; /* Specifies the double data rate mode for address, alternate byte and data phase + This parameter can be a value of @ref QSPI_DdrMode */ + uint32_t DdrHoldHalfCycle; /* Specifies the DDR hold half cycle. It delays the data output by one half of + system clock in DDR mode. + This parameter can be a value of @ref QSPI_DdrHoldHalfCycle */ + uint32_t SIOOMode; /* Specifies the send instruction only once mode + This parameter can be a value of @ref QSPI_SIOOMode */ +}QSPI_CommandTypeDef; + +/** + * @brief QSPI Auto Polling mode configuration structure definition + */ +typedef struct +{ + uint32_t Match; /* Specifies the value to be compared with the masked status register to get a match. + This parameter can be any value between 0 and 0xFFFFFFFF */ + uint32_t Mask; /* Specifies the mask to be applied to the status bytes received. + This parameter can be any value between 0 and 0xFFFFFFFF */ + uint32_t Interval; /* Specifies the number of clock cycles between two read during automatic polling phases. + This parameter can be any value between 0 and 0xFFFF */ + uint32_t StatusBytesSize; /* Specifies the size of the status bytes received. + This parameter can be any value between 1 and 4 */ + uint32_t MatchMode; /* Specifies the method used for determining a match. + This parameter can be a value of @ref QSPI_MatchMode */ + uint32_t AutomaticStop; /* Specifies if automatic polling is stopped after a match. + This parameter can be a value of @ref QSPI_AutomaticStop */ +}QSPI_AutoPollingTypeDef; + +/** + * @brief QSPI Memory Mapped mode configuration structure definition + */ +typedef struct +{ + uint32_t TimeOutPeriod; /* Specifies the number of clock to wait when the FIFO is full before to release the chip select. + This parameter can be any value between 0 and 0xFFFF */ + uint32_t TimeOutActivation; /* Specifies if the time out counter is enabled to release the chip select. + This parameter can be a value of @ref QSPI_TimeOutActivation */ +}QSPI_MemoryMappedTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup QSPI_Exported_Constants QSPI Exported Constants + * @{ + */ +/** @defgroup QSPI_ErrorCode QSPI Error Code + * @{ + */ +#define HAL_QSPI_ERROR_NONE ((uint32_t)0x00000000) /*!< No error */ +#define HAL_QSPI_ERROR_TIMEOUT ((uint32_t)0x00000001) /*!< Timeout error */ +#define HAL_QSPI_ERROR_TRANSFER ((uint32_t)0x00000002) /*!< Transfer error */ +#define HAL_QSPI_ERROR_DMA ((uint32_t)0x00000004) /*!< DMA transfer error */ +/** + * @} + */ + +/** @defgroup QSPI_SampleShifting QSPI Sample Shifting + * @{ + */ +#define QSPI_SAMPLE_SHIFTING_NONE ((uint32_t)0x00000000) /*!State = HAL_QSPI_STATE_RESET) + +/** @brief Enable QSPI + * @param __HANDLE__: specifies the QSPI Handle. + * @retval None + */ +#define __HAL_QSPI_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR, QUADSPI_CR_EN) + +/** @brief Disable QSPI + * @param __HANDLE__: specifies the QSPI Handle. + * @retval None + */ +#define __HAL_QSPI_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR, QUADSPI_CR_EN) + +/** @brief Enables the specified QSPI interrupt. + * @param __HANDLE__: specifies the QSPI Handle. + * @param __INTERRUPT__: specifies the QSPI interrupt source to enable. + * This parameter can be one of the following values: + * @arg QSPI_IT_TO: QSPI Time out interrupt + * @arg QSPI_IT_SM: QSPI Status match interrupt + * @arg QSPI_IT_FT: QSPI FIFO threshold interrupt + * @arg QSPI_IT_TC: QSPI Transfer complete interrupt + * @arg QSPI_IT_TE: QSPI Transfer error interrupt + * @retval None + */ +#define __HAL_QSPI_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CR, (__INTERRUPT__)) + + +/** @brief Disables the specified QSPI interrupt. + * @param __HANDLE__: specifies the QSPI Handle. + * @param __INTERRUPT__: specifies the QSPI interrupt source to disable. + * This parameter can be one of the following values: + * @arg QSPI_IT_TO: QSPI Timeout interrupt + * @arg QSPI_IT_SM: QSPI Status match interrupt + * @arg QSPI_IT_FT: QSPI FIFO threshold interrupt + * @arg QSPI_IT_TC: QSPI Transfer complete interrupt + * @arg QSPI_IT_TE: QSPI Transfer error interrupt + * @retval None + */ +#define __HAL_QSPI_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT((__HANDLE__)->Instance->CR, (__INTERRUPT__)) + +/** @brief Checks whether the specified QSPI interrupt source is enabled. + * @param __HANDLE__: specifies the QSPI Handle. + * @param __INTERRUPT__: specifies the QSPI interrupt source to check. + * This parameter can be one of the following values: + * @arg QSPI_IT_TO: QSPI Time out interrupt + * @arg QSPI_IT_SM: QSPI Status match interrupt + * @arg QSPI_IT_FT: QSPI FIFO threshold interrupt + * @arg QSPI_IT_TC: QSPI Transfer complete interrupt + * @arg QSPI_IT_TE: QSPI Transfer error interrupt + * @retval The new state of __INTERRUPT__ (TRUE or FALSE). + */ +#define __HAL_QSPI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (READ_BIT((__HANDLE__)->Instance->CR, (__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @brief Get the selected QSPI's flag status. + * @param __HANDLE__: specifies the QSPI Handle. + * @param __FLAG__: specifies the QSPI flag to check. + * This parameter can be one of the following values: + * @arg QSPI_FLAG_BUSY: QSPI Busy flag + * @arg QSPI_FLAG_TO: QSPI Time out flag + * @arg QSPI_FLAG_SM: QSPI Status match flag + * @arg QSPI_FLAG_FT: QSPI FIFO threshold flag + * @arg QSPI_FLAG_TC: QSPI Transfer complete flag + * @arg QSPI_FLAG_TE: QSPI Transfer error flag + * @retval None + */ +#define __HAL_QSPI_GET_FLAG(__HANDLE__, __FLAG__) (READ_BIT((__HANDLE__)->Instance->SR, (__FLAG__)) != 0) + +/** @brief Clears the specified QSPI's flag status. + * @param __HANDLE__: specifies the QSPI Handle. + * @param __FLAG__: specifies the QSPI clear register flag that needs to be set + * This parameter can be one of the following values: + * @arg QSPI_FLAG_TO: QSPI Time out flag + * @arg QSPI_FLAG_SM: QSPI Status match flag + * @arg QSPI_FLAG_TC: QSPI Transfer complete flag + * @arg QSPI_FLAG_TE: QSPI Transfer error flag + * @retval None + */ +#define __HAL_QSPI_CLEAR_FLAG(__HANDLE__, __FLAG__) WRITE_REG((__HANDLE__)->Instance->FCR, (__FLAG__)) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup QSPI_Exported_Functions + * @{ + */ + +/** @addtogroup QSPI_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions ********************************/ +HAL_StatusTypeDef HAL_QSPI_Init (QSPI_HandleTypeDef *hqspi); +HAL_StatusTypeDef HAL_QSPI_DeInit (QSPI_HandleTypeDef *hqspi); +void HAL_QSPI_MspInit (QSPI_HandleTypeDef *hqspi); +void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi); +/** + * @} + */ + +/** @addtogroup QSPI_Exported_Functions_Group2 + * @{ + */ +/* IO operation functions *****************************************************/ +/* QSPI IRQ handler method */ +void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi); + +/* QSPI indirect mode */ +HAL_StatusTypeDef HAL_QSPI_Command (QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout); +HAL_StatusTypeDef HAL_QSPI_Transmit (QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout); +HAL_StatusTypeDef HAL_QSPI_Receive (QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout); +HAL_StatusTypeDef HAL_QSPI_Command_IT (QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd); +HAL_StatusTypeDef HAL_QSPI_Transmit_IT (QSPI_HandleTypeDef *hqspi, uint8_t *pData); +HAL_StatusTypeDef HAL_QSPI_Receive_IT (QSPI_HandleTypeDef *hqspi, uint8_t *pData); +HAL_StatusTypeDef HAL_QSPI_Transmit_DMA (QSPI_HandleTypeDef *hqspi, uint8_t *pData); +HAL_StatusTypeDef HAL_QSPI_Receive_DMA (QSPI_HandleTypeDef *hqspi, uint8_t *pData); + +/* QSPI status flag polling mode */ +HAL_StatusTypeDef HAL_QSPI_AutoPolling (QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout); +HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg); + +/* QSPI memory-mapped mode */ +HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg); +/** + * @} + */ + +/** @addtogroup QSPI_Exported_Functions_Group3 + * @{ + */ +/* Callback functions in non-blocking modes ***********************************/ +void HAL_QSPI_ErrorCallback (QSPI_HandleTypeDef *hqspi); +void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi); + +/* QSPI indirect mode */ +void HAL_QSPI_CmdCpltCallback (QSPI_HandleTypeDef *hqspi); +void HAL_QSPI_RxCpltCallback (QSPI_HandleTypeDef *hqspi); +void HAL_QSPI_TxCpltCallback (QSPI_HandleTypeDef *hqspi); +void HAL_QSPI_RxHalfCpltCallback (QSPI_HandleTypeDef *hqspi); +void HAL_QSPI_TxHalfCpltCallback (QSPI_HandleTypeDef *hqspi); + +/* QSPI status flag polling mode */ +void HAL_QSPI_StatusMatchCallback (QSPI_HandleTypeDef *hqspi); + +/* QSPI memory-mapped mode */ +void HAL_QSPI_TimeOutCallback (QSPI_HandleTypeDef *hqspi); +/** + * @} + */ + +/** @addtogroup QSPI_Exported_Functions_Group4 + * @{ + */ +/* Peripheral Control and State functions ************************************/ +HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi); +uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi); +HAL_StatusTypeDef HAL_QSPI_Abort (QSPI_HandleTypeDef *hqspi); +void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup QSPI_Private_Constants QSPI Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup QSPI_Private_Macros QSPI Private Macros + * @{ + */ +/** @defgroup QSPI_ClockPrescaler QSPI Clock Prescaler + * @{ + */ +#define IS_QSPI_CLOCK_PRESCALER(PRESCALER) ((PRESCALER) <= 0xFF) +/** + * @} + */ + +/** @defgroup QSPI_FifoThreshold QSPI Fifo Threshold + * @{ + */ +#define IS_QSPI_FIFO_THRESHOLD(THR) (((THR) > 0) && ((THR) <= 32)) +/** + * @} + */ + +#define IS_QSPI_SSHIFT(SSHIFT) (((SSHIFT) == QSPI_SAMPLE_SHIFTING_NONE) || \ + ((SSHIFT) == QSPI_SAMPLE_SHIFTING_HALFCYCLE)) + +/** @defgroup QSPI_FlashSize QSPI Flash Size + * @{ + */ +#define IS_QSPI_FLASH_SIZE(FSIZE) (((FSIZE) <= 31)) +/** + * @} + */ + +#define IS_QSPI_CS_HIGH_TIME(CSHTIME) (((CSHTIME) == QSPI_CS_HIGH_TIME_1_CYCLE) || \ + ((CSHTIME) == QSPI_CS_HIGH_TIME_2_CYCLE) || \ + ((CSHTIME) == QSPI_CS_HIGH_TIME_3_CYCLE) || \ + ((CSHTIME) == QSPI_CS_HIGH_TIME_4_CYCLE) || \ + ((CSHTIME) == QSPI_CS_HIGH_TIME_5_CYCLE) || \ + ((CSHTIME) == QSPI_CS_HIGH_TIME_6_CYCLE) || \ + ((CSHTIME) == QSPI_CS_HIGH_TIME_7_CYCLE) || \ + ((CSHTIME) == QSPI_CS_HIGH_TIME_8_CYCLE)) + +#define IS_QSPI_CLOCK_MODE(CLKMODE) (((CLKMODE) == QSPI_CLOCK_MODE_0) || \ + ((CLKMODE) == QSPI_CLOCK_MODE_3)) + +#define IS_QSPI_FLASH_ID(FLA) (((FLA) == QSPI_FLASH_ID_1) || \ + ((FLA) == QSPI_FLASH_ID_2)) + +#define IS_QSPI_DUAL_FLASH_MODE(MODE) (((MODE) == QSPI_DUALFLASH_ENABLE) || \ + ((MODE) == QSPI_DUALFLASH_DISABLE)) + + +/** @defgroup QSPI_Instruction QSPI Instruction + * @{ + */ +#define IS_QSPI_INSTRUCTION(INSTRUCTION) ((INSTRUCTION) <= 0xFF) +/** + * @} + */ + +#define IS_QSPI_ADDRESS_SIZE(ADDR_SIZE) (((ADDR_SIZE) == QSPI_ADDRESS_8_BITS) || \ + ((ADDR_SIZE) == QSPI_ADDRESS_16_BITS) || \ + ((ADDR_SIZE) == QSPI_ADDRESS_24_BITS) || \ + ((ADDR_SIZE) == QSPI_ADDRESS_32_BITS)) + +#define IS_QSPI_ALTERNATE_BYTES_SIZE(SIZE) (((SIZE) == QSPI_ALTERNATE_BYTES_8_BITS) || \ + ((SIZE) == QSPI_ALTERNATE_BYTES_16_BITS) || \ + ((SIZE) == QSPI_ALTERNATE_BYTES_24_BITS) || \ + ((SIZE) == QSPI_ALTERNATE_BYTES_32_BITS)) + + +/** @defgroup QSPI_DummyCycles QSPI Dummy Cycles + * @{ + */ +#define IS_QSPI_DUMMY_CYCLES(DCY) ((DCY) <= 31) +/** + * @} + */ + +#define IS_QSPI_INSTRUCTION_MODE(MODE) (((MODE) == QSPI_INSTRUCTION_NONE) || \ + ((MODE) == QSPI_INSTRUCTION_1_LINE) || \ + ((MODE) == QSPI_INSTRUCTION_2_LINES) || \ + ((MODE) == QSPI_INSTRUCTION_4_LINES)) + +#define IS_QSPI_ADDRESS_MODE(MODE) (((MODE) == QSPI_ADDRESS_NONE) || \ + ((MODE) == QSPI_ADDRESS_1_LINE) || \ + ((MODE) == QSPI_ADDRESS_2_LINES) || \ + ((MODE) == QSPI_ADDRESS_4_LINES)) + +#define IS_QSPI_ALTERNATE_BYTES_MODE(MODE) (((MODE) == QSPI_ALTERNATE_BYTES_NONE) || \ + ((MODE) == QSPI_ALTERNATE_BYTES_1_LINE) || \ + ((MODE) == QSPI_ALTERNATE_BYTES_2_LINES) || \ + ((MODE) == QSPI_ALTERNATE_BYTES_4_LINES)) + +#define IS_QSPI_DATA_MODE(MODE) (((MODE) == QSPI_DATA_NONE) || \ + ((MODE) == QSPI_DATA_1_LINE) || \ + ((MODE) == QSPI_DATA_2_LINES) || \ + ((MODE) == QSPI_DATA_4_LINES)) + +#define IS_QSPI_DDR_MODE(DDR_MODE) (((DDR_MODE) == QSPI_DDR_MODE_DISABLE) || \ + ((DDR_MODE) == QSPI_DDR_MODE_ENABLE)) + +#define IS_QSPI_DDR_HHC(DDR_HHC) (((DDR_HHC) == QSPI_DDR_HHC_ANALOG_DELAY) || \ + ((DDR_HHC) == QSPI_DDR_HHC_HALF_CLK_DELAY)) + +#define IS_QSPI_SIOO_MODE(SIOO_MODE) (((SIOO_MODE) == QSPI_SIOO_INST_EVERY_CMD) || \ + ((SIOO_MODE) == QSPI_SIOO_INST_ONLY_FIRST_CMD)) + +/** @defgroup QSPI_Interval QSPI Interval + * @{ + */ +#define IS_QSPI_INTERVAL(INTERVAL) ((INTERVAL) <= QUADSPI_PIR_INTERVAL) +/** + * @} + */ + +/** @defgroup QSPI_StatusBytesSize QSPI Status Bytes Size + * @{ + */ +#define IS_QSPI_STATUS_BYTES_SIZE(SIZE) (((SIZE) >= 1) && ((SIZE) <= 4)) +/** + * @} + */ +#define IS_QSPI_MATCH_MODE(MODE) (((MODE) == QSPI_MATCH_MODE_AND) || \ + ((MODE) == QSPI_MATCH_MODE_OR)) + +#define IS_QSPI_AUTOMATIC_STOP(APMS) (((APMS) == QSPI_AUTOMATIC_STOP_DISABLE) || \ + ((APMS) == QSPI_AUTOMATIC_STOP_ENABLE)) + +#define IS_QSPI_TIMEOUT_ACTIVATION(TCEN) (((TCEN) == QSPI_TIMEOUT_COUNTER_DISABLE) || \ + ((TCEN) == QSPI_TIMEOUT_COUNTER_ENABLE)) + +/** @defgroup QSPI_TimeOutPeriod QSPI TimeOut Period + * @{ + */ +#define IS_QSPI_TIMEOUT_PERIOD(PERIOD) ((PERIOD) <= 0xFFFF) +/** + * @} + */ + +#define IS_QSPI_GET_FLAG(FLAG) (((FLAG) == QSPI_FLAG_BUSY) || \ + ((FLAG) == QSPI_FLAG_TO) || \ + ((FLAG) == QSPI_FLAG_SM) || \ + ((FLAG) == QSPI_FLAG_FT) || \ + ((FLAG) == QSPI_FLAG_TC) || \ + ((FLAG) == QSPI_FLAG_TE)) + +#define IS_QSPI_IT(IT) ((((IT) & (uint32_t)0xFFE0FFFF) == 0x00000000) && ((IT) != 0x00000000)) +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup QSPI_Private_Functions QSPI Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F446xx */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_QSPI_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h new file mode 100644 index 0000000..596f7ef --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h @@ -0,0 +1,1537 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_rcc.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of RCC HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_RCC_H +#define __STM32F4xx_HAL_RCC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/* Include RCC HAL Extended module */ +/* (include on top of file since RCC structures are defined in extended file) */ +#include "stm32f4xx_hal_rcc_ex.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup RCC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup RCC_Exported_Types RCC Exported Types + * @{ + */ + +/** + * @brief RCC Internal/External Oscillator (HSE, HSI, LSE and LSI) configuration structure definition + */ +typedef struct +{ + uint32_t OscillatorType; /*!< The oscillators to be configured. + This parameter can be a value of @ref RCC_Oscillator_Type */ + + uint32_t HSEState; /*!< The new state of the HSE. + This parameter can be a value of @ref RCC_HSE_Config */ + + uint32_t LSEState; /*!< The new state of the LSE. + This parameter can be a value of @ref RCC_LSE_Config */ + + uint32_t HSIState; /*!< The new state of the HSI. + This parameter can be a value of @ref RCC_HSI_Config */ + + uint32_t HSICalibrationValue; /*!< The calibration trimming value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x1F */ + + uint32_t LSIState; /*!< The new state of the LSI. + This parameter can be a value of @ref RCC_LSI_Config */ + + RCC_PLLInitTypeDef PLL; /*!< PLL structure parameters */ + +}RCC_OscInitTypeDef; + +/** + * @brief RCC System, AHB and APB busses clock configuration structure definition + */ +typedef struct +{ + uint32_t ClockType; /*!< The clock to be configured. + This parameter can be a value of @ref RCC_System_Clock_Type */ + + uint32_t SYSCLKSource; /*!< The clock source (SYSCLKS) used as system clock. + This parameter can be a value of @ref RCC_System_Clock_Source */ + + uint32_t AHBCLKDivider; /*!< The AHB clock (HCLK) divider. This clock is derived from the system clock (SYSCLK). + This parameter can be a value of @ref RCC_AHB_Clock_Source */ + + uint32_t APB1CLKDivider; /*!< The APB1 clock (PCLK1) divider. This clock is derived from the AHB clock (HCLK). + This parameter can be a value of @ref RCC_APB1_APB2_Clock_Source */ + + uint32_t APB2CLKDivider; /*!< The APB2 clock (PCLK2) divider. This clock is derived from the AHB clock (HCLK). + This parameter can be a value of @ref RCC_APB1_APB2_Clock_Source */ + +}RCC_ClkInitTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RCC_Exported_Constants RCC Exported Constants + * @{ + */ + +/** @defgroup RCC_Oscillator_Type Oscillator Type + * @{ + */ +#define RCC_OSCILLATORTYPE_NONE ((uint32_t)0x00000000) +#define RCC_OSCILLATORTYPE_HSE ((uint32_t)0x00000001) +#define RCC_OSCILLATORTYPE_HSI ((uint32_t)0x00000002) +#define RCC_OSCILLATORTYPE_LSE ((uint32_t)0x00000004) +#define RCC_OSCILLATORTYPE_LSI ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup RCC_HSE_Config HSE Config + * @{ + */ +#define RCC_HSE_OFF ((uint8_t)0x00) +#define RCC_HSE_ON ((uint8_t)0x01) +#define RCC_HSE_BYPASS ((uint8_t)0x05) +/** + * @} + */ + +/** @defgroup RCC_LSE_Config LSE Config + * @{ + */ +#define RCC_LSE_OFF ((uint8_t)0x00) +#define RCC_LSE_ON ((uint8_t)0x01) +#define RCC_LSE_BYPASS ((uint8_t)0x05) +/** + * @} + */ + +/** @defgroup RCC_HSI_Config HSI Config + * @{ + */ +#define RCC_HSI_OFF ((uint8_t)0x00) +#define RCC_HSI_ON ((uint8_t)0x01) +/** + * @} + */ + +/** @defgroup RCC_LSI_Config LSI Config + * @{ + */ +#define RCC_LSI_OFF ((uint8_t)0x00) +#define RCC_LSI_ON ((uint8_t)0x01) +/** + * @} + */ + +/** @defgroup RCC_PLL_Config PLL Config + * @{ + */ +#define RCC_PLL_NONE ((uint8_t)0x00) +#define RCC_PLL_OFF ((uint8_t)0x01) +#define RCC_PLL_ON ((uint8_t)0x02) +/** + * @} + */ + +/** @defgroup RCC_PLLP_Clock_Divider PLLP Clock Divider + * @{ + */ +#define RCC_PLLP_DIV2 ((uint32_t)0x00000002) +#define RCC_PLLP_DIV4 ((uint32_t)0x00000004) +#define RCC_PLLP_DIV6 ((uint32_t)0x00000006) +#define RCC_PLLP_DIV8 ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup RCC_PLL_Clock_Source PLL Clock Source + * @{ + */ +#define RCC_PLLSOURCE_HSI RCC_PLLCFGR_PLLSRC_HSI +#define RCC_PLLSOURCE_HSE RCC_PLLCFGR_PLLSRC_HSE +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Type System Clock Type + * @{ + */ +#define RCC_CLOCKTYPE_SYSCLK ((uint32_t)0x00000001) +#define RCC_CLOCKTYPE_HCLK ((uint32_t)0x00000002) +#define RCC_CLOCKTYPE_PCLK1 ((uint32_t)0x00000004) +#define RCC_CLOCKTYPE_PCLK2 ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Source System Clock Source + * @{ + */ +#define RCC_SYSCLKSOURCE_HSI RCC_CFGR_SW_HSI +#define RCC_SYSCLKSOURCE_HSE RCC_CFGR_SW_HSE +#define RCC_SYSCLKSOURCE_PLLCLK RCC_CFGR_SW_PLL +#define RCC_SYSCLKSOURCE_PLLRCLK ((uint32_t)(RCC_CFGR_SW_0 | RCC_CFGR_SW_1)) +/** + * @} + */ + +/** @defgroup RCC_System_Clock_Source_Status System Clock Source Status + * @{ + */ +#define RCC_SYSCLKSOURCE_STATUS_HSI RCC_CFGR_SWS_HSI /*!< HSI used as system clock */ +#define RCC_SYSCLKSOURCE_STATUS_HSE RCC_CFGR_SWS_HSE /*!< HSE used as system clock */ +#define RCC_SYSCLKSOURCE_STATUS_PLLCLK RCC_CFGR_SWS_PLL /*!< PLL used as system clock */ +#define RCC_SYSCLKSOURCE_STATUS_PLLRCLK ((uint32_t)(RCC_CFGR_SW_0 | RCC_CFGR_SW_1)) /*!< PLLR used as system clock */ +/** + * @} + */ + +/** @defgroup RCC_AHB_Clock_Source AHB Clock Source + * @{ + */ +#define RCC_SYSCLK_DIV1 RCC_CFGR_HPRE_DIV1 +#define RCC_SYSCLK_DIV2 RCC_CFGR_HPRE_DIV2 +#define RCC_SYSCLK_DIV4 RCC_CFGR_HPRE_DIV4 +#define RCC_SYSCLK_DIV8 RCC_CFGR_HPRE_DIV8 +#define RCC_SYSCLK_DIV16 RCC_CFGR_HPRE_DIV16 +#define RCC_SYSCLK_DIV64 RCC_CFGR_HPRE_DIV64 +#define RCC_SYSCLK_DIV128 RCC_CFGR_HPRE_DIV128 +#define RCC_SYSCLK_DIV256 RCC_CFGR_HPRE_DIV256 +#define RCC_SYSCLK_DIV512 RCC_CFGR_HPRE_DIV512 +/** + * @} + */ + +/** @defgroup RCC_APB1_APB2_Clock_Source APB1/APB2 Clock Source + * @{ + */ +#define RCC_HCLK_DIV1 RCC_CFGR_PPRE1_DIV1 +#define RCC_HCLK_DIV2 RCC_CFGR_PPRE1_DIV2 +#define RCC_HCLK_DIV4 RCC_CFGR_PPRE1_DIV4 +#define RCC_HCLK_DIV8 RCC_CFGR_PPRE1_DIV8 +#define RCC_HCLK_DIV16 RCC_CFGR_PPRE1_DIV16 +/** + * @} + */ + +/** @defgroup RCC_RTC_Clock_Source RTC Clock Source + * @{ + */ +#define RCC_RTCCLKSOURCE_LSE ((uint32_t)0x00000100) +#define RCC_RTCCLKSOURCE_LSI ((uint32_t)0x00000200) +#define RCC_RTCCLKSOURCE_HSE_DIV2 ((uint32_t)0x00020300) +#define RCC_RTCCLKSOURCE_HSE_DIV3 ((uint32_t)0x00030300) +#define RCC_RTCCLKSOURCE_HSE_DIV4 ((uint32_t)0x00040300) +#define RCC_RTCCLKSOURCE_HSE_DIV5 ((uint32_t)0x00050300) +#define RCC_RTCCLKSOURCE_HSE_DIV6 ((uint32_t)0x00060300) +#define RCC_RTCCLKSOURCE_HSE_DIV7 ((uint32_t)0x00070300) +#define RCC_RTCCLKSOURCE_HSE_DIV8 ((uint32_t)0x00080300) +#define RCC_RTCCLKSOURCE_HSE_DIV9 ((uint32_t)0x00090300) +#define RCC_RTCCLKSOURCE_HSE_DIV10 ((uint32_t)0x000A0300) +#define RCC_RTCCLKSOURCE_HSE_DIV11 ((uint32_t)0x000B0300) +#define RCC_RTCCLKSOURCE_HSE_DIV12 ((uint32_t)0x000C0300) +#define RCC_RTCCLKSOURCE_HSE_DIV13 ((uint32_t)0x000D0300) +#define RCC_RTCCLKSOURCE_HSE_DIV14 ((uint32_t)0x000E0300) +#define RCC_RTCCLKSOURCE_HSE_DIV15 ((uint32_t)0x000F0300) +#define RCC_RTCCLKSOURCE_HSE_DIV16 ((uint32_t)0x00100300) +#define RCC_RTCCLKSOURCE_HSE_DIV17 ((uint32_t)0x00110300) +#define RCC_RTCCLKSOURCE_HSE_DIV18 ((uint32_t)0x00120300) +#define RCC_RTCCLKSOURCE_HSE_DIV19 ((uint32_t)0x00130300) +#define RCC_RTCCLKSOURCE_HSE_DIV20 ((uint32_t)0x00140300) +#define RCC_RTCCLKSOURCE_HSE_DIV21 ((uint32_t)0x00150300) +#define RCC_RTCCLKSOURCE_HSE_DIV22 ((uint32_t)0x00160300) +#define RCC_RTCCLKSOURCE_HSE_DIV23 ((uint32_t)0x00170300) +#define RCC_RTCCLKSOURCE_HSE_DIV24 ((uint32_t)0x00180300) +#define RCC_RTCCLKSOURCE_HSE_DIV25 ((uint32_t)0x00190300) +#define RCC_RTCCLKSOURCE_HSE_DIV26 ((uint32_t)0x001A0300) +#define RCC_RTCCLKSOURCE_HSE_DIV27 ((uint32_t)0x001B0300) +#define RCC_RTCCLKSOURCE_HSE_DIV28 ((uint32_t)0x001C0300) +#define RCC_RTCCLKSOURCE_HSE_DIV29 ((uint32_t)0x001D0300) +#define RCC_RTCCLKSOURCE_HSE_DIV30 ((uint32_t)0x001E0300) +#define RCC_RTCCLKSOURCE_HSE_DIV31 ((uint32_t)0x001F0300) +/** + * @} + */ + +/** @defgroup RCC_I2S_Clock_Source I2S Clock Source + * @{ + */ +#define RCC_I2SCLKSOURCE_PLLI2S ((uint32_t)0x00000000) +#define RCC_I2SCLKSOURCE_EXT ((uint32_t)0x00000001) +/** + * @} + */ + +/** @defgroup RCC_MCO_Index MCO Index + * @{ + */ +#define RCC_MCO1 ((uint32_t)0x00000000) +#define RCC_MCO2 ((uint32_t)0x00000001) +/** + * @} + */ + +/** @defgroup RCC_MCO1_Clock_Source MCO1 Clock Source + * @{ + */ +#define RCC_MCO1SOURCE_HSI ((uint32_t)0x00000000) +#define RCC_MCO1SOURCE_LSE RCC_CFGR_MCO1_0 +#define RCC_MCO1SOURCE_HSE RCC_CFGR_MCO1_1 +#define RCC_MCO1SOURCE_PLLCLK RCC_CFGR_MCO1 +/** + * @} + */ + +/** @defgroup RCC_MCO2_Clock_Source MCO2 Clock Source + * @{ + */ +#define RCC_MCO2SOURCE_SYSCLK ((uint32_t)0x00000000) +#define RCC_MCO2SOURCE_PLLI2SCLK RCC_CFGR_MCO2_0 +#define RCC_MCO2SOURCE_HSE RCC_CFGR_MCO2_1 +#define RCC_MCO2SOURCE_PLLCLK RCC_CFGR_MCO2 +/** + * @} + */ + +/** @defgroup RCC_MCOx_Clock_Prescaler MCOx Clock Prescaler + * @{ + */ +#define RCC_MCODIV_1 ((uint32_t)0x00000000) +#define RCC_MCODIV_2 RCC_CFGR_MCO1PRE_2 +#define RCC_MCODIV_3 ((uint32_t)RCC_CFGR_MCO1PRE_0 | RCC_CFGR_MCO1PRE_2) +#define RCC_MCODIV_4 ((uint32_t)RCC_CFGR_MCO1PRE_1 | RCC_CFGR_MCO1PRE_2) +#define RCC_MCODIV_5 RCC_CFGR_MCO1PRE +/** + * @} + */ + +/** @defgroup RCC_Interrupt Interrupts + * @{ + */ +#define RCC_IT_LSIRDY ((uint8_t)0x01) +#define RCC_IT_LSERDY ((uint8_t)0x02) +#define RCC_IT_HSIRDY ((uint8_t)0x04) +#define RCC_IT_HSERDY ((uint8_t)0x08) +#define RCC_IT_PLLRDY ((uint8_t)0x10) +#define RCC_IT_PLLI2SRDY ((uint8_t)0x20) +#define RCC_IT_CSS ((uint8_t)0x80) +/** + * @} + */ + +/** @defgroup RCC_Flag Flags + * Elements values convention: 0XXYYYYYb + * - YYYYY : Flag position in the register + * - 0XX : Register index + * - 01: CR register + * - 10: BDCR register + * - 11: CSR register + * @{ + */ +/* Flags in the CR register */ +#define RCC_FLAG_HSIRDY ((uint8_t)0x21) +#define RCC_FLAG_HSERDY ((uint8_t)0x31) +#define RCC_FLAG_PLLRDY ((uint8_t)0x39) +#define RCC_FLAG_PLLI2SRDY ((uint8_t)0x3B) + +/* Flags in the BDCR register */ +#define RCC_FLAG_LSERDY ((uint8_t)0x41) + +/* Flags in the CSR register */ +#define RCC_FLAG_LSIRDY ((uint8_t)0x61) +#define RCC_FLAG_BORRST ((uint8_t)0x79) +#define RCC_FLAG_PINRST ((uint8_t)0x7A) +#define RCC_FLAG_PORRST ((uint8_t)0x7B) +#define RCC_FLAG_SFTRST ((uint8_t)0x7C) +#define RCC_FLAG_IWDGRST ((uint8_t)0x7D) +#define RCC_FLAG_WWDGRST ((uint8_t)0x7E) +#define RCC_FLAG_LPWRRST ((uint8_t)0x7F) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup RCC_Exported_Macros RCC Exported Macros + * @{ + */ + +/** @defgroup RCC_AHB1_Clock_Enable_Disable AHB1 Peripheral Clock Enable Disable + * @brief Enable or disable the AHB1 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_GPIOA_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_GPIOB_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOBEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOBEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_GPIOC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_GPIOD_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_GPIOE_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOEEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOEEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_GPIOH_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOHEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOHEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_CRC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_CRCEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_CRCEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_BKPSRAM_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_BKPSRAMEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_BKPSRAMEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_CCMDATARAMEN_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_CCMDATARAMEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_CCMDATARAMEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_DMA1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_DMA1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_DMA1EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_DMA2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_DMA2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_DMA2EN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOA_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOAEN)) +#define __HAL_RCC_GPIOB_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOBEN)) +#define __HAL_RCC_GPIOC_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOCEN)) +#define __HAL_RCC_GPIOD_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIODEN)) +#define __HAL_RCC_GPIOE_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOEEN)) +#define __HAL_RCC_GPIOH_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOHEN)) +#define __HAL_RCC_CRC_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_CRCEN)) +#define __HAL_RCC_BKPSRAM_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_BKPSRAMEN)) +#define __HAL_RCC_CCMDATARAMEN_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_CCMDATARAMEN)) +#define __HAL_RCC_DMA1_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_DMA1EN)) +#define __HAL_RCC_DMA2_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_DMA2EN)) + +/** + * @} + */ + +/** @defgroup RCC_AHB2_Clock_Enable_Disable AHB2 Peripheral Clock Enable Disable + * @brief Enable or disable the AHB2 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_USB_OTG_FS_CLK_ENABLE() do {(RCC->AHB2ENR |= (RCC_AHB2ENR_OTGFSEN));\ + __HAL_RCC_SYSCFG_CLK_ENABLE();\ + }while(0) + +#define __HAL_RCC_USB_OTG_FS_CLK_DISABLE() do { (RCC->AHB2ENR &= ~(RCC_AHB2ENR_OTGFSEN));\ + __HAL_RCC_SYSCFG_CLK_DISABLE();\ + }while(0) + +#define __HAL_RCC_RNG_CLK_ENABLE() (RCC->AHB2ENR |= (RCC_AHB2ENR_RNGEN)) +#define __HAL_RCC_RNG_CLK_DISABLE() (RCC->AHB2ENR &= ~(RCC_AHB2ENR_RNGEN)) + +/** + * @} + */ + +/** @defgroup RCC_APB1_Clock_Enable_Disable APB1 Peripheral Clock Enable Disable + * @brief Enable or disable the Low Speed APB (APB1) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_TIM2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM2EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM3EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM3EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM4_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM4EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM4EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM5_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM5EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM5EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_WWDG_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_WWDGEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_WWDGEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_SPI2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_SPI2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_SPI2EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_SPI3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_SPI3EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_SPI3EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_USART2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_I2C1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_I2C2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C2EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_I2C3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C3EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C3EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_PWR_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM2EN)) +#define __HAL_RCC_TIM3_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM3EN)) +#define __HAL_RCC_TIM4_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM4EN)) +#define __HAL_RCC_TIM5_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM5EN)) +#define __HAL_RCC_WWDG_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_WWDGEN)) +#define __HAL_RCC_SPI2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_SPI2EN)) +#define __HAL_RCC_SPI3_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_SPI3EN)) +#define __HAL_RCC_USART2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART2EN)) +#define __HAL_RCC_I2C1_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C1EN)) +#define __HAL_RCC_I2C2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C2EN)) +#define __HAL_RCC_I2C3_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C3EN)) +#define __HAL_RCC_PWR_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_PWREN)) +/** + * @} + */ + +/** @defgroup RCC_APB2_Clock_Enable_Disable APB2 Peripheral Clock Enable Disable + * @brief Enable or disable the High Speed APB (APB2) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + * @{ + */ +#define __HAL_RCC_TIM1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_USART1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_USART6_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART6EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART6EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_ADC1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_SDIO_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SDIOEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SDIOEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_SPI1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_SPI4_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI4EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI4EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_SYSCFG_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM9_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM9EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM9EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM10_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM10EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM10EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM11_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM11EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM11EN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM1EN)) +#define __HAL_RCC_USART1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_USART1EN)) +#define __HAL_RCC_USART6_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_USART6EN)) +#define __HAL_RCC_ADC1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN)) +#define __HAL_RCC_SDIO_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_SDIOEN)) +#define __HAL_RCC_SPI1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_SPI1EN)) +#define __HAL_RCC_SPI4_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_SPI4EN)) +#define __HAL_RCC_SYSCFG_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_SYSCFGEN)) +#define __HAL_RCC_TIM9_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM9EN)) +#define __HAL_RCC_TIM10_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM10EN)) +#define __HAL_RCC_TIM11_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM11EN)) +/** + * @} + */ + +/** @defgroup RCC_AHB1_Force_Release_Reset AHB1 Force Release Reset + * @brief Force or release AHB1 peripheral reset. + * @{ + */ +#define __HAL_RCC_AHB1_FORCE_RESET() (RCC->AHB1RSTR = 0xFFFFFFFF) +#define __HAL_RCC_GPIOA_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_GPIOARST)) +#define __HAL_RCC_GPIOB_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_GPIOBRST)) +#define __HAL_RCC_GPIOC_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_GPIOCRST)) +#define __HAL_RCC_GPIOD_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_GPIODRST)) +#define __HAL_RCC_GPIOE_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_GPIOERST)) +#define __HAL_RCC_GPIOH_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_GPIOHRST)) +#define __HAL_RCC_CRC_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_CRCRST)) +#define __HAL_RCC_DMA1_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_DMA1RST)) +#define __HAL_RCC_DMA2_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_DMA2RST)) + +#define __HAL_RCC_AHB1_RELEASE_RESET() (RCC->AHB1RSTR = 0x00) +#define __HAL_RCC_GPIOA_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOARST)) +#define __HAL_RCC_GPIOB_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOBRST)) +#define __HAL_RCC_GPIOC_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOCRST)) +#define __HAL_RCC_GPIOD_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIODRST)) +#define __HAL_RCC_GPIOE_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOERST)) +#define __HAL_RCC_GPIOF_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOFRST)) +#define __HAL_RCC_GPIOG_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOGRST)) +#define __HAL_RCC_GPIOH_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOHRST)) +#define __HAL_RCC_GPIOI_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOIRST)) +#define __HAL_RCC_CRC_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_CRCRST)) +#define __HAL_RCC_DMA1_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_DMA1RST)) +#define __HAL_RCC_DMA2_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_DMA2RST)) +/** + * @} + */ + +/** @defgroup RCC_AHB2_Force_Release_Reset AHB2 Force Release Reset + * @brief Force or release AHB2 peripheral reset. + * @{ + */ +#define __HAL_RCC_AHB2_FORCE_RESET() (RCC->AHB2RSTR = 0xFFFFFFFF) +#define __HAL_RCC_USB_OTG_FS_FORCE_RESET() (RCC->AHB2RSTR |= (RCC_AHB2RSTR_OTGFSRST)) + +#define __HAL_RCC_AHB2_RELEASE_RESET() (RCC->AHB2RSTR = 0x00) +#define __HAL_RCC_USB_OTG_FS_RELEASE_RESET() (RCC->AHB2RSTR &= ~(RCC_AHB2RSTR_OTGFSRST)) + +#define __HAL_RCC_RNG_FORCE_RESET() (RCC->AHB2RSTR |= (RCC_AHB2RSTR_RNGRST)) +#define __HAL_RCC_RNG_RELEASE_RESET() (RCC->AHB2RSTR &= ~(RCC_AHB2RSTR_RNGRST)) +/** + * @} + */ + +/** @defgroup RCC_APB1_Force_Release_Reset APB1 Force Release Reset + * @brief Force or release APB1 peripheral reset. + * @{ + */ +#define __HAL_RCC_APB1_FORCE_RESET() (RCC->APB1RSTR = 0xFFFFFFFF) +#define __HAL_RCC_TIM2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM2RST)) +#define __HAL_RCC_TIM3_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM3RST)) +#define __HAL_RCC_TIM4_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM4RST)) +#define __HAL_RCC_TIM5_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM5RST)) +#define __HAL_RCC_WWDG_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_WWDGRST)) +#define __HAL_RCC_SPI2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_SPI2RST)) +#define __HAL_RCC_SPI3_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_SPI3RST)) +#define __HAL_RCC_USART2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_USART2RST)) +#define __HAL_RCC_I2C1_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_I2C1RST)) +#define __HAL_RCC_I2C2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_I2C2RST)) +#define __HAL_RCC_I2C3_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_I2C3RST)) +#define __HAL_RCC_PWR_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_PWRRST)) + +#define __HAL_RCC_APB1_RELEASE_RESET() (RCC->APB1RSTR = 0x00) +#define __HAL_RCC_TIM2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM2RST)) +#define __HAL_RCC_TIM3_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM3RST)) +#define __HAL_RCC_TIM4_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM4RST)) +#define __HAL_RCC_TIM5_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM5RST)) +#define __HAL_RCC_WWDG_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_WWDGRST)) +#define __HAL_RCC_SPI2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_SPI2RST)) +#define __HAL_RCC_SPI3_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_SPI3RST)) +#define __HAL_RCC_USART2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USART2RST)) +#define __HAL_RCC_I2C1_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_I2C1RST)) +#define __HAL_RCC_I2C2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_I2C2RST)) +#define __HAL_RCC_I2C3_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_I2C3RST)) +#define __HAL_RCC_PWR_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_PWRRST)) +/** + * @} + */ + +/** @defgroup RCC_APB2_Force_Release_Reset APB2 Force Release Reset + * @brief Force or release APB2 peripheral reset. + * @{ + */ +#define __HAL_RCC_APB2_FORCE_RESET() (RCC->APB2RSTR = 0xFFFFFFFF) +#define __HAL_RCC_TIM1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM1RST)) +#define __HAL_RCC_USART1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_USART1RST)) +#define __HAL_RCC_USART6_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_USART6RST)) +#define __HAL_RCC_ADC_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_ADCRST)) +#define __HAL_RCC_SDIO_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_SDIORST)) +#define __HAL_RCC_SPI1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_SPI1RST)) +#define __HAL_RCC_SPI4_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_SPI4RST)) +#define __HAL_RCC_SYSCFG_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_SYSCFGRST)) +#define __HAL_RCC_TIM9_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM9RST)) +#define __HAL_RCC_TIM10_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM10RST)) +#define __HAL_RCC_TIM11_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM11RST)) + +#define __HAL_RCC_APB2_RELEASE_RESET() (RCC->APB2RSTR = 0x00) +#define __HAL_RCC_TIM1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM1RST)) +#define __HAL_RCC_USART1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_USART1RST)) +#define __HAL_RCC_USART6_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_USART6RST)) +#define __HAL_RCC_ADC_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_ADCRST)) +#define __HAL_RCC_SDIO_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_SDIORST)) +#define __HAL_RCC_SPI1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_SPI1RST)) +#define __HAL_RCC_SPI4_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_SPI4RST)) +#define __HAL_RCC_SYSCFG_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_SYSCFGRST)) +#define __HAL_RCC_TIM9_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM9RST)) +#define __HAL_RCC_TIM10_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM10RST)) +#define __HAL_RCC_TIM11_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM11RST)) +/** + * @} + */ + +/** @defgroup RCC_AHB3_Force_Release_Reset AHB3 Force Release Reset + * @brief Force or release AHB3 peripheral reset. + * @{ + */ +#define __HAL_RCC_AHB3_FORCE_RESET() (RCC->AHB3RSTR = 0xFFFFFFFF) +#define __HAL_RCC_AHB3_RELEASE_RESET() (RCC->AHB3RSTR = 0x00) +/** + * @} + */ + +/** @defgroup RCC_AHB1_LowPower_Enable_Disable AHB1 Peripheral Low Power Enable Disable + * @brief Enable or disable the AHB1 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wake-up from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @{ + */ +#define __HAL_RCC_GPIOA_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_GPIOALPEN)) +#define __HAL_RCC_GPIOB_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_GPIOBLPEN)) +#define __HAL_RCC_GPIOC_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_GPIOCLPEN)) +#define __HAL_RCC_GPIOD_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_GPIODLPEN)) +#define __HAL_RCC_GPIOE_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_GPIOELPEN)) +#define __HAL_RCC_GPIOH_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_GPIOHLPEN)) +#define __HAL_RCC_CRC_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_CRCLPEN)) +#define __HAL_RCC_FLITF_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_FLITFLPEN)) +#define __HAL_RCC_SRAM1_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_SRAM1LPEN)) +#define __HAL_RCC_BKPSRAM_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_BKPSRAMLPEN)) +#define __HAL_RCC_DMA1_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_DMA1LPEN)) +#define __HAL_RCC_DMA2_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_DMA2LPEN)) + +#define __HAL_RCC_GPIOA_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_GPIOALPEN)) +#define __HAL_RCC_GPIOB_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_GPIOBLPEN)) +#define __HAL_RCC_GPIOC_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_GPIOCLPEN)) +#define __HAL_RCC_GPIOD_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_GPIODLPEN)) +#define __HAL_RCC_GPIOE_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_GPIOELPEN)) +#define __HAL_RCC_GPIOH_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_GPIOHLPEN)) +#define __HAL_RCC_CRC_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_CRCLPEN)) +#define __HAL_RCC_FLITF_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_FLITFLPEN)) +#define __HAL_RCC_SRAM1_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_SRAM1LPEN)) +#define __HAL_RCC_BKPSRAM_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_BKPSRAMLPEN)) +#define __HAL_RCC_DMA1_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_DMA1LPEN)) +#define __HAL_RCC_DMA2_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_DMA2LPEN)) +/** + * @} + */ + +/** @defgroup RCC_AHB2_LowPower_Enable_Disable AHB2 Peripheral Low Power Enable Disable + * @brief Enable or disable the AHB2 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wake-up from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @{ + */ +#define __HAL_RCC_USB_OTG_FS_CLK_SLEEP_ENABLE() (RCC->AHB2LPENR |= (RCC_AHB2LPENR_OTGFSLPEN)) + +#define __HAL_RCC_USB_OTG_FS_CLK_SLEEP_DISABLE() (RCC->AHB2LPENR &= ~(RCC_AHB2LPENR_OTGFSLPEN)) + +#define __HAL_RCC_RNG_CLK_SLEEP_ENABLE() (RCC->AHB2LPENR |= (RCC_AHB2LPENR_RNGLPEN)) +#define __HAL_RCC_RNG_CLK_SLEEP_DISABLE() (RCC->AHB2LPENR &= ~(RCC_AHB2LPENR_RNGLPEN)) +/** + * @} + */ + +/** @defgroup RCC_APB1_LowPower_Enable_Disable APB1 Peripheral Low Power Enable Disable + * @brief Enable or disable the APB1 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wake-up from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @{ + */ +#define __HAL_RCC_TIM2_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM2LPEN)) +#define __HAL_RCC_TIM3_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM3LPEN)) +#define __HAL_RCC_TIM4_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM4LPEN)) +#define __HAL_RCC_TIM5_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM5LPEN)) +#define __HAL_RCC_WWDG_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_WWDGLPEN)) +#define __HAL_RCC_SPI2_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_SPI2LPEN)) +#define __HAL_RCC_SPI3_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_SPI3LPEN)) +#define __HAL_RCC_USART2_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_USART2LPEN)) +#define __HAL_RCC_I2C1_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_I2C1LPEN)) +#define __HAL_RCC_I2C2_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_I2C2LPEN)) +#define __HAL_RCC_I2C3_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_I2C3LPEN)) +#define __HAL_RCC_PWR_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_PWRLPEN)) + +#define __HAL_RCC_TIM2_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM2LPEN)) +#define __HAL_RCC_TIM3_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM3LPEN)) +#define __HAL_RCC_TIM4_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM4LPEN)) +#define __HAL_RCC_TIM5_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM5LPEN)) +#define __HAL_RCC_WWDG_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_WWDGLPEN)) +#define __HAL_RCC_SPI2_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_SPI2LPEN)) +#define __HAL_RCC_SPI3_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_SPI3LPEN)) +#define __HAL_RCC_USART2_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_USART2LPEN)) +#define __HAL_RCC_I2C1_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_I2C1LPEN)) +#define __HAL_RCC_I2C2_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_I2C2LPEN)) +#define __HAL_RCC_I2C3_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_I2C3LPEN)) +#define __HAL_RCC_PWR_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_PWRLPEN)) +/** + * @} + */ + +/** @defgroup RCC_APB2_LowPower_Enable_Disable APB2 Peripheral Low Power Enable Disable + * @brief Enable or disable the APB2 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wake-up from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + * @{ + */ +#define __HAL_RCC_TIM1_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_TIM1LPEN)) +#define __HAL_RCC_USART1_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_USART1LPEN)) +#define __HAL_RCC_USART6_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_USART6LPEN)) +#define __HAL_RCC_ADC1_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_ADC1LPEN)) +#define __HAL_RCC_SDIO_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_SDIOLPEN)) +#define __HAL_RCC_SPI1_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_SPI1LPEN)) +#define __HAL_RCC_SPI4_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_SPI4LPEN)) +#define __HAL_RCC_SYSCFG_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_SYSCFGLPEN)) +#define __HAL_RCC_TIM9_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_TIM9LPEN)) +#define __HAL_RCC_TIM10_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_TIM10LPEN)) +#define __HAL_RCC_TIM11_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_TIM11LPEN)) + +#define __HAL_RCC_TIM1_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_TIM1LPEN)) +#define __HAL_RCC_USART1_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_USART1LPEN)) +#define __HAL_RCC_USART6_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_USART6LPEN)) +#define __HAL_RCC_ADC1_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_ADC1LPEN)) +#define __HAL_RCC_SDIO_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_SDIOLPEN)) +#define __HAL_RCC_SPI1_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_SPI1LPEN)) +#define __HAL_RCC_SPI4_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_SPI4LPEN)) +#define __HAL_RCC_SYSCFG_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_SYSCFGLPEN)) +#define __HAL_RCC_TIM9_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_TIM9LPEN)) +#define __HAL_RCC_TIM10_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_TIM10LPEN)) +#define __HAL_RCC_TIM11_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_TIM11LPEN)) +/** + * @} + */ + +/** @defgroup RCC_HSI_Configuration HSI Configuration + * @{ + */ + +/** @brief Macros to enable or disable the Internal High Speed oscillator (HSI). + * @note The HSI is stopped by hardware when entering STOP and STANDBY modes. + * It is used (enabled by hardware) as system clock source after startup + * from Reset, wake-up from STOP and STANDBY mode, or in case of failure + * of the HSE used directly or indirectly as system clock (if the Clock + * Security System CSS is enabled). + * @note HSI can not be stopped if it is used as system clock source. In this case, + * you have to select another source of the system clock then stop the HSI. + * @note After enabling the HSI, the application software should wait on HSIRDY + * flag to be set indicating that HSI clock is stable and can be used as + * system clock source. + * This parameter can be: ENABLE or DISABLE. + * @note When the HSI is stopped, HSIRDY flag goes low after 6 HSI oscillator + * clock cycles. + */ +#define __HAL_RCC_HSI_ENABLE() (*(__IO uint32_t *) RCC_CR_HSION_BB = ENABLE) +#define __HAL_RCC_HSI_DISABLE() (*(__IO uint32_t *) RCC_CR_HSION_BB = DISABLE) + +/** @brief Macro to adjust the Internal High Speed oscillator (HSI) calibration value. + * @note The calibration is used to compensate for the variations in voltage + * and temperature that influence the frequency of the internal HSI RC. + * @param __HSICalibrationValue__: specifies the calibration trimming value. + * This parameter must be a number between 0 and 0x1F. + */ +#define __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(__HSICalibrationValue__) (MODIFY_REG(RCC->CR,\ + RCC_CR_HSITRIM, (uint32_t)(__HSICalibrationValue__) << POSITION_VAL(RCC_CR_HSITRIM))) +/** + * @} + */ + +/** @defgroup RCC_LSI_Configuration LSI Configuration + * @{ + */ + +/** @brief Macros to enable or disable the Internal Low Speed oscillator (LSI). + * @note After enabling the LSI, the application software should wait on + * LSIRDY flag to be set indicating that LSI clock is stable and can + * be used to clock the IWDG and/or the RTC. + * @note LSI can not be disabled if the IWDG is running. + * @note When the LSI is stopped, LSIRDY flag goes low after 6 LSI oscillator + * clock cycles. + */ +#define __HAL_RCC_LSI_ENABLE() (*(__IO uint32_t *) RCC_CSR_LSION_BB = ENABLE) +#define __HAL_RCC_LSI_DISABLE() (*(__IO uint32_t *) RCC_CSR_LSION_BB = DISABLE) +/** + * @} + */ + +/** @defgroup RCC_HSE_Configuration HSE Configuration + * @{ + */ + +/** + * @brief Macro to configure the External High Speed oscillator (HSE). + * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not supported by this macro. + * User should request a transition to HSE Off first and then HSE On or HSE Bypass. + * @note After enabling the HSE (RCC_HSE_ON or RCC_HSE_Bypass), the application + * software should wait on HSERDY flag to be set indicating that HSE clock + * is stable and can be used to clock the PLL and/or system clock. + * @note HSE state can not be changed if it is used directly or through the + * PLL as system clock. In this case, you have to select another source + * of the system clock then change the HSE state (ex. disable it). + * @note The HSE is stopped by hardware when entering STOP and STANDBY modes. + * @note This function reset the CSSON bit, so if the clock security system(CSS) + * was previously enabled you have to enable it again after calling this + * function. + * @param __STATE__: specifies the new state of the HSE. + * This parameter can be one of the following values: + * @arg RCC_HSE_OFF: turn OFF the HSE oscillator, HSERDY flag goes low after + * 6 HSE oscillator clock cycles. + * @arg RCC_HSE_ON: turn ON the HSE oscillator. + * @arg RCC_HSE_BYPASS: HSE oscillator bypassed with external clock. + */ +#define __HAL_RCC_HSE_CONFIG(__STATE__) (*(__IO uint8_t *) RCC_CR_BYTE2_ADDRESS = (__STATE__)) +/** + * @} + */ + +/** @defgroup RCC_LSE_Configuration LSE Configuration + * @{ + */ + +/** + * @brief Macro to configure the External Low Speed oscillator (LSE). + * @note Transition LSE Bypass to LSE On and LSE On to LSE Bypass are not supported by this macro. + * User should request a transition to LSE Off first and then LSE On or LSE Bypass. + * @note As the LSE is in the Backup domain and write access is denied to + * this domain after reset, you have to enable write access using + * HAL_PWR_EnableBkUpAccess() function before to configure the LSE + * (to be done once after reset). + * @note After enabling the LSE (RCC_LSE_ON or RCC_LSE_BYPASS), the application + * software should wait on LSERDY flag to be set indicating that LSE clock + * is stable and can be used to clock the RTC. + * @param __STATE__: specifies the new state of the LSE. + * This parameter can be one of the following values: + * @arg RCC_LSE_OFF: turn OFF the LSE oscillator, LSERDY flag goes low after + * 6 LSE oscillator clock cycles. + * @arg RCC_LSE_ON: turn ON the LSE oscillator. + * @arg RCC_LSE_BYPASS: LSE oscillator bypassed with external clock. + */ +#define __HAL_RCC_LSE_CONFIG(__STATE__) (*(__IO uint8_t *) RCC_BDCR_BYTE0_ADDRESS = (__STATE__)) + +/** + * @} + */ + +/** @defgroup RCC_Internal_RTC_Clock_Configuration RTC Clock Configuration + * @{ + */ + +/** @brief Macros to enable or disable the RTC clock. + * @note These macros must be used only after the RTC clock source was selected. + */ +#define __HAL_RCC_RTC_ENABLE() (*(__IO uint32_t *) RCC_BDCR_RTCEN_BB = ENABLE) +#define __HAL_RCC_RTC_DISABLE() (*(__IO uint32_t *) RCC_BDCR_RTCEN_BB = DISABLE) + +/** @brief Macros to configure the RTC clock (RTCCLK). + * @note As the RTC clock configuration bits are in the Backup domain and write + * access is denied to this domain after reset, you have to enable write + * access using the Power Backup Access macro before to configure + * the RTC clock source (to be done once after reset). + * @note Once the RTC clock is configured it can't be changed unless the + * Backup domain is reset using __HAL_RCC_BackupReset_RELEASE() macro, or by + * a Power On Reset (POR). + * @param __RTCCLKSource__: specifies the RTC clock source. + * This parameter can be one of the following values: + * @arg RCC_RTCCLKSOURCE_LSE: LSE selected as RTC clock. + * @arg RCC_RTCCLKSOURCE_LSI: LSI selected as RTC clock. + * @arg RCC_RTCCLKSOURCE_HSE_DIVx: HSE clock divided by x selected + * as RTC clock, where x:[2,31] + * @note If the LSE or LSI is used as RTC clock source, the RTC continues to + * work in STOP and STANDBY modes, and can be used as wake-up source. + * However, when the HSE clock is used as RTC clock source, the RTC + * cannot be used in STOP and STANDBY modes. + * @note The maximum input clock frequency for RTC is 1MHz (when using HSE as + * RTC clock source). + */ +#define __HAL_RCC_RTC_CLKPRESCALER(__RTCCLKSource__) (((__RTCCLKSource__) & RCC_BDCR_RTCSEL) == RCC_BDCR_RTCSEL) ? \ + MODIFY_REG(RCC->CFGR, RCC_CFGR_RTCPRE, ((__RTCCLKSource__) & 0xFFFFCFF)) : CLEAR_BIT(RCC->CFGR, RCC_CFGR_RTCPRE) + +#define __HAL_RCC_RTC_CONFIG(__RTCCLKSource__) do { __HAL_RCC_RTC_CLKPRESCALER(__RTCCLKSource__); \ + RCC->BDCR |= ((__RTCCLKSource__) & 0x00000FFF); \ + } while (0) + +/** @brief Macros to force or release the Backup domain reset. + * @note This function resets the RTC peripheral (including the backup registers) + * and the RTC clock source selection in RCC_CSR register. + * @note The BKPSRAM is not affected by this reset. + */ +#define __HAL_RCC_BACKUPRESET_FORCE() (*(__IO uint32_t *) RCC_BDCR_BDRST_BB = ENABLE) +#define __HAL_RCC_BACKUPRESET_RELEASE() (*(__IO uint32_t *) RCC_BDCR_BDRST_BB = DISABLE) +/** + * @} + */ + +/** @defgroup RCC_PLL_Configuration PLL Configuration + * @{ + */ + +/** @brief Macros to enable or disable the main PLL. + * @note After enabling the main PLL, the application software should wait on + * PLLRDY flag to be set indicating that PLL clock is stable and can + * be used as system clock source. + * @note The main PLL can not be disabled if it is used as system clock source + * @note The main PLL is disabled by hardware when entering STOP and STANDBY modes. + */ +#define __HAL_RCC_PLL_ENABLE() (*(__IO uint32_t *) RCC_CR_PLLON_BB = ENABLE) +#define __HAL_RCC_PLL_DISABLE() (*(__IO uint32_t *) RCC_CR_PLLON_BB = DISABLE) +/** + * @} + */ + +/** @brief Macro to configure the PLL clock source. + * @note This function must be used only when the main PLL is disabled. + * @param __PLLSOURCE__: specifies the PLL entry clock source. + * This parameter can be one of the following values: + * @arg RCC_PLLSOURCE_HSI: HSI oscillator clock selected as PLL clock entry + * @arg RCC_PLLSOURCE_HSE: HSE oscillator clock selected as PLL clock entry + * + */ +#define __HAL_RCC_PLL_PLLSOURCE_CONFIG(__PLLSOURCE__) MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, (__PLLSOURCE__)) + +/** @brief Macro to configure the PLL multiplication factor. + * @note This function must be used only when the main PLL is disabled. + * @param __PLLM__: specifies the division factor for PLL VCO input clock + * This parameter must be a number between Min_Data = 2 and Max_Data = 63. + * @note You have to set the PLLM parameter correctly to ensure that the VCO input + * frequency ranges from 1 to 2 MHz. It is recommended to select a frequency + * of 2 MHz to limit PLL jitter. + * + */ +#define __HAL_RCC_PLL_PLLM_CONFIG(__PLLM__) MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLM, (__PLLM__)) + +/** @defgroup RCC_PLL_I2S_Configuration PLL I2S Configuration + * @{ + */ + +/** @brief Macros to enable or disable the PLLI2S. + * @note The PLLI2S is disabled by hardware when entering STOP and STANDBY modes. + */ +#define __HAL_RCC_PLLI2S_ENABLE() (*(__IO uint32_t *) RCC_CR_PLLI2SON_BB = ENABLE) +#define __HAL_RCC_PLLI2S_DISABLE() (*(__IO uint32_t *) RCC_CR_PLLI2SON_BB = DISABLE) +/** + * @} + */ + +/** @defgroup RCC_Get_Clock_source Get Clock source + * @{ + */ +/** + * @brief Macro to configure the system clock source. + * @param __RCC_SYSCLKSOURCE__: specifies the system clock source. + * This parameter can be one of the following values: + * - RCC_SYSCLKSOURCE_HSI: HSI oscillator is used as system clock source. + * - RCC_SYSCLKSOURCE_HSE: HSE oscillator is used as system clock source. + * - RCC_SYSCLKSOURCE_PLLCLK: PLL output is used as system clock source. + * - RCC_SYSCLKSOURCE_PLLRCLK: PLLR output is used as system clock source. + */ +#define __HAL_RCC_SYSCLK_CONFIG(__RCC_SYSCLKSOURCE__) MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, (__RCC_SYSCLKSOURCE__)) + +/** @brief Macro to get the clock source used as system clock. + * @retval The clock source used as system clock. The returned value can be one + * of the following: + * - RCC_SYSCLKSOURCE_STATUS_HSI: HSI used as system clock. + * - RCC_SYSCLKSOURCE_STATUS_HSE: HSE used as system clock. + * - RCC_SYSCLKSOURCE_STATUS_PLLCLK: PLL used as system clock. + * - RCC_SYSCLKSOURCE_STATUS_PLLRCLK: PLLR used as system clock. + */ +#define __HAL_RCC_GET_SYSCLK_SOURCE() ((uint32_t)(RCC->CFGR & RCC_CFGR_SWS)) + +/** @brief Macro to get the oscillator used as PLL clock source. + * @retval The oscillator used as PLL clock source. The returned value can be one + * of the following: + * - RCC_PLLSOURCE_HSI: HSI oscillator is used as PLL clock source. + * - RCC_PLLSOURCE_HSE: HSE oscillator is used as PLL clock source. + */ +#define __HAL_RCC_GET_PLL_OSCSOURCE() ((uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC)) +/** + * @} + */ + +/** @defgroup RCC_Flags_Interrupts_Management Flags Interrupts Management + * @brief macros to manage the specified RCC Flags and interrupts. + * @{ + */ + +/** @brief Enable RCC interrupt (Perform Byte access to RCC_CIR[14:8] bits to enable + * the selected interrupts). + * @param __INTERRUPT__: specifies the RCC interrupt sources to be enabled. + * This parameter can be any combination of the following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt. + * @arg RCC_IT_LSERDY: LSE ready interrupt. + * @arg RCC_IT_HSIRDY: HSI ready interrupt. + * @arg RCC_IT_HSERDY: HSE ready interrupt. + * @arg RCC_IT_PLLRDY: Main PLL ready interrupt. + * @arg RCC_IT_PLLI2SRDY: PLLI2S ready interrupt. + */ +#define __HAL_RCC_ENABLE_IT(__INTERRUPT__) (*(__IO uint8_t *) RCC_CIR_BYTE1_ADDRESS |= (__INTERRUPT__)) + +/** @brief Disable RCC interrupt (Perform Byte access to RCC_CIR[14:8] bits to disable + * the selected interrupts). + * @param __INTERRUPT__: specifies the RCC interrupt sources to be disabled. + * This parameter can be any combination of the following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt. + * @arg RCC_IT_LSERDY: LSE ready interrupt. + * @arg RCC_IT_HSIRDY: HSI ready interrupt. + * @arg RCC_IT_HSERDY: HSE ready interrupt. + * @arg RCC_IT_PLLRDY: Main PLL ready interrupt. + * @arg RCC_IT_PLLI2SRDY: PLLI2S ready interrupt. + */ +#define __HAL_RCC_DISABLE_IT(__INTERRUPT__) (*(__IO uint8_t *) RCC_CIR_BYTE1_ADDRESS &= ~(__INTERRUPT__)) + +/** @brief Clear the RCC's interrupt pending bits (Perform Byte access to RCC_CIR[23:16] + * bits to clear the selected interrupt pending bits. + * @param __INTERRUPT__: specifies the interrupt pending bit to clear. + * This parameter can be any combination of the following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt. + * @arg RCC_IT_LSERDY: LSE ready interrupt. + * @arg RCC_IT_HSIRDY: HSI ready interrupt. + * @arg RCC_IT_HSERDY: HSE ready interrupt. + * @arg RCC_IT_PLLRDY: Main PLL ready interrupt. + * @arg RCC_IT_PLLI2SRDY: PLLI2S ready interrupt. + * @arg RCC_IT_CSS: Clock Security System interrupt + */ +#define __HAL_RCC_CLEAR_IT(__INTERRUPT__) (*(__IO uint8_t *) RCC_CIR_BYTE2_ADDRESS = (__INTERRUPT__)) + +/** @brief Check the RCC's interrupt has occurred or not. + * @param __INTERRUPT__: specifies the RCC interrupt source to check. + * This parameter can be one of the following values: + * @arg RCC_IT_LSIRDY: LSI ready interrupt. + * @arg RCC_IT_LSERDY: LSE ready interrupt. + * @arg RCC_IT_HSIRDY: HSI ready interrupt. + * @arg RCC_IT_HSERDY: HSE ready interrupt. + * @arg RCC_IT_PLLRDY: Main PLL ready interrupt. + * @arg RCC_IT_PLLI2SRDY: PLLI2S ready interrupt. + * @arg RCC_IT_CSS: Clock Security System interrupt + * @retval The new state of __INTERRUPT__ (TRUE or FALSE). + */ +#define __HAL_RCC_GET_IT(__INTERRUPT__) ((RCC->CIR & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** @brief Set RMVF bit to clear the reset flags: RCC_FLAG_PINRST, RCC_FLAG_PORRST, + * RCC_FLAG_SFTRST, RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST and RCC_FLAG_LPWRRST. + */ +#define __HAL_RCC_CLEAR_RESET_FLAGS() (RCC->CSR |= RCC_CSR_RMVF) + +/** @brief Check RCC flag is set or not. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg RCC_FLAG_HSIRDY: HSI oscillator clock ready. + * @arg RCC_FLAG_HSERDY: HSE oscillator clock ready. + * @arg RCC_FLAG_PLLRDY: Main PLL clock ready. + * @arg RCC_FLAG_PLLI2SRDY: PLLI2S clock ready. + * @arg RCC_FLAG_LSERDY: LSE oscillator clock ready. + * @arg RCC_FLAG_LSIRDY: LSI oscillator clock ready. + * @arg RCC_FLAG_BORRST: POR/PDR or BOR reset. + * @arg RCC_FLAG_PINRST: Pin reset. + * @arg RCC_FLAG_PORRST: POR/PDR reset. + * @arg RCC_FLAG_SFTRST: Software reset. + * @arg RCC_FLAG_IWDGRST: Independent Watchdog reset. + * @arg RCC_FLAG_WWDGRST: Window Watchdog reset. + * @arg RCC_FLAG_LPWRRST: Low Power reset. + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define RCC_FLAG_MASK ((uint8_t)0x1F) +#define __HAL_RCC_GET_FLAG(__FLAG__) (((((((__FLAG__) >> 5) == 1)? RCC->CR :((((__FLAG__) >> 5) == 2) ? RCC->BDCR :((((__FLAG__) >> 5) == 3)? RCC->CSR :RCC->CIR))) & ((uint32_t)1 << ((__FLAG__) & RCC_FLAG_MASK)))!= 0)? 1 : 0) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + /** @addtogroup RCC_Exported_Functions + * @{ + */ + +/** @addtogroup RCC_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions ******************************/ +void HAL_RCC_DeInit(void); +HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct); +HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency); +/** + * @} + */ + +/** @addtogroup RCC_Exported_Functions_Group2 + * @{ + */ +/* Peripheral Control functions ************************************************/ +void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv); +void HAL_RCC_EnableCSS(void); +void HAL_RCC_DisableCSS(void); +uint32_t HAL_RCC_GetSysClockFreq(void); +uint32_t HAL_RCC_GetHCLKFreq(void); +uint32_t HAL_RCC_GetPCLK1Freq(void); +uint32_t HAL_RCC_GetPCLK2Freq(void); +void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct); +void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency); + +/* CSS NMI IRQ handler */ +void HAL_RCC_NMI_IRQHandler(void); + +/* User Callbacks in non blocking mode (IT mode) */ +void HAL_RCC_CSSCallback(void); + +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup RCC_Private_Constants RCC Private Constants + * @{ + */ + +/** @defgroup RCC_BitAddress_AliasRegion RCC BitAddress AliasRegion + * @brief RCC registers bit address in the alias region + * @{ + */ +#define RCC_OFFSET (RCC_BASE - PERIPH_BASE) +/* --- CR Register ---*/ +/* Alias word address of HSION bit */ +#define RCC_CR_OFFSET (RCC_OFFSET + 0x00) +#define RCC_HSION_BIT_NUMBER 0x00 +#define RCC_CR_HSION_BB (PERIPH_BB_BASE + (RCC_CR_OFFSET * 32) + (RCC_HSION_BIT_NUMBER * 4)) +/* Alias word address of CSSON bit */ +#define RCC_CSSON_BIT_NUMBER 0x13 +#define RCC_CR_CSSON_BB (PERIPH_BB_BASE + (RCC_CR_OFFSET * 32) + (RCC_CSSON_BIT_NUMBER * 4)) +/* Alias word address of PLLON bit */ +#define RCC_PLLON_BIT_NUMBER 0x18 +#define RCC_CR_PLLON_BB (PERIPH_BB_BASE + (RCC_CR_OFFSET * 32) + (RCC_PLLON_BIT_NUMBER * 4)) +/* Alias word address of PLLI2SON bit */ +#define RCC_PLLI2SON_BIT_NUMBER 0x1A +#define RCC_CR_PLLI2SON_BB (PERIPH_BB_BASE + (RCC_CR_OFFSET * 32) + (RCC_PLLI2SON_BIT_NUMBER * 4)) + +/* --- CFGR Register ---*/ +/* Alias word address of I2SSRC bit */ +#define RCC_CFGR_OFFSET (RCC_OFFSET + 0x08) +#define RCC_I2SSRC_BIT_NUMBER 0x17 +#define RCC_CFGR_I2SSRC_BB (PERIPH_BB_BASE + (RCC_CFGR_OFFSET * 32) + (RCC_I2SSRC_BIT_NUMBER * 4)) + +/* --- BDCR Register ---*/ +/* Alias word address of RTCEN bit */ +#define RCC_BDCR_OFFSET (RCC_OFFSET + 0x70) +#define RCC_RTCEN_BIT_NUMBER 0x0F +#define RCC_BDCR_RTCEN_BB (PERIPH_BB_BASE + (RCC_BDCR_OFFSET * 32) + (RCC_RTCEN_BIT_NUMBER * 4)) +/* Alias word address of BDRST bit */ +#define RCC_BDRST_BIT_NUMBER 0x10 +#define RCC_BDCR_BDRST_BB (PERIPH_BB_BASE + (RCC_BDCR_OFFSET * 32) + (RCC_BDRST_BIT_NUMBER * 4)) + +/* --- CSR Register ---*/ +/* Alias word address of LSION bit */ +#define RCC_CSR_OFFSET (RCC_OFFSET + 0x74) +#define RCC_LSION_BIT_NUMBER 0x00 +#define RCC_CSR_LSION_BB (PERIPH_BB_BASE + (RCC_CSR_OFFSET * 32) + (RCC_LSION_BIT_NUMBER * 4)) + +/* CR register byte 3 (Bits[23:16]) base address */ +#define RCC_CR_BYTE2_ADDRESS ((uint32_t)0x40023802) + +/* CIR register byte 2 (Bits[15:8]) base address */ +#define RCC_CIR_BYTE1_ADDRESS ((uint32_t)(RCC_BASE + 0x0C + 0x01)) + +/* CIR register byte 3 (Bits[23:16]) base address */ +#define RCC_CIR_BYTE2_ADDRESS ((uint32_t)(RCC_BASE + 0x0C + 0x02)) + +/* BDCR register base address */ +#define RCC_BDCR_BYTE0_ADDRESS (PERIPH_BASE + RCC_BDCR_OFFSET) + +#define RCC_DBP_TIMEOUT_VALUE ((uint32_t)100) +#define RCC_LSE_TIMEOUT_VALUE ((uint32_t)5000) + +#define HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT +#define HSI_TIMEOUT_VALUE ((uint32_t)100) /* 100 ms */ +#define LSI_TIMEOUT_VALUE ((uint32_t)100) /* 100 ms */ + +#define PLLI2S_TIMEOUT_VALUE ((uint32_t)100) /* Timeout value fixed to 100 ms */ +#define PLLSAI_TIMEOUT_VALUE ((uint32_t)100) /* Timeout value fixed to 100 ms */ +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup RCC_Private_Macros RCC Private Macros + * @{ + */ + +/** @defgroup RCC_IS_RCC_Definitions RCC Private macros to check input parameters + * @{ + */ +#define IS_RCC_OSCILLATORTYPE(OSCILLATOR) ((OSCILLATOR) <= 15) + +#define IS_RCC_HSE(HSE) (((HSE) == RCC_HSE_OFF) || ((HSE) == RCC_HSE_ON) || \ + ((HSE) == RCC_HSE_BYPASS)) + +#define IS_RCC_LSE(LSE) (((LSE) == RCC_LSE_OFF) || ((LSE) == RCC_LSE_ON) || \ + ((LSE) == RCC_LSE_BYPASS)) + +#define IS_RCC_HSI(HSI) (((HSI) == RCC_HSI_OFF) || ((HSI) == RCC_HSI_ON)) + +#define IS_RCC_LSI(LSI) (((LSI) == RCC_LSI_OFF) || ((LSI) == RCC_LSI_ON)) + +#define IS_RCC_PLL(PLL) (((PLL) == RCC_PLL_NONE) ||((PLL) == RCC_PLL_OFF) || ((PLL) == RCC_PLL_ON)) + +#define IS_RCC_PLLSOURCE(SOURCE) (((SOURCE) == RCC_PLLSOURCE_HSI) || \ + ((SOURCE) == RCC_PLLSOURCE_HSE)) + +#define IS_RCC_SYSCLKSOURCE(SOURCE) (((SOURCE) == RCC_SYSCLKSOURCE_HSI) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_HSE) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_PLLCLK) || \ + ((SOURCE) == RCC_SYSCLKSOURCE_PLLRCLK)) + +#define IS_RCC_PLLM_VALUE(VALUE) ((VALUE) <= 63) + +#define IS_RCC_PLLN_VALUE(VALUE) ((192 <= (VALUE)) && ((VALUE) <= 432)) + +#define IS_RCC_PLLP_VALUE(VALUE) (((VALUE) == 2) || ((VALUE) == 4) || ((VALUE) == 6) || ((VALUE) == 8)) + +#define IS_RCC_PLLQ_VALUE(VALUE) ((4 <= (VALUE)) && ((VALUE) <= 15)) + +#define IS_RCC_HCLK(HCLK) (((HCLK) == RCC_SYSCLK_DIV1) || ((HCLK) == RCC_SYSCLK_DIV2) || \ + ((HCLK) == RCC_SYSCLK_DIV4) || ((HCLK) == RCC_SYSCLK_DIV8) || \ + ((HCLK) == RCC_SYSCLK_DIV16) || ((HCLK) == RCC_SYSCLK_DIV64) || \ + ((HCLK) == RCC_SYSCLK_DIV128) || ((HCLK) == RCC_SYSCLK_DIV256) || \ + ((HCLK) == RCC_SYSCLK_DIV512)) + +#define IS_RCC_CLOCKTYPE(CLK) ((1 <= (CLK)) && ((CLK) <= 15)) + +#define IS_RCC_PCLK(PCLK) (((PCLK) == RCC_HCLK_DIV1) || ((PCLK) == RCC_HCLK_DIV2) || \ + ((PCLK) == RCC_HCLK_DIV4) || ((PCLK) == RCC_HCLK_DIV8) || \ + ((PCLK) == RCC_HCLK_DIV16)) + +#define IS_RCC_MCO(MCOx) (((MCOx) == RCC_MCO1) || ((MCOx) == RCC_MCO2)) + +#define IS_RCC_MCO1SOURCE(SOURCE) (((SOURCE) == RCC_MCO1SOURCE_HSI) || ((SOURCE) == RCC_MCO1SOURCE_LSE) || \ + ((SOURCE) == RCC_MCO1SOURCE_HSE) || ((SOURCE) == RCC_MCO1SOURCE_PLLCLK)) + +#define IS_RCC_MCO2SOURCE(SOURCE) (((SOURCE) == RCC_MCO2SOURCE_SYSCLK) || ((SOURCE) == RCC_MCO2SOURCE_PLLI2SCLK)|| \ + ((SOURCE) == RCC_MCO2SOURCE_HSE) || ((SOURCE) == RCC_MCO2SOURCE_PLLCLK)) + +#define IS_RCC_MCODIV(DIV) (((DIV) == RCC_MCODIV_1) || ((DIV) == RCC_MCODIV_2) || \ + ((DIV) == RCC_MCODIV_3) || ((DIV) == RCC_MCODIV_4) || \ + ((DIV) == RCC_MCODIV_5)) +#define IS_RCC_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x1F) + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_RCC_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h new file mode 100644 index 0000000..3f7722a --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc_ex.h @@ -0,0 +1,2707 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_rcc_ex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of RCC HAL Extension module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_RCC_EX_H +#define __STM32F4xx_HAL_RCC_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup RCCEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup RCCEx_Exported_Types RCCEx Exported Types + * @{ + */ + +/** + * @brief RCC PLL configuration structure definition + */ +typedef struct +{ + uint32_t PLLState; /*!< The new state of the PLL. + This parameter can be a value of @ref RCC_PLL_Config */ + + uint32_t PLLSource; /*!< RCC_PLLSource: PLL entry clock source. + This parameter must be a value of @ref RCC_PLL_Clock_Source */ + + uint32_t PLLM; /*!< PLLM: Division factor for PLL VCO input clock. + This parameter must be a number between Min_Data = 0 and Max_Data = 63 */ + + uint32_t PLLN; /*!< PLLN: Multiplication factor for PLL VCO output clock. + This parameter must be a number between Min_Data = 192 and Max_Data = 432 */ + + uint32_t PLLP; /*!< PLLP: Division factor for main system clock (SYSCLK). + This parameter must be a value of @ref RCC_PLLP_Clock_Divider */ + + uint32_t PLLQ; /*!< PLLQ: Division factor for OTG FS, SDIO and RNG clocks. + This parameter must be a number between Min_Data = 4 and Max_Data = 15 */ +#if defined(STM32F446xx) + uint32_t PLLR; /*!< PLLR: PLL division factor for I2S, SAI, SYSTEM, SPDIFRX clocks. + This parameter is only available in STM32F446xx devices. + This parameter must be a number between Min_Data = 2 and Max_Data = 7 */ +#endif /* STM32F446xx */ +}RCC_PLLInitTypeDef; + +#if defined(STM32F446xx) +/** + * @brief PLLI2S Clock structure definition + */ +typedef struct +{ + uint32_t PLLI2SM; /*!< Specifies division factor for PLL VCO input clock. + This parameter must be a number between Min_Data = 2 and Max_Data = 63 */ + + uint32_t PLLI2SN; /*!< Specifies the multiplication factor for PLLI2S VCO output clock. + This parameter must be a number between Min_Data = 192 and Max_Data = 432 */ + + uint32_t PLLI2SP; /*!< Specifies division factor for SPDIFRX Clock. + This parameter must be a value of @ref RCCEx_PLLI2SP_Clock_Divider */ + + uint32_t PLLI2SQ; /*!< Specifies the division factor for SAI clock. + This parameter must be a number between Min_Data = 2 and Max_Data = 15. + This parameter will be used only when PLLI2S is selected as Clock Source SAI */ + + uint32_t PLLI2SR; /*!< Specifies the division factor for I2S clock. + This parameter must be a number between Min_Data = 2 and Max_Data = 7. + This parameter will be used only when PLLI2S is selected as Clock Source I2S */ +}RCC_PLLI2SInitTypeDef; + +/** + * @brief PLLSAI Clock structure definition + */ +typedef struct +{ + uint32_t PLLSAIM; /*!< Spcifies division factor for PLL VCO input clock. + This parameter must be a number between Min_Data = 2 and Max_Data = 63 */ + + uint32_t PLLSAIN; /*!< Specifies the multiplication factor for PLLI2S VCO output clock. + This parameter must be a number between Min_Data = 192 and Max_Data = 432 */ + + uint32_t PLLSAIP; /*!< Specifies division factor for OTG FS, SDIO and RNG clocks. + This parameter must be a value of @ref RCCEx_PLLSAIP_Clock_Divider */ + + uint32_t PLLSAIQ; /*!< Specifies the division factor for SAI clock. + This parameter must be a number between Min_Data = 2 and Max_Data = 15. + This parameter will be used only when PLLSAI is selected as Clock Source SAI */ +}RCC_PLLSAIInitTypeDef; +/** + * @brief RCC extended clocks structure definition + */ +typedef struct +{ + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref RCCEx_Periph_Clock_Selection */ + + RCC_PLLI2SInitTypeDef PLLI2S; /*!< PLL I2S structure parameters. + This parameter will be used only when PLLI2S is selected as Clock Source I2S or SAI */ + + RCC_PLLSAIInitTypeDef PLLSAI; /*!< PLL SAI structure parameters. + This parameter will be used only when PLLI2S is selected as Clock Source SAI or LTDC */ + + uint32_t PLLI2SDivQ; /*!< Specifies the PLLI2S division factor for SAI1 clock. + This parameter must be a number between Min_Data = 1 and Max_Data = 32 + This parameter will be used only when PLLI2S is selected as Clock Source SAI */ + + uint32_t PLLSAIDivQ; /*!< Specifies the PLLI2S division factor for SAI1 clock. + This parameter must be a number between Min_Data = 1 and Max_Data = 32 + This parameter will be used only when PLLSAI is selected as Clock Source SAI */ + + uint32_t Sai1ClockSelection; /*!< Specifies SAI1 Clock Source Selection. + This parameter can be a value of @ref RCCEx_SAI1_Clock_Source */ + + uint32_t Sai2ClockSelection; /*!< Specifies SAI2 Clock Source Selection. + This parameter can be a value of @ref RCCEx_SAI2_Clock_Source */ + + uint32_t I2sApb1ClockSelection; /*!< Specifies I2S APB1 Clock Source Selection. + This parameter can be a value of @ref RCCEx_I2SAPB1_Clock_Source */ + + uint32_t I2sApb2ClockSelection; /*!< Specifies I2S APB2 Clock Source Selection. + This parameter can be a value of @ref RCCEx_I2SAPB2_Clock_Source */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Source Selection. + This parameter can be a value of @ref RCC_RTC_Clock_Source */ + + uint32_t SdioClockSelection; /*!< Specifies SDIO Clock Source Selection. + This parameter can be a value of @ref RCCEx_SDIO_Clock_Source */ + + uint32_t CecClockSelection; /*!< Specifies CEC Clock Source Selection. + This parameter can be a value of @ref RCCEx_CEC_Clock_Source */ + + uint32_t Fmpi2c1ClockSelection; /*!< Specifies FMPI2C1 Clock Source Selection. + This parameter can be a value of @ref RCCEx_FMPI2C1_Clock_Source */ + + uint32_t SpdifClockSelection; /*!< Specifies SPDIFRX Clock Source Selection. + This parameter can be a value of @ref RCCEx_SPDIFRX_Clock_Source */ + + uint32_t Clk48ClockSelection; /*!< Specifies CK48 Clock Selection this clock used OTG FS, SDIO and RNG clocks. + This parameter can be a value of @ref RCCEx_CK48_Clock_Source */ + + uint8_t TIMPresSelection; /*!< Specifies TIM Clock Source Selection. + This parameter can be a value of @ref RCCEx_TIM_PRescaler_Selection */ +}RCC_PeriphCLKInitTypeDef; +#endif /* STM32F446xx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + +/** + * @brief PLLI2S Clock structure definition + */ +typedef struct +{ + uint32_t PLLI2SN; /*!< Specifies the multiplication factor for PLLI2S VCO output clock. + This parameter must be a number between Min_Data = 192 and Max_Data = 432. + This parameter will be used only when PLLI2S is selected as Clock Source I2S or SAI */ + + uint32_t PLLI2SR; /*!< Specifies the division factor for I2S clock. + This parameter must be a number between Min_Data = 2 and Max_Data = 7. + This parameter will be used only when PLLI2S is selected as Clock Source I2S or SAI */ + + uint32_t PLLI2SQ; /*!< Specifies the division factor for SAI1 clock. + This parameter must be a number between Min_Data = 2 and Max_Data = 15. + This parameter will be used only when PLLI2S is selected as Clock Source SAI */ +}RCC_PLLI2SInitTypeDef; + +/** + * @brief PLLSAI Clock structure definition + */ +typedef struct +{ + uint32_t PLLSAIN; /*!< Specifies the multiplication factor for PLLI2S VCO output clock. + This parameter must be a number between Min_Data = 192 and Max_Data = 432. + This parameter will be used only when PLLSAI is selected as Clock Source SAI or LTDC */ + + uint32_t PLLSAIQ; /*!< Specifies the division factor for SAI1 clock. + This parameter must be a number between Min_Data = 2 and Max_Data = 15. + This parameter will be used only when PLLSAI is selected as Clock Source SAI or LTDC */ + + uint32_t PLLSAIR; /*!< specifies the division factor for LTDC clock + This parameter must be a number between Min_Data = 2 and Max_Data = 7. + This parameter will be used only when PLLSAI is selected as Clock Source LTDC */ + +}RCC_PLLSAIInitTypeDef; +/** + * @brief RCC extended clocks structure definition + */ +typedef struct +{ + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref RCCEx_Periph_Clock_Selection */ + + RCC_PLLI2SInitTypeDef PLLI2S; /*!< PLL I2S structure parameters. + This parameter will be used only when PLLI2S is selected as Clock Source I2S or SAI */ + + RCC_PLLSAIInitTypeDef PLLSAI; /*!< PLL SAI structure parameters. + This parameter will be used only when PLLI2S is selected as Clock Source SAI or LTDC */ + + uint32_t PLLI2SDivQ; /*!< Specifies the PLLI2S division factor for SAI1 clock. + This parameter must be a number between Min_Data = 1 and Max_Data = 32 + This parameter will be used only when PLLI2S is selected as Clock Source SAI */ + + uint32_t PLLSAIDivQ; /*!< Specifies the PLLI2S division factor for SAI1 clock. + This parameter must be a number between Min_Data = 1 and Max_Data = 32 + This parameter will be used only when PLLSAI is selected as Clock Source SAI */ + + uint32_t PLLSAIDivR; /*!< Specifies the PLLSAI division factor for LTDC clock. + This parameter must be one value of @ref RCCEx_PLLSAI_DIVR */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection. + This parameter can be a value of @ref RCC_RTC_Clock_Source */ + + uint8_t TIMPresSelection; /*!< Specifies TIM Clock Prescalers Selection. + This parameter can be a value of @ref RCCEx_TIM_PRescaler_Selection */ + +}RCC_PeriphCLKInitTypeDef; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) +/** + * @brief PLLI2S Clock structure definition + */ +typedef struct +{ +#if defined(STM32F411xE) + uint32_t PLLI2SM; /*!< PLLM: Division factor for PLLI2S VCO input clock. + This parameter must be a number between Min_Data = 2 and Max_Data = 62 */ +#endif /* STM32F411xE */ + + uint32_t PLLI2SN; /*!< Specifies the multiplication factor for PLLI2S VCO output clock. + This parameter must be a number between Min_Data = 192 and Max_Data = 432 + This parameter will be used only when PLLI2S is selected as Clock Source I2S or SAI */ + + uint32_t PLLI2SR; /*!< Specifies the division factor for I2S clock. + This parameter must be a number between Min_Data = 2 and Max_Data = 7. + This parameter will be used only when PLLI2S is selected as Clock Source I2S or SAI */ + +}RCC_PLLI2SInitTypeDef; + + +/** + * @brief RCC extended clocks structure definition + */ +typedef struct +{ + uint32_t PeriphClockSelection; /*!< The Extended Clock to be configured. + This parameter can be a value of @ref RCCEx_Periph_Clock_Selection */ + + RCC_PLLI2SInitTypeDef PLLI2S; /*!< PLL I2S structure parameters. + This parameter will be used only when PLLI2S is selected as Clock Source I2S or SAI */ + + uint32_t RTCClockSelection; /*!< Specifies RTC Clock Prescalers Selection. + This parameter can be a value of @ref RCC_RTC_Clock_Source */ + +}RCC_PeriphCLKInitTypeDef; +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F411xE */ +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RCCEx_Exported_Constants RCCEx Exported Constants + * @{ + */ + +/** @defgroup RCCEx_Periph_Clock_Selection RCC Periph Clock Selection + * @{ + */ +/*------------------------------- Peripheral Clock source for STM32F446xx -----------------------------*/ +#if defined(STM32F446xx) +#define RCC_PERIPHCLK_I2S_APB1 ((uint32_t)0x00000001) +#define RCC_PERIPHCLK_I2S_APB2 ((uint32_t)0x00000002) +#define RCC_PERIPHCLK_SAI1 ((uint32_t)0x00000004) +#define RCC_PERIPHCLK_SAI2 ((uint32_t)0x00000008) +#define RCC_PERIPHCLK_TIM ((uint32_t)0x00000010) +#define RCC_PERIPHCLK_RTC ((uint32_t)0x00000020) +#define RCC_PERIPHCLK_CEC ((uint32_t)0x00000040) +#define RCC_PERIPHCLK_FMPI2C1 ((uint32_t)0x00000080) +#define RCC_PERIPHCLK_CK48 ((uint32_t)0x00000100) +#define RCC_PERIPHCLK_SDIO ((uint32_t)0x00000200) +#define RCC_PERIPHCLK_SPDIFRX ((uint32_t)0x00000400) +#define RCC_PERIPHCLK_PLLI2S ((uint32_t)0x00000800) +#endif /* STM32F446xx */ +/*-----------------------------------------------------------------------------------------------------*/ + +/*--------------- Peripheral Clock source for STM32F42xxx/STM32F43xxx ---------------------*/ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) +#define RCC_PERIPHCLK_I2S ((uint32_t)0x00000001) +#define RCC_PERIPHCLK_SAI_PLLI2S ((uint32_t)0x00000002) +#define RCC_PERIPHCLK_SAI_PLLSAI ((uint32_t)0x00000004) +#define RCC_PERIPHCLK_LTDC ((uint32_t)0x00000008) +#define RCC_PERIPHCLK_TIM ((uint32_t)0x00000010) +#define RCC_PERIPHCLK_RTC ((uint32_t)0x00000020) +#define RCC_PERIPHCLK_PLLI2S ((uint32_t)0x00000040) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +/*-----------------------------------------------------------------------------------------------------*/ + +/*------------------------ Peripheral Clock source for STM32F40xxx/STM32F41xxx ------------------------*/ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) +#define RCC_PERIPHCLK_I2S ((uint32_t)0x00000001) +#define RCC_PERIPHCLK_RTC ((uint32_t)0x00000002) +#define RCC_PERIPHCLK_PLLI2S ((uint32_t)0x00000004) +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F411xE */ +/*-----------------------------------------------------------------------------------------------------*/ +/** + * @} + */ + +/** @defgroup RCCEx_PLLSAI_DIVR RCC PLLSAI DIVR + * @{ + */ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) +#define RCC_PLLSAIDIVR_2 ((uint32_t)0x00000000) +#define RCC_PLLSAIDIVR_4 ((uint32_t)0x00010000) +#define RCC_PLLSAIDIVR_8 ((uint32_t)0x00020000) +#define RCC_PLLSAIDIVR_16 ((uint32_t)0x00030000) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ +/** + * @} + */ + +/** @defgroup RCCEx_PLLI2SP_Clock_Divider RCC PLLI2SP Clock Divider + * @{ + */ +#if defined(STM32F446xx) +#define RCC_PLLI2SP_DIV2 ((uint32_t)0x00000002) +#define RCC_PLLI2SP_DIV4 ((uint32_t)0x00000004) +#define RCC_PLLI2SP_DIV6 ((uint32_t)0x00000006) +#define RCC_PLLI2SP_DIV8 ((uint32_t)0x00000008) +#endif /* STM32F446xx */ +/** + * @} + */ + +/** @defgroup RCCEx_PLLSAIP_Clock_Divider RCC PLLSAIP Clock Divider + * @{ + */ +#if defined(STM32F446xx) +#define RCC_PLLSAIP_DIV2 ((uint32_t)0x00000002) +#define RCC_PLLSAIP_DIV4 ((uint32_t)0x00000004) +#define RCC_PLLSAIP_DIV6 ((uint32_t)0x00000006) +#define RCC_PLLSAIP_DIV8 ((uint32_t)0x00000008) +#endif /* STM32F446xx */ +/** + * @} + */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) +/** @defgroup RCCEx_SAI_BlockA_Clock_Source RCC SAI BlockA Clock Source + * @{ + */ +#define RCC_SAIACLKSOURCE_PLLSAI ((uint32_t)0x00000000) +#define RCC_SAIACLKSOURCE_PLLI2S ((uint32_t)0x00100000) +#define RCC_SAIACLKSOURCE_EXT ((uint32_t)0x00200000) +/** + * @} + */ + +/** @defgroup RCCEx_SAI_BlockB_Clock_Source RCC SAI BlockB Clock Source + * @{ + */ +#define RCC_SAIBCLKSOURCE_PLLSAI ((uint32_t)0x00000000) +#define RCC_SAIBCLKSOURCE_PLLI2S ((uint32_t)0x00400000) +#define RCC_SAIBCLKSOURCE_EXT ((uint32_t)0x00800000) +/** + * @} + */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +#if defined(STM32F446xx) +/** @defgroup RCCEx_SAI1_Clock_Source RCC SAI1 Clock Source + * @{ + */ +#define RCC_SAI1CLKSOURCE_PLLSAI ((uint32_t)0x00000000) +#define RCC_SAI1CLKSOURCE_PLLI2S ((uint32_t)RCC_DCKCFGR_SAI1SRC_0) +#define RCC_SAI1CLKSOURCE_PLLR ((uint32_t)RCC_DCKCFGR_SAI1SRC_1) +#define RCC_SAI1CLKSOURCE_EXT ((uint32_t)RCC_DCKCFGR_SAI1SRC) +/** + * @} + */ + +/** @defgroup RCCEx_SAI2_Clock_Source RCC SAI2 Clock Source + * @{ + */ +#define RCC_SAI2CLKSOURCE_PLLSAI ((uint32_t)0x00000000) +#define RCC_SAI2CLKSOURCE_PLLI2S ((uint32_t)RCC_DCKCFGR_SAI2SRC_0) +#define RCC_SAI2CLKSOURCE_PLLR ((uint32_t)RCC_DCKCFGR_SAI2SRC_1) +#define RCC_SAI2CLKSOURCE_PLLSRC ((uint32_t)RCC_DCKCFGR_SAI2SRC) +/** + * @} + */ + +/** @defgroup RCCEx_I2SAPB1_Clock_Source RCC I2S APB1 Clock Source + * @{ + */ +#define RCC_I2SAPB1CLKSOURCE_PLLI2S ((uint32_t)0x00000000) +#define RCC_I2SAPB1CLKSOURCE_EXT ((uint32_t)RCC_DCKCFGR_I2S1SRC_0) +#define RCC_I2SAPB1CLKSOURCE_PLLR ((uint32_t)RCC_DCKCFGR_I2S1SRC_1) +#define RCC_I2SAPB1CLKSOURCE_PLLSRC ((uint32_t)RCC_DCKCFGR_I2S1SRC) +/** + * @} + */ + +/** @defgroup RCCEx_I2SAPB2_Clock_Source RCC I2S APB2 Clock Source + * @{ + */ +#define RCC_I2SAPB2CLKSOURCE_PLLI2S ((uint32_t)0x00000000) +#define RCC_I2SAPB2CLKSOURCE_EXT ((uint32_t)RCC_DCKCFGR_I2S2SRC_0) +#define RCC_I2SAPB2CLKSOURCE_PLLR ((uint32_t)RCC_DCKCFGR_I2S2SRC_1) +#define RCC_I2SAPB2CLKSOURCE_PLLSRC ((uint32_t)RCC_DCKCFGR_I2S2SRC) +/** + * @} + */ + +/** @defgroup RCCEx_FMPI2C1_Clock_Source RCC FMPI2C1 Clock Source + * @{ + */ +#define RCC_FMPI2C1CLKSOURCE_APB ((uint32_t)0x00000000) +#define RCC_FMPI2C1CLKSOURCE_SYSCLK ((uint32_t)RCC_DCKCFGR2_FMPI2C1SEL_0) +#define RCC_FMPI2C1CLKSOURCE_HSI ((uint32_t)RCC_DCKCFGR2_FMPI2C1SEL_1) +/** + * @} + */ + +/** @defgroup RCCEx_CEC_Clock_Source RCC CEC Clock Source + * @{ + */ +#define RCC_CECCLKSOURCE_HSI ((uint32_t)0x00000000) +#define RCC_CECCLKSOURCE_LSE ((uint32_t)RCC_DCKCFGR2_CECSEL) +/** + * @} + */ + +/** @defgroup RCCEx_CK48_Clock_Source RCC CK48 Clock Source + * @{ + */ +#define RCC_CK48CLKSOURCE_PLLQ ((uint32_t)0x00000000) +#define RCC_CK48CLKSOURCE_PLLSAIP ((uint32_t)RCC_DCKCFGR2_CK48MSEL) +/** + * @} + */ + +/** @defgroup RCCEx_SDIO_Clock_Source RCC SDIO Clock Source + * @{ + */ +#define RCC_SDIOCLKSOURCE_CK48 ((uint32_t)0x00000000) +#define RCC_SDIOCLKSOURCE_SYSCLK ((uint32_t)RCC_DCKCFGR2_SDIOSEL) +/** + * @} + */ + +/** @defgroup RCCEx_SPDIFRX_Clock_Source RCC SPDIFRX Clock Source + * @{ + */ +#define RCC_SPDIFRXCLKSOURCE_PLLR ((uint32_t)0x00000000) +#define RCC_SPDIFRXCLKSOURCE_PLLI2SP ((uint32_t)RCC_DCKCFGR2_SPDIFRXSEL) +/** + * @} + */ + +#endif /* STM32F446xx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) +/** @defgroup RCCEx_TIM_PRescaler_Selection RCC TIM PRescaler Selection + * @{ + */ +#define RCC_TIMPRES_DESACTIVATED ((uint8_t)0x00) +#define RCC_TIMPRES_ACTIVATED ((uint8_t)0x01) +/** + * @} + */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx) || STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx */ + +#if defined(STM32F411xE) || defined(STM32F446xx) +/** @defgroup RCCEx_LSE_Dual_Mode_Selection RCC LSE Dual Mode Selection + * @{ + */ +#define RCC_LSE_LOWPOWER_MODE ((uint8_t)0x00) +#define RCC_LSE_HIGHDRIVE_MODE ((uint8_t)0x01) +/** + * @} + */ +#endif /* STM32F411xE || STM32F446xx */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup RCCEx_Exported_Macros RCCEx Exported Macros + * @{ + */ +/*------------------------------- STM32F42xxx/STM32F43xxx ----------------------------------*/ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) +/** @brief Enables or disables the AHB1 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#define __HAL_RCC_GPIOI_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOIEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOIEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_GPIOF_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOFEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOFEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_GPIOG_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOGEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOGEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_GPIOJ_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOJEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOJEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_GPIOK_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOKEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOKEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_DMA2D_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_DMA2DEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_DMA2DEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_ETHMAC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHMACEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHMACEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_ETHMACTX_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHMACTXEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHMACTXEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_ETHMACRX_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHMACRXEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHMACRXEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_ETHMACPTP_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHMACPTPEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHMACPTPEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_USB_OTG_HS_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGHSEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGHSEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGHSULPIEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGHSULPIEN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOF_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOFEN)) +#define __HAL_RCC_GPIOG_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOGEN)) +#define __HAL_RCC_GPIOI_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOIEN)) +#define __HAL_RCC_GPIOJ_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOJEN)) +#define __HAL_RCC_GPIOK_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOKEN)) +#define __HAL_RCC_DMA2D_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_DMA2DEN)) +#define __HAL_RCC_ETHMAC_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_ETHMACEN)) +#define __HAL_RCC_ETHMACTX_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_ETHMACTXEN)) +#define __HAL_RCC_ETHMACRX_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_ETHMACRXEN)) +#define __HAL_RCC_ETHMACPTP_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_ETHMACPTPEN)) +#define __HAL_RCC_USB_OTG_HS_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_OTGHSEN)) +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_OTGHSULPIEN)) + +/** + * @brief Enable ETHERNET clock. + */ +#define __HAL_RCC_ETH_CLK_ENABLE() do { \ + __HAL_RCC_ETHMAC_CLK_ENABLE(); \ + __HAL_RCC_ETHMACTX_CLK_ENABLE(); \ + __HAL_RCC_ETHMACRX_CLK_ENABLE(); \ + } while(0) +/** + * @brief Disable ETHERNET clock. + */ +#define __HAL_RCC_ETH_CLK_DISABLE() do { \ + __HAL_RCC_ETHMACTX_CLK_DISABLE(); \ + __HAL_RCC_ETHMACRX_CLK_DISABLE(); \ + __HAL_RCC_ETHMAC_CLK_DISABLE(); \ + } while(0) + +/** @brief Enable or disable the AHB2 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ + +#define __HAL_RCC_DCMI_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_DCMIEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_DCMIEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_DCMI_CLK_DISABLE() (RCC->AHB2ENR &= ~(RCC_AHB2ENR_DCMIEN)) + +#if defined(STM32F437xx)|| defined(STM32F439xx) +#define __HAL_RCC_CRYP_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_CRYPEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_CRYPEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_HASH_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_HASHEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_HASHEN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_CRYP_CLK_DISABLE() (RCC->AHB2ENR &= ~(RCC_AHB2ENR_CRYPEN)) +#define __HAL_RCC_HASH_CLK_DISABLE() (RCC->AHB2ENR &= ~(RCC_AHB2ENR_HASHEN)) +#endif /* STM32F437xx || STM32F439xx */ + +/** @brief Enables or disables the AHB3 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#define __HAL_RCC_FMC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_FMC_CLK_DISABLE() (RCC->AHB3ENR &= ~(RCC_AHB3ENR_FMCEN)) + +/** @brief Enable or disable the Low Speed APB (APB1) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#define __HAL_RCC_TIM6_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM6EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM6EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM7_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM7EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM7EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM12_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM12EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM12EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM13_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM13EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM13EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM14_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM14EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM14EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM14_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM14EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM14EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_USART3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USART3EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART3EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_UART4_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_UART4EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_UART4EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_UART5_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_UART5EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_UART5EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_CAN1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_CAN1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_CAN1EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_CAN2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_CAN2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_CAN2EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_DAC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_DACEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_DACEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_UART7_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_UART7EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_UART7EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_UART8_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_UART8EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_UART8EN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM6_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM6EN)) +#define __HAL_RCC_TIM7_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM7EN)) +#define __HAL_RCC_TIM12_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM12EN)) +#define __HAL_RCC_TIM13_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM13EN)) +#define __HAL_RCC_TIM14_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM14EN)) +#define __HAL_RCC_USART3_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART3EN)) +#define __HAL_RCC_UART4_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_UART4EN)) +#define __HAL_RCC_UART5_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_UART5EN)) +#define __HAL_RCC_CAN1_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_CAN1EN)) +#define __HAL_RCC_CAN2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_CAN2EN)) +#define __HAL_RCC_DAC_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_DACEN)) +#define __HAL_RCC_UART7_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_UART7EN)) +#define __HAL_RCC_UART8_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_UART8EN)) + +/** @brief Enable or disable the High Speed APB (APB2) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#define __HAL_RCC_TIM8_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM8EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM8EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_ADC2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC2EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_ADC3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC3EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC3EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_SPI5_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI5EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI5EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_SPI6_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI6EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI6EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_SAI1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI1EN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM8_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM8EN)) +#define __HAL_RCC_ADC2_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_ADC2EN)) +#define __HAL_RCC_ADC3_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_ADC3EN)) +#define __HAL_RCC_SPI5_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_SPI5EN)) +#define __HAL_RCC_SPI6_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_SPI6EN)) +#define __HAL_RCC_SAI1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_SAI1EN)) + +#if defined(STM32F429xx)|| defined(STM32F439xx) +#define __HAL_RCC_LTDC_CLK_ENABLE() (RCC->APB2ENR |= (RCC_APB2ENR_LTDCEN)) + +#define __HAL_RCC_LTDC_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_LTDCEN)) +#endif /* STM32F429xx || STM32F439xx */ + +/** @brief Force or release AHB1 peripheral reset. + */ +#define __HAL_RCC_GPIOF_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_GPIOFRST)) +#define __HAL_RCC_GPIOG_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_GPIOGRST)) +#define __HAL_RCC_GPIOI_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_GPIOIRST)) +#define __HAL_RCC_ETHMAC_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_ETHMACRST)) +#define __HAL_RCC_USB_OTG_HS_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_OTGHRST)) +#define __HAL_RCC_GPIOJ_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_GPIOJRST)) +#define __HAL_RCC_GPIOK_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_GPIOKRST)) +#define __HAL_RCC_DMA2D_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_DMA2DRST)) + +#define __HAL_RCC_GPIOF_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOFRST)) +#define __HAL_RCC_GPIOG_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOGRST)) +#define __HAL_RCC_GPIOI_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOIRST)) +#define __HAL_RCC_ETHMAC_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_ETHMACRST)) +#define __HAL_RCC_USB_OTG_HS_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_OTGHRST)) +#define __HAL_RCC_GPIOJ_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOJRST)) +#define __HAL_RCC_GPIOK_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOKRST)) +#define __HAL_RCC_DMA2D_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_DMA2DRST)) + +/** @brief Force or release AHB2 peripheral reset. + */ +#define __HAL_RCC_DCMI_FORCE_RESET() (RCC->AHB2RSTR |= (RCC_AHB2RSTR_DCMIRST)) +#define __HAL_RCC_DCMI_RELEASE_RESET() (RCC->AHB2RSTR &= ~(RCC_AHB2RSTR_DCMIRST)) + +#if defined(STM32F437xx)|| defined(STM32F439xx) +#define __HAL_RCC_CRYP_FORCE_RESET() (RCC->AHB2RSTR |= (RCC_AHB2RSTR_CRYPRST)) +#define __HAL_RCC_HASH_FORCE_RESET() (RCC->AHB2RSTR |= (RCC_AHB2RSTR_HASHRST)) + +#define __HAL_RCC_CRYP_RELEASE_RESET() (RCC->AHB2RSTR &= ~(RCC_AHB2RSTR_CRYPRST)) +#define __HAL_RCC_HASH_RELEASE_RESET() (RCC->AHB2RSTR &= ~(RCC_AHB2RSTR_HASHRST)) +#endif /* STM32F437xx || STM32F439xx */ + +/** @brief Force or release AHB3 peripheral reset + */ +#define __HAL_RCC_FMC_FORCE_RESET() (RCC->AHB3RSTR |= (RCC_AHB3RSTR_FMCRST)) +#define __HAL_RCC_FMC_RELEASE_RESET() (RCC->AHB3RSTR &= ~(RCC_AHB3RSTR_FMCRST)) + +/** @brief Force or release APB1 peripheral reset. + */ +#define __HAL_RCC_TIM6_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM6RST)) +#define __HAL_RCC_TIM7_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM7RST)) +#define __HAL_RCC_TIM12_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM12RST)) +#define __HAL_RCC_TIM13_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM13RST)) +#define __HAL_RCC_TIM14_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM14RST)) +#define __HAL_RCC_USART3_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_USART3RST)) +#define __HAL_RCC_UART4_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_UART4RST)) +#define __HAL_RCC_UART5_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_UART5RST)) +#define __HAL_RCC_CAN1_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_CAN1RST)) +#define __HAL_RCC_CAN2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_CAN2RST)) +#define __HAL_RCC_DAC_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_DACRST)) +#define __HAL_RCC_UART7_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_UART7RST)) +#define __HAL_RCC_UART8_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_UART8RST)) + +#define __HAL_RCC_TIM6_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM6RST)) +#define __HAL_RCC_TIM7_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM7RST)) +#define __HAL_RCC_TIM12_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM12RST)) +#define __HAL_RCC_TIM13_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM13RST)) +#define __HAL_RCC_TIM14_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM14RST)) +#define __HAL_RCC_USART3_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USART3RST)) +#define __HAL_RCC_UART4_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_UART4RST)) +#define __HAL_RCC_UART5_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_UART5RST)) +#define __HAL_RCC_CAN1_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_CAN1RST)) +#define __HAL_RCC_CAN2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_CAN2RST)) +#define __HAL_RCC_DAC_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_DACRST)) +#define __HAL_RCC_UART7_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_UART7RST)) +#define __HAL_RCC_UART8_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_UART8RST)) + +/** @brief Force or release APB2 peripheral reset. + */ +#define __HAL_RCC_TIM8_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM8RST)) +#define __HAL_RCC_SPI5_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_SPI5RST)) +#define __HAL_RCC_SPI6_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_SPI6RST)) +#define __HAL_RCC_SAI1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_SAI1RST)) + +#define __HAL_RCC_TIM8_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM8RST)) +#define __HAL_RCC_SPI5_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_SPI5RST)) +#define __HAL_RCC_SPI6_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_SPI6RST)) +#define __HAL_RCC_SAI1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_SAI1RST)) + +#if defined(STM32F429xx)|| defined(STM32F439xx) +#define __HAL_RCC_LTDC_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_LTDCRST)) +#define __HAL_RCC_LTDC_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_LTDCRST)) +#endif /* STM32F429xx|| STM32F439xx */ + +/** @brief Enable or disable the AHB1 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + */ +#define __HAL_RCC_GPIOF_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_GPIOFLPEN)) +#define __HAL_RCC_GPIOG_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_GPIOGLPEN)) +#define __HAL_RCC_GPIOI_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_GPIOILPEN)) +#define __HAL_RCC_SRAM2_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_SRAM2LPEN)) +#define __HAL_RCC_ETHMAC_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_ETHMACLPEN)) +#define __HAL_RCC_ETHMACTX_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_ETHMACTXLPEN)) +#define __HAL_RCC_ETHMACRX_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_ETHMACRXLPEN)) +#define __HAL_RCC_ETHMACPTP_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_ETHMACPTPLPEN)) +#define __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_OTGHSLPEN)) +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_OTGHSULPILPEN)) +#define __HAL_RCC_GPIOJ_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_GPIOJLPEN)) +#define __HAL_RCC_GPIOK_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_GPIOKLPEN)) +#define __HAL_RCC_SRAM3_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_SRAM3LPEN)) +#define __HAL_RCC_DMA2D_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_DMA2DLPEN)) + +#define __HAL_RCC_GPIOF_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_GPIOFLPEN)) +#define __HAL_RCC_GPIOG_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_GPIOGLPEN)) +#define __HAL_RCC_GPIOI_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_GPIOILPEN)) +#define __HAL_RCC_SRAM2_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_SRAM2LPEN)) +#define __HAL_RCC_ETHMAC_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_ETHMACLPEN)) +#define __HAL_RCC_ETHMACTX_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_ETHMACTXLPEN)) +#define __HAL_RCC_ETHMACRX_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_ETHMACRXLPEN)) +#define __HAL_RCC_ETHMACPTP_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_ETHMACPTPLPEN)) +#define __HAL_RCC_USB_OTG_HS_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_OTGHSLPEN)) +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_OTGHSULPILPEN)) +#define __HAL_RCC_GPIOJ_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_GPIOJLPEN)) +#define __HAL_RCC_GPIOK_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_GPIOKLPEN)) +#define __HAL_RCC_DMA2D_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_DMA2DLPEN)) + +/** @brief Enable or disable the AHB2 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + */ +#define __HAL_RCC_DCMI_CLK_SLEEP_ENABLE() (RCC->AHB2LPENR |= (RCC_AHB2LPENR_DCMILPEN)) +#define __HAL_RCC_DCMI_CLK_SLEEP_DISABLE() (RCC->AHB2LPENR &= ~(RCC_AHB2LPENR_DCMILPEN)) + +#if defined(STM32F437xx)|| defined(STM32F439xx) +#define __HAL_RCC_CRYP_CLK_SLEEP_ENABLE() (RCC->AHB2LPENR |= (RCC_AHB2LPENR_CRYPLPEN)) +#define __HAL_RCC_HASH_CLK_SLEEP_ENABLE() (RCC->AHB2LPENR |= (RCC_AHB2LPENR_HASHLPEN)) + +#define __HAL_RCC_CRYP_CLK_SLEEP_DISABLE() (RCC->AHB2LPENR &= ~(RCC_AHB2LPENR_CRYPLPEN)) +#define __HAL_RCC_HASH_CLK_SLEEP_DISABLE() (RCC->AHB2LPENR &= ~(RCC_AHB2LPENR_HASHLPEN)) +#endif /* STM32F437xx || STM32F439xx */ + +/** @brief Enable or disable the AHB3 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + */ +#define __HAL_RCC_FMC_CLK_SLEEP_ENABLE() (RCC->AHB3LPENR |= (RCC_AHB3LPENR_FMCLPEN)) +#define __HAL_RCC_FMC_CLK_SLEEP_DISABLE() (RCC->AHB3LPENR &= ~(RCC_AHB3LPENR_FMCLPEN)) + +/** @brief Enable or disable the APB1 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + */ +#define __HAL_RCC_TIM6_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM6LPEN)) +#define __HAL_RCC_TIM7_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM7LPEN)) +#define __HAL_RCC_TIM12_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM12LPEN)) +#define __HAL_RCC_TIM13_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM13LPEN)) +#define __HAL_RCC_TIM14_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM14LPEN)) +#define __HAL_RCC_USART3_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_USART3LPEN)) +#define __HAL_RCC_UART4_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_UART4LPEN)) +#define __HAL_RCC_UART5_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_UART5LPEN)) +#define __HAL_RCC_CAN1_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_CAN1LPEN)) +#define __HAL_RCC_CAN2_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_CAN2LPEN)) +#define __HAL_RCC_DAC_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_DACLPEN)) +#define __HAL_RCC_UART7_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_UART7LPEN)) +#define __HAL_RCC_UART8_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_UART8LPEN)) + +#define __HAL_RCC_TIM6_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM6LPEN)) +#define __HAL_RCC_TIM7_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM7LPEN)) +#define __HAL_RCC_TIM12_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM12LPEN)) +#define __HAL_RCC_TIM13_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM13LPEN)) +#define __HAL_RCC_TIM14_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM14LPEN)) +#define __HAL_RCC_USART3_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_USART3LPEN)) +#define __HAL_RCC_UART4_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_UART4LPEN)) +#define __HAL_RCC_UART5_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_UART5LPEN)) +#define __HAL_RCC_CAN1_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_CAN1LPEN)) +#define __HAL_RCC_CAN2_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_CAN2LPEN)) +#define __HAL_RCC_DAC_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_DACLPEN)) +#define __HAL_RCC_UART7_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_UART7LPEN)) +#define __HAL_RCC_UART8_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_UART8LPEN)) + +/** @brief Enable or disable the APB2 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + */ +#define __HAL_RCC_TIM8_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_TIM8LPEN)) +#define __HAL_RCC_ADC2_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_ADC2LPEN)) +#define __HAL_RCC_ADC3_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_ADC3LPEN)) +#define __HAL_RCC_SPI5_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_SPI5LPEN)) +#define __HAL_RCC_SPI6_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_SPI6LPEN)) +#define __HAL_RCC_SAI1_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_SAI1LPEN)) + +#define __HAL_RCC_TIM8_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_TIM8LPEN)) +#define __HAL_RCC_ADC2_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_ADC2LPEN)) +#define __HAL_RCC_ADC3_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_ADC3LPEN)) +#define __HAL_RCC_SPI5_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_SPI5LPEN)) +#define __HAL_RCC_SPI6_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_SPI6LPEN)) +#define __HAL_RCC_SAI1_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_SAI1LPEN)) + +#if defined(STM32F429xx)|| defined(STM32F439xx) +#define __HAL_RCC_LTDC_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_LTDCLPEN)) + +#define __HAL_RCC_LTDC_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_LTDCLPEN)) +#endif /* STM32F429xx || STM32F439xx */ + +#endif /* STM32F427xx || STM32F437xx || STM32F429xx|| STM32F439xx */ +/*---------------------------------------------------------------------------------------------*/ + +/*----------------------------------- STM32F40xxx/STM32F41xxx----------------------------------*/ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) +/** @brief Enables or disables the AHB1 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#define __HAL_RCC_GPIOI_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOIEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOIEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_GPIOF_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOFEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOFEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_GPIOG_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOGEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOGEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_USB_OTG_HS_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGHSEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGHSEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGHSULPIEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGHSULPIEN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOF_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOFEN)) +#define __HAL_RCC_GPIOG_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOGEN)) +#define __HAL_RCC_GPIOI_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOIEN)) +#define __HAL_RCC_USB_OTG_HS_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_OTGHSEN)) +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_OTGHSULPIEN)) + +#if defined(STM32F407xx)|| defined(STM32F417xx) +/** + * @brief Enable ETHERNET clock. + */ +#define __HAL_RCC_ETHMAC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHMACEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHMACEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_ETHMACTX_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHMACTXEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHMACTXEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_ETHMACRX_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHMACRXEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHMACRXEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_ETHMACPTP_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHMACPTPEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ETHMACPTPEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_ETH_CLK_ENABLE() do { \ + __HAL_RCC_ETHMAC_CLK_ENABLE(); \ + __HAL_RCC_ETHMACTX_CLK_ENABLE(); \ + __HAL_RCC_ETHMACRX_CLK_ENABLE(); \ + } while(0) + +/** + * @brief Disable ETHERNET clock. + */ +#define __HAL_RCC_ETHMAC_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_ETHMACEN)) +#define __HAL_RCC_ETHMACTX_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_ETHMACTXEN)) +#define __HAL_RCC_ETHMACRX_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_ETHMACRXEN)) +#define __HAL_RCC_ETHMACPTP_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_ETHMACPTPEN)) +#define __HAL_RCC_ETH_CLK_DISABLE() do { \ + __HAL_RCC_ETHMACTX_CLK_DISABLE(); \ + __HAL_RCC_ETHMACRX_CLK_DISABLE(); \ + __HAL_RCC_ETHMAC_CLK_DISABLE(); \ + } while(0) +#endif /* STM32F407xx || STM32F417xx */ + +/** @brief Enable or disable the AHB2 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#if defined(STM32F407xx)|| defined(STM32F417xx) +#define __HAL_RCC_DCMI_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_DCMIEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_DCMIEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_DCMI_CLK_DISABLE() (RCC->AHB2ENR &= ~(RCC_AHB2ENR_DCMIEN)) +#endif /* STM32F407xx || STM32F417xx */ + +#if defined(STM32F415xx) || defined(STM32F417xx) +#define __HAL_RCC_CRYP_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_CRYPEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_CRYPEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_HASH_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_HASHEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_HASHEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_CRYP_CLK_DISABLE() (RCC->AHB2ENR &= ~(RCC_AHB2ENR_CRYPEN)) +#define __HAL_RCC_HASH_CLK_DISABLE() (RCC->AHB2ENR &= ~(RCC_AHB2ENR_HASHEN)) +#endif /* STM32F415xx || STM32F417xx */ + +/** @brief Enables or disables the AHB3 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#define __HAL_RCC_FSMC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_FSMC_CLK_DISABLE() (RCC->AHB3ENR &= ~(RCC_AHB3ENR_FSMCEN)) + +/** @brief Enable or disable the Low Speed APB (APB1) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#define __HAL_RCC_TIM6_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM6EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM6EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM7_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM7EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM7EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM12_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM12EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM12EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM13_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM13EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM13EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM14_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM14EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM14EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_USART3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USART3EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART3EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_UART4_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_UART4EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_UART4EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_UART5_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_UART5EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_UART5EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_CAN1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_CAN1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_CAN1EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_CAN2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_CAN2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_CAN2EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_DAC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_DACEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_DACEN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM6_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM6EN)) +#define __HAL_RCC_TIM7_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM7EN)) +#define __HAL_RCC_TIM12_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM12EN)) +#define __HAL_RCC_TIM13_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM13EN)) +#define __HAL_RCC_TIM14_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM14EN)) +#define __HAL_RCC_USART3_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART3EN)) +#define __HAL_RCC_UART4_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_UART4EN)) +#define __HAL_RCC_UART5_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_UART5EN)) +#define __HAL_RCC_CAN1_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_CAN1EN)) +#define __HAL_RCC_CAN2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_CAN2EN)) +#define __HAL_RCC_DAC_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_DACEN)) + +/** @brief Enable or disable the High Speed APB (APB2) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#define __HAL_RCC_TIM8_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM8EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM8EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_ADC2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC2EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_ADC3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC3EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC3EN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM8_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM8EN)) +#define __HAL_RCC_ADC2_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_ADC2EN)) +#define __HAL_RCC_ADC3_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_ADC3EN)) + +/** @brief Force or release AHB1 peripheral reset. + */ +#define __HAL_RCC_GPIOF_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_GPIOFRST)) +#define __HAL_RCC_GPIOG_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_GPIOGRST)) +#define __HAL_RCC_GPIOI_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_GPIOIRST)) +#define __HAL_RCC_ETHMAC_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_ETHMACRST)) +#define __HAL_RCC_USB_OTG_HS_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_OTGHRST)) + +#define __HAL_RCC_GPIOF_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOFRST)) +#define __HAL_RCC_GPIOG_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOGRST)) +#define __HAL_RCC_GPIOI_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOIRST)) +#define __HAL_RCC_ETHMAC_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_ETHMACRST)) +#define __HAL_RCC_USB_OTG_HS_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_OTGHRST)) + +/** @brief Force or release AHB2 peripheral reset. + */ +#if defined(STM32F407xx)|| defined(STM32F417xx) +#define __HAL_RCC_DCMI_FORCE_RESET() (RCC->AHB2RSTR |= (RCC_AHB2RSTR_DCMIRST)) +#define __HAL_RCC_DCMI_RELEASE_RESET() (RCC->AHB2RSTR &= ~(RCC_AHB2RSTR_DCMIRST)) +#endif /* STM32F407xx || STM32F417xx */ + +#if defined(STM32F415xx) || defined(STM32F417xx) +#define __HAL_RCC_CRYP_FORCE_RESET() (RCC->AHB2RSTR |= (RCC_AHB2RSTR_CRYPRST)) +#define __HAL_RCC_HASH_FORCE_RESET() (RCC->AHB2RSTR |= (RCC_AHB2RSTR_HASHRST)) + +#define __HAL_RCC_CRYP_RELEASE_RESET() (RCC->AHB2RSTR &= ~(RCC_AHB2RSTR_CRYPRST)) +#define __HAL_RCC_HASH_RELEASE_RESET() (RCC->AHB2RSTR &= ~(RCC_AHB2RSTR_HASHRST)) + +#endif /* STM32F415xx || STM32F417xx */ + +/** @brief Force or release AHB3 peripheral reset + */ +#define __HAL_RCC_FSMC_FORCE_RESET() (RCC->AHB3RSTR |= (RCC_AHB3RSTR_FSMCRST)) +#define __HAL_RCC_FSMC_RELEASE_RESET() (RCC->AHB3RSTR &= ~(RCC_AHB3RSTR_FSMCRST)) + +/** @brief Force or release APB1 peripheral reset. + */ +#define __HAL_RCC_TIM6_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM6RST)) +#define __HAL_RCC_TIM7_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM7RST)) +#define __HAL_RCC_TIM12_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM12RST)) +#define __HAL_RCC_TIM13_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM13RST)) +#define __HAL_RCC_TIM14_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM14RST)) +#define __HAL_RCC_USART3_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_USART3RST)) +#define __HAL_RCC_UART4_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_UART4RST)) +#define __HAL_RCC_UART5_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_UART5RST)) +#define __HAL_RCC_CAN1_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_CAN1RST)) +#define __HAL_RCC_CAN2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_CAN2RST)) +#define __HAL_RCC_DAC_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_DACRST)) + +#define __HAL_RCC_TIM6_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM6RST)) +#define __HAL_RCC_TIM7_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM7RST)) +#define __HAL_RCC_TIM12_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM12RST)) +#define __HAL_RCC_TIM13_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM13RST)) +#define __HAL_RCC_TIM14_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM14RST)) +#define __HAL_RCC_USART3_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USART3RST)) +#define __HAL_RCC_UART4_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_UART4RST)) +#define __HAL_RCC_UART5_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_UART5RST)) +#define __HAL_RCC_CAN1_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_CAN1RST)) +#define __HAL_RCC_CAN2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_CAN2RST)) +#define __HAL_RCC_DAC_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_DACRST)) + +/** @brief Force or release APB2 peripheral reset. + */ +#define __HAL_RCC_TIM8_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM8RST)) +#define __HAL_RCC_TIM8_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM8RST)) + +/** @brief Enable or disable the AHB1 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + */ +#define __HAL_RCC_GPIOF_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_GPIOFLPEN)) +#define __HAL_RCC_GPIOG_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_GPIOGLPEN)) +#define __HAL_RCC_GPIOI_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_GPIOILPEN)) +#define __HAL_RCC_SRAM2_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_SRAM2LPEN)) +#define __HAL_RCC_ETHMAC_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_ETHMACLPEN)) +#define __HAL_RCC_ETHMACTX_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_ETHMACTXLPEN)) +#define __HAL_RCC_ETHMACRX_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_ETHMACRXLPEN)) +#define __HAL_RCC_ETHMACPTP_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_ETHMACPTPLPEN)) +#define __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_OTGHSLPEN)) +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_OTGHSULPILPEN)) + +#define __HAL_RCC_GPIOF_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_GPIOFLPEN)) +#define __HAL_RCC_GPIOG_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_GPIOGLPEN)) +#define __HAL_RCC_GPIOI_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_GPIOILPEN)) +#define __HAL_RCC_SRAM2_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_SRAM2LPEN)) +#define __HAL_RCC_ETHMAC_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_ETHMACLPEN)) +#define __HAL_RCC_ETHMACTX_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_ETHMACTXLPEN)) +#define __HAL_RCC_ETHMACRX_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_ETHMACRXLPEN)) +#define __HAL_RCC_ETHMACPTP_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_ETHMACPTPLPEN)) +#define __HAL_RCC_USB_OTG_HS_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_OTGHSLPEN)) +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_OTGHSULPILPEN)) + +/** @brief Enable or disable the AHB2 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + */ +#if defined(STM32F407xx)|| defined(STM32F417xx) +#define __HAL_RCC_DCMI_CLK_SLEEP_ENABLE() (RCC->AHB2LPENR |= (RCC_AHB2LPENR_DCMILPEN)) +#define __HAL_RCC_DCMI_CLK_SLEEP_DISABLE() (RCC->AHB2LPENR &= ~(RCC_AHB2LPENR_DCMILPEN)) +#endif /* STM32F407xx || STM32F417xx */ + +#if defined(STM32F415xx) || defined(STM32F417xx) +#define __HAL_RCC_CRYP_CLK_SLEEP_ENABLE() (RCC->AHB2LPENR |= (RCC_AHB2LPENR_CRYPLPEN)) +#define __HAL_RCC_HASH_CLK_SLEEP_ENABLE() (RCC->AHB2LPENR |= (RCC_AHB2LPENR_HASHLPEN)) + +#define __HAL_RCC_CRYP_CLK_SLEEP_DISABLE() (RCC->AHB2LPENR &= ~(RCC_AHB2LPENR_CRYPLPEN)) +#define __HAL_RCC_HASH_CLK_SLEEP_DISABLE() (RCC->AHB2LPENR &= ~(RCC_AHB2LPENR_HASHLPEN)) +#endif /* STM32F415xx || STM32F417xx */ + +/** @brief Enable or disable the AHB3 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + */ +#define __HAL_RCC_FSMC_CLK_SLEEP_ENABLE() (RCC->AHB3LPENR |= (RCC_AHB3LPENR_FSMCLPEN)) +#define __HAL_RCC_FSMC_CLK_SLEEP_DISABLE() (RCC->AHB3LPENR &= ~(RCC_AHB3LPENR_FSMCLPEN)) + +/** @brief Enable or disable the APB1 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + */ +#define __HAL_RCC_TIM6_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM6LPEN)) +#define __HAL_RCC_TIM7_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM7LPEN)) +#define __HAL_RCC_TIM12_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM12LPEN)) +#define __HAL_RCC_TIM13_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM13LPEN)) +#define __HAL_RCC_TIM14_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM14LPEN)) +#define __HAL_RCC_USART3_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_USART3LPEN)) +#define __HAL_RCC_UART4_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_UART4LPEN)) +#define __HAL_RCC_UART5_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_UART5LPEN)) +#define __HAL_RCC_CAN1_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_CAN1LPEN)) +#define __HAL_RCC_CAN2_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_CAN2LPEN)) +#define __HAL_RCC_DAC_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_DACLPEN)) + +#define __HAL_RCC_TIM6_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM6LPEN)) +#define __HAL_RCC_TIM7_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM7LPEN)) +#define __HAL_RCC_TIM12_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM12LPEN)) +#define __HAL_RCC_TIM13_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM13LPEN)) +#define __HAL_RCC_TIM14_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM14LPEN)) +#define __HAL_RCC_USART3_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_USART3LPEN)) +#define __HAL_RCC_UART4_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_UART4LPEN)) +#define __HAL_RCC_UART5_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_UART5LPEN)) +#define __HAL_RCC_CAN1_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_CAN1LPEN)) +#define __HAL_RCC_CAN2_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_CAN2LPEN)) +#define __HAL_RCC_DAC_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_DACLPEN)) + +/** @brief Enable or disable the APB2 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + */ +#define __HAL_RCC_TIM8_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_TIM8LPEN)) +#define __HAL_RCC_ADC2_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_ADC2LPEN)) +#define __HAL_RCC_ADC3_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_ADC3LPEN)) + +#define __HAL_RCC_TIM8_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_TIM8LPEN)) +#define __HAL_RCC_ADC2_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_ADC2LPEN)) +#define __HAL_RCC_ADC3_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_ADC3LPEN)) +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */ +/*---------------------------------------------------------------------------------------------*/ + +/*------------------------------------------ STM32F411xx --------------------------------------*/ +#if defined(STM32F411xE) +/** @brief Enable or disable the High Speed APB (APB2) peripheral clock. + */ +#define __HAL_RCC_SPI5_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI5EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI5EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_SPI5_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_SPI5EN)) + +/** @brief Force or release APB2 peripheral reset. + */ +#define __HAL_RCC_SPI5_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_SPI5RST)) +#define __HAL_RCC_SPI5_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_SPI5RST)) + +/** @brief Enable or disable the APB2 peripheral clock during Low Power (Sleep) mode. + */ +#define __HAL_RCC_SPI5_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_SPI5LPEN)) +#define __HAL_RCC_SPI5_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_SPI5LPEN)) + +#endif /* STM32F411xE */ +/*---------------------------------------------------------------------------------------------*/ + +/*----------------------------------------- STM32F446xx ---------------------------------------*/ +#if defined(STM32F446xx) +/** @brief Enables or disables the AHB1 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#define __HAL_RCC_GPIOF_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOFEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOFEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_GPIOG_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOGEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOGEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_USB_OTG_HS_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGHSEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGHSEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGHSULPIEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_OTGHSULPIEN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_GPIOF_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOFEN)) +#define __HAL_RCC_GPIOG_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOGEN)) +#define __HAL_RCC_USB_OTG_HS_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_OTGHSEN)) +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_OTGHSULPIEN)) + +/** @brief Enable or disable the AHB2 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#define __HAL_RCC_DCMI_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_DCMIEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_DCMIEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_DCMI_CLK_DISABLE() (RCC->AHB2ENR &= ~(RCC_AHB2ENR_DCMIEN)) + +/** @brief Enables or disables the AHB3 peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#define __HAL_RCC_FMC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_QSPI_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->AHB3ENR, RCC_AHB3ENR_QSPIEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_QSPIEN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_FMC_CLK_DISABLE() (RCC->AHB3ENR &= ~(RCC_AHB3ENR_FMCEN)) +#define __HAL_RCC_QSPI_CLK_DISABLE() (RCC->AHB3ENR &= ~(RCC_AHB3ENR_QSPIEN)) + +/** @brief Enable or disable the Low Speed APB (APB1) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#define __HAL_RCC_TIM6_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM6EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM6EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM7_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM7EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM7EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM12_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM12EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM12EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM13_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM13EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM13EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_TIM14_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM14EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM14EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_SPDIFRX_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_SPDIFRXEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_SPDIFRXEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_USART3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USART3EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_USART3EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_UART4_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_UART4EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_UART4EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_UART5_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_UART5EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_UART5EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_FMPI2C1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_FMPI2C1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_FMPI2C1EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_CAN1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_CAN1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_CAN1EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_CAN2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_CAN2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_CAN2EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_CEC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_CECEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_CECEN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_DAC_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB1ENR, RCC_APB1ENR_DACEN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_DACEN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM6_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM6EN)) +#define __HAL_RCC_TIM7_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM7EN)) +#define __HAL_RCC_TIM12_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM12EN)) +#define __HAL_RCC_TIM13_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM13EN)) +#define __HAL_RCC_TIM14_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_TIM14EN)) +#define __HAL_RCC_SPDIFRX_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_SPDIFRXEN)) +#define __HAL_RCC_USART3_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_USART3EN)) +#define __HAL_RCC_UART4_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_UART4EN)) +#define __HAL_RCC_UART5_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_UART5EN)) +#define __HAL_RCC_FMPI2C1_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_FMPI2C1EN)) +#define __HAL_RCC_CAN1_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_CAN1EN)) +#define __HAL_RCC_CAN2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_CAN2EN)) +#define __HAL_RCC_CEC_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_CECEN)) +#define __HAL_RCC_DAC_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_DACEN)) + +/** @brief Enable or disable the High Speed APB (APB2) peripheral clock. + * @note After reset, the peripheral clock (used for registers read/write access) + * is disabled and the application software has to enable this clock before + * using it. + */ +#define __HAL_RCC_TIM8_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM8EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM8EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_ADC2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC2EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_ADC3_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC3EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC3EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_SAI1_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI1EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI1EN);\ + UNUSED(tmpreg); \ + } while(0) +#define __HAL_RCC_SAI2_CLK_ENABLE() do { \ + __IO uint32_t tmpreg; \ + SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI2EN);\ + /* Delay after an RCC peripheral clock enabling */ \ + tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SAI2EN);\ + UNUSED(tmpreg); \ + } while(0) + +#define __HAL_RCC_TIM8_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM8EN)) +#define __HAL_RCC_ADC2_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_ADC2EN)) +#define __HAL_RCC_ADC3_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_ADC3EN)) +#define __HAL_RCC_SAI1_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_SAI1EN)) +#define __HAL_RCC_SAI2_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_SAI2EN)) + +/** @brief Force or release AHB1 peripheral reset. + */ +#define __HAL_RCC_GPIOF_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_GPIOFRST)) +#define __HAL_RCC_GPIOG_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_GPIOGRST)) +#define __HAL_RCC_USB_OTG_HS_FORCE_RESET() (RCC->AHB1RSTR |= (RCC_AHB1RSTR_OTGHRST)) + +#define __HAL_RCC_GPIOF_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOFRST)) +#define __HAL_RCC_GPIOG_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIOGRST)) +#define __HAL_RCC_USB_OTG_HS_RELEASE_RESET() (RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_OTGHRST)) + +/** @brief Force or release AHB2 peripheral reset. + */ +#define __HAL_RCC_DCMI_FORCE_RESET() (RCC->AHB2RSTR |= (RCC_AHB2RSTR_DCMIRST)) +#define __HAL_RCC_DCMI_RELEASE_RESET() (RCC->AHB2RSTR &= ~(RCC_AHB2RSTR_DCMIRST)) + +/** @brief Force or release AHB3 peripheral reset + */ +#define __HAL_RCC_FMC_FORCE_RESET() (RCC->AHB3RSTR |= (RCC_AHB3RSTR_FMCRST)) +#define __HAL_RCC_QSPI_FORCE_RESET() (RCC->AHB3RSTR |= (RCC_AHB3RSTR_QSPIRST)) + +#define __HAL_RCC_FMC_RELEASE_RESET() (RCC->AHB3RSTR &= ~(RCC_AHB3RSTR_FMCRST)) +#define __HAL_RCC_QSPI_RELEASE_RESET() (RCC->AHB3RSTR &= ~(RCC_AHB3RSTR_QSPIRST)) + +/** @brief Force or release APB1 peripheral reset. + */ +#define __HAL_RCC_TIM6_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM6RST)) +#define __HAL_RCC_TIM7_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM7RST)) +#define __HAL_RCC_TIM12_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM12RST)) +#define __HAL_RCC_TIM13_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM13RST)) +#define __HAL_RCC_TIM14_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_TIM14RST)) +#define __HAL_RCC_SPDIFRX_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_SPDIFRXRST)) +#define __HAL_RCC_USART3_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_USART3RST)) +#define __HAL_RCC_UART4_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_UART4RST)) +#define __HAL_RCC_UART5_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_UART5RST)) +#define __HAL_RCC_FMPI2C1_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_FMPI2C1RST)) +#define __HAL_RCC_CAN1_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_CAN1RST)) +#define __HAL_RCC_CAN2_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_CAN2RST)) +#define __HAL_RCC_CEC_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_CECRST)) +#define __HAL_RCC_DAC_FORCE_RESET() (RCC->APB1RSTR |= (RCC_APB1RSTR_DACRST)) + +#define __HAL_RCC_TIM6_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM6RST)) +#define __HAL_RCC_TIM7_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM7RST)) +#define __HAL_RCC_TIM12_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM12RST)) +#define __HAL_RCC_TIM13_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM13RST)) +#define __HAL_RCC_TIM14_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM14RST)) +#define __HAL_RCC_SPDIFRX_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_SPDIFRXRST)) +#define __HAL_RCC_USART3_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_USART3RST)) +#define __HAL_RCC_UART4_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_UART4RST)) +#define __HAL_RCC_UART5_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_UART5RST)) +#define __HAL_RCC_FMPI2C1_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_FMPI2C1RST)) +#define __HAL_RCC_CAN1_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_CAN1RST)) +#define __HAL_RCC_CAN2_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_CAN2RST)) +#define __HAL_RCC_CEC_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_CECRST)) +#define __HAL_RCC_DAC_RELEASE_RESET() (RCC->APB1RSTR &= ~(RCC_APB1RSTR_DACRST)) + +/** @brief Force or release APB2 peripheral reset. + */ +#define __HAL_RCC_TIM8_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_TIM8RST)) +#define __HAL_RCC_SAI1_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_SAI1RST)) +#define __HAL_RCC_SAI2_FORCE_RESET() (RCC->APB2RSTR |= (RCC_APB2RSTR_SAI2RST)) + +#define __HAL_RCC_TIM8_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_TIM8RST)) +#define __HAL_RCC_SAI1_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_SAI1RST)) +#define __HAL_RCC_SAI2_RELEASE_RESET() (RCC->APB2RSTR &= ~(RCC_APB2RSTR_SAI2RST)) + +/** @brief Enable or disable the AHB1 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + */ +#define __HAL_RCC_GPIOF_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_GPIOFLPEN)) +#define __HAL_RCC_GPIOG_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_GPIOGLPEN)) +#define __HAL_RCC_SRAM2_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_SRAM2LPEN)) +#define __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_OTGHSLPEN)) +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE() (RCC->AHB1LPENR |= (RCC_AHB1LPENR_OTGHSULPILPEN)) + +#define __HAL_RCC_GPIOF_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_GPIOFLPEN)) +#define __HAL_RCC_GPIOG_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_GPIOGLPEN)) +#define __HAL_RCC_SRAM2_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_SRAM2LPEN)) +#define __HAL_RCC_USB_OTG_HS_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_OTGHSLPEN)) +#define __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE() (RCC->AHB1LPENR &= ~(RCC_AHB1LPENR_OTGHSULPILPEN)) +/** @brief Enable or disable the AHB2 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + */ +#define __HAL_RCC_DCMI_CLK_SLEEP_ENABLE() (RCC->AHB2LPENR |= (RCC_AHB2LPENR_DCMILPEN)) +#define __HAL_RCC_DCMI_CLK_SLEEP_DISABLE() (RCC->AHB2LPENR &= ~(RCC_AHB2LPENR_DCMILPEN)) + +/** @brief Enable or disable the AHB3 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + */ +#define __HAL_RCC_FMC_CLK_SLEEP_ENABLE() (RCC->AHB3LPENR |= (RCC_AHB3LPENR_FMCLPEN)) +#define __HAL_RCC_QSPI_CLK_SLEEP_ENABLE() (RCC->AHB3LPENR |= (RCC_AHB3LPENR_QSPILPEN)) + +#define __HAL_RCC_FMC_CLK_SLEEP_DISABLE() (RCC->AHB3LPENR &= ~(RCC_AHB3LPENR_FMCLPEN)) +#define __HAL_RCC_QSPI_CLK_SLEEP_DISABLE() (RCC->AHB3LPENR &= ~(RCC_AHB3LPENR_QSPILPEN)) + +/** @brief Enable or disable the APB1 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + */ +#define __HAL_RCC_TIM6_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM6LPEN)) +#define __HAL_RCC_TIM7_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM7LPEN)) +#define __HAL_RCC_TIM12_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM12LPEN)) +#define __HAL_RCC_TIM13_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM13LPEN)) +#define __HAL_RCC_TIM14_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_TIM14LPEN)) +#define __HAL_RCC_SPDIFRX_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_SPDIFRXLPEN)) +#define __HAL_RCC_USART3_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_USART3LPEN)) +#define __HAL_RCC_UART4_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_UART4LPEN)) +#define __HAL_RCC_UART5_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_UART5LPEN)) +#define __HAL_RCC_FMPI2C1_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_FMPI2C1LPEN)) +#define __HAL_RCC_CAN1_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_CAN1LPEN)) +#define __HAL_RCC_CAN2_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_CAN2LPEN)) +#define __HAL_RCC_CEC_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_CECLPEN)) +#define __HAL_RCC_DAC_CLK_SLEEP_ENABLE() (RCC->APB1LPENR |= (RCC_APB1LPENR_DACLPEN)) + +#define __HAL_RCC_TIM6_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM6LPEN)) +#define __HAL_RCC_TIM7_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM7LPEN)) +#define __HAL_RCC_TIM12_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM12LPEN)) +#define __HAL_RCC_TIM13_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM13LPEN)) +#define __HAL_RCC_TIM14_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_TIM14LPEN)) +#define __HAL_RCC_SPDIFRX_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_SPDIFRXLPEN)) +#define __HAL_RCC_USART3_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_USART3LPEN)) +#define __HAL_RCC_UART4_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_UART4LPEN)) +#define __HAL_RCC_UART5_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_UART5LPEN)) +#define __HAL_RCC_FMPI2C1_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_FMPI2C1LPEN)) +#define __HAL_RCC_CAN1_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_CAN1LPEN)) +#define __HAL_RCC_CAN2_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_CAN2LPEN)) +#define __HAL_RCC_CEC_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_CECLPEN)) +#define __HAL_RCC_DAC_CLK_SLEEP_DISABLE() (RCC->APB1LPENR &= ~(RCC_APB1LPENR_DACLPEN)) + +/** @brief Enable or disable the APB2 peripheral clock during Low Power (Sleep) mode. + * @note Peripheral clock gating in SLEEP mode can be used to further reduce + * power consumption. + * @note After wakeup from SLEEP mode, the peripheral clock is enabled again. + * @note By default, all peripheral clocks are enabled during SLEEP mode. + */ +#define __HAL_RCC_TIM8_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_TIM8LPEN)) +#define __HAL_RCC_ADC2_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_ADC2LPEN)) +#define __HAL_RCC_ADC3_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_ADC3LPEN)) +#define __HAL_RCC_SAI1_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_SAI1LPEN)) +#define __HAL_RCC_SAI2_CLK_SLEEP_ENABLE() (RCC->APB2LPENR |= (RCC_APB2LPENR_SAI2LPEN)) + +#define __HAL_RCC_TIM8_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_TIM8LPEN)) +#define __HAL_RCC_ADC2_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_ADC2LPEN)) +#define __HAL_RCC_ADC3_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_ADC3LPEN)) +#define __HAL_RCC_SAI1_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_SAI1LPEN)) +#define __HAL_RCC_SAI2_CLK_SLEEP_DISABLE() (RCC->APB2LPENR &= ~(RCC_APB2LPENR_SAI2LPEN)) + +#endif /* STM32F446xx */ +/*------------------------------------------------------------------------------------------------------------*/ + +/*------------------------------------------------- PLL Configuration ----------------------------------------*/ +#if defined(STM32F446xx) +/** @brief Macro to configure the main PLL clock source, multiplication and division factors. + * @note This function must be used only when the main PLL is disabled. + * @param __RCC_PLLSource__: specifies the PLL entry clock source. + * This parameter can be one of the following values: + * @arg RCC_PLLSOURCE_HSI: HSI oscillator clock selected as PLL clock entry + * @arg RCC_PLLSOURCE_HSE: HSE oscillator clock selected as PLL clock entry + * @note This clock source (RCC_PLLSource) is common for the main PLL and PLLI2S. + * @param __PLLM__: specifies the division factor for PLL VCO input clock + * This parameter must be a number between Min_Data = 2 and Max_Data = 63. + * @note You have to set the PLLM parameter correctly to ensure that the VCO input + * frequency ranges from 1 to 2 MHz. It is recommended to select a frequency + * of 2 MHz to limit PLL jitter. + * @param __PLLN__: specifies the multiplication factor for PLL VCO output clock + * This parameter must be a number between Min_Data = 192 and Max_Data = 432. + * @note You have to set the PLLN parameter correctly to ensure that the VCO + * output frequency is between 192 and 432 MHz. + * + * @param __PLLP__: specifies the division factor for main system clock (SYSCLK) + * This parameter must be a number in the range {2, 4, 6, or 8}. + * + * @param __PLLQ__: specifies the division factor for OTG FS, SDIO and RNG clocks + * This parameter must be a number between Min_Data = 2 and Max_Data = 15. + * @note If the USB OTG FS is used in your application, you have to set the + * PLLQ parameter correctly to have 48 MHz clock for the USB. However, + * the SDIO and RNG need a frequency lower than or equal to 48 MHz to work + * correctly. + * + * @param __PLLR__: PLL division factor for I2S, SAI, SYSTEM, SPDIFRX clocks. + * This parameter must be a number between Min_Data = 2 and Max_Data = 7. + * @note This parameter is only available in STM32F446xx devices. + * + */ +#define __HAL_RCC_PLL_CONFIG(__RCC_PLLSource__, __PLLM__, __PLLN__, __PLLP__, __PLLQ__,__PLLR__) \ + (RCC->PLLCFGR = ((__RCC_PLLSource__) | (__PLLM__) | \ + ((__PLLN__) << POSITION_VAL(RCC_PLLCFGR_PLLN)) | \ + ((((__PLLP__) >> 1) -1) << POSITION_VAL(RCC_PLLCFGR_PLLP)) | \ + ((__PLLQ__) << POSITION_VAL(RCC_PLLCFGR_PLLQ)) | \ + ((__PLLR__) << POSITION_VAL(RCC_PLLCFGR_PLLR)))) +#else +/** @brief Macro to configure the main PLL clock source, multiplication and division factors. + * @note This function must be used only when the main PLL is disabled. + * @param __RCC_PLLSource__: specifies the PLL entry clock source. + * This parameter can be one of the following values: + * @arg RCC_PLLSOURCE_HSI: HSI oscillator clock selected as PLL clock entry + * @arg RCC_PLLSOURCE_HSE: HSE oscillator clock selected as PLL clock entry + * @note This clock source (RCC_PLLSource) is common for the main PLL and PLLI2S. + * @param __PLLM__: specifies the division factor for PLL VCO input clock + * This parameter must be a number between Min_Data = 2 and Max_Data = 63. + * @note You have to set the PLLM parameter correctly to ensure that the VCO input + * frequency ranges from 1 to 2 MHz. It is recommended to select a frequency + * of 2 MHz to limit PLL jitter. + * @param __PLLN__: specifies the multiplication factor for PLL VCO output clock + * This parameter must be a number between Min_Data = 192 and Max_Data = 432. + * @note You have to set the PLLN parameter correctly to ensure that the VCO + * output frequency is between 192 and 432 MHz. + * + * @param __PLLP__: specifies the division factor for main system clock (SYSCLK) + * This parameter must be a number in the range {2, 4, 6, or 8}. + * + * @param __PLLQ__: specifies the division factor for OTG FS, SDIO and RNG clocks + * This parameter must be a number between Min_Data = 2 and Max_Data = 15. + * @note If the USB OTG FS is used in your application, you have to set the + * PLLQ parameter correctly to have 48 MHz clock for the USB. However, + * the SDIO and RNG need a frequency lower than or equal to 48 MHz to work + * correctly. + * + */ +#define __HAL_RCC_PLL_CONFIG(__RCC_PLLSource__, __PLLM__, __PLLN__, __PLLP__, __PLLQ__) \ + (RCC->PLLCFGR = (0x20000000 | (__RCC_PLLSource__) | (__PLLM__)| \ + ((__PLLN__) << POSITION_VAL(RCC_PLLCFGR_PLLN)) | \ + ((((__PLLP__) >> 1) -1) << POSITION_VAL(RCC_PLLCFGR_PLLP)) | \ + ((__PLLQ__) << POSITION_VAL(RCC_PLLCFGR_PLLQ)))) + #endif /* STM32F446xx */ +/*-------------------------------------------------------------------------------------------------------*/ + +/*------------------------------------------- PLLI2S Configuration --------------------------------------*/ +#if defined(STM32F446xx) +/** @brief Macro to configure the PLLI2S clock multiplication and division factors . + * @note This macro must be used only when the PLLI2S is disabled. + * @note PLLI2S clock source is common with the main PLL (configured in + * HAL_RCC_ClockConfig() API). + * @param __PLLI2SM__: specifies the division factor for PLLI2S VCO input clock + * This parameter must be a number between Min_Data = 2 and Max_Data = 63. + * @note You have to set the PLLI2SM parameter correctly to ensure that the VCO input + * frequency ranges from 1 to 2 MHz. It is recommended to select a frequency + * of 1 MHz to limit PLLI2S jitter. + * @note The PLLI2SM parameter is only used with STM32F411xE and STM32F446xx Devices + * + * @param __PLLI2SN__: specifies the multiplication factor for PLLI2S VCO output clock + * This parameter must be a number between Min_Data = 192 and Max_Data = 432. + * @note You have to set the PLLI2SN parameter correctly to ensure that the VCO + * output frequency is between Min_Data = 192 and Max_Data = 432 MHz. + * + * @param __PLLI2SP__: specifies division factor for SPDIFRX Clock. + * This parameter must be a number in the range {2, 4, 6, or 8}. + * @note the PLLI2SP parameter is only available with STM32F446xx Devices + * + * @param __PLLI2SR__: specifies the division factor for I2S clock + * This parameter must be a number between Min_Data = 2 and Max_Data = 7. + * @note You have to set the PLLI2SR parameter correctly to not exceed 192 MHz + * on the I2S clock frequency. + * + * @param __PLLI2SQ__: specifies the division factor for SAI clock + * This parameter must be a number between Min_Data = 2 and Max_Data = 15. + * @note the PLLI2SQ parameter is only available with STM32F427/437/429x/439xx Devices + * + */ +#define __HAL_RCC_PLLI2S_CONFIG(__PLLI2SM__, __PLLI2SN__, __PLLI2SP__, __PLLI2SQ__, __PLLI2SR__) \ + (RCC->PLLI2SCFGR = ((__PLLI2SM__) |\ + ((__PLLI2SN__) << POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN)) |\ + ((((__PLLI2SP__) >> 1) -1) << POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP)) |\ + ((__PLLI2SQ__) << POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ)) |\ + ((__PLLI2SR__) << POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR)))) +#else +/** @brief Macro to configure the PLLI2S clock multiplication and division factors . + * @note This macro must be used only when the PLLI2S is disabled. + * @note PLLI2S clock source is common with the main PLL (configured in + * HAL_RCC_ClockConfig() API). + * @param __PLLI2SN__: specifies the multiplication factor for PLLI2S VCO output clock + * This parameter must be a number between Min_Data = 192 and Max_Data = 432. + * @note You have to set the PLLI2SN parameter correctly to ensure that the VCO + * output frequency is between Min_Data = 192 and Max_Data = 432 MHz. + * @param __PLLI2SR__: specifies the division factor for I2S clock + * This parameter must be a number between Min_Data = 2 and Max_Data = 7. + * @note You have to set the PLLI2SR parameter correctly to not exceed 192 MHz + * on the I2S clock frequency. + * + */ +#define __HAL_RCC_PLLI2S_CONFIG(__PLLI2SN__, __PLLI2SR__) \ + (RCC->PLLI2SCFGR = (((__PLLI2SN__) << POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN)) | \ + ((__PLLI2SR__) << POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR)))) +#endif /* STM32F446xx */ + +#if defined(STM32F411xE) + +/** @brief Macro to configure the PLLI2S clock multiplication and division factors . + * @note This macro must be used only when the PLLI2S is disabled. + * @note This macro must be used only when the PLLI2S is disabled. + * @note PLLI2S clock source is common with the main PLL (configured in + * HAL_RCC_ClockConfig() API). + * @param __PLLI2SM__: specifies the division factor for PLLI2S VCO input clock + * This parameter must be a number between Min_Data = 2 and Max_Data = 63. + * @note The PLLI2SM parameter is only used with STM32F411xE Devices + * @note You have to set the PLLI2SM parameter correctly to ensure that the VCO input + * frequency ranges from 1 to 2 MHz. It is recommended to select a frequency + * of 2 MHz to limit PLLI2S jitter. + * @param __PLLI2SN__: specifies the multiplication factor for PLLI2S VCO output clock + * This parameter must be a number between Min_Data = 192 and Max_Data = 432. + * @note You have to set the PLLI2SN parameter correctly to ensure that the VCO + * output frequency is between Min_Data = 192 and Max_Data = 432 MHz. + * @param __PLLI2SR__: specifies the division factor for I2S clock + * This parameter must be a number between Min_Data = 2 and Max_Data = 7. + * @note You have to set the PLLI2SR parameter correctly to not exceed 192 MHz + * on the I2S clock frequency. + */ +#define __HAL_RCC_PLLI2S_I2SCLK_CONFIG(__PLLI2SM__, __PLLI2SN__, __PLLI2SR__) (RCC->PLLI2SCFGR = ((__PLLI2SM__) |\ + ((__PLLI2SN__) << POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN)) |\ + ((__PLLI2SR__) << POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR)))) +#endif /* STM32F411xE */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) +/** @brief Macro used by the SAI HAL driver to configure the PLLI2S clock multiplication and division factors. + * @note This macro must be used only when the PLLI2S is disabled. + * @note PLLI2S clock source is common with the main PLL (configured in + * HAL_RCC_ClockConfig() API) + * @param __PLLI2SN__: specifies the multiplication factor for PLLI2S VCO output clock. + * This parameter must be a number between Min_Data = 192 and Max_Data = 432. + * @note You have to set the PLLI2SN parameter correctly to ensure that the VCO + * output frequency is between Min_Data = 192 and Max_Data = 432 MHz. + * @param __PLLI2SQ__: specifies the division factor for SAI1 clock. + * This parameter must be a number between Min_Data = 2 and Max_Data = 15. + * @note the PLLI2SQ parameter is only available with STM32F427xx/437xx/429xx/439xx Devices + * and can be configured using the __HAL_RCC_PLLI2S_PLLSAICLK_CONFIG() macro + * @param __PLLI2SR__: specifies the division factor for I2S clock + * This parameter must be a number between Min_Data = 2 and Max_Data = 7. + * @note You have to set the PLLI2SR parameter correctly to not exceed 192 MHz + * on the I2S clock frequency. + */ +#define __HAL_RCC_PLLI2S_SAICLK_CONFIG(__PLLI2SN__, __PLLI2SQ__, __PLLI2SR__) (RCC->PLLI2SCFGR = ((__PLLI2SN__) << 6) |\ + ((__PLLI2SQ__) << 24) |\ + ((__PLLI2SR__) << 28)) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +/*----------------------------------------------------------------------------------------------------------------*/ + +/*--------------------------------------------------- PLLSAI Configuration ---------------------------------------*/ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) +/** @brief Macros to Enable or Disable the PLLISAI. + * @note The PLLSAI is only available with STM32F429x/439x Devices. + * @note The PLLSAI is disabled by hardware when entering STOP and STANDBY modes. + */ +#define __HAL_RCC_PLLSAI_ENABLE() (*(__IO uint32_t *) RCC_CR_PLLSAION_BB = ENABLE) +#define __HAL_RCC_PLLSAI_DISABLE() (*(__IO uint32_t *) RCC_CR_PLLSAION_BB = DISABLE) + +#if defined(STM32F446xx) +/** @brief Macro to configure the PLLSAI clock multiplication and division factors. + * + * @param __PLLSAIM__: specifies the division factor for PLLSAI VCO input clock + * This parameter must be a number between Min_Data = 2 and Max_Data = 63. + * @note You have to set the PLLSAIM parameter correctly to ensure that the VCO input + * frequency ranges from 1 to 2 MHz. It is recommended to select a frequency + * of 1 MHz to limit PLLI2S jitter. + * @note The PLLSAIM parameter is only used with STM32F446xx Devices + * + * @param __PLLSAIN__: specifies the multiplication factor for PLLSAI VCO output clock. + * This parameter must be a number between Min_Data = 192 and Max_Data = 432. + * @note You have to set the PLLSAIN parameter correctly to ensure that the VCO + * output frequency is between Min_Data = 192 and Max_Data = 432 MHz. + * + * @param __PLLSAIP__: specifies division factor for OTG FS, SDIO and RNG clocks. + * This parameter must be a number in the range {2, 4, 6, or 8}. + * @note the PLLSAIP parameter is only available with STM32F446xx Devices + * + * @param __PLLSAIQ__: specifies the division factor for SAI clock + * This parameter must be a number between Min_Data = 2 and Max_Data = 15. + * + * @param __PLLSAIR__: specifies the division factor for LTDC clock + * This parameter must be a number between Min_Data = 2 and Max_Data = 7. + * @note the PLLI2SR parameter is only available with STM32F427/437/429/439xx Devices + */ +#define __HAL_RCC_PLLSAI_CONFIG(__PLLSAIM__, __PLLSAIN__, __PLLSAIP__, __PLLSAIQ__, __PLLSAIR__) \ + (RCC->PLLSAICFGR = ((__PLLSAIM__) | \ + ((__PLLSAIN__) << POSITION_VAL(RCC_PLLSAICFGR_PLLSAIN)) | \ + ((((__PLLSAIP__) >> 1) -1) << POSITION_VAL(RCC_PLLSAICFGR_PLLSAIP)) | \ + ((__PLLSAIQ__) << POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ)))) +#endif /* STM32F446xx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) +/** @brief Macro to configure the PLLSAI clock multiplication and division factors. + * + * @param __PLLSAIN__: specifies the multiplication factor for PLLSAI VCO output clock. + * This parameter must be a number between Min_Data = 192 and Max_Data = 432. + * @note You have to set the PLLSAIN parameter correctly to ensure that the VCO + * output frequency is between Min_Data = 192 and Max_Data = 432 MHz. + * + * @param __PLLSAIQ__: specifies the division factor for SAI clock + * This parameter must be a number between Min_Data = 2 and Max_Data = 15. + * + * @param __PLLSAIR__: specifies the division factor for LTDC clock + * This parameter must be a number between Min_Data = 2 and Max_Data = 7. + * @note the PLLI2SR parameter is only available with STM32F427/437/429/439xx Devices + */ +#define __HAL_RCC_PLLSAI_CONFIG(__PLLSAIN__, __PLLSAIQ__, __PLLSAIR__) \ + (RCC->PLLSAICFGR = (((__PLLSAIN__) << POSITION_VAL(RCC_PLLSAICFGR_PLLSAIN)) | \ + ((__PLLSAIQ__) << POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ)) | \ + ((__PLLSAIR__) << POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR)))) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ +/*----------------------------------------------------------------------------------------------------------------------*/ + +/*----------------------------------------- PLLSAI/PLLI2S Dividers Configuration ---------------------------------------*/ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) +/** @brief Macro to configure the SAI clock Divider coming from PLLI2S. + * @note This function must be called before enabling the PLLI2S. + * @param __PLLI2SDivQ__: specifies the PLLI2S division factor for SAI1 clock . + * This parameter must be a number between 1 and 32. + * SAI1 clock frequency = f(PLLI2SQ) / __PLLI2SDivQ__ + */ +#define __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(__PLLI2SDivQ__) (MODIFY_REG(RCC->DCKCFGR, RCC_DCKCFGR_PLLI2SDIVQ, (__PLLI2SDivQ__)-1)) + +/** @brief Macro to configure the SAI clock Divider coming from PLLSAI. + * @note This function must be called before enabling the PLLSAI. + * @param __PLLSAIDivQ__: specifies the PLLSAI division factor for SAI1 clock . + * This parameter must be a number between Min_Data = 1 and Max_Data = 32. + * SAI1 clock frequency = f(PLLSAIQ) / __PLLSAIDivQ__ + */ +#define __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(__PLLSAIDivQ__) (MODIFY_REG(RCC->DCKCFGR, RCC_DCKCFGR_PLLSAIDIVQ, ((__PLLSAIDivQ__)-1)<<8)) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) +/** @brief Macro to configure the LTDC clock Divider coming from PLLSAI. + * + * @note The LTDC peripheral is only available with STM32F427/437/429/439xx Devices. + * @note This function must be called before enabling the PLLSAI. + * @param __PLLSAIDivR__: specifies the PLLSAI division factor for LTDC clock . + * This parameter must be a number between Min_Data = 2 and Max_Data = 16. + * LTDC clock frequency = f(PLLSAIR) / __PLLSAIDivR__ + */ +#define __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(__PLLSAIDivR__) (MODIFY_REG(RCC->DCKCFGR, RCC_DCKCFGR_PLLSAIDIVR, (__PLLSAIDivR__))) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +/*-----------------------------------------------------------------------------------------------------------------------------------*/ + +/*-------------------------------------------------- Peripheral Clock selection -----------------------------------------------------*/ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) +/** @brief Macro to configure the I2S clock source (I2SCLK). + * @note This function must be called before enabling the I2S APB clock. + * @param __SOURCE__: specifies the I2S clock source. + * This parameter can be one of the following values: + * @arg RCC_I2SCLKSOURCE_PLLI2S: PLLI2S clock used as I2S clock source. + * @arg RCC_I2SCLKSOURCE_EXT: External clock mapped on the I2S_CKIN pin + * used as I2S clock source. + */ +#define __HAL_RCC_I2S_CONFIG(__SOURCE__) (*(__IO uint32_t *) RCC_CFGR_I2SSRC_BB = (__SOURCE__)) +#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + +/** @brief Macro to configure SAI1BlockA clock source selection. + * @note The SAI peripheral is only available with STM32F427/437/429/439xx Devices. + * @note This function must be called before enabling PLLSAI, PLLI2S and + * the SAI clock. + * @param __SOURCE__: specifies the SAI Block A clock source. + * This parameter can be one of the following values: + * @arg RCC_SAIACLKSOURCE_PLLI2S: PLLI2S_Q clock divided by PLLI2SDIVQ used + * as SAI1 Block A clock. + * @arg RCC_SAIACLKSOURCE_PLLSAI: PLLISAI_Q clock divided by PLLSAIDIVQ used + * as SAI1 Block A clock. + * @arg RCC_SAIACLKSOURCE_Ext: External clock mapped on the I2S_CKIN pin + * used as SAI1 Block A clock. + */ +#define __HAL_RCC_SAI_BLOCKACLKSOURCE_CONFIG(__SOURCE__) (MODIFY_REG(RCC->DCKCFGR, RCC_DCKCFGR_SAI1ASRC, (__SOURCE__))) + +/** @brief Macro to configure SAI1BlockB clock source selection. + * @note The SAI peripheral is only available with STM32F427/437/429/439xx Devices. + * @note This function must be called before enabling PLLSAI, PLLI2S and + * the SAI clock. + * @param __SOURCE__: specifies the SAI Block B clock source. + * This parameter can be one of the following values: + * @arg RCC_SAIBCLKSOURCE_PLLI2S: PLLI2S_Q clock divided by PLLI2SDIVQ used + * as SAI1 Block B clock. + * @arg RCC_SAIBCLKSOURCE_PLLSAI: PLLISAI_Q clock divided by PLLSAIDIVQ used + * as SAI1 Block B clock. + * @arg RCC_SAIBCLKSOURCE_Ext: External clock mapped on the I2S_CKIN pin + * used as SAI1 Block B clock. + */ +#define __HAL_RCC_SAI_BLOCKBCLKSOURCE_CONFIG(__SOURCE__) (MODIFY_REG(RCC->DCKCFGR, RCC_DCKCFGR_SAI1BSRC, (__SOURCE__))) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +#if defined(STM32F446xx) +/** @brief Macro to configure SAI1 clock source selection. + * @note This configuration is only available with STM32F446xx Devices. + * @note This function must be called before enabling PLL, PLLSAI, PLLI2S and + * the SAI clock. + * @param __SOURCE__: specifies the SAI1 clock source. + * This parameter can be one of the following values: + * @arg RCC_SAI1CLKSOURCE_PLLI2S: PLLI2S_Q clock divided by PLLI2SDIVQ used as SAI1 clock. + * @arg RCC_SAI1CLKSOURCE_PLLSAI: PLLISAI_Q clock divided by PLLSAIDIVQ used as SAI1 clock. + * @arg RCC_SAI1CLKSOURCE_PLLR: PLL VCO Output divided by PLLR used as SAI1 clock. + * @arg RCC_SAI1CLKSOURCE_EXT: External clock mapped on the I2S_CKIN pin used as SAI1 clock. + */ +#define __HAL_RCC_SAI1_CONFIG(__SOURCE__) (MODIFY_REG(RCC->DCKCFGR, RCC_DCKCFGR_SAI1SRC, (__SOURCE__))) + +/** @brief Macro to Get SAI1 clock source selection. + * @note This configuration is only available with STM32F446xx Devices. + * @retval The clock source can be one of the following values: + * @arg RCC_SAI1CLKSOURCE_PLLI2S: PLLI2S_Q clock divided by PLLI2SDIVQ used as SAI1 clock. + * @arg RCC_SAI1CLKSOURCE_PLLSAI: PLLISAI_Q clock divided by PLLSAIDIVQ used as SAI1 clock. + * @arg RCC_SAI1CLKSOURCE_PLLR: PLL VCO Output divided by PLLR used as SAI1 clock. + * @arg RCC_SAI1CLKSOURCE_EXT: External clock mapped on the I2S_CKIN pin used as SAI1 clock. + */ +#define __HAL_RCC_GET_SAI1_SOURCE() (READ_BIT(RCC->DCKCFGR, RCC_DCKCFGR_SAI1SRC)) + +/** @brief Macro to configure SAI2 clock source selection. + * @note This configuration is only available with STM32F446xx Devices. + * @note This function must be called before enabling PLL, PLLSAI, PLLI2S and + * the SAI clock. + * @param __SOURCE__: specifies the SAI2 clock source. + * This parameter can be one of the following values: + * @arg RCC_SAI2CLKSOURCE_PLLI2S: PLLI2S_Q clock divided by PLLI2SDIVQ used as SAI2 clock. + * @arg RCC_SAI2CLKSOURCE_PLLSAI: PLLISAI_Q clock divided by PLLSAIDIVQ used as SAI2 clock. + * @arg RCC_SAI2CLKSOURCE_PLLR: PLL VCO Output divided by PLLR used as SAI2 clock. + * @arg RCC_SAI2CLKSOURCE_PLLSRC: HSI or HSE depending from PLL Source clock used as SAI2 clock. + */ +#define __HAL_RCC_SAI2_CONFIG(__SOURCE__) (MODIFY_REG(RCC->DCKCFGR, RCC_DCKCFGR_SAI2SRC, (__SOURCE__))) + +/** @brief Macro to Get SAI2 clock source selection. + * @note This configuration is only available with STM32F446xx Devices. + * @retval The clock source can be one of the following values: + * @arg RCC_SAI2CLKSOURCE_PLLI2S: PLLI2S_Q clock divided by PLLI2SDIVQ used as SAI2 clock. + * @arg RCC_SAI2CLKSOURCE_PLLSAI: PLLISAI_Q clock divided by PLLSAIDIVQ used as SAI2 clock. + * @arg RCC_SAI2CLKSOURCE_PLLR: PLL VCO Output divided by PLLR used as SAI2 clock. + * @arg RCC_SAI2CLKSOURCE_PLLSRC: HSI or HSE depending from PLL Source clock used as SAI2 clock. + */ +#define __HAL_RCC_GET_SAI2_SOURCE() (READ_BIT(RCC->DCKCFGR, RCC_DCKCFGR_SAI2SRC)) + +/** @brief Macro to configure I2S APB1 clock source selection. + * @note This configuration is only available with STM32F446xx Devices. + * @note This function must be called before enabling PLL, PLLI2S and the I2S clock. + * @param __SOURCE__: specifies the I2S APB1 clock source. + * This parameter can be one of the following values: + * @arg RCC_I2SAPB1CLKSOURCE_PLLI2S: PLLI2S VCO output clock divided by PLLI2SR used as I2S clock. + * @arg RCC_I2SAPB1CLKSOURCE_EXT: External clock mapped on the I2S_CKIN pin used as SAI1 clock. + * @arg RCC_I2SAPB1CLKSOURCE_PLLR: PLL VCO Output divided by PLLR used as SAI1 clock. + * @arg RCC_I2SAPB1CLKSOURCE_PLLSRC: HSI or HSE depending from PLL source Clock. + */ +#define __HAL_RCC_I2S_APB1_CONFIG(__SOURCE__) (MODIFY_REG(RCC->DCKCFGR, RCC_DCKCFGR_I2S1SRC, (__SOURCE__))) + +/** @brief Macro to Get I2S APB1 clock source selection. + * @note This configuration is only available with STM32F446xx Devices. + * @retval The clock source can be one of the following values: + * @arg RCC_I2SAPB1CLKSOURCE_PLLI2S: PLLI2S VCO output clock divided by PLLI2SR used as I2S clock. + * @arg RCC_I2SAPB1CLKSOURCE_EXT: External clock mapped on the I2S_CKIN pin used as SAI1 clock. + * @arg RCC_I2SAPB1CLKSOURCE_PLLR: PLL VCO Output divided by PLLR used as SAI1 clock. + * @arg RCC_I2SAPB1CLKSOURCE_PLLSRC: HSI or HSE depending from PLL source Clock. + */ +#define __HAL_RCC_GET_I2S_APB1_SOURCE() (READ_BIT(RCC->DCKCFGR, RCC_DCKCFGR_I2S1SRC)) + +/** @brief Macro to configure I2S APB2 clock source selection. + * @note This configuration is only available with STM32F446xx Devices. + * @note This function must be called before enabling PLL, PLLI2S and the I2S clock. + * @param __SOURCE__: specifies the SAI Block A clock source. + * This parameter can be one of the following values: + * @arg RCC_I2SAPB2CLKSOURCE_PLLI2S: PLLI2S VCO output clock divided by PLLI2SR used as I2S clock. + * @arg RCC_I2SAPB2CLKSOURCE_EXT: External clock mapped on the I2S_CKIN pin used as SAI1 clock. + * @arg RCC_I2SAPB2CLKSOURCE_PLLR: PLL VCO Output divided by PLLR used as SAI1 clock. + * @arg RCC_I2SAPB2CLKSOURCE_PLLSRC: HSI or HSE depending from PLL source Clock. + */ +#define __HAL_RCC_I2S_APB2_CONFIG(__SOURCE__) (MODIFY_REG(RCC->DCKCFGR, RCC_DCKCFGR_I2S2SRC, (__SOURCE__))) + +/** @brief Macro to Get I2S APB2 clock source selection. + * @note This configuration is only available with STM32F446xx Devices. + * @retval The clock source can be one of the following values: + * @arg RCC_I2SAPB2CLKSOURCE_PLLI2S: PLLI2S VCO output clock divided by PLLI2SR used as I2S clock. + * @arg RCC_I2SAPB2CLKSOURCE_EXT: External clock mapped on the I2S_CKIN pin used as SAI1 clock. + * @arg RCC_I2SAPB2CLKSOURCE_PLLR: PLL VCO Output divided by PLLR used as SAI1 clock. + * @arg RCC_I2SAPB2CLKSOURCE_PLLSRC: HSI or HSE depending from PLL source Clock. + */ +#define __HAL_RCC_GET_I2S_APB2_SOURCE() (READ_BIT(RCC->DCKCFGR, RCC_DCKCFGR_I2S2SRC)) + +/** @brief Macro to configure the CEC clock. + * @param __SOURCE__: specifies the CEC clock source. + * This parameter can be one of the following values: + * @arg RCC_CECCLKSOURCE_HSI: HSI selected as CEC clock + * @arg RCC_CECCLKSOURCE_LSE: LSE selected as CEC clock + */ +#define __HAL_RCC_CEC_CONFIG(__SOURCE__) (MODIFY_REG(RCC->DCKCFGR2, RCC_DCKCFGR2_CECSEL, (uint32_t)(__SOURCE__))) + +/** @brief Macro to Get the CEC clock. + * @retval The clock source can be one of the following values: + * @arg RCC_CECCLKSOURCE_HSI488: HSI selected as CEC clock + * @arg RCC_CECCLKSOURCE_LSE: LSE selected as CEC clock + */ +#define __HAL_RCC_GET_CEC_SOURCE() (READ_BIT(RCC->DCKCFGR2, RCC_DCKCFGR2_CECSEL)) + +/** @brief Macro to configure the FMPI2C1 clock. + * @param __SOURCE__: specifies the FMPI2C1 clock source. + * This parameter can be one of the following values: + * @arg RCC_FMPI2C1CLKSOURCE_APB: APB selected as CEC clock + * @arg RCC_FMPI2C1CLKSOURCE_SYSCLK: SYS clock selected as CEC clock + * @arg RCC_FMPI2C1CLKSOURCE_HSI: HSI selected as CEC clock + */ +#define __HAL_RCC_FMPI2C1_CONFIG(__SOURCE__) (MODIFY_REG(RCC->DCKCFGR2, RCC_DCKCFGR2_FMPI2C1SEL, (uint32_t)(__SOURCE__))) + +/** @brief Macro to Get the FMPI2C1 clock. + * @retval The clock source can be one of the following values: + * @arg RCC_FMPI2C1CLKSOURCE_APB: APB selected as CEC clock + * @arg RCC_FMPI2C1CLKSOURCE_SYSCLK: SYS clock selected as CEC clock + * @arg RCC_FMPI2C1CLKSOURCE_HSI: HSI selected as CEC clock + */ +#define __HAL_RCC_GET_FMPI2C1_SOURCE() (READ_BIT(RCC->DCKCFGR2, RCC_DCKCFGR2_FMPI2C1SEL)) + +/** @brief Macro to configure the CLK48 clock. + * @param __SOURCE__: specifies the CK48 clock source. + * This parameter can be one of the following values: + * @arg RCC_CK48CLKSOURCE_PLLQ: PLL VCO Output divided by PLLQ used as CK48 clock. + * @arg RCC_CK48CLKSOURCE_PLLSAIP: PLLSAI VCO Output divided by PLLSAIP used as CK48 clock. + */ +#define __HAL_RCC_CLK48_CONFIG(__SOURCE__) (MODIFY_REG(RCC->DCKCFGR2, RCC_DCKCFGR2_CK48MSEL, (uint32_t)(__SOURCE__))) + +/** @brief Macro to Get the CLK48 clock. + * @retval The clock source can be one of the following values: + * @arg RCC_CK48CLKSOURCE_PLLQ: PLL VCO Output divided by PLLQ used as CK48 clock. + * @arg RCC_CK48CLKSOURCE_PLLSAIP: PLLSAI VCO Output divided by PLLSAIP used as CK48 clock. + */ +#define __HAL_RCC_GET_CLK48_SOURCE() (READ_BIT(RCC->DCKCFGR2, RCC_DCKCFGR2_CK48MSEL)) + +/** @brief Macro to configure the SDIO clock. + * @param __SOURCE__: specifies the SDIO clock source. + * This parameter can be one of the following values: + * @arg RCC_SDIOCLKSOURCE_CK48: CK48 output used as SDIO clock. + * @arg RCC_SDIOCLKSOURCE_SYSCLK: System clock output used as SDIO clock. + */ +#define __HAL_RCC_SDIO_CONFIG(__SOURCE__) (MODIFY_REG(RCC->DCKCFGR2, RCC_DCKCFGR2_SDIOSEL, (uint32_t)(__SOURCE__))) + +/** @brief Macro to Get the SDIO clock. + * @retval The clock source can be one of the following values: + * @arg RCC_SDIOCLKSOURCE_CK48: CK48 output used as SDIO clock. + * @arg RCC_SDIOCLKSOURCE_SYSCLK: System clock output used as SDIO clock. + */ +#define __HAL_RCC_GET_SDIO_SOURCE() (READ_BIT(RCC->DCKCFGR2, RCC_DCKCFGR2_SDIOSEL)) + +/** @brief Macro to configure the SPDIFRX clock. + * @param __SOURCE__: specifies the SPDIFRX clock source. + * This parameter can be one of the following values: + * @arg RCC_SPDIFRXCLKSOURCE_PLLR: PLL VCO Output divided by PLLR used as SPDIFRX clock. + * @arg RCC_SPDIFRXCLKSOURCE_PLLI2SP: PLLI2S VCO Output divided by PLLI2SP used as SPDIFRX clock. + */ +#define __HAL_RCC_SPDIFRX_CONFIG(__SOURCE__) (MODIFY_REG(RCC->DCKCFGR2, RCC_DCKCFGR2_SPDIFRXSEL, (uint32_t)(__SOURCE__))) + +/** @brief Macro to Get the SPDIFRX clock. + * @retval The clock source can be one of the following values: + * @arg RCC_SPDIFRXCLKSOURCE_PLLR: PLL VCO Output divided by PLLR used as SPDIFRX clock. + * @arg RCC_SPDIFRXCLKSOURCE_PLLI2SP: PLLI2S VCO Output divided by PLLI2SP used as SPDIFRX clock. + */ +#define __HAL_RCC_GET_SPDIFRX_SOURCE() (READ_BIT(RCC->DCKCFGR2, RCC_DCKCFGR2_SPDIFRXSEL)) +#endif /* STM32F446xx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) + +/** @brief Macro to configure the Timers clocks prescalers + * @note This feature is only available with STM32F429x/439x Devices. + * @param __PRESC__ : specifies the Timers clocks prescalers selection + * This parameter can be one of the following values: + * @arg RCC_TIMPRES_DESACTIVATED: The Timers kernels clocks prescaler is + * equal to HPRE if PPREx is corresponding to division by 1 or 2, + * else it is equal to [(HPRE * PPREx) / 2] if PPREx is corresponding to + * division by 4 or more. + * @arg RCC_TIMPRES_ACTIVATED: The Timers kernels clocks prescaler is + * equal to HPRE if PPREx is corresponding to division by 1, 2 or 4, + * else it is equal to [(HPRE * PPREx) / 4] if PPREx is corresponding + * to division by 8 or more. + */ +#define __HAL_RCC_TIMCLKPRESCALER(__PRESC__) (*(__IO uint32_t *) RCC_DCKCFGR_TIMPRE_BB = (__PRESC__)) + +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx) || STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx */ + +/*-------------------------------------------------------------------------------------------------------------------*/ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) +/** @brief Enable PLLSAI_RDY interrupt. + */ +#define __HAL_RCC_PLLSAI_ENABLE_IT() (RCC->CIR |= (RCC_CIR_PLLSAIRDYIE)) + +/** @brief Disable PLLSAI_RDY interrupt. + */ +#define __HAL_RCC_PLLSAI_DISABLE_IT() (RCC->CIR &= ~(RCC_CIR_PLLSAIRDYIE)) + +/** @brief Clear the PLLSAI RDY interrupt pending bits. + */ +#define __HAL_RCC_PLLSAI_CLEAR_IT() (RCC->CIR |= (RCC_CIR_PLLSAIRDYF)) + +/** @brief Check the PLLSAI RDY interrupt has occurred or not. + * @retval The new state (TRUE or FALSE). + */ +#define __HAL_RCC_PLLSAI_GET_IT() ((RCC->CIR & (RCC_CIR_PLLSAIRDYIE)) == (RCC_CIR_PLLSAIRDYIE)) + +/** @brief Check PLLSAI RDY flag is set or not. + * @retval The new state (TRUE or FALSE). + */ +#define __HAL_RCC_PLLSAI_GET_FLAG() ((RCC->CR & (RCC_CR_PLLSAIRDY)) == (RCC_CR_PLLSAIRDY)) + +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup RCCEx_Exported_Functions + * @{ + */ + +/** @addtogroup RCCEx_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit); +void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit); + +#if defined(STM32F446xx) +uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk); +#endif /* STM32F446xx */ + +#if defined(STM32F411xE) || defined(STM32F446xx) +void HAL_RCCEx_SelectLSEMode(uint8_t Mode); +#endif /* STM32F411xE || STM32F446xx */ +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup RCCEx_Private_Constants RCCEx Private Constants + * @{ + */ + +/** @defgroup RCCEx_BitAddress_AliasRegion RCC BitAddress AliasRegion + * @brief RCC registers bit address in the alias region + * @{ + */ +/* --- CR Register ---*/ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) +/* Alias word address of PLLSAION bit */ +#define RCC_PLLSAION_BIT_NUMBER 0x1C +#define RCC_CR_PLLSAION_BB (PERIPH_BB_BASE + (RCC_CR_OFFSET * 32) + (RCC_PLLSAION_BIT_NUMBER * 4)) + +/* --- DCKCFGR Register ---*/ +/* Alias word address of TIMPRE bit */ +#define RCC_DCKCFGR_OFFSET (RCC_OFFSET + 0x8C) +#define RCC_TIMPRE_BIT_NUMBER 0x18 +#define RCC_DCKCFGR_TIMPRE_BB (PERIPH_BB_BASE + (RCC_DCKCFGR_OFFSET * 32) + (RCC_TIMPRE_BIT_NUMBER * 4)) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ + +#define PLL_TIMEOUT_VALUE ((uint32_t)100) /* 100 ms */ + +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup RCCEx_Private_Macros RCCEx Private Macros + * @{ + */ +/** @defgroup RCCEx_IS_RCC_Definitions RCC Private macros to check input parameters + * @{ + */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) +#define IS_RCC_PERIPHCLOCK(SELECTION) ((1 <= (SELECTION)) && ((SELECTION) <= 0x0000002F)) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) +#define IS_RCC_PERIPHCLOCK(SELECTION) ((1 <= (SELECTION)) && ((SELECTION) <= 0x00000003)) +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F411xE */ + +#if defined(STM32F446xx) +#define IS_RCC_PERIPHCLOCK(SELECTION) ((1 <= (SELECTION)) && ((SELECTION) <= 0x000007FF)) +#endif /* STM32F446xx */ + +#define IS_RCC_PLLI2SN_VALUE(VALUE) ((192 <= (VALUE)) && ((VALUE) <= 432)) +#define IS_RCC_PLLI2SR_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 7)) + + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) || defined(STM32F446xx) +#define IS_RCC_PLLI2SQ_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 15)) + +#define IS_RCC_PLLSAIN_VALUE(VALUE) ((49 <= (VALUE)) && ((VALUE) <= 432)) + +#define IS_RCC_PLLSAIQ_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 15)) + +#define IS_RCC_PLLSAIR_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 7)) + +#define IS_RCC_PLLSAI_DIVQ_VALUE(VALUE) ((1 <= (VALUE)) && ((VALUE) <= 32)) + +#define IS_RCC_PLLI2S_DIVQ_VALUE(VALUE) ((1 <= (VALUE)) && ((VALUE) <= 32)) + +#define IS_RCC_PLLSAI_DIVR_VALUE(VALUE) (((VALUE) == RCC_PLLSAIDIVR_2) ||\ + ((VALUE) == RCC_PLLSAIDIVR_4) ||\ + ((VALUE) == RCC_PLLSAIDIVR_8) ||\ + ((VALUE) == RCC_PLLSAIDIVR_16)) +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +#if defined(STM32F446xx) || defined(STM32F411xE) +#define IS_RCC_PLLI2SM_VALUE(VALUE) ((VALUE) <= 63) + +#define IS_RCC_LSE_MODE(MODE) (((MODE) == RCC_LSE_LOWPOWER_MODE) ||\ + ((MODE) == RCC_LSE_HIGHDRIVE_MODE)) +#endif /* STM32F446xx || STM32F411xE */ + +#if defined(STM32F446xx) +#define IS_RCC_PLLR_VALUE(VALUE) ((2 <= (VALUE)) && ((VALUE) <= 7)) + +#define IS_RCC_PLLI2SP_VALUE(VALUE) (((VALUE) == RCC_PLLI2SP_DIV2) ||\ + ((VALUE) == RCC_PLLI2SP_DIV4) ||\ + ((VALUE) == RCC_PLLI2SP_DIV6) ||\ + ((VALUE) == RCC_PLLI2SP_DIV8)) + +#define IS_RCC_PLLSAIM_VALUE(VALUE) ((VALUE) <= 63) + +#define IS_RCC_PLLSAIP_VALUE(VALUE) (((VALUE) == RCC_PLLSAIP_DIV2) ||\ + ((VALUE) == RCC_PLLSAIP_DIV4) ||\ + ((VALUE) == RCC_PLLSAIP_DIV6) ||\ + ((VALUE) == RCC_PLLSAIP_DIV8)) + +#define IS_RCC_SAI1CLKSOURCE(SOURCE) (((SOURCE) == RCC_SAI1CLKSOURCE_PLLSAI) ||\ + ((SOURCE) == RCC_SAI1CLKSOURCE_PLLI2S) ||\ + ((SOURCE) == RCC_SAI1CLKSOURCE_PLLR) ||\ + ((SOURCE) == RCC_SAI1CLKSOURCE_EXT)) + +#define IS_RCC_SAI2CLKSOURCE(SOURCE) (((SOURCE) == RCC_SAI2CLKSOURCE_PLLSAI) ||\ + ((SOURCE) == RCC_SAI2CLKSOURCE_PLLI2S) ||\ + ((SOURCE) == RCC_SAI2CLKSOURCE_PLLR) ||\ + ((SOURCE) == RCC_SAI2CLKSOURCE_PLLSRC)) + +#define IS_RCC_I2SAPB1CLKSOURCE(SOURCE) (((SOURCE) == RCC_I2SAPB1CLKSOURCE_PLLI2S) ||\ + ((SOURCE) == RCC_I2SAPB1CLKSOURCE_EXT) ||\ + ((SOURCE) == RCC_I2SAPB1CLKSOURCE_PLLR) ||\ + ((SOURCE) == RCC_I2SAPB1CLKSOURCE_PLLSRC)) + + #define IS_RCC_I2SAPB2CLKSOURCE(SOURCE) (((SOURCE) == RCC_I2SAPB2CLKSOURCE_PLLI2S) ||\ + ((SOURCE) == RCC_I2SAPB2CLKSOURCE_EXT) ||\ + ((SOURCE) == RCC_I2SAPB2CLKSOURCE_PLLR) ||\ + ((SOURCE) == RCC_I2SAPB2CLKSOURCE_PLLSRC)) + +#define IS_RCC_FMPI2C1CLKSOURCE(SOURCE) (((SOURCE) == RCC_FMPI2C1CLKSOURCE_APB) ||\ + ((SOURCE) == RCC_FMPI2C1CLKSOURCE_SYSCLK) ||\ + ((SOURCE) == RCC_FMPI2C1CLKSOURCE_HSI)) + +#define IS_RCC_CECCLKSOURCE(SOURCE) (((SOURCE) == RCC_CECCLKSOURCE_HSI) ||\ + ((SOURCE) == RCC_CECCLKSOURCE_LSE)) + +#define IS_RCC_CK48CLKSOURCE(SOURCE) (((SOURCE) == RCC_CK48CLKSOURCE_PLLQ) ||\ + ((SOURCE) == RCC_CK48CLKSOURCE_PLLSAIP)) + +#define IS_RCC_SDIOCLKSOURCE(SOURCE) (((SOURCE) == RCC_SDIOCLKSOURCE_CK48) ||\ + ((SOURCE) == RCC_SDIOCLKSOURCE_SYSCLK)) + +#define IS_RCC_SPDIFRXCLKSOURCE(SOURCE) (((SOURCE) == RCC_SPDIFRXCLKSOURCE_PLLR) ||\ + ((SOURCE) == RCC_SPDIFRXCLKSOURCE_PLLI2SP)) +#endif /* STM32F446xx */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_RCC_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rng.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rng.h new file mode 100644 index 0000000..e4890fd --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rng.h @@ -0,0 +1,364 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_rng.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of RNG HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_RNG_H +#define __STM32F4xx_HAL_RNG_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup RNG RNG + * @brief RNG HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** @defgroup RNG_Exported_Types RNG Exported Types + * @{ + */ + +/** @defgroup RNG_Exported_Types_Group1 RNG State Structure definition + * @{ + */ +typedef enum +{ + HAL_RNG_STATE_RESET = 0x00, /*!< RNG not yet initialized or disabled */ + HAL_RNG_STATE_READY = 0x01, /*!< RNG initialized and ready for use */ + HAL_RNG_STATE_BUSY = 0x02, /*!< RNG internal process is ongoing */ + HAL_RNG_STATE_TIMEOUT = 0x03, /*!< RNG timeout state */ + HAL_RNG_STATE_ERROR = 0x04 /*!< RNG error state */ + +}HAL_RNG_StateTypeDef; + +/** + * @} + */ + +/** @defgroup RNG_Exported_Types_Group2 RNG Handle Structure definition + * @{ + */ +typedef struct +{ + RNG_TypeDef *Instance; /*!< Register base address */ + + HAL_LockTypeDef Lock; /*!< RNG locking object */ + + __IO HAL_RNG_StateTypeDef State; /*!< RNG communication state */ + + uint32_t RandomNumber; /*!< Last Generated RNG Data */ + +}RNG_HandleTypeDef; + +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup RNG_Exported_Constants RNG Exported Constants + * @{ + */ + +/** @defgroup RNG_Exported_Constants_Group1 RNG Interrupt definition + * @{ + */ +#define RNG_IT_DRDY RNG_SR_DRDY /*!< Data Ready interrupt */ +#define RNG_IT_CEI RNG_SR_CEIS /*!< Clock error interrupt */ +#define RNG_IT_SEI RNG_SR_SEIS /*!< Seed error interrupt */ +/** + * @} + */ + +/** @defgroup RNG_Exported_Constants_Group2 RNG Flag definition + * @{ + */ +#define RNG_FLAG_DRDY RNG_SR_DRDY /*!< Data ready */ +#define RNG_FLAG_CECS RNG_SR_CECS /*!< Clock error current status */ +#define RNG_FLAG_SECS RNG_SR_SECS /*!< Seed error current status */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ + +/** @defgroup RNG_Exported_Macros RNG Exported Macros + * @{ + */ + +/** @brief Reset RNG handle state + * @param __HANDLE__: RNG Handle + * @retval None + */ +#define __HAL_RNG_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_RNG_STATE_RESET) + +/** + * @brief Enables the RNG peripheral. + * @param __HANDLE__: RNG Handle + * @retval None + */ +#define __HAL_RNG_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= RNG_CR_RNGEN) + +/** + * @brief Disables the RNG peripheral. + * @param __HANDLE__: RNG Handle + * @retval None + */ +#define __HAL_RNG_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~RNG_CR_RNGEN) + +/** + * @brief Check the selected RNG flag status. + * @param __HANDLE__: RNG Handle + * @param __FLAG__: RNG flag + * This parameter can be one of the following values: + * @arg RNG_FLAG_DRDY: Data ready + * @arg RNG_FLAG_CECS: Clock error current status + * @arg RNG_FLAG_SECS: Seed error current status + * @retval The new state of __FLAG__ (SET or RESET). + */ +#define __HAL_RNG_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__)) + +/** + * @brief Clears the selected RNG flag status. + * @param __HANDLE__: RNG handle + * @param __FLAG__: RNG flag to clear + * @note WARNING: This is a dummy macro for HAL code alignment, + * flags RNG_FLAG_DRDY, RNG_FLAG_CECS and RNG_FLAG_SECS are read-only. + * @retval None + */ +#define __HAL_RNG_CLEAR_FLAG(__HANDLE__, __FLAG__) /* dummy macro */ + + + +/** + * @brief Enables the RNG interrupts. + * @param __HANDLE__: RNG Handle + * @retval None + */ +#define __HAL_RNG_ENABLE_IT(__HANDLE__) ((__HANDLE__)->Instance->CR |= RNG_CR_IE) + +/** + * @brief Disables the RNG interrupts. + * @param __HANDLE__: RNG Handle + * @retval None + */ +#define __HAL_RNG_DISABLE_IT(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~RNG_CR_IE) + +/** + * @brief Checks whether the specified RNG interrupt has occurred or not. + * @param __HANDLE__: RNG Handle + * @param __INTERRUPT__: specifies the RNG interrupt status flag to check. + * This parameter can be one of the following values: + * @arg RNG_IT_DRDY: Data ready interrupt + * @arg RNG_IT_CEI: Clock error interrupt + * @arg RNG_IT_SEI: Seed error interrupt + * @retval The new state of __INTERRUPT__ (SET or RESET). + */ +#define __HAL_RNG_GET_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->SR & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @brief Clear the RNG interrupt status flags. + * @param __HANDLE__: RNG Handle + * @param __INTERRUPT__: specifies the RNG interrupt status flag to clear. + * This parameter can be one of the following values: + * @arg RNG_IT_CEI: Clock error interrupt + * @arg RNG_IT_SEI: Seed error interrupt + * @note RNG_IT_DRDY flag is read-only, reading RNG_DR register automatically clears RNG_IT_DRDY. + * @retval None + */ +#define __HAL_RNG_CLEAR_IT(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->SR) = ~(__INTERRUPT__)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup RNG_Exported_Functions RNG Exported Functions + * @{ + */ + +/** @defgroup RNG_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng); +HAL_StatusTypeDef HAL_RNG_DeInit (RNG_HandleTypeDef *hrng); +void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng); +void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng); + +/** + * @} + */ + +/** @defgroup RNG_Exported_Functions_Group2 Peripheral Control functions + * @{ + */ +uint32_t HAL_RNG_GetRandomNumber(RNG_HandleTypeDef *hrng); /* Obsolete, use HAL_RNG_GenerateRandomNumber() instead */ +uint32_t HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef *hrng); /* Obsolete, use HAL_RNG_GenerateRandomNumber_IT() instead */ + +HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit); +HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng); +uint32_t HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef *hrng); + +void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng); +void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng); +void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef* hrng, uint32_t random32bit); + +/** + * @} + */ + +/** @defgroup RNG_Exported_Functions_Group3 Peripheral State functions + * @{ + */ +HAL_RNG_StateTypeDef HAL_RNG_GetState(RNG_HandleTypeDef *hrng); + +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/** @defgroup RNG_Private_Types RNG Private Types + * @{ + */ + +/** + * @} + */ + +/* Private defines -----------------------------------------------------------*/ +/** @defgroup RNG_Private_Defines RNG Private Defines + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup RNG_Private_Variables RNG Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup RNG_Private_Constants RNG Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup RNG_Private_Macros RNG Private Macros + * @{ + */ +#define IS_RNG_IT(IT) (((IT) == RNG_IT_CEI) || \ + ((IT) == RNG_IT_SEI)) + +#define IS_RNG_FLAG(FLAG) (((FLAG) == RNG_FLAG_DRDY) || \ + ((FLAG) == RNG_FLAG_CECS) || \ + ((FLAG) == RNG_FLAG_SECS)) + +/** + * @} + */ + +/* Private functions prototypes ----------------------------------------------*/ +/** @defgroup RNG_Private_Functions_Prototypes RNG Private Functions Prototypes + * @{ + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup RNG_Private_Functions RNG Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F4xx_HAL_RNG_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc.h new file mode 100644 index 0000000..76bf948 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc.h @@ -0,0 +1,830 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_rtc.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of RTC HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_RTC_H +#define __STM32F4xx_HAL_RTC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup RTC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup RTC_Exported_Types RTC Exported Types + * @{ + */ + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_RTC_STATE_RESET = 0x00, /*!< RTC not yet initialized or disabled */ + HAL_RTC_STATE_READY = 0x01, /*!< RTC initialized and ready for use */ + HAL_RTC_STATE_BUSY = 0x02, /*!< RTC process is ongoing */ + HAL_RTC_STATE_TIMEOUT = 0x03, /*!< RTC timeout state */ + HAL_RTC_STATE_ERROR = 0x04 /*!< RTC error state */ + +}HAL_RTCStateTypeDef; + +/** + * @brief RTC Configuration Structure definition + */ +typedef struct +{ + uint32_t HourFormat; /*!< Specifies the RTC Hour Format. + This parameter can be a value of @ref RTC_Hour_Formats */ + + uint32_t AsynchPrediv; /*!< Specifies the RTC Asynchronous Predivider value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x7F */ + + uint32_t SynchPrediv; /*!< Specifies the RTC Synchronous Predivider value. + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0x7FFF */ + + uint32_t OutPut; /*!< Specifies which signal will be routed to the RTC output. + This parameter can be a value of @ref RTC_Output_selection_Definitions */ + + uint32_t OutPutPolarity; /*!< Specifies the polarity of the output signal. + This parameter can be a value of @ref RTC_Output_Polarity_Definitions */ + + uint32_t OutPutType; /*!< Specifies the RTC Output Pin mode. + This parameter can be a value of @ref RTC_Output_Type_ALARM_OUT */ +}RTC_InitTypeDef; + +/** + * @brief RTC Time structure definition + */ +typedef struct +{ + uint8_t Hours; /*!< Specifies the RTC Time Hour. + This parameter must be a number between Min_Data = 0 and Max_Data = 12 if the RTC_HourFormat_12 is selected. + This parameter must be a number between Min_Data = 0 and Max_Data = 23 if the RTC_HourFormat_24 is selected */ + + uint8_t Minutes; /*!< Specifies the RTC Time Minutes. + This parameter must be a number between Min_Data = 0 and Max_Data = 59 */ + + uint8_t Seconds; /*!< Specifies the RTC Time Seconds. + This parameter must be a number between Min_Data = 0 and Max_Data = 59 */ + + uint8_t TimeFormat; /*!< Specifies the RTC AM/PM Time. + This parameter can be a value of @ref RTC_AM_PM_Definitions */ + + uint32_t SubSeconds; /*!< Specifies the RTC_SSR RTC Sub Second register content. + This parameter corresponds to a time unit range between [0-1] Second + with [1 Sec / SecondFraction +1] granularity */ + + uint32_t SecondFraction; /*!< Specifies the range or granularity of Sub Second register content + corresponding to Synchronous pre-scaler factor value (PREDIV_S) + This parameter corresponds to a time unit range between [0-1] Second + with [1 Sec / SecondFraction +1] granularity. + This field will be used only by HAL_RTC_GetTime function */ + + uint32_t DayLightSaving; /*!< Specifies DayLight Save Operation. + This parameter can be a value of @ref RTC_DayLightSaving_Definitions */ + + uint32_t StoreOperation; /*!< Specifies RTC_StoreOperation value to be written in the BCK bit + in CR register to store the operation. + This parameter can be a value of @ref RTC_StoreOperation_Definitions */ +}RTC_TimeTypeDef; + +/** + * @brief RTC Date structure definition + */ +typedef struct +{ + uint8_t WeekDay; /*!< Specifies the RTC Date WeekDay. + This parameter can be a value of @ref RTC_WeekDay_Definitions */ + + uint8_t Month; /*!< Specifies the RTC Date Month (in BCD format). + This parameter can be a value of @ref RTC_Month_Date_Definitions */ + + uint8_t Date; /*!< Specifies the RTC Date. + This parameter must be a number between Min_Data = 1 and Max_Data = 31 */ + + uint8_t Year; /*!< Specifies the RTC Date Year. + This parameter must be a number between Min_Data = 0 and Max_Data = 99 */ + +}RTC_DateTypeDef; + +/** + * @brief RTC Alarm structure definition + */ +typedef struct +{ + RTC_TimeTypeDef AlarmTime; /*!< Specifies the RTC Alarm Time members */ + + uint32_t AlarmMask; /*!< Specifies the RTC Alarm Masks. + This parameter can be a value of @ref RTC_AlarmMask_Definitions */ + + uint32_t AlarmSubSecondMask; /*!< Specifies the RTC Alarm SubSeconds Masks. + This parameter can be a value of @ref RTC_Alarm_Sub_Seconds_Masks_Definitions */ + + uint32_t AlarmDateWeekDaySel; /*!< Specifies the RTC Alarm is on Date or WeekDay. + This parameter can be a value of @ref RTC_AlarmDateWeekDay_Definitions */ + + uint8_t AlarmDateWeekDay; /*!< Specifies the RTC Alarm Date/WeekDay. + If the Alarm Date is selected, this parameter must be set to a value in the 1-31 range. + If the Alarm WeekDay is selected, this parameter can be a value of @ref RTC_WeekDay_Definitions */ + + uint32_t Alarm; /*!< Specifies the alarm . + This parameter can be a value of @ref RTC_Alarms_Definitions */ +}RTC_AlarmTypeDef; + +/** + * @brief RTC Handle Structure definition + */ +typedef struct +{ + RTC_TypeDef *Instance; /*!< Register base address */ + + RTC_InitTypeDef Init; /*!< RTC required parameters */ + + HAL_LockTypeDef Lock; /*!< RTC locking object */ + + __IO HAL_RTCStateTypeDef State; /*!< Time communication state */ + +}RTC_HandleTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RTC_Exported_Constants RTC Exported Constants + * @{ + */ + +/** @defgroup RTC_Hour_Formats RTC Hour Formats + * @{ + */ +#define RTC_HOURFORMAT_24 ((uint32_t)0x00000000) +#define RTC_HOURFORMAT_12 ((uint32_t)0x00000040) +/** + * @} + */ + +/** @defgroup RTC_Output_selection_Definitions RTC Output Selection Definitions + * @{ + */ +#define RTC_OUTPUT_DISABLE ((uint32_t)0x00000000) +#define RTC_OUTPUT_ALARMA ((uint32_t)0x00200000) +#define RTC_OUTPUT_ALARMB ((uint32_t)0x00400000) +#define RTC_OUTPUT_WAKEUP ((uint32_t)0x00600000) +/** + * @} + */ + +/** @defgroup RTC_Output_Polarity_Definitions RTC Output Polarity Definitions + * @{ + */ +#define RTC_OUTPUT_POLARITY_HIGH ((uint32_t)0x00000000) +#define RTC_OUTPUT_POLARITY_LOW ((uint32_t)0x00100000) +/** + * @} + */ + +/** @defgroup RTC_Output_Type_ALARM_OUT RTC Output Type ALARM OUT + * @{ + */ +#define RTC_OUTPUT_TYPE_OPENDRAIN ((uint32_t)0x00000000) +#define RTC_OUTPUT_TYPE_PUSHPULL ((uint32_t)0x00040000) +/** + * @} + */ + +/** @defgroup RTC_AM_PM_Definitions RTC AM PM Definitions + * @{ + */ +#define RTC_HOURFORMAT12_AM ((uint8_t)0x00) +#define RTC_HOURFORMAT12_PM ((uint8_t)0x40) +/** + * @} + */ + +/** @defgroup RTC_DayLightSaving_Definitions RTC DayLight Saving Definitions + * @{ + */ +#define RTC_DAYLIGHTSAVING_SUB1H ((uint32_t)0x00020000) +#define RTC_DAYLIGHTSAVING_ADD1H ((uint32_t)0x00010000) +#define RTC_DAYLIGHTSAVING_NONE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup RTC_StoreOperation_Definitions RTC Store Operation Definitions + * @{ + */ +#define RTC_STOREOPERATION_RESET ((uint32_t)0x00000000) +#define RTC_STOREOPERATION_SET ((uint32_t)0x00040000) +/** + * @} + */ + +/** @defgroup RTC_Input_parameter_format_definitions RTC Input Parameter Format Definitions + * @{ + */ +#define RTC_FORMAT_BIN ((uint32_t)0x000000000) +#define RTC_FORMAT_BCD ((uint32_t)0x000000001) +/** + * @} + */ + +/** @defgroup RTC_Month_Date_Definitions RTC Month Date Definitions + * @{ + */ +/* Coded in BCD format */ +#define RTC_MONTH_JANUARY ((uint8_t)0x01) +#define RTC_MONTH_FEBRUARY ((uint8_t)0x02) +#define RTC_MONTH_MARCH ((uint8_t)0x03) +#define RTC_MONTH_APRIL ((uint8_t)0x04) +#define RTC_MONTH_MAY ((uint8_t)0x05) +#define RTC_MONTH_JUNE ((uint8_t)0x06) +#define RTC_MONTH_JULY ((uint8_t)0x07) +#define RTC_MONTH_AUGUST ((uint8_t)0x08) +#define RTC_MONTH_SEPTEMBER ((uint8_t)0x09) +#define RTC_MONTH_OCTOBER ((uint8_t)0x10) +#define RTC_MONTH_NOVEMBER ((uint8_t)0x11) +#define RTC_MONTH_DECEMBER ((uint8_t)0x12) +/** + * @} + */ + +/** @defgroup RTC_WeekDay_Definitions RTC WeekDay Definitions + * @{ + */ +#define RTC_WEEKDAY_MONDAY ((uint8_t)0x01) +#define RTC_WEEKDAY_TUESDAY ((uint8_t)0x02) +#define RTC_WEEKDAY_WEDNESDAY ((uint8_t)0x03) +#define RTC_WEEKDAY_THURSDAY ((uint8_t)0x04) +#define RTC_WEEKDAY_FRIDAY ((uint8_t)0x05) +#define RTC_WEEKDAY_SATURDAY ((uint8_t)0x06) +#define RTC_WEEKDAY_SUNDAY ((uint8_t)0x07) +/** + * @} + */ + +/** @defgroup RTC_AlarmDateWeekDay_Definitions RTC Alarm Date WeekDay Definitions + * @{ + */ +#define RTC_ALARMDATEWEEKDAYSEL_DATE ((uint32_t)0x00000000) +#define RTC_ALARMDATEWEEKDAYSEL_WEEKDAY ((uint32_t)0x40000000) +/** + * @} + */ + +/** @defgroup RTC_AlarmMask_Definitions RTC Alarm Mask Definitions + * @{ + */ +#define RTC_ALARMMASK_NONE ((uint32_t)0x00000000) +#define RTC_ALARMMASK_DATEWEEKDAY RTC_ALRMAR_MSK4 +#define RTC_ALARMMASK_HOURS RTC_ALRMAR_MSK3 +#define RTC_ALARMMASK_MINUTES RTC_ALRMAR_MSK2 +#define RTC_ALARMMASK_SECONDS RTC_ALRMAR_MSK1 +#define RTC_ALARMMASK_ALL ((uint32_t)0x80808080) +/** + * @} + */ + +/** @defgroup RTC_Alarms_Definitions RTC Alarms Definitions + * @{ + */ +#define RTC_ALARM_A RTC_CR_ALRAE +#define RTC_ALARM_B RTC_CR_ALRBE +/** + * @} + */ + +/** @defgroup RTC_Alarm_Sub_Seconds_Masks_Definitions RTC Alarm Sub Seconds Masks Definitions + * @{ + */ +#define RTC_ALARMSUBSECONDMASK_ALL ((uint32_t)0x00000000) /*!< All Alarm SS fields are masked. + There is no comparison on sub seconds + for Alarm */ +#define RTC_ALARMSUBSECONDMASK_SS14_1 ((uint32_t)0x01000000) /*!< SS[14:1] are don't care in Alarm + comparison. Only SS[0] is compared. */ +#define RTC_ALARMSUBSECONDMASK_SS14_2 ((uint32_t)0x02000000) /*!< SS[14:2] are don't care in Alarm + comparison. Only SS[1:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_3 ((uint32_t)0x03000000) /*!< SS[14:3] are don't care in Alarm + comparison. Only SS[2:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_4 ((uint32_t)0x04000000) /*!< SS[14:4] are don't care in Alarm + comparison. Only SS[3:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_5 ((uint32_t)0x05000000) /*!< SS[14:5] are don't care in Alarm + comparison. Only SS[4:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_6 ((uint32_t)0x06000000) /*!< SS[14:6] are don't care in Alarm + comparison. Only SS[5:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_7 ((uint32_t)0x07000000) /*!< SS[14:7] are don't care in Alarm + comparison. Only SS[6:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_8 ((uint32_t)0x08000000) /*!< SS[14:8] are don't care in Alarm + comparison. Only SS[7:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_9 ((uint32_t)0x09000000) /*!< SS[14:9] are don't care in Alarm + comparison. Only SS[8:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_10 ((uint32_t)0x0A000000) /*!< SS[14:10] are don't care in Alarm + comparison. Only SS[9:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_11 ((uint32_t)0x0B000000) /*!< SS[14:11] are don't care in Alarm + comparison. Only SS[10:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_12 ((uint32_t)0x0C000000) /*!< SS[14:12] are don't care in Alarm + comparison.Only SS[11:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14_13 ((uint32_t)0x0D000000) /*!< SS[14:13] are don't care in Alarm + comparison. Only SS[12:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_SS14 ((uint32_t)0x0E000000) /*!< SS[14] is don't care in Alarm + comparison.Only SS[13:0] are compared */ +#define RTC_ALARMSUBSECONDMASK_NONE ((uint32_t)0x0F000000) /*!< SS[14:0] are compared and must match + to activate alarm. */ +/** + * @} + */ + +/** @defgroup RTC_Interrupts_Definitions RTC Interrupts Definitions + * @{ + */ +#define RTC_IT_TS ((uint32_t)0x00008000) +#define RTC_IT_WUT ((uint32_t)0x00004000) +#define RTC_IT_ALRB ((uint32_t)0x00002000) +#define RTC_IT_ALRA ((uint32_t)0x00001000) +#define RTC_IT_TAMP ((uint32_t)0x00000004) /* Used only to Enable the Tamper Interrupt */ +#define RTC_IT_TAMP1 ((uint32_t)0x00020000) +#define RTC_IT_TAMP2 ((uint32_t)0x00040000) +/** + * @} + */ + +/** @defgroup RTC_Flags_Definitions RTC Flags Definitions + * @{ + */ +#define RTC_FLAG_RECALPF ((uint32_t)0x00010000) +#define RTC_FLAG_TAMP2F ((uint32_t)0x00004000) +#define RTC_FLAG_TAMP1F ((uint32_t)0x00002000) +#define RTC_FLAG_TSOVF ((uint32_t)0x00001000) +#define RTC_FLAG_TSF ((uint32_t)0x00000800) +#define RTC_FLAG_WUTF ((uint32_t)0x00000400) +#define RTC_FLAG_ALRBF ((uint32_t)0x00000200) +#define RTC_FLAG_ALRAF ((uint32_t)0x00000100) +#define RTC_FLAG_INITF ((uint32_t)0x00000040) +#define RTC_FLAG_RSF ((uint32_t)0x00000020) +#define RTC_FLAG_INITS ((uint32_t)0x00000010) +#define RTC_FLAG_SHPF ((uint32_t)0x00000008) +#define RTC_FLAG_WUTWF ((uint32_t)0x00000004) +#define RTC_FLAG_ALRBWF ((uint32_t)0x00000002) +#define RTC_FLAG_ALRAWF ((uint32_t)0x00000001) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup RTC_Exported_Macros RTC Exported Macros + * @{ + */ + +/** @brief Reset RTC handle state + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_RTC_STATE_RESET) + +/** + * @brief Disable the write protection for RTC registers. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_WRITEPROTECTION_DISABLE(__HANDLE__) \ + do{ \ + (__HANDLE__)->Instance->WPR = 0xCA; \ + (__HANDLE__)->Instance->WPR = 0x53; \ + } while(0) + +/** + * @brief Enable the write protection for RTC registers. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_WRITEPROTECTION_ENABLE(__HANDLE__) \ + do{ \ + (__HANDLE__)->Instance->WPR = 0xFF; \ + } while(0) + +/** + * @brief Enable the RTC ALARMA peripheral. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_ALARMA_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= (RTC_CR_ALRAE)) + +/** + * @brief Disable the RTC ALARMA peripheral. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_ALARMA_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~(RTC_CR_ALRAE)) + +/** + * @brief Enable the RTC ALARMB peripheral. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_ALARMB_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= (RTC_CR_ALRBE)) + +/** + * @brief Disable the RTC ALARMB peripheral. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_ALARMB_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~(RTC_CR_ALRBE)) + +/** + * @brief Enable the RTC Alarm interrupt. + * @param __HANDLE__: specifies the RTC handle. + * @param __INTERRUPT__: specifies the RTC Alarm interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg RTC_IT_ALRA: Alarm A interrupt + * @arg RTC_IT_ALRB: Alarm B interrupt + * @retval None + */ +#define __HAL_RTC_ALARM_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR |= (__INTERRUPT__)) + +/** + * @brief Disable the RTC Alarm interrupt. + * @param __HANDLE__: specifies the RTC handle. + * @param __INTERRUPT__: specifies the RTC Alarm interrupt sources to be enabled or disabled. + * This parameter can be any combination of the following values: + * @arg RTC_IT_ALRA: Alarm A interrupt + * @arg RTC_IT_ALRB: Alarm B interrupt + * @retval None + */ +#define __HAL_RTC_ALARM_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR &= ~(__INTERRUPT__)) + +/** + * @brief Check whether the specified RTC Alarm interrupt has occurred or not. + * @param __HANDLE__: specifies the RTC handle. + * @param __INTERRUPT__: specifies the RTC Alarm interrupt to check. + * This parameter can be: + * @arg RTC_IT_ALRA: Alarm A interrupt + * @arg RTC_IT_ALRB: Alarm B interrupt + * @retval None + */ +#define __HAL_RTC_ALARM_GET_IT(__HANDLE__, __INTERRUPT__) (((((__HANDLE__)->Instance->ISR)& ((__INTERRUPT__)>> 4)) != RESET)? SET : RESET) + +/** + * @brief Get the selected RTC Alarm's flag status. + * @param __HANDLE__: specifies the RTC handle. + * @param __FLAG__: specifies the RTC Alarm Flag to check. + * This parameter can be: + * @arg RTC_FLAG_ALRAF + * @arg RTC_FLAG_ALRBF + * @arg RTC_FLAG_ALRAWF + * @arg RTC_FLAG_ALRBWF + * @retval None + */ +#define __HAL_RTC_ALARM_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->ISR) & (__FLAG__)) != RESET)? SET : RESET) + +/** + * @brief Clear the RTC Alarm's pending flags. + * @param __HANDLE__: specifies the RTC handle. + * @param __FLAG__: specifies the RTC Alarm Flag sources to be enabled or disabled. + * This parameter can be: + * @arg RTC_FLAG_ALRAF + * @arg RTC_FLAG_ALRBF + * @retval None + */ +#define __HAL_RTC_ALARM_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ISR) = (~((__FLAG__) | RTC_ISR_INIT)|((__HANDLE__)->Instance->ISR & RTC_ISR_INIT)) + + +/** + * @brief Check whether the specified RTC Alarm interrupt has been enabled or not. + * @param __HANDLE__: specifies the RTC handle. + * @param __INTERRUPT__: specifies the RTC Alarm interrupt sources to check. + * This parameter can be: + * @arg RTC_IT_ALRA: Alarm A interrupt + * @arg RTC_IT_ALRB: Alarm B interrupt + * @retval None + */ +#define __HAL_RTC_ALARM_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((((__HANDLE__)->Instance->CR) & (__INTERRUPT__)) != RESET) ? SET : RESET) + +/** + * @brief Enable interrupt on the RTC Alarm associated Exti line. + * @retval None + */ +#define __HAL_RTC_ALARM_EXTI_ENABLE_IT() (EXTI->IMR |= RTC_EXTI_LINE_ALARM_EVENT) + +/** + * @brief Disable interrupt on the RTC Alarm associated Exti line. + * @retval None + */ +#define __HAL_RTC_ALARM_EXTI_DISABLE_IT() (EXTI->IMR &= ~(RTC_EXTI_LINE_ALARM_EVENT)) + +/** + * @brief Enable event on the RTC Alarm associated Exti line. + * @retval None. + */ +#define __HAL_RTC_ALARM_EXTI_ENABLE_EVENT() (EXTI->EMR |= RTC_EXTI_LINE_ALARM_EVENT) + +/** + * @brief Disable event on the RTC Alarm associated Exti line. + * @retval None. + */ +#define __HAL_RTC_ALARM_EXTI_DISABLE_EVENT() (EXTI->EMR &= ~(RTC_EXTI_LINE_ALARM_EVENT)) + +/** + * @brief Enable falling edge trigger on the RTC Alarm associated Exti line. + * @retval None. + */ +#define __HAL_RTC_ALARM_EXTI_ENABLE_FALLING_EDGE() (EXTI->FTSR |= RTC_EXTI_LINE_ALARM_EVENT) + +/** + * @brief Disable falling edge trigger on the RTC Alarm associated Exti line. + * @retval None. + */ +#define __HAL_RTC_ALARM_EXTI_DISABLE_FALLING_EDGE() (EXTI->FTSR &= ~(RTC_EXTI_LINE_ALARM_EVENT)) + +/** + * @brief Enable rising edge trigger on the RTC Alarm associated Exti line. + * @retval None. + */ +#define __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE() (EXTI->RTSR |= RTC_EXTI_LINE_ALARM_EVENT) + +/** + * @brief Disable rising edge trigger on the RTC Alarm associated Exti line. + * @retval None. + */ +#define __HAL_RTC_ALARM_EXTI_DISABLE_RISING_EDGE() (EXTI->RTSR &= ~(RTC_EXTI_LINE_ALARM_EVENT)) + +/** + * @brief Enable rising & falling edge trigger on the RTC Alarm associated Exti line. + * @retval None. + */ +#define __HAL_RTC_ALARM_EXTI_ENABLE_RISING_FALLING_EDGE() __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE();__HAL_RTC_ALARM_EXTI_ENABLE_FALLING_EDGE(); + +/** + * @brief Disable rising & falling edge trigger on the RTC Alarm associated Exti line. + * @retval None. + */ +#define __HAL_RTC_ALARM_EXTI_DISABLE_RISING_FALLING_EDGE() __HAL_RTC_ALARM_EXTI_DISABLE_RISING_EDGE();__HAL_RTC_ALARM_EXTI_DISABLE_FALLING_EDGE(); + +/** + * @brief Check whether the RTC Alarm associated Exti line interrupt flag is set or not. + * @retval Line Status. + */ +#define __HAL_RTC_ALARM_EXTI_GET_FLAG() (EXTI->PR & RTC_EXTI_LINE_ALARM_EVENT) + +/** + * @brief Clear the RTC Alarm associated Exti line flag. + * @retval None. + */ +#define __HAL_RTC_ALARM_EXTI_CLEAR_FLAG() (EXTI->PR = RTC_EXTI_LINE_ALARM_EVENT) + +/** + * @brief Generate a Software interrupt on RTC Alarm associated Exti line. + * @retval None. + */ +#define __HAL_RTC_ALARM_EXTI_GENERATE_SWIT() (EXTI->SWIER |= RTC_EXTI_LINE_ALARM_EVENT) +/** + * @} + */ + +/* Include RTC HAL Extension module */ +#include "stm32f4xx_hal_rtc_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup RTC_Exported_Functions + * @{ + */ + +/** @addtogroup RTC_Exported_Functions_Group1 + * @{ + */ +/* Initialization and de-initialization functions ****************************/ +HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTC_DeInit(RTC_HandleTypeDef *hrtc); +void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc); +void HAL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc); +/** + * @} + */ + +/** @addtogroup RTC_Exported_Functions_Group2 + * @{ + */ +/* RTC Time and Date functions ************************************************/ +HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format); +HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format); +HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format); +HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format); +/** + * @} + */ + +/** @addtogroup RTC_Exported_Functions_Group3 + * @{ + */ +/* RTC Alarm functions ********************************************************/ +HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format); +HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format); +HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm); +HAL_StatusTypeDef HAL_RTC_GetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Alarm, uint32_t Format); +void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout); +void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc); +/** + * @} + */ + +/** @addtogroup RTC_Exported_Functions_Group4 + * @{ + */ +/* Peripheral Control functions ***********************************************/ +HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef* hrtc); +/** + * @} + */ + +/** @addtogroup RTC_Exported_Functions_Group5 + * @{ + */ +/* Peripheral State functions *************************************************/ +HAL_RTCStateTypeDef HAL_RTC_GetState(RTC_HandleTypeDef *hrtc); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup RTC_Private_Constants RTC Private Constants + * @{ + */ +/* Masks Definition */ +#define RTC_TR_RESERVED_MASK ((uint32_t)0x007F7F7F) +#define RTC_DR_RESERVED_MASK ((uint32_t)0x00FFFF3F) +#define RTC_INIT_MASK ((uint32_t)0xFFFFFFFF) +#define RTC_RSF_MASK ((uint32_t)0xFFFFFF5F) +#define RTC_FLAGS_MASK ((uint32_t)(RTC_FLAG_TSOVF | RTC_FLAG_TSF | RTC_FLAG_WUTF | \ + RTC_FLAG_ALRBF | RTC_FLAG_ALRAF | RTC_FLAG_INITF | \ + RTC_FLAG_RSF | RTC_FLAG_INITS | RTC_FLAG_WUTWF | \ + RTC_FLAG_ALRBWF | RTC_FLAG_ALRAWF | RTC_FLAG_TAMP1F | \ + RTC_FLAG_RECALPF | RTC_FLAG_SHPF)) + +#define RTC_TIMEOUT_VALUE 1000 + +#define RTC_EXTI_LINE_ALARM_EVENT ((uint32_t)EXTI_IMR_MR17) /*!< External interrupt line 17 Connected to the RTC Alarm event */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup RTC_Private_Macros RTC Private Macros + * @{ + */ + +/** @defgroup RTC_IS_RTC_Definitions RTC Private macros to check input parameters + * @{ + */ +#define IS_RTC_HOUR_FORMAT(FORMAT) (((FORMAT) == RTC_HOURFORMAT_12) || \ + ((FORMAT) == RTC_HOURFORMAT_24)) +#define IS_RTC_OUTPUT(OUTPUT) (((OUTPUT) == RTC_OUTPUT_DISABLE) || \ + ((OUTPUT) == RTC_OUTPUT_ALARMA) || \ + ((OUTPUT) == RTC_OUTPUT_ALARMB) || \ + ((OUTPUT) == RTC_OUTPUT_WAKEUP)) +#define IS_RTC_OUTPUT_POL(POL) (((POL) == RTC_OUTPUT_POLARITY_HIGH) || \ + ((POL) == RTC_OUTPUT_POLARITY_LOW)) +#define IS_RTC_OUTPUT_TYPE(TYPE) (((TYPE) == RTC_OUTPUT_TYPE_OPENDRAIN) || \ + ((TYPE) == RTC_OUTPUT_TYPE_PUSHPULL)) +#define IS_RTC_HOUR12(HOUR) (((HOUR) > (uint32_t)0) && ((HOUR) <= (uint32_t)12)) +#define IS_RTC_HOUR24(HOUR) ((HOUR) <= (uint32_t)23) +#define IS_RTC_ASYNCH_PREDIV(PREDIV) ((PREDIV) <= (uint32_t)0x7F) +#define IS_RTC_SYNCH_PREDIV(PREDIV) ((PREDIV) <= (uint32_t)0x7FFF) +#define IS_RTC_MINUTES(MINUTES) ((MINUTES) <= (uint32_t)59) +#define IS_RTC_SECONDS(SECONDS) ((SECONDS) <= (uint32_t)59) + +#define IS_RTC_HOURFORMAT12(PM) (((PM) == RTC_HOURFORMAT12_AM) || ((PM) == RTC_HOURFORMAT12_PM)) +#define IS_RTC_DAYLIGHT_SAVING(SAVE) (((SAVE) == RTC_DAYLIGHTSAVING_SUB1H) || \ + ((SAVE) == RTC_DAYLIGHTSAVING_ADD1H) || \ + ((SAVE) == RTC_DAYLIGHTSAVING_NONE)) +#define IS_RTC_STORE_OPERATION(OPERATION) (((OPERATION) == RTC_STOREOPERATION_RESET) || \ + ((OPERATION) == RTC_STOREOPERATION_SET)) +#define IS_RTC_FORMAT(FORMAT) (((FORMAT) == RTC_FORMAT_BIN) || ((FORMAT) == RTC_FORMAT_BCD)) +#define IS_RTC_YEAR(YEAR) ((YEAR) <= (uint32_t)99) +#define IS_RTC_MONTH(MONTH) (((MONTH) >= (uint32_t)1) && ((MONTH) <= (uint32_t)12)) +#define IS_RTC_DATE(DATE) (((DATE) >= (uint32_t)1) && ((DATE) <= (uint32_t)31)) +#define IS_RTC_WEEKDAY(WEEKDAY) (((WEEKDAY) == RTC_WEEKDAY_MONDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_TUESDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_WEDNESDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_THURSDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_FRIDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_SATURDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_SUNDAY)) +#define IS_RTC_ALARM_DATE_WEEKDAY_DATE(DATE) (((DATE) >(uint32_t) 0) && ((DATE) <= (uint32_t)31)) +#define IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(WEEKDAY) (((WEEKDAY) == RTC_WEEKDAY_MONDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_TUESDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_WEDNESDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_THURSDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_FRIDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_SATURDAY) || \ + ((WEEKDAY) == RTC_WEEKDAY_SUNDAY)) +#define IS_RTC_ALARM_DATE_WEEKDAY_SEL(SEL) (((SEL) == RTC_ALARMDATEWEEKDAYSEL_DATE) || \ + ((SEL) == RTC_ALARMDATEWEEKDAYSEL_WEEKDAY)) +#define IS_RTC_ALARM_MASK(MASK) (((MASK) & 0x7F7F7F7F) == (uint32_t)RESET) +#define IS_RTC_ALARM(ALARM) (((ALARM) == RTC_ALARM_A) || ((ALARM) == RTC_ALARM_B)) +#define IS_RTC_ALARM_SUB_SECOND_VALUE(VALUE) ((VALUE) <= (uint32_t)0x00007FFF) + +#define IS_RTC_ALARM_SUB_SECOND_MASK(MASK) (((MASK) == RTC_ALARMSUBSECONDMASK_ALL) || \ + ((MASK) == RTC_ALARMSUBSECONDMASK_SS14_1) || \ + ((MASK) == RTC_ALARMSUBSECONDMASK_SS14_2) || \ + ((MASK) == RTC_ALARMSUBSECONDMASK_SS14_3) || \ + ((MASK) == RTC_ALARMSUBSECONDMASK_SS14_4) || \ + ((MASK) == RTC_ALARMSUBSECONDMASK_SS14_5) || \ + ((MASK) == RTC_ALARMSUBSECONDMASK_SS14_6) || \ + ((MASK) == RTC_ALARMSUBSECONDMASK_SS14_7) || \ + ((MASK) == RTC_ALARMSUBSECONDMASK_SS14_8) || \ + ((MASK) == RTC_ALARMSUBSECONDMASK_SS14_9) || \ + ((MASK) == RTC_ALARMSUBSECONDMASK_SS14_10) || \ + ((MASK) == RTC_ALARMSUBSECONDMASK_SS14_11) || \ + ((MASK) == RTC_ALARMSUBSECONDMASK_SS14_12) || \ + ((MASK) == RTC_ALARMSUBSECONDMASK_SS14_13) || \ + ((MASK) == RTC_ALARMSUBSECONDMASK_SS14) || \ + ((MASK) == RTC_ALARMSUBSECONDMASK_NONE)) +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup RTC_Private_Functions RTC Private Functions + * @{ + */ +HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef* hrtc); +uint8_t RTC_ByteToBcd2(uint8_t Value); +uint8_t RTC_Bcd2ToByte(uint8_t Value); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_RTC_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc_ex.h new file mode 100644 index 0000000..dcc820e --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rtc_ex.h @@ -0,0 +1,1000 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_rtc_ex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of RTC HAL Extension module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_RTC_EX_H +#define __STM32F4xx_HAL_RTC_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup RTCEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup RTCEx_Exported_Types RTCEx Exported Types + * @{ + */ + +/** + * @brief RTC Tamper structure definition + */ +typedef struct +{ + uint32_t Tamper; /*!< Specifies the Tamper Pin. + This parameter can be a value of @ref RTCEx_Tamper_Pins_Definitions */ + + uint32_t PinSelection; /*!< Specifies the Tamper Pin. + This parameter can be a value of @ref RTCEx_Tamper_Pins_Selection */ + + uint32_t Trigger; /*!< Specifies the Tamper Trigger. + This parameter can be a value of @ref RTCEx_Tamper_Trigger_Definitions */ + + uint32_t Filter; /*!< Specifies the RTC Filter Tamper. + This parameter can be a value of @ref RTCEx_Tamper_Filter_Definitions */ + + uint32_t SamplingFrequency; /*!< Specifies the sampling frequency. + This parameter can be a value of @ref RTCEx_Tamper_Sampling_Frequencies_Definitions */ + + uint32_t PrechargeDuration; /*!< Specifies the Precharge Duration . + This parameter can be a value of @ref RTCEx_Tamper_Pin_Precharge_Duration_Definitions */ + + uint32_t TamperPullUp; /*!< Specifies the Tamper PullUp . + This parameter can be a value of @ref RTCEx_Tamper_Pull_UP_Definitions */ + + uint32_t TimeStampOnTamperDetection; /*!< Specifies the TimeStampOnTamperDetection. + This parameter can be a value of @ref RTCEx_Tamper_TimeStampOnTamperDetection_Definitions */ +}RTC_TamperTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup RTCEx_Exported_Constants RTCEx Exported Constants + * @{ + */ + +/** @defgroup RTCEx_Backup_Registers_Definitions RTC Backup Registers Definitions + * @{ + */ +#define RTC_BKP_DR0 ((uint32_t)0x00000000) +#define RTC_BKP_DR1 ((uint32_t)0x00000001) +#define RTC_BKP_DR2 ((uint32_t)0x00000002) +#define RTC_BKP_DR3 ((uint32_t)0x00000003) +#define RTC_BKP_DR4 ((uint32_t)0x00000004) +#define RTC_BKP_DR5 ((uint32_t)0x00000005) +#define RTC_BKP_DR6 ((uint32_t)0x00000006) +#define RTC_BKP_DR7 ((uint32_t)0x00000007) +#define RTC_BKP_DR8 ((uint32_t)0x00000008) +#define RTC_BKP_DR9 ((uint32_t)0x00000009) +#define RTC_BKP_DR10 ((uint32_t)0x0000000A) +#define RTC_BKP_DR11 ((uint32_t)0x0000000B) +#define RTC_BKP_DR12 ((uint32_t)0x0000000C) +#define RTC_BKP_DR13 ((uint32_t)0x0000000D) +#define RTC_BKP_DR14 ((uint32_t)0x0000000E) +#define RTC_BKP_DR15 ((uint32_t)0x0000000F) +#define RTC_BKP_DR16 ((uint32_t)0x00000010) +#define RTC_BKP_DR17 ((uint32_t)0x00000011) +#define RTC_BKP_DR18 ((uint32_t)0x00000012) +#define RTC_BKP_DR19 ((uint32_t)0x00000013) +/** + * @} + */ + +/** @defgroup RTCEx_Time_Stamp_Edges_definitions RTC TimeStamp Edges Definitions + * @{ + */ +#define RTC_TIMESTAMPEDGE_RISING ((uint32_t)0x00000000) +#define RTC_TIMESTAMPEDGE_FALLING ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_Pins_Definitions RTC Tamper Pins Definitions + * @{ + */ +#define RTC_TAMPER_1 RTC_TAFCR_TAMP1E +#define RTC_TAMPER_2 RTC_TAFCR_TAMP2E +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_Pins_Selection RTC tamper Pins Selection + * @{ + */ +#define RTC_TAMPERPIN_DEFAULT ((uint32_t)0x00000000) +#define RTC_TAMPERPIN_POS1 ((uint32_t)0x00010000) + +/** + * @} + */ + +/** @defgroup RTCEx_TimeStamp_Pin_Selection RTC TimeStamp Pins Selection + * @{ + */ +#define RTC_TIMESTAMPPIN_DEFAULT ((uint32_t)0x00000000) +#define RTC_TIMESTAMPPIN_POS1 ((uint32_t)0x00020000) + +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_Trigger_Definitions RTC Tamper Triggers Definitions + * @{ + */ +#define RTC_TAMPERTRIGGER_RISINGEDGE ((uint32_t)0x00000000) +#define RTC_TAMPERTRIGGER_FALLINGEDGE ((uint32_t)0x00000002) +#define RTC_TAMPERTRIGGER_LOWLEVEL RTC_TAMPERTRIGGER_RISINGEDGE +#define RTC_TAMPERTRIGGER_HIGHLEVEL RTC_TAMPERTRIGGER_FALLINGEDGE +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_Filter_Definitions RTC Tamper Filter Definitions + * @{ + */ +#define RTC_TAMPERFILTER_DISABLE ((uint32_t)0x00000000) /*!< Tamper filter is disabled */ + +#define RTC_TAMPERFILTER_2SAMPLE ((uint32_t)0x00000800) /*!< Tamper is activated after 2 + consecutive samples at the active level */ +#define RTC_TAMPERFILTER_4SAMPLE ((uint32_t)0x00001000) /*!< Tamper is activated after 4 + consecutive samples at the active level */ +#define RTC_TAMPERFILTER_8SAMPLE ((uint32_t)0x00001800) /*!< Tamper is activated after 8 + consecutive samples at the active level. */ +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_Sampling_Frequencies_Definitions RTC Tamper Sampling Frequencies Definitions + * @{ + */ +#define RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV32768 ((uint32_t)0x00000000) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 32768 */ +#define RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV16384 ((uint32_t)0x00000100) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 16384 */ +#define RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV8192 ((uint32_t)0x00000200) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 8192 */ +#define RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV4096 ((uint32_t)0x00000300) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 4096 */ +#define RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV2048 ((uint32_t)0x00000400) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 2048 */ +#define RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV1024 ((uint32_t)0x00000500) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 1024 */ +#define RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV512 ((uint32_t)0x00000600) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 512 */ +#define RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV256 ((uint32_t)0x00000700) /*!< Each of the tamper inputs are sampled + with a frequency = RTCCLK / 256 */ +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_Pin_Precharge_Duration_Definitions RTC Tamper Pin Precharge Duration Definitions + * @{ + */ +#define RTC_TAMPERPRECHARGEDURATION_1RTCCLK ((uint32_t)0x00000000) /*!< Tamper pins are pre-charged before + sampling during 1 RTCCLK cycle */ +#define RTC_TAMPERPRECHARGEDURATION_2RTCCLK ((uint32_t)0x00002000) /*!< Tamper pins are pre-charged before + sampling during 2 RTCCLK cycles */ +#define RTC_TAMPERPRECHARGEDURATION_4RTCCLK ((uint32_t)0x00004000) /*!< Tamper pins are pre-charged before + sampling during 4 RTCCLK cycles */ +#define RTC_TAMPERPRECHARGEDURATION_8RTCCLK ((uint32_t)0x00006000) /*!< Tamper pins are pre-charged before + sampling during 8 RTCCLK cycles */ +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_TimeStampOnTamperDetection_Definitions RTC Tamper TimeStamp On Tamper Detection Definitions + * @{ + */ +#define RTC_TIMESTAMPONTAMPERDETECTION_ENABLE ((uint32_t)RTC_TAFCR_TAMPTS) /*!< TimeStamp on Tamper Detection event saved */ +#define RTC_TIMESTAMPONTAMPERDETECTION_DISABLE ((uint32_t)0x00000000) /*!< TimeStamp on Tamper Detection event is not saved */ +/** + * @} + */ + +/** @defgroup RTCEx_Tamper_Pull_UP_Definitions RTC Tamper Pull Up Definitions + * @{ + */ +#define RTC_TAMPER_PULLUP_ENABLE ((uint32_t)0x00000000) /*!< TimeStamp on Tamper Detection event saved */ +#define RTC_TAMPER_PULLUP_DISABLE ((uint32_t)RTC_TAFCR_TAMPPUDIS) /*!< TimeStamp on Tamper Detection event is not saved */ +/** + * @} + */ + +/** @defgroup RTCEx_Wakeup_Timer_Definitions RTC Wake-up Timer Definitions + * @{ + */ +#define RTC_WAKEUPCLOCK_RTCCLK_DIV16 ((uint32_t)0x00000000) +#define RTC_WAKEUPCLOCK_RTCCLK_DIV8 ((uint32_t)0x00000001) +#define RTC_WAKEUPCLOCK_RTCCLK_DIV4 ((uint32_t)0x00000002) +#define RTC_WAKEUPCLOCK_RTCCLK_DIV2 ((uint32_t)0x00000003) +#define RTC_WAKEUPCLOCK_CK_SPRE_16BITS ((uint32_t)0x00000004) +#define RTC_WAKEUPCLOCK_CK_SPRE_17BITS ((uint32_t)0x00000006) +/** + * @} + */ + +/** @defgroup RTCEx_Digital_Calibration_Definitions RTC Digital Calib Definitions + * @{ + */ +#define RTC_CALIBSIGN_POSITIVE ((uint32_t)0x00000000) +#define RTC_CALIBSIGN_NEGATIVE ((uint32_t)0x00000080) +/** + * @} + */ + +/** @defgroup RTCEx_Smooth_calib_period_Definitions RTC Smooth Calib Period Definitions + * @{ + */ +#define RTC_SMOOTHCALIB_PERIOD_32SEC ((uint32_t)0x00000000) /*!< If RTCCLK = 32768 Hz, Smooth calibration + period is 32s, else 2exp20 RTCCLK seconds */ +#define RTC_SMOOTHCALIB_PERIOD_16SEC ((uint32_t)0x00002000) /*!< If RTCCLK = 32768 Hz, Smooth calibration + period is 16s, else 2exp19 RTCCLK seconds */ +#define RTC_SMOOTHCALIB_PERIOD_8SEC ((uint32_t)0x00004000) /*!< If RTCCLK = 32768 Hz, Smooth calibration + period is 8s, else 2exp18 RTCCLK seconds */ +/** + * @} + */ + +/** @defgroup RTCEx_Smooth_calib_Plus_pulses_Definitions RTC Smooth Calib Plus Pulses Definitions + * @{ + */ +#define RTC_SMOOTHCALIB_PLUSPULSES_SET ((uint32_t)0x00008000) /*!< The number of RTCCLK pulses added + during a X -second window = Y - CALM[8:0] + with Y = 512, 256, 128 when X = 32, 16, 8 */ +#define RTC_SMOOTHCALIB_PLUSPULSES_RESET ((uint32_t)0x00000000) /*!< The number of RTCCLK pulses subbstited + during a 32-second window = CALM[8:0] */ +/** + * @} + */ + +/** @defgroup RTCEx_Add_1_Second_Parameter_Definitions RTC Add 1 Second Parameter Definitions + * @{ + */ +#define RTC_SHIFTADD1S_RESET ((uint32_t)0x00000000) +#define RTC_SHIFTADD1S_SET ((uint32_t)0x80000000) +/** + * @} + */ + + + /** @defgroup RTCEx_Calib_Output_selection_Definitions RTC Calib Output Selection Definitions + * @{ + */ +#define RTC_CALIBOUTPUT_512HZ ((uint32_t)0x00000000) +#define RTC_CALIBOUTPUT_1HZ ((uint32_t)0x00080000) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup RTCEx_Exported_Macros RTCEx Exported Macros + * @{ + */ + +/* ---------------------------------WAKEUPTIMER---------------------------------*/ +/** @defgroup RTCEx_WakeUp_Timer RTC WakeUp Timer + * @{ + */ + +/** + * @brief Enable the RTC WakeUp Timer peripheral. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= (RTC_CR_WUTE)) + +/** + * @brief Disable the RTC Wake-up Timer peripheral. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~(RTC_CR_WUTE)) + +/** + * @brief Enable the RTC WakeUpTimer interrupt. + * @param __HANDLE__: specifies the RTC handle. + * @param __INTERRUPT__: specifies the RTC WakeUpTimer interrupt sources to be enabled or disabled. + * This parameter can be: + * @arg RTC_IT_WUT: WakeUpTimer A interrupt + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR |= (__INTERRUPT__)) + +/** + * @brief Disable the RTC WakeUpTimer interrupt. + * @param __HANDLE__: specifies the RTC handle. + * @param __INTERRUPT__: specifies the RTC WakeUpTimer interrupt sources to be enabled or disabled. + * This parameter can be: + * @arg RTC_IT_WUT: WakeUpTimer A interrupt + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR &= ~(__INTERRUPT__)) + +/** + * @brief Check whether the specified RTC WakeUpTimer interrupt has occurred or not. + * @param __HANDLE__: specifies the RTC handle. + * @param __INTERRUPT__: specifies the RTC WakeUpTimer interrupt to check. + * This parameter can be: + * @arg RTC_IT_WUT: WakeUpTimer A interrupt + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_GET_IT(__HANDLE__, __INTERRUPT__) (((((__HANDLE__)->Instance->ISR) & ((__INTERRUPT__)>> 4)) != RESET)? SET : RESET) + +/** + * @brief Check whether the specified RTC Wake Up timer interrupt has been enabled or not. + * @param __HANDLE__: specifies the RTC handle. + * @param __INTERRUPT__: specifies the RTC Wake Up timer interrupt sources to check. + * This parameter can be: + * @arg RTC_IT_WUT: WakeUpTimer interrupt + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((((__HANDLE__)->Instance->CR) & (__INTERRUPT__)) != RESET) ? SET : RESET) + +/** + * @brief Get the selected RTC WakeUpTimer's flag status. + * @param __HANDLE__: specifies the RTC handle. + * @param __FLAG__: specifies the RTC WakeUpTimer Flag to check. + * This parameter can be: + * @arg RTC_FLAG_WUTF + * @arg RTC_FLAG_WUTWF + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->ISR) & (__FLAG__)) != RESET)? SET : RESET) + +/** + * @brief Clear the RTC Wake Up timer's pending flags. + * @param __HANDLE__: specifies the RTC handle. + * @param __FLAG__: specifies the RTC Tamper Flag sources to be enabled or disabled. + * This parameter can be: + * @arg RTC_FLAG_WUTF + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ISR) = (~((__FLAG__) | RTC_ISR_INIT)|((__HANDLE__)->Instance->ISR & RTC_ISR_INIT)) + +/** + * @brief Enable interrupt on the RTC Wake-up Timer associated Exti line. + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT() (EXTI->IMR |= RTC_EXTI_LINE_WAKEUPTIMER_EVENT) + +/** + * @brief Disable interrupt on the RTC Wake-up Timer associated Exti line. + * @retval None + */ +#define __HAL_RTC_WAKEUPTIMER_EXTI_DISABLE_IT() (EXTI->IMR &= ~(RTC_EXTI_LINE_WAKEUPTIMER_EVENT)) + +/** + * @brief Enable event on the RTC Wake-up Timer associated Exti line. + * @retval None. + */ +#define __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_EVENT() (EXTI->EMR |= RTC_EXTI_LINE_WAKEUPTIMER_EVENT) + +/** + * @brief Disable event on the RTC Wake-up Timer associated Exti line. + * @retval None. + */ +#define __HAL_RTC_WAKEUPTIMER_EXTI_DISABLE_EVENT() (EXTI->EMR &= ~(RTC_EXTI_LINE_WAKEUPTIMER_EVENT)) + +/** + * @brief Enable falling edge trigger on the RTC Wake-up Timer associated Exti line. + * @retval None. + */ +#define __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_FALLING_EDGE() (EXTI->FTSR |= RTC_EXTI_LINE_WAKEUPTIMER_EVENT) + +/** + * @brief Disable falling edge trigger on the RTC Wake-up Timer associated Exti line. + * @retval None. + */ +#define __HAL_RTC_WAKEUPTIMER_EXTI_DISABLE_FALLING_EDGE() (EXTI->FTSR &= ~(RTC_EXTI_LINE_WAKEUPTIMER_EVENT)) + +/** + * @brief Enable rising edge trigger on the RTC Wake-up Timer associated Exti line. + * @retval None. + */ +#define __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_RISING_EDGE() (EXTI->RTSR |= RTC_EXTI_LINE_WAKEUPTIMER_EVENT) + +/** + * @brief Disable rising edge trigger on the RTC Wake-up Timer associated Exti line. + * @retval None. + */ +#define __HAL_RTC_WAKEUPTIMER_EXTI_DISABLE_RISING_EDGE() (EXTI->RTSR &= ~(RTC_EXTI_LINE_WAKEUPTIMER_EVENT)) + +/** + * @brief Enable rising & falling edge trigger on the RTC Wake-up Timer associated Exti line. + * @retval None. + */ +#define __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_RISING_FALLING_EDGE() __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_RISING_EDGE();__HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_FALLING_EDGE(); + +/** + * @brief Disable rising & falling edge trigger on the RTC Wake-up Timer associated Exti line. + * This parameter can be: + * @retval None. + */ +#define __HAL_RTC_WAKEUPTIMER_EXTI_DISABLE_RISING_FALLING_EDGE() __HAL_RTC_WAKEUPTIMER_EXTI_DISABLE_RISING_EDGE();__HAL_RTC_WAKEUPTIMER_EXTI_DISABLE_FALLING_EDGE(); + +/** + * @brief Check whether the RTC Wake-up Timer associated Exti line interrupt flag is set or not. + * @retval Line Status. + */ +#define __HAL_RTC_WAKEUPTIMER_EXTI_GET_FLAG() (EXTI->PR & RTC_EXTI_LINE_WAKEUPTIMER_EVENT) + +/** + * @brief Clear the RTC Wake-up Timer associated Exti line flag. + * @retval None. + */ +#define __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG() (EXTI->PR = RTC_EXTI_LINE_WAKEUPTIMER_EVENT) + +/** + * @brief Generate a Software interrupt on the RTC Wake-up Timer associated Exti line. + * @retval None. + */ +#define __HAL_RTC_WAKEUPTIMER_EXTI_GENERATE_SWIT() (EXTI->SWIER |= RTC_EXTI_LINE_WAKEUPTIMER_EVENT) + +/** + * @} + */ + +/* ---------------------------------TIMESTAMP---------------------------------*/ +/** @defgroup RTCEx_Timestamp RTC Timestamp + * @{ + */ + +/** + * @brief Enable the RTC TimeStamp peripheral. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_TIMESTAMP_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= (RTC_CR_TSE)) + +/** + * @brief Disable the RTC TimeStamp peripheral. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_TIMESTAMP_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~(RTC_CR_TSE)) + +/** + * @brief Enable the RTC TimeStamp interrupt. + * @param __HANDLE__: specifies the RTC handle. + * @param __INTERRUPT__: specifies the RTC TimeStamp interrupt sources to be enabled or disabled. + * This parameter can be: + * @arg RTC_IT_TS: TimeStamp interrupt + * @retval None + */ +#define __HAL_RTC_TIMESTAMP_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR |= (__INTERRUPT__)) + +/** + * @brief Disable the RTC TimeStamp interrupt. + * @param __HANDLE__: specifies the RTC handle. + * @param __INTERRUPT__: specifies the RTC TimeStamp interrupt sources to be enabled or disabled. + * This parameter can be: + * @arg RTC_IT_TS: TimeStamp interrupt + * @retval None + */ +#define __HAL_RTC_TIMESTAMP_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR &= ~(__INTERRUPT__)) + +/** + * @brief Check whether the specified RTC TimeStamp interrupt has occurred or not. + * @param __HANDLE__: specifies the RTC handle. + * @param __INTERRUPT__: specifies the RTC TimeStamp interrupt to check. + * This parameter can be: + * @arg RTC_IT_TS: TimeStamp interrupt + * @retval None + */ +#define __HAL_RTC_TIMESTAMP_GET_IT(__HANDLE__, __INTERRUPT__) (((((__HANDLE__)->Instance->ISR) & ((__INTERRUPT__)>> 4)) != RESET)? SET : RESET) + +/** + * @brief Check whether the specified RTC Time Stamp interrupt has been enabled or not. + * @param __HANDLE__: specifies the RTC handle. + * @param __INTERRUPT__: specifies the RTC Time Stamp interrupt source to check. + * This parameter can be: + * @arg RTC_IT_TS: TimeStamp interrupt + * @retval None + */ +#define __HAL_RTC_TIMESTAMP_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((((__HANDLE__)->Instance->CR) & (__INTERRUPT__)) != RESET) ? SET : RESET) + +/** + * @brief Get the selected RTC TimeStamp's flag status. + * @param __HANDLE__: specifies the RTC handle. + * @param __FLAG__: specifies the RTC TimeStamp flag to check. + * This parameter can be: + * @arg RTC_FLAG_TSF + * @arg RTC_FLAG_TSOVF + * @retval None + */ +#define __HAL_RTC_TIMESTAMP_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->ISR) & (__FLAG__)) != RESET)? SET : RESET) + +/** + * @brief Clear the RTC Time Stamp's pending flags. + * @param __HANDLE__: specifies the RTC handle. + * @param __FLAG__: specifies the RTC Alarm Flag sources to be enabled or disabled. + * This parameter can be: + * @arg RTC_FLAG_TSF + * @retval None + */ +#define __HAL_RTC_TIMESTAMP_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ISR) = (~((__FLAG__) | RTC_ISR_INIT)|((__HANDLE__)->Instance->ISR & RTC_ISR_INIT)) + +/** + * @} + */ + +/* ---------------------------------TAMPER------------------------------------*/ +/** @defgroup RTCEx_Tamper RTC Tamper + * @{ + */ + +/** + * @brief Enable the RTC Tamper1 input detection. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_TAMPER1_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->TAFCR |= (RTC_TAFCR_TAMP1E)) + +/** + * @brief Disable the RTC Tamper1 input detection. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_TAMPER1_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->TAFCR &= ~(RTC_TAFCR_TAMP1E)) + +/** + * @brief Enable the RTC Tamper2 input detection. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_TAMPER2_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->TAFCR |= (RTC_TAFCR_TAMP2E)) + +/** + * @brief Disable the RTC Tamper2 input detection. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_TAMPER2_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->TAFCR &= ~(RTC_TAFCR_TAMP2E)) + +/** + * @brief Check whether the specified RTC Tamper interrupt has occurred or not. + * @param __HANDLE__: specifies the RTC handle. + * @param __INTERRUPT__: specifies the RTC Tamper interrupt to check. + * This parameter can be: + * @arg RTC_IT_TAMP1 + * @arg RTC_IT_TAMP2 + * @retval None + */ +#define __HAL_RTC_TAMPER_GET_IT(__HANDLE__, __INTERRUPT__) (((((__HANDLE__)->Instance->ISR) & ((__INTERRUPT__)>> 4)) != RESET)? SET : RESET) + +/** + * @brief Check whether the specified RTC Tamper interrupt has been enabled or not. + * @param __HANDLE__: specifies the RTC handle. + * @param __INTERRUPT__: specifies the RTC Tamper interrupt source to check. + * This parameter can be: + * @arg RTC_IT_TAMP: Tamper interrupt + * @retval None + */ +#define __HAL_RTC_TAMPER_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((((__HANDLE__)->Instance->TAFCR) & (__INTERRUPT__)) != RESET) ? SET : RESET) + +/** + * @brief Get the selected RTC Tamper's flag status. + * @param __HANDLE__: specifies the RTC handle. + * @param __FLAG__: specifies the RTC Tamper Flag sources to be enabled or disabled. + * This parameter can be: + * @arg RTC_FLAG_TAMP1F + * @arg RTC_FLAG_TAMP2F + * @retval None + */ +#define __HAL_RTC_TAMPER_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->ISR) & (__FLAG__)) != RESET)? SET : RESET) + +/** + * @brief Clear the RTC Tamper's pending flags. + * @param __HANDLE__: specifies the RTC handle. + * @param __FLAG__: specifies the RTC Tamper Flag to clear. + * This parameter can be: + * @arg RTC_FLAG_TAMP1F + * @arg RTC_FLAG_TAMP2F + * @retval None + */ +#define __HAL_RTC_TAMPER_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ISR) = (~((__FLAG__) | RTC_ISR_INIT)|((__HANDLE__)->Instance->ISR & RTC_ISR_INIT)) +/** + * @} + */ + +/* --------------------------TAMPER/TIMESTAMP---------------------------------*/ +/** @defgroup RTCEx_Tamper_Timestamp EXTI RTC Tamper Timestamp EXTI + * @{ + */ + +/** + * @brief Enable interrupt on the RTC Tamper and Timestamp associated Exti line. + * @retval None + */ +#define __HAL_RTC_TAMPER_TIMESTAMP_EXTI_ENABLE_IT() (EXTI->IMR |= RTC_EXTI_LINE_TAMPER_TIMESTAMP_EVENT) + +/** + * @brief Disable interrupt on the RTC Tamper and Timestamp associated Exti line. + * @retval None + */ +#define __HAL_RTC_TAMPER_TIMESTAMP_EXTI_DISABLE_IT() (EXTI->IMR &= ~(RTC_EXTI_LINE_TAMPER_TIMESTAMP_EVENT)) + +/** + * @brief Enable event on the RTC Tamper and Timestamp associated Exti line. + * @retval None. + */ +#define __HAL_RTC_TAMPER_TIMESTAMP_EXTI_ENABLE_EVENT() (EXTI->EMR |= RTC_EXTI_LINE_TAMPER_TIMESTAMP_EVENT) + +/** + * @brief Disable event on the RTC Tamper and Timestamp associated Exti line. + * @retval None. + */ +#define __HAL_RTC_TAMPER_TIMESTAMP_EXTI_DISABLE_EVENT() (EXTI->EMR &= ~(RTC_EXTI_LINE_TAMPER_TIMESTAMP_EVENT)) + +/** + * @brief Enable falling edge trigger on the RTC Tamper and Timestamp associated Exti line. + * @retval None. + */ +#define __HAL_RTC_TAMPER_TIMESTAMP_EXTI_ENABLE_FALLING_EDGE() (EXTI->FTSR |= RTC_EXTI_LINE_TAMPER_TIMESTAMP_EVENT) + +/** + * @brief Disable falling edge trigger on the RTC Tamper and Timestamp associated Exti line. + * @retval None. + */ +#define __HAL_RTC_TAMPER_TIMESTAMP_EXTI_DISABLE_FALLING_EDGE() (EXTI->FTSR &= ~(RTC_EXTI_LINE_TAMPER_TIMESTAMP_EVENT)) + +/** + * @brief Enable rising edge trigger on the RTC Tamper and Timestamp associated Exti line. + * @retval None. + */ +#define __HAL_RTC_TAMPER_TIMESTAMP_EXTI_ENABLE_RISING_EDGE() (EXTI->RTSR |= RTC_EXTI_LINE_TAMPER_TIMESTAMP_EVENT) + +/** + * @brief Disable rising edge trigger on the RTC Tamper and Timestamp associated Exti line. + * @retval None. + */ +#define __HAL_RTC_TAMPER_TIMESTAMP_EXTI_DISABLE_RISING_EDGE() (EXTI->RTSR &= ~(RTC_EXTI_LINE_TAMPER_TIMESTAMP_EVENT)) + +/** + * @brief Enable rising & falling edge trigger on the RTC Tamper and Timestamp associated Exti line. + * @retval None. + */ +#define __HAL_RTC_TAMPER_TIMESTAMP_EXTI_ENABLE_RISING_FALLING_EDGE() __HAL_RTC_TAMPER_TIMESTAMP_EXTI_ENABLE_RISING_EDGE();__HAL_RTC_TAMPER_TIMESTAMP_EXTI_ENABLE_FALLING_EDGE(); + +/** + * @brief Disable rising & falling edge trigger on the RTC Tamper and Timestamp associated Exti line. + * This parameter can be: + * @retval None. + */ +#define __HAL_RTC_TAMPER_TIMESTAMP_EXTI_DISABLE_RISING_FALLING_EDGE() __HAL_RTC_TAMPER_TIMESTAMP_EXTI_DISABLE_RISING_EDGE();__HAL_RTC_TAMPER_TIMESTAMP_EXTI_DISABLE_FALLING_EDGE(); + +/** + * @brief Check whether the RTC Tamper and Timestamp associated Exti line interrupt flag is set or not. + * @retval Line Status. + */ +#define __HAL_RTC_TAMPER_TIMESTAMP_EXTI_GET_FLAG() (EXTI->PR & RTC_EXTI_LINE_TAMPER_TIMESTAMP_EVENT) + +/** + * @brief Clear the RTC Tamper and Timestamp associated Exti line flag. + * @retval None. + */ +#define __HAL_RTC_TAMPER_TIMESTAMP_EXTI_CLEAR_FLAG() (EXTI->PR = RTC_EXTI_LINE_TAMPER_TIMESTAMP_EVENT) + +/** + * @brief Generate a Software interrupt on the RTC Tamper and Timestamp associated Exti line + * @retval None. + */ +#define __HAL_RTC_TAMPER_TIMESTAMP_EXTI_GENERATE_SWIT() (EXTI->SWIER |= RTC_EXTI_LINE_TAMPER_TIMESTAMP_EVENT) +/** + * @} + */ + +/* ------------------------------Calibration----------------------------------*/ +/** @defgroup RTCEx_Calibration RTC Calibration + * @{ + */ + +/** + * @brief Enable the Coarse calibration process. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_COARSE_CALIB_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= (RTC_CR_DCE)) + +/** + * @brief Disable the Coarse calibration process. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_COARSE_CALIB_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~(RTC_CR_DCE)) + +/** + * @brief Enable the RTC calibration output. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_CALIBRATION_OUTPUT_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= (RTC_CR_COE)) + +/** + * @brief Disable the calibration output. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_CALIBRATION_OUTPUT_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~(RTC_CR_COE)) + +/** + * @brief Enable the clock reference detection. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_CLOCKREF_DETECTION_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR |= (RTC_CR_REFCKON)) + +/** + * @brief Disable the clock reference detection. + * @param __HANDLE__: specifies the RTC handle. + * @retval None + */ +#define __HAL_RTC_CLOCKREF_DETECTION_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= ~(RTC_CR_REFCKON)) + +/** + * @brief Get the selected RTC shift operation's flag status. + * @param __HANDLE__: specifies the RTC handle. + * @param __FLAG__: specifies the RTC shift operation Flag is pending or not. + * This parameter can be: + * @arg RTC_FLAG_SHPF + * @retval None + */ +#define __HAL_RTC_SHIFT_GET_FLAG(__HANDLE__, __FLAG__) (((((__HANDLE__)->Instance->ISR) & (__FLAG__)) != RESET)? SET : RESET) +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup RTCEx_Exported_Functions RTCEx Exported Functions + * @{ + */ + +/** @addtogroup RTCEx_Exported_Functions_Group1 + * @{ + */ +/* RTC TimeStamp and Tamper functions *****************************************/ +HAL_StatusTypeDef HAL_RTCEx_SetTimeStamp(RTC_HandleTypeDef *hrtc, uint32_t TimeStampEdge, uint32_t RTC_TimeStampPin); +HAL_StatusTypeDef HAL_RTCEx_SetTimeStamp_IT(RTC_HandleTypeDef *hrtc, uint32_t TimeStampEdge, uint32_t RTC_TimeStampPin); +HAL_StatusTypeDef HAL_RTCEx_DeactivateTimeStamp(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_GetTimeStamp(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTimeStamp, RTC_DateTypeDef *sTimeStampDate, uint32_t Format); + +HAL_StatusTypeDef HAL_RTCEx_SetTamper(RTC_HandleTypeDef *hrtc, RTC_TamperTypeDef* sTamper); +HAL_StatusTypeDef HAL_RTCEx_SetTamper_IT(RTC_HandleTypeDef *hrtc, RTC_TamperTypeDef* sTamper); +HAL_StatusTypeDef HAL_RTCEx_DeactivateTamper(RTC_HandleTypeDef *hrtc, uint32_t Tamper); +void HAL_RTCEx_TamperTimeStampIRQHandler(RTC_HandleTypeDef *hrtc); + +void HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_Tamper2EventCallback(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_TimeStampEventCallback(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_PollForTimeStampEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout); +HAL_StatusTypeDef HAL_RTCEx_PollForTamper1Event(RTC_HandleTypeDef *hrtc, uint32_t Timeout); +HAL_StatusTypeDef HAL_RTCEx_PollForTamper2Event(RTC_HandleTypeDef *hrtc, uint32_t Timeout); +/** + * @} + */ + +/** @addtogroup RTCEx_Exported_Functions_Group2 + * @{ + */ +/* RTC Wake-up functions ******************************************************/ +HAL_StatusTypeDef HAL_RTCEx_SetWakeUpTimer(RTC_HandleTypeDef *hrtc, uint32_t WakeUpCounter, uint32_t WakeUpClock); +HAL_StatusTypeDef HAL_RTCEx_SetWakeUpTimer_IT(RTC_HandleTypeDef *hrtc, uint32_t WakeUpCounter, uint32_t WakeUpClock); +uint32_t HAL_RTCEx_DeactivateWakeUpTimer(RTC_HandleTypeDef *hrtc); +uint32_t HAL_RTCEx_GetWakeUpTimer(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_WakeUpTimerIRQHandler(RTC_HandleTypeDef *hrtc); +void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_PollForWakeUpTimerEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout); +/** + * @} + */ + +/** @addtogroup RTCEx_Exported_Functions_Group3 + * @{ + */ +/* Extension Control functions ************************************************/ +void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data); +uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister); + +HAL_StatusTypeDef HAL_RTCEx_SetCoarseCalib(RTC_HandleTypeDef *hrtc, uint32_t CalibSign, uint32_t Value); +HAL_StatusTypeDef HAL_RTCEx_DeactivateCoarseCalib(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_SetSmoothCalib(RTC_HandleTypeDef *hrtc, uint32_t SmoothCalibPeriod, uint32_t SmoothCalibPlusPulses, uint32_t SmouthCalibMinusPulsesValue); +HAL_StatusTypeDef HAL_RTCEx_SetSynchroShift(RTC_HandleTypeDef *hrtc, uint32_t ShiftAdd1S, uint32_t ShiftSubFS); +HAL_StatusTypeDef HAL_RTCEx_SetCalibrationOutPut(RTC_HandleTypeDef *hrtc, uint32_t CalibOutput); +HAL_StatusTypeDef HAL_RTCEx_DeactivateCalibrationOutPut(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_SetRefClock(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_DeactivateRefClock(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_EnableBypassShadow(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_DisableBypassShadow(RTC_HandleTypeDef *hrtc); +/** + * @} + */ + +/** @addtogroup RTCEx_Exported_Functions_Group4 + * @{ + */ +/* Extension RTC features functions *******************************************/ +void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc); +HAL_StatusTypeDef HAL_RTCEx_PollForAlarmBEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup RTCEx_Private_Constants RTCEx Private Constants + * @{ + */ +#define RTC_EXTI_LINE_TAMPER_TIMESTAMP_EVENT ((uint32_t)EXTI_IMR_MR21) /*!< External interrupt line 21 Connected to the RTC Tamper and Time Stamp events */ +#define RTC_EXTI_LINE_WAKEUPTIMER_EVENT ((uint32_t)EXTI_IMR_MR22) /*!< External interrupt line 22 Connected to the RTC Wake-up event */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup RTCEx_Private_Macros RTCEx Private Macros + * @{ + */ + +/** @defgroup RTCEx_IS_RTC_Definitions Private macros to check input parameters + * @{ + */ +#define IS_RTC_BKP(BKP) (((BKP) == RTC_BKP_DR0) || \ + ((BKP) == RTC_BKP_DR1) || \ + ((BKP) == RTC_BKP_DR2) || \ + ((BKP) == RTC_BKP_DR3) || \ + ((BKP) == RTC_BKP_DR4) || \ + ((BKP) == RTC_BKP_DR5) || \ + ((BKP) == RTC_BKP_DR6) || \ + ((BKP) == RTC_BKP_DR7) || \ + ((BKP) == RTC_BKP_DR8) || \ + ((BKP) == RTC_BKP_DR9) || \ + ((BKP) == RTC_BKP_DR10) || \ + ((BKP) == RTC_BKP_DR11) || \ + ((BKP) == RTC_BKP_DR12) || \ + ((BKP) == RTC_BKP_DR13) || \ + ((BKP) == RTC_BKP_DR14) || \ + ((BKP) == RTC_BKP_DR15) || \ + ((BKP) == RTC_BKP_DR16) || \ + ((BKP) == RTC_BKP_DR17) || \ + ((BKP) == RTC_BKP_DR18) || \ + ((BKP) == RTC_BKP_DR19)) +#define IS_TIMESTAMP_EDGE(EDGE) (((EDGE) == RTC_TIMESTAMPEDGE_RISING) || \ + ((EDGE) == RTC_TIMESTAMPEDGE_FALLING)) +#define IS_RTC_TAMPER(TAMPER) ((((TAMPER) & ((uint32_t)!(RTC_TAFCR_TAMP1E | RTC_TAFCR_TAMP2E))) == 0x00) && ((TAMPER) != (uint32_t)RESET)) + +#define IS_RTC_TAMPER_PIN(PIN) (((PIN) == RTC_TAMPERPIN_DEFAULT) || \ + ((PIN) == RTC_TAMPERPIN_POS1)) + +#define IS_RTC_TIMESTAMP_PIN(PIN) (((PIN) == RTC_TIMESTAMPPIN_DEFAULT) || \ + ((PIN) == RTC_TIMESTAMPPIN_POS1)) + +#define IS_RTC_TAMPER_TRIGGER(TRIGGER) (((TRIGGER) == RTC_TAMPERTRIGGER_RISINGEDGE) || \ + ((TRIGGER) == RTC_TAMPERTRIGGER_FALLINGEDGE) || \ + ((TRIGGER) == RTC_TAMPERTRIGGER_LOWLEVEL) || \ + ((TRIGGER) == RTC_TAMPERTRIGGER_HIGHLEVEL)) +#define IS_RTC_TAMPER_FILTER(FILTER) (((FILTER) == RTC_TAMPERFILTER_DISABLE) || \ + ((FILTER) == RTC_TAMPERFILTER_2SAMPLE) || \ + ((FILTER) == RTC_TAMPERFILTER_4SAMPLE) || \ + ((FILTER) == RTC_TAMPERFILTER_8SAMPLE)) +#define IS_RTC_TAMPER_SAMPLING_FREQ(FREQ) (((FREQ) == RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV32768)|| \ + ((FREQ) == RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV16384)|| \ + ((FREQ) == RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV8192) || \ + ((FREQ) == RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV4096) || \ + ((FREQ) == RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV2048) || \ + ((FREQ) == RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV1024) || \ + ((FREQ) == RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV512) || \ + ((FREQ) == RTC_TAMPERSAMPLINGFREQ_RTCCLK_DIV256)) +#define IS_RTC_TAMPER_PRECHARGE_DURATION(DURATION) (((DURATION) == RTC_TAMPERPRECHARGEDURATION_1RTCCLK) || \ + ((DURATION) == RTC_TAMPERPRECHARGEDURATION_2RTCCLK) || \ + ((DURATION) == RTC_TAMPERPRECHARGEDURATION_4RTCCLK) || \ + ((DURATION) == RTC_TAMPERPRECHARGEDURATION_8RTCCLK)) +#define IS_RTC_TAMPER_TIMESTAMPONTAMPER_DETECTION(DETECTION) (((DETECTION) == RTC_TIMESTAMPONTAMPERDETECTION_ENABLE) || \ + ((DETECTION) == RTC_TIMESTAMPONTAMPERDETECTION_DISABLE)) +#define IS_RTC_TAMPER_PULLUP_STATE(STATE) (((STATE) == RTC_TAMPER_PULLUP_ENABLE) || \ + ((STATE) == RTC_TAMPER_PULLUP_DISABLE)) +#define IS_RTC_WAKEUP_CLOCK(CLOCK) (((CLOCK) == RTC_WAKEUPCLOCK_RTCCLK_DIV16) || \ + ((CLOCK) == RTC_WAKEUPCLOCK_RTCCLK_DIV8) || \ + ((CLOCK) == RTC_WAKEUPCLOCK_RTCCLK_DIV4) || \ + ((CLOCK) == RTC_WAKEUPCLOCK_RTCCLK_DIV2) || \ + ((CLOCK) == RTC_WAKEUPCLOCK_CK_SPRE_16BITS) || \ + ((CLOCK) == RTC_WAKEUPCLOCK_CK_SPRE_17BITS)) + +#define IS_RTC_WAKEUP_COUNTER(COUNTER) ((COUNTER) <= 0xFFFF) +#define IS_RTC_CALIB_SIGN(SIGN) (((SIGN) == RTC_CALIBSIGN_POSITIVE) || \ + ((SIGN) == RTC_CALIBSIGN_NEGATIVE)) + +#define IS_RTC_CALIB_VALUE(VALUE) ((VALUE) < 0x20) + +#define IS_RTC_SMOOTH_CALIB_PERIOD(PERIOD) (((PERIOD) == RTC_SMOOTHCALIB_PERIOD_32SEC) || \ + ((PERIOD) == RTC_SMOOTHCALIB_PERIOD_16SEC) || \ + ((PERIOD) == RTC_SMOOTHCALIB_PERIOD_8SEC)) +#define IS_RTC_SMOOTH_CALIB_PLUS(PLUS) (((PLUS) == RTC_SMOOTHCALIB_PLUSPULSES_SET) || \ + ((PLUS) == RTC_SMOOTHCALIB_PLUSPULSES_RESET)) + + +#define IS_RTC_SMOOTH_CALIB_MINUS(VALUE) ((VALUE) <= 0x000001FF) +#define IS_RTC_SHIFT_ADD1S(SEL) (((SEL) == RTC_SHIFTADD1S_RESET) || \ + ((SEL) == RTC_SHIFTADD1S_SET)) +#define IS_RTC_SHIFT_SUBFS(FS) ((FS) <= 0x00007FFF) +#define IS_RTC_CALIB_OUTPUT(OUTPUT) (((OUTPUT) == RTC_CALIBOUTPUT_512HZ) || \ + ((OUTPUT) == RTC_CALIBOUTPUT_1HZ)) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_RTC_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sai.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sai.h new file mode 100644 index 0000000..13d9d2f --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sai.h @@ -0,0 +1,908 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_sai.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of SAI HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_SAI_H +#define __STM32F4xx_HAL_SAI_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) + +/** @addtogroup SAI + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SAI_Exported_Types SAI Exported Types + * @{ + */ + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_SAI_STATE_RESET = 0x00, /*!< SAI not yet initialized or disabled */ + HAL_SAI_STATE_READY = 0x01, /*!< SAI initialized and ready for use */ + HAL_SAI_STATE_BUSY = 0x02, /*!< SAI internal process is ongoing */ + HAL_SAI_STATE_BUSY_TX = 0x12, /*!< Data transmission process is ongoing */ + HAL_SAI_STATE_BUSY_RX = 0x22, /*!< Data reception process is ongoing */ + HAL_SAI_STATE_TIMEOUT = 0x03, /*!< SAI timeout state */ + HAL_SAI_STATE_ERROR = 0x04 /*!< SAI error state */ +}HAL_SAI_StateTypeDef; + +/** + * @brief SAI Callback prototype + */ +typedef void (*SAIcallback)(void); + +/** + * @brief SAI Init Structure definition + */ +typedef struct +{ + uint32_t AudioMode; /*!< Specifies the SAI Block audio Mode. + This parameter can be a value of @ref SAI_Block_Mode */ + + uint32_t Synchro; /*!< Specifies SAI Block synchronization + This parameter can be a value of @ref SAI_Block_Synchronization */ + + uint32_t SynchroExt; /*!< Specifies SAI Block synchronization, this setup is common + for BLOCKA and BLOCKB + This parameter can be a value of @ref SAI_Block_SyncExt */ + + uint32_t OutputDrive; /*!< Specifies when SAI Block outputs are driven. + This parameter can be a value of @ref SAI_Block_Output_Drive + @note this value has to be set before enabling the audio block + but after the audio block configuration. */ + + uint32_t NoDivider; /*!< Specifies whether master clock will be divided or not. + This parameter can be a value of @ref SAI_Block_NoDivider + @note: If bit NODIV in the SAI_xCR1 register is cleared, the frame length + should be aligned to a number equal to a power of 2, from 8 to 256. + If bit NODIV in the SAI_xCR1 register is set, the frame length can + take any of the values without constraint since the input clock of + the audio block should be equal to the bit clock. + There is no MCLK_x clock which can be output. */ + + uint32_t FIFOThreshold; /*!< Specifies SAI Block FIFO threshold. + This parameter can be a value of @ref SAI_Block_Fifo_Threshold */ + + uint32_t ClockSource; /*!< Specifies the SAI Block x Clock source. + This parameter is not used for STM32F446xx devices. */ + + uint32_t AudioFrequency; /*!< Specifies the audio frequency sampling. + This parameter can be a value of @ref SAI_Audio_Frequency */ + + uint32_t Mckdiv; /*!< Specifies the master clock divider, the parameter will be used if for + AudioFrequency the user choice + This parameter must be a number between Min_Data = 0 and Max_Data = 15 */ + + uint32_t MonoStereoMode; /*!< Specifies if the mono or stereo mode is selected. + This parameter can be a value of @ref SAI_Mono_Stereo_Mode */ + + uint32_t CompandingMode; /*!< Specifies the companding mode type. + This parameter can be a value of @ref SAI_Block_Companding_Mode */ + + uint32_t TriState; /*!< Specifies the companding mode type. + This parameter can be a value of @ref SAI_TRIState_Management */ + + /* This part of the structure is automatically filled if your are using the high level intialisation + function HAL_SAI_InitProtocol */ + + uint32_t Protocol; /*!< Specifies the SAI Block protocol. + This parameter can be a value of @ref SAI_Block_Protocol */ + + uint32_t DataSize; /*!< Specifies the SAI Block data size. + This parameter can be a value of @ref SAI_Block_Data_Size */ + + uint32_t FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit. + This parameter can be a value of @ref SAI_Block_MSB_LSB_transmission */ + + uint32_t ClockStrobing; /*!< Specifies the SAI Block clock strobing edge sensitivity. + This parameter can be a value of @ref SAI_Block_Clock_Strobing */ +}SAI_InitTypeDef; + +/** + * @brief SAI Block Frame Init structure definition + */ + +typedef struct +{ + + uint32_t FrameLength; /*!< Specifies the Frame length, the number of SCK clocks for each audio frame. + This parameter must be a number between Min_Data = 8 and Max_Data = 256. + @note: If master clock MCLK_x pin is declared as an output, the frame length + should be aligned to a number equal to power of 2 in order to keep + in an audio frame, an integer number of MCLK pulses by bit Clock. */ + + uint32_t ActiveFrameLength; /*!< Specifies the Frame synchronization active level length. + This Parameter specifies the length in number of bit clock (SCK + 1) + of the active level of FS signal in audio frame. + This parameter must be a number between Min_Data = 1 and Max_Data = 128 */ + + uint32_t FSDefinition; /*!< Specifies the Frame synchronization definition. + This parameter can be a value of @ref SAI_Block_FS_Definition */ + + uint32_t FSPolarity; /*!< Specifies the Frame synchronization Polarity. + This parameter can be a value of @ref SAI_Block_FS_Polarity */ + + uint32_t FSOffset; /*!< Specifies the Frame synchronization Offset. + This parameter can be a value of @ref SAI_Block_FS_Offset */ + +}SAI_FrameInitTypeDef; + +/** + * @brief SAI Block Slot Init Structure definition + */ + +typedef struct +{ + uint32_t FirstBitOffset; /*!< Specifies the position of first data transfer bit in the slot. + This parameter must be a number between Min_Data = 0 and Max_Data = 24 */ + + uint32_t SlotSize; /*!< Specifies the Slot Size. + This parameter can be a value of @ref SAI_Block_Slot_Size */ + + uint32_t SlotNumber; /*!< Specifies the number of slot in the audio frame. + This parameter must be a number between Min_Data = 1 and Max_Data = 16 */ + + uint32_t SlotActive; /*!< Specifies the slots in audio frame that will be activated. + This parameter can be a value of @ref SAI_Block_Slot_Active */ +}SAI_SlotInitTypeDef; + +/** + * @brief SAI handle Structure definition + */ +typedef struct __SAI_HandleTypeDef +{ + SAI_Block_TypeDef *Instance; /*!< SAI Blockx registers base address */ + + SAI_InitTypeDef Init; /*!< SAI communication parameters */ + + SAI_FrameInitTypeDef FrameInit; /*!< SAI Frame configuration parameters */ + + SAI_SlotInitTypeDef SlotInit; /*!< SAI Slot configuration parameters */ + + uint8_t *pBuffPtr; /*!< Pointer to SAI transfer Buffer */ + + uint16_t XferSize; /*!< SAI transfer size */ + + uint16_t XferCount; /*!< SAI transfer counter */ + + DMA_HandleTypeDef *hdmatx; /*!< SAI Tx DMA handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< SAI Rx DMA handle parameters */ + + SAIcallback mutecallback;/*!< SAI mute callback */ + + void (*InterruptServiceRoutine)(struct __SAI_HandleTypeDef *hsai); /* function pointer for IRQ handler */ + + HAL_LockTypeDef Lock; /*!< SAI locking object */ + + __IO HAL_SAI_StateTypeDef State; /*!< SAI communication state */ + + __IO uint32_t ErrorCode; /*!< SAI Error code */ +}SAI_HandleTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup SAI_Exported_Constants SAI Exported Constants + * @{ + */ + +/** @defgroup SAI_Error_Code SAI Error Code + * @{ + */ +#define HAL_SAI_ERROR_NONE ((uint32_t)0x00000000) /*!< No error */ +#define HAL_SAI_ERROR_OVR ((uint32_t)0x00000001) /*!< Overrun Error */ +#define HAL_SAI_ERROR_UDR ((uint32_t)0x00000002) /*!< Underrun error */ +#define HAL_SAI_ERROR_AFSDET ((uint32_t)0x00000004) /*!< Anticipated Frame synchronisation detection */ +#define HAL_SAI_ERROR_LFSDET ((uint32_t)0x00000008) /*!< Late Frame synchronisation detection */ +#define HAL_SAI_ERROR_CNREADY ((uint32_t)0x00000010) /*!< codec not ready */ +#define HAL_SAI_ERROR_WCKCFG ((uint32_t)0x00000020) /*!< Wrong clock configuration */ +#define HAL_SAI_ERROR_TIMEOUT ((uint32_t)0x00000040) /*!< Timeout error */ +/** + * @} + */ + +/** @defgroup SAI_Block_SyncExt SAI External synchronisation + * @{ + */ +#define SAI_SYNCEXT_DISABLE ((uint32_t)0x00000000) +#define SAI_SYNCEXT_IN_ENABLE ((uint32_t)0x00000001) +#define SAI_SYNCEXT_OUTBLOCKA_ENABLE ((uint32_t)0x00000002) +#define SAI_SYNCEXT_OUTBLOCKB_ENABLE ((uint32_t)0x00000004) +/** + * @} + */ + +/** @defgroup SAI_Protocol SAI Supported protocol + * @{ + */ +#define SAI_I2S_STANDARD ((uint32_t)0x00000000) +#define SAI_I2S_MSBJUSTIFIED ((uint32_t)0x00000001) +#define SAI_I2S_LSBJUSTIFIED ((uint32_t)0x00000002) +#define SAI_PCM_LONG ((uint32_t)0x00000004) +#define SAI_PCM_SHORT ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup SAI_Protocol_DataSize SAI protocol data size + * @{ + */ +#define SAI_PROTOCOL_DATASIZE_16BIT ((uint32_t)0x00000000) +#define SAI_PROTOCOL_DATASIZE_16BITEXTENDED ((uint32_t)0x00000001) +#define SAI_PROTOCOL_DATASIZE_24BIT ((uint32_t)0x00000002) +#define SAI_PROTOCOL_DATASIZE_32BIT ((uint32_t)0x00000004) +/** + * @} + */ + +/** @defgroup SAI_Clock_Source SAI Clock Source + * @{ + */ +#define SAI_CLKSOURCE_PLLSAI ((uint32_t)0x00000000) +#define SAI_CLKSOURCE_PLLI2S ((uint32_t)0x00100000) +#define SAI_CLKSOURCE_EXT ((uint32_t)0x00200000) +#define SAI_CLKSOURCE_NA ((uint32_t)0x00400000) /*!< No applicable for STM32F446xx */ +/** + * @} + */ + +/** @defgroup SAI_Audio_Frequency SAI Audio Frequency + * @{ + */ +#define SAI_AUDIO_FREQUENCY_192K ((uint32_t)192000) +#define SAI_AUDIO_FREQUENCY_96K ((uint32_t)96000) +#define SAI_AUDIO_FREQUENCY_48K ((uint32_t)48000) +#define SAI_AUDIO_FREQUENCY_44K ((uint32_t)44100) +#define SAI_AUDIO_FREQUENCY_32K ((uint32_t)32000) +#define SAI_AUDIO_FREQUENCY_22K ((uint32_t)22050) +#define SAI_AUDIO_FREQUENCY_16K ((uint32_t)16000) +#define SAI_AUDIO_FREQUENCY_11K ((uint32_t)11025) +#define SAI_AUDIO_FREQUENCY_8K ((uint32_t)8000) +#define SAI_AUDIO_FREQUENCY_MCKDIV ((uint32_t)0) + +/** + * @} + */ + +/** @defgroup SAI_Block_Mode SAI Block Mode + * @{ + */ +#define SAI_MODEMASTER_TX ((uint32_t)0x00000000) +#define SAI_MODEMASTER_RX ((uint32_t)SAI_xCR1_MODE_0) +#define SAI_MODESLAVE_TX ((uint32_t)SAI_xCR1_MODE_1) +#define SAI_MODESLAVE_RX ((uint32_t)(SAI_xCR1_MODE_1 | SAI_xCR1_MODE_0)) + +/** + * @} + */ + +/** @defgroup SAI_Block_Protocol SAI Block Protocol + * @{ + */ +#define SAI_FREE_PROTOCOL ((uint32_t)0x00000000) +#define SAI_SPDIF_PROTOCOL ((uint32_t)SAI_xCR1_PRTCFG_0) +#define SAI_AC97_PROTOCOL ((uint32_t)SAI_xCR1_PRTCFG_1) + +/** + * @} + */ + +/** @defgroup SAI_Block_Data_Size SAI Block Data Size + * @{ + */ +#define SAI_DATASIZE_8 ((uint32_t)SAI_xCR1_DS_1) +#define SAI_DATASIZE_10 ((uint32_t)(SAI_xCR1_DS_1 | SAI_xCR1_DS_0)) +#define SAI_DATASIZE_16 ((uint32_t)SAI_xCR1_DS_2) +#define SAI_DATASIZE_20 ((uint32_t)(SAI_xCR1_DS_2 | SAI_xCR1_DS_0)) +#define SAI_DATASIZE_24 ((uint32_t)(SAI_xCR1_DS_2 | SAI_xCR1_DS_1)) +#define SAI_DATASIZE_32 ((uint32_t)(SAI_xCR1_DS_2 | SAI_xCR1_DS_1 | SAI_xCR1_DS_0)) + +/** + * @} + */ + +/** @defgroup SAI_Block_MSB_LSB_transmission SAI Block MSB LSB transmission + * @{ + */ +#define SAI_FIRSTBIT_MSB ((uint32_t)0x00000000) +#define SAI_FIRSTBIT_LSB ((uint32_t)SAI_xCR1_LSBFIRST) + +/** + * @} + */ + +/** @defgroup SAI_Block_Clock_Strobing SAI Block Clock Strobing + * @{ + */ +#define SAI_CLOCKSTROBING_FALLINGEDGE ((uint32_t)0x00000000) +#define SAI_CLOCKSTROBING_RISINGEDGE ((uint32_t)SAI_xCR1_CKSTR) + +/** + * @} + */ + +/** @defgroup SAI_Block_Synchronization SAI Block Synchronization + * @{ + */ +#define SAI_ASYNCHRONOUS ((uint32_t)0x00000000) +#define SAI_SYNCHRONOUS ((uint32_t)SAI_xCR1_SYNCEN_0) +#define SAI_SYNCHRONOUS_EXT ((uint32_t)SAI_xCR1_SYNCEN_1) + +/** + * @} + */ + +/** @defgroup SAI_Block_Output_Drive SAI Block Output Drive + * @{ + */ +#define SAI_OUTPUTDRIVE_DISABLE ((uint32_t)0x00000000) +#define SAI_OUTPUTDRIVE_ENABLE ((uint32_t)SAI_xCR1_OUTDRIV) + +/** + * @} + */ + +/** @defgroup SAI_Block_NoDivider SAI Block NoDivider + * @{ + */ +#define SAI_MASTERDIVIDER_ENABLE ((uint32_t)0x00000000) +#define SAI_MASTERDIVIDER_DISABLE ((uint32_t)SAI_xCR1_NODIV) + +/** + * @} + */ + + +/** @defgroup SAI_Block_FS_Definition SAI Block FS Definition + * @{ + */ +#define SAI_FS_STARTFRAME ((uint32_t)0x00000000) +#define SAI_FS_CHANNEL_IDENTIFICATION ((uint32_t)SAI_xFRCR_FSDEF) + +/** + * @} + */ + +/** @defgroup SAI_Block_FS_Polarity SAI Block FS Polarity + * @{ + */ +#define SAI_FS_ACTIVE_LOW ((uint32_t)0x00000000) +#define SAI_FS_ACTIVE_HIGH ((uint32_t)SAI_xFRCR_FSPO) + +/** + * @} + */ + +/** @defgroup SAI_Block_FS_Offset SAI Block FS Offset + * @{ + */ +#define SAI_FS_FIRSTBIT ((uint32_t)0x00000000) +#define SAI_FS_BEFOREFIRSTBIT ((uint32_t)SAI_xFRCR_FSOFF) + +/** + * @} + */ + + + /** @defgroup SAI_Block_Slot_Size SAI Block Slot Size + * @{ + */ +#define SAI_SLOTSIZE_DATASIZE ((uint32_t)0x00000000) +#define SAI_SLOTSIZE_16B ((uint32_t)SAI_xSLOTR_SLOTSZ_0) +#define SAI_SLOTSIZE_32B ((uint32_t)SAI_xSLOTR_SLOTSZ_1) +/** + * @} + */ + +/** @defgroup SAI_Block_Slot_Active SAI Block Slot Active + * @{ + */ +#define SAI_SLOT_NOTACTIVE ((uint32_t)0x00000000) +#define SAI_SLOTACTIVE_0 ((uint32_t)0x00010000) +#define SAI_SLOTACTIVE_1 ((uint32_t)0x00020000) +#define SAI_SLOTACTIVE_2 ((uint32_t)0x00040000) +#define SAI_SLOTACTIVE_3 ((uint32_t)0x00080000) +#define SAI_SLOTACTIVE_4 ((uint32_t)0x00100000) +#define SAI_SLOTACTIVE_5 ((uint32_t)0x00200000) +#define SAI_SLOTACTIVE_6 ((uint32_t)0x00400000) +#define SAI_SLOTACTIVE_7 ((uint32_t)0x00800000) +#define SAI_SLOTACTIVE_8 ((uint32_t)0x01000000) +#define SAI_SLOTACTIVE_9 ((uint32_t)0x02000000) +#define SAI_SLOTACTIVE_10 ((uint32_t)0x04000000) +#define SAI_SLOTACTIVE_11 ((uint32_t)0x08000000) +#define SAI_SLOTACTIVE_12 ((uint32_t)0x10000000) +#define SAI_SLOTACTIVE_13 ((uint32_t)0x20000000) +#define SAI_SLOTACTIVE_14 ((uint32_t)0x40000000) +#define SAI_SLOTACTIVE_15 ((uint32_t)0x80000000) +#define SAI_SLOTACTIVE_ALL ((uint32_t)0xFFFF0000) + +/** + * @} + */ + +/** @defgroup SAI_Mono_Stereo_Mode SAI Mono Stereo Mode + * @{ + */ +#define SAI_STEREOMODE ((uint32_t)0x00000000) +#define SAI_MONOMODE ((uint32_t)SAI_xCR1_MONO) + +/** + * @} + */ + +/** @defgroup SAI_TRIState_Management SAI TRIState Management + * @{ + */ +#define SAI_OUTPUT_NOTRELEASED ((uint32_t)0x00000000) +#define SAI_OUTPUT_RELEASED ((uint32_t)SAI_xCR2_TRIS) + +/** + * @} + */ + +/** @defgroup SAI_Block_Fifo_Threshold SAI Block Fifo Threshold + * @{ + */ +#define SAI_FIFOTHRESHOLD_EMPTY ((uint32_t)0x00000000) +#define SAI_FIFOTHRESHOLD_1QF ((uint32_t)SAI_xCR2_FTH_0) +#define SAI_FIFOTHRESHOLD_HF ((uint32_t)SAI_xCR2_FTH_1) +#define SAI_FIFOTHRESHOLD_3QF ((uint32_t)(SAI_xCR2_FTH_1 | SAI_xCR2_FTH_0)) +#define SAI_FIFOTHRESHOLD_FULL ((uint32_t)SAI_xCR2_FTH_2) + +/** + * @} + */ + +/** @defgroup SAI_Block_Companding_Mode SAI Block Companding Mode + * @{ + */ +#define SAI_NOCOMPANDING ((uint32_t)0x00000000) +#define SAI_ULAW_1CPL_COMPANDING ((uint32_t)SAI_xCR2_COMP_1) +#define SAI_ALAW_1CPL_COMPANDING ((uint32_t)(SAI_xCR2_COMP_1 | SAI_xCR2_COMP_0)) +#define SAI_ULAW_2CPL_COMPANDING ((uint32_t)(SAI_xCR2_COMP_1 | SAI_xCR2_CPL)) +#define SAI_ALAW_2CPL_COMPANDING ((uint32_t)(SAI_xCR2_COMP_1 | SAI_xCR2_COMP_0 | SAI_xCR2_CPL)) + +/** + * @} + */ + +/** @defgroup SAI_Block_Mute_Value SAI Block Mute Value + * @{ + */ +#define SAI_ZERO_VALUE ((uint32_t)0x00000000) +#define SAI_LAST_SENT_VALUE ((uint32_t)SAI_xCR2_MUTEVAL) + +/** + * @} + */ + + +/** @defgroup SAI_Block_Interrupts_Definition SAI Block Interrupts Definition + * @{ + */ +#define SAI_IT_OVRUDR ((uint32_t)SAI_xIMR_OVRUDRIE) +#define SAI_IT_MUTEDET ((uint32_t)SAI_xIMR_MUTEDETIE) +#define SAI_IT_WCKCFG ((uint32_t)SAI_xIMR_WCKCFGIE) +#define SAI_IT_FREQ ((uint32_t)SAI_xIMR_FREQIE) +#define SAI_IT_CNRDY ((uint32_t)SAI_xIMR_CNRDYIE) +#define SAI_IT_AFSDET ((uint32_t)SAI_xIMR_AFSDETIE) +#define SAI_IT_LFSDET ((uint32_t)SAI_xIMR_LFSDETIE) + +/** + * @} + */ + +/** @defgroup SAI_Block_Flags_Definition SAI Block Flags Definition + * @{ + */ +#define SAI_FLAG_OVRUDR ((uint32_t)SAI_xSR_OVRUDR) +#define SAI_FLAG_MUTEDET ((uint32_t)SAI_xSR_MUTEDET) +#define SAI_FLAG_WCKCFG ((uint32_t)SAI_xSR_WCKCFG) +#define SAI_FLAG_FREQ ((uint32_t)SAI_xSR_FREQ) +#define SAI_FLAG_CNRDY ((uint32_t)SAI_xSR_CNRDY) +#define SAI_FLAG_AFSDET ((uint32_t)SAI_xSR_AFSDET) +#define SAI_FLAG_LFSDET ((uint32_t)SAI_xSR_LFSDET) + +/** + * @} + */ + +/** @defgroup SAI_Block_Fifo_Status_Level SAI Block Fifo Status Level + * @{ + */ +#define SAI_FIFOSTATUS_EMPTY ((uint32_t)0x00000000) +#define SAI_FIFOSTATUS_LESS1QUARTERFULL ((uint32_t)0x00010000) +#define SAI_FIFOSTATUS_1QUARTERFULL ((uint32_t)0x00020000) +#define SAI_FIFOSTATUS_HALFFULL ((uint32_t)0x00030000) +#define SAI_FIFOSTATUS_3QUARTERFULL ((uint32_t)0x00040000) +#define SAI_FIFOSTATUS_FULL ((uint32_t)0x00050000) + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup SAI_Exported_Macros SAI Exported Macros + * @brief macros to handle interrupts and specific configurations + * @{ + */ + +/** @brief Reset SAI handle state + * @param __HANDLE__: specifies the SAI Handle. + * @retval None + */ +#define __HAL_SAI_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SAI_STATE_RESET) + +/** @brief Enable or disable the specified SAI interrupts. + * @param __HANDLE__: specifies the SAI Handle. + * @param __INTERRUPT__: specifies the interrupt source to enable or disable. + * This parameter can be one of the following values: + * @arg SAI_IT_OVRUDR: Overrun underrun interrupt enable + * @arg SAI_IT_MUTEDET: Mute detection interrupt enable + * @arg SAI_IT_WCKCFG: Wrong Clock Configuration interrupt enable + * @arg SAI_IT_FREQ: FIFO request interrupt enable + * @arg SAI_IT_CNRDY: Codec not ready interrupt enable + * @arg SAI_IT_AFSDET: Anticipated frame synchronization detection interrupt enable + * @arg SAI_IT_LFSDET: Late frame synchronization detection interrupt enabl + * @retval None + */ + +#define __HAL_SAI_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IMR |= (__INTERRUPT__)) +#define __HAL_SAI_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IMR &= (~(__INTERRUPT__))) + +/** @brief Check if the specified SAI interrupt source is enabled or disabled. + * @param __HANDLE__: specifies the SAI Handle. + * This parameter can be SAI where x: 1, 2, or 3 to select the SAI peripheral. + * @param __INTERRUPT__: specifies the SAI interrupt source to check. + * This parameter can be one of the following values: + * @arg SAI_IT_TXE: Tx buffer empty interrupt enable. + * @arg SAI_IT_RXNE: Rx buffer not empty interrupt enable. + * @arg SAI_IT_ERR: Error interrupt enable. + * @retval The new state of __INTERRUPT__ (TRUE or FALSE). + */ +#define __HAL_SAI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->IMR & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Check whether the specified SAI flag is set or not. + * @param __HANDLE__: specifies the SAI Handle. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg SAI_FLAG_OVRUDR: Overrun underrun flag. + * @arg SAI_FLAG_MUTEDET: Mute detection flag. + * @arg SAI_FLAG_WCKCFG: Wrong Clock Configuration flag. + * @arg SAI_FLAG_FREQ: FIFO request flag. + * @arg SAI_FLAG_CNRDY: Codec not ready flag. + * @arg SAI_FLAG_AFSDET: Anticipated frame synchronization detection flag. + * @arg SAI_FLAG_LFSDET: Late frame synchronization detection flag. + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_SAI_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__)) + +/** @brief Clears the specified SAI pending flag. + * @param __HANDLE__: specifies the SAI Handle. + * @param __FLAG__: specifies the flag to check. + * This parameter can be any combination of the following values: + * @arg SAI_FLAG_OVRUDR: Clear Overrun underrun + * @arg SAI_FLAG_MUTEDET: Clear Mute detection + * @arg SAI_FLAG_WCKCFG: Clear Wrong Clock Configuration + * @arg SAI_FLAG_FREQ: Clear FIFO request + * @arg SAI_FLAG_CNRDY: Clear Codec not ready + * @arg SAI_FLAG_AFSDET: Clear Anticipated frame synchronization detection + * @arg SAI_FLAG_LFSDET: Clear Late frame synchronization detection + * + * @retval None + */ +#define __HAL_SAI_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->CLRFR = (__FLAG__)) + +#define __HAL_SAI_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= SAI_xCR1_SAIEN) +#define __HAL_SAI_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~SAI_xCR1_SAIEN) + + /** + * @} + */ + +/* Include RCC SAI Extension module */ +#include "stm32f4xx_hal_sai_ex.h" + +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup SAI_Exported_Functions + * @{ + */ + +/* Initialization/de-initialization functions **********************************/ +/** @addtogroup SAI_Exported_Functions_Group1 + * @{ + */ +HAL_StatusTypeDef HAL_SAI_InitProtocol(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot); +HAL_StatusTypeDef HAL_SAI_Init(SAI_HandleTypeDef *hsai); +HAL_StatusTypeDef HAL_SAI_DeInit (SAI_HandleTypeDef *hsai); +void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai); +void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai); + +/** + * @} + */ + +/* I/O operation functions *****************************************************/ +/** @addtogroup SAI_Exported_Functions_Group2 + * @{ + */ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_SAI_Transmit(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_SAI_Receive(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout); + +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_SAI_Transmit_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SAI_Receive_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size); + +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_SAI_Transmit_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SAI_Receive_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SAI_DMAPause(SAI_HandleTypeDef *hsai); +HAL_StatusTypeDef HAL_SAI_DMAResume(SAI_HandleTypeDef *hsai); +HAL_StatusTypeDef HAL_SAI_DMAStop(SAI_HandleTypeDef *hsai); + +/* Abort function */ +HAL_StatusTypeDef HAL_SAI_Abort(SAI_HandleTypeDef *hsai); + +/* Mute management */ +HAL_StatusTypeDef HAL_SAI_EnableTxMuteMode(SAI_HandleTypeDef *hsai, uint16_t val); +HAL_StatusTypeDef HAL_SAI_DisableTxMuteMode(SAI_HandleTypeDef *hsai); +HAL_StatusTypeDef HAL_SAI_EnableRxMuteMode(SAI_HandleTypeDef *hsai, SAIcallback callback, uint16_t counter); +HAL_StatusTypeDef HAL_SAI_DisableRxMuteMode(SAI_HandleTypeDef *hsai); + +/* SAI IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */ +void HAL_SAI_IRQHandler(SAI_HandleTypeDef *hsai); +void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai); +void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai); +void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai); +void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai); +void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai); +/** + * @} + */ + +/** @addtogroup SAI_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State functions **************************************************/ +HAL_SAI_StateTypeDef HAL_SAI_GetState(SAI_HandleTypeDef *hsai); +uint32_t HAL_SAI_GetError(SAI_HandleTypeDef *hsai); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/** @defgroup SAI_Private_Types SAI Private Types + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup SAI_Private_Variables SAI Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup SAI_Private_Constants SAI Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @addtogroup SAI_Private_Macros + * @{ + */ +#define IS_SAI_BLOCK_SYNCEXT(STATE) (((STATE) == SAI_SYNCEXT_DISABLE) ||\ + ((STATE) == SAI_SYNCEXT_IN_ENABLE) ||\ + ((STATE) == SAI_SYNCEXT_OUTBLOCKA_ENABLE) ||\ + ((STATE) == SAI_SYNCEXT_OUTBLOCKB_ENABLE)) + +#define IS_SAI_SUPPORTED_PROTOCOL(PROTOCOL) (((PROTOCOL) == SAI_I2S_STANDARD) ||\ + ((PROTOCOL) == SAI_I2S_MSBJUSTIFIED) ||\ + ((PROTOCOL) == SAI_I2S_LSBJUSTIFIED) ||\ + ((PROTOCOL) == SAI_PCM_LONG) ||\ + ((PROTOCOL) == SAI_PCM_SHORT)) + +#define IS_SAI_PROTOCOL_DATASIZE(DATASIZE) (((DATASIZE) == SAI_PROTOCOL_DATASIZE_16BIT) ||\ + ((DATASIZE) == SAI_PROTOCOL_DATASIZE_16BITEXTENDED) ||\ + ((DATASIZE) == SAI_PROTOCOL_DATASIZE_24BIT) ||\ + ((DATASIZE) == SAI_PROTOCOL_DATASIZE_32BIT)) + +#define IS_SAI_CLK_SOURCE(SOURCE) (((SOURCE) == SAI_CLKSOURCE_PLLSAI) ||\ + ((SOURCE) == SAI_CLKSOURCE_PLLI2S) ||\ + ((SOURCE) == SAI_CLKSOURCE_EXT)) + +#define IS_SAI_AUDIO_FREQUENCY(AUDIO) (((AUDIO) == SAI_AUDIO_FREQUENCY_192K) || ((AUDIO) == SAI_AUDIO_FREQUENCY_96K) || \ + ((AUDIO) == SAI_AUDIO_FREQUENCY_48K) || ((AUDIO) == SAI_AUDIO_FREQUENCY_44K) || \ + ((AUDIO) == SAI_AUDIO_FREQUENCY_32K) || ((AUDIO) == SAI_AUDIO_FREQUENCY_22K) || \ + ((AUDIO) == SAI_AUDIO_FREQUENCY_16K) || ((AUDIO) == SAI_AUDIO_FREQUENCY_11K) || \ + ((AUDIO) == SAI_AUDIO_FREQUENCY_8K) || ((AUDIO) == SAI_AUDIO_FREQUENCY_MCKDIV)) + +#define IS_SAI_BLOCK_MODE(MODE) (((MODE) == SAI_MODEMASTER_TX) || \ + ((MODE) == SAI_MODEMASTER_RX) || \ + ((MODE) == SAI_MODESLAVE_TX) || \ + ((MODE) == SAI_MODESLAVE_RX)) + +#define IS_SAI_BLOCK_PROTOCOL(PROTOCOL) (((PROTOCOL) == SAI_FREE_PROTOCOL) || \ + ((PROTOCOL) == SAI_AC97_PROTOCOL) || \ + ((PROTOCOL) == SAI_SPDIF_PROTOCOL)) + +#define IS_SAI_BLOCK_DATASIZE(DATASIZE) (((DATASIZE) == SAI_DATASIZE_8) || \ + ((DATASIZE) == SAI_DATASIZE_10) || \ + ((DATASIZE) == SAI_DATASIZE_16) || \ + ((DATASIZE) == SAI_DATASIZE_20) || \ + ((DATASIZE) == SAI_DATASIZE_24) || \ + ((DATASIZE) == SAI_DATASIZE_32)) + +#define IS_SAI_BLOCK_FIRST_BIT(BIT) (((BIT) == SAI_FIRSTBIT_MSB) || \ + ((BIT) == SAI_FIRSTBIT_LSB)) + +#define IS_SAI_BLOCK_CLOCK_STROBING(CLOCK) (((CLOCK) == SAI_CLOCKSTROBING_FALLINGEDGE) || \ + ((CLOCK) == SAI_CLOCKSTROBING_RISINGEDGE)) + +#define IS_SAI_BLOCK_SYNCHRO(SYNCHRO) (((SYNCHRO) == SAI_ASYNCHRONOUS) || \ + ((SYNCHRO) == SAI_SYNCHRONOUS) || \ + ((SYNCHRO) == SAI_SYNCHRONOUS_EXT)) + +#define IS_SAI_BLOCK_OUTPUT_DRIVE(DRIVE) (((DRIVE) == SAI_OUTPUTDRIVE_DISABLE) || \ + ((DRIVE) == SAI_OUTPUTDRIVE_ENABLE)) + +#define IS_SAI_BLOCK_NODIVIDER(NODIVIDER) (((NODIVIDER) == SAI_MASTERDIVIDER_ENABLE) || \ + ((NODIVIDER) == SAI_MASTERDIVIDER_DISABLE)) + +#define IS_SAI_BLOCK_FIFO_STATUS(STATUS) (((STATUS) == SAI_FIFOSTATUS_LESS1QUARTERFULL ) || \ + ((STATUS) == SAI_FIFOSTATUS_HALFFULL) || \ + ((STATUS) == SAI_FIFOSTATUS_1QUARTERFULL) || \ + ((STATUS) == SAI_FIFOSTATUS_3QUARTERFULL) || \ + ((STATUS) == SAI_FIFOSTATUS_FULL) || \ + ((STATUS) == SAI_FIFOSTATUS_EMPTY)) + +#define IS_SAI_BLOCK_MUTE_COUNTER(COUNTER) ((COUNTER) <= 63) + +#define IS_SAI_BLOCK_MUTE_VALUE(VALUE) (((VALUE) == SAI_ZERO_VALUE) || \ + ((VALUE) == SAI_LAST_SENT_VALUE)) + +#define IS_SAI_BLOCK_COMPANDING_MODE(MODE) (((MODE) == SAI_NOCOMPANDING) || \ + ((MODE) == SAI_ULAW_1CPL_COMPANDING) || \ + ((MODE) == SAI_ALAW_1CPL_COMPANDING) || \ + ((MODE) == SAI_ULAW_2CPL_COMPANDING) || \ + ((MODE) == SAI_ALAW_2CPL_COMPANDING)) + +#define IS_SAI_BLOCK_FIFO_THRESHOLD(THRESHOLD) (((THRESHOLD) == SAI_FIFOTHRESHOLD_EMPTY) || \ + ((THRESHOLD) == SAI_FIFOTHRESHOLD_1QF) || \ + ((THRESHOLD) == SAI_FIFOTHRESHOLD_HF) || \ + ((THRESHOLD) == SAI_FIFOTHRESHOLD_3QF) || \ + ((THRESHOLD) == SAI_FIFOTHRESHOLD_FULL)) + +#define IS_SAI_BLOCK_TRISTATE_MANAGEMENT(STATE) (((STATE) == SAI_OUTPUT_NOTRELEASED) ||\ + ((STATE) == SAI_OUTPUT_RELEASED)) + +#define IS_SAI_MONO_STEREO_MODE(MODE) (((MODE) == SAI_MONOMODE) ||\ + ((MODE) == SAI_STEREOMODE)) + +#define IS_SAI_SLOT_ACTIVE(ACTIVE) ((((ACTIVE) >> 16 ) > 0) && (((ACTIVE) >> 16 ) <= (SAI_SLOTACTIVE_ALL >> 16))) + +#define IS_SAI_BLOCK_SLOT_NUMBER(NUMBER) ((1 <= (NUMBER)) && ((NUMBER) <= 16)) + +#define IS_SAI_BLOCK_SLOT_SIZE(SIZE) (((SIZE) == SAI_SLOTSIZE_DATASIZE) || \ + ((SIZE) == SAI_SLOTSIZE_16B) || \ + ((SIZE) == SAI_SLOTSIZE_32B)) + +#define IS_SAI_BLOCK_FIRSTBIT_OFFSET(OFFSET) ((OFFSET) <= 24) + +#define IS_SAI_BLOCK_FS_OFFSET(OFFSET) (((OFFSET) == SAI_FS_FIRSTBIT) || \ + ((OFFSET) == SAI_FS_BEFOREFIRSTBIT)) + +#define IS_SAI_BLOCK_FS_POLARITY(POLARITY) (((POLARITY) == SAI_FS_ACTIVE_LOW) || \ + ((POLARITY) == SAI_FS_ACTIVE_HIGH)) + +#define IS_SAI_BLOCK_FS_DEFINITION(DEFINITION) (((DEFINITION) == SAI_FS_STARTFRAME) || \ + ((DEFINITION) == SAI_FS_CHANNEL_IDENTIFICATION)) + +#define IS_SAI_BLOCK_MASTER_DIVIDER(DIVIDER) ((DIVIDER) <= 15) + +#define IS_SAI_BLOCK_FRAME_LENGTH(LENGTH) ((8 <= (LENGTH)) && ((LENGTH) <= 256)) + +#define IS_SAI_BLOCK_ACTIVE_FRAME(LENGTH) ((1 <= (LENGTH)) && ((LENGTH) <= 128)) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup SAI_Private_Functions SAI Private Functions + * @{ + */ + +/** + * @} + */ + +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_SAI_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sai_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sai_ex.h new file mode 100644 index 0000000..638bfd7 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sai_ex.h @@ -0,0 +1,101 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_sai_ex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of SAI Extension HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_SAI_EX_H +#define __STM32F4xx_HAL_SAI_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup SAIEx + * @{ + */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SAIEx_Exported_Functions + * @{ + */ + +/** @addtogroup SAIEx_Exported_Functions_Group1 + * @{ + */ + +/* Extended features functions ************************************************/ +void SAI_BlockSynchroConfig(SAI_HandleTypeDef *hsai); +uint32_t SAI_GetInputClock(SAI_HandleTypeDef *hsai); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_SAI_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sd.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sd.h new file mode 100644 index 0000000..8d8a1ac --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sd.h @@ -0,0 +1,789 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_sd.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of SD HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_SD_H +#define __STM32F4xx_HAL_SD_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_ll_sdmmc.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup SD SD + * @brief SD HAL module driver + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SD_Exported_Types SD Exported Types + * @{ + */ + +/** @defgroup SD_Exported_Types_Group1 SD Handle Structure definition + * @{ + */ +#define SD_InitTypeDef SDIO_InitTypeDef +#define SD_TypeDef SDIO_TypeDef + +typedef struct +{ + SD_TypeDef *Instance; /*!< SDIO register base address */ + + SD_InitTypeDef Init; /*!< SD required parameters */ + + HAL_LockTypeDef Lock; /*!< SD locking object */ + + uint32_t CardType; /*!< SD card type */ + + uint32_t RCA; /*!< SD relative card address */ + + uint32_t CSD[4]; /*!< SD card specific data table */ + + uint32_t CID[4]; /*!< SD card identification number table */ + + __IO uint32_t SdTransferCplt; /*!< SD transfer complete flag in non blocking mode */ + + __IO uint32_t SdTransferErr; /*!< SD transfer error flag in non blocking mode */ + + __IO uint32_t DmaTransferCplt; /*!< SD DMA transfer complete flag */ + + __IO uint32_t SdOperation; /*!< SD transfer operation (read/write) */ + + DMA_HandleTypeDef *hdmarx; /*!< SD Rx DMA handle parameters */ + + DMA_HandleTypeDef *hdmatx; /*!< SD Tx DMA handle parameters */ + +}SD_HandleTypeDef; +/** + * @} + */ + +/** @defgroup SD_Exported_Types_Group2 Card Specific Data: CSD Register + * @{ + */ +typedef struct +{ + __IO uint8_t CSDStruct; /*!< CSD structure */ + __IO uint8_t SysSpecVersion; /*!< System specification version */ + __IO uint8_t Reserved1; /*!< Reserved */ + __IO uint8_t TAAC; /*!< Data read access time 1 */ + __IO uint8_t NSAC; /*!< Data read access time 2 in CLK cycles */ + __IO uint8_t MaxBusClkFrec; /*!< Max. bus clock frequency */ + __IO uint16_t CardComdClasses; /*!< Card command classes */ + __IO uint8_t RdBlockLen; /*!< Max. read data block length */ + __IO uint8_t PartBlockRead; /*!< Partial blocks for read allowed */ + __IO uint8_t WrBlockMisalign; /*!< Write block misalignment */ + __IO uint8_t RdBlockMisalign; /*!< Read block misalignment */ + __IO uint8_t DSRImpl; /*!< DSR implemented */ + __IO uint8_t Reserved2; /*!< Reserved */ + __IO uint32_t DeviceSize; /*!< Device Size */ + __IO uint8_t MaxRdCurrentVDDMin; /*!< Max. read current @ VDD min */ + __IO uint8_t MaxRdCurrentVDDMax; /*!< Max. read current @ VDD max */ + __IO uint8_t MaxWrCurrentVDDMin; /*!< Max. write current @ VDD min */ + __IO uint8_t MaxWrCurrentVDDMax; /*!< Max. write current @ VDD max */ + __IO uint8_t DeviceSizeMul; /*!< Device size multiplier */ + __IO uint8_t EraseGrSize; /*!< Erase group size */ + __IO uint8_t EraseGrMul; /*!< Erase group size multiplier */ + __IO uint8_t WrProtectGrSize; /*!< Write protect group size */ + __IO uint8_t WrProtectGrEnable; /*!< Write protect group enable */ + __IO uint8_t ManDeflECC; /*!< Manufacturer default ECC */ + __IO uint8_t WrSpeedFact; /*!< Write speed factor */ + __IO uint8_t MaxWrBlockLen; /*!< Max. write data block length */ + __IO uint8_t WriteBlockPaPartial; /*!< Partial blocks for write allowed */ + __IO uint8_t Reserved3; /*!< Reserved */ + __IO uint8_t ContentProtectAppli; /*!< Content protection application */ + __IO uint8_t FileFormatGrouop; /*!< File format group */ + __IO uint8_t CopyFlag; /*!< Copy flag (OTP) */ + __IO uint8_t PermWrProtect; /*!< Permanent write protection */ + __IO uint8_t TempWrProtect; /*!< Temporary write protection */ + __IO uint8_t FileFormat; /*!< File format */ + __IO uint8_t ECC; /*!< ECC code */ + __IO uint8_t CSD_CRC; /*!< CSD CRC */ + __IO uint8_t Reserved4; /*!< Always 1 */ + +}HAL_SD_CSDTypedef; +/** + * @} + */ + +/** @defgroup SD_Exported_Types_Group3 Card Identification Data: CID Register + * @{ + */ +typedef struct +{ + __IO uint8_t ManufacturerID; /*!< Manufacturer ID */ + __IO uint16_t OEM_AppliID; /*!< OEM/Application ID */ + __IO uint32_t ProdName1; /*!< Product Name part1 */ + __IO uint8_t ProdName2; /*!< Product Name part2 */ + __IO uint8_t ProdRev; /*!< Product Revision */ + __IO uint32_t ProdSN; /*!< Product Serial Number */ + __IO uint8_t Reserved1; /*!< Reserved1 */ + __IO uint16_t ManufactDate; /*!< Manufacturing Date */ + __IO uint8_t CID_CRC; /*!< CID CRC */ + __IO uint8_t Reserved2; /*!< Always 1 */ + +}HAL_SD_CIDTypedef; +/** + * @} + */ + +/** @defgroup SD_Exported_Types_Group4 SD Card Status returned by ACMD13 + * @{ + */ +typedef struct +{ + __IO uint8_t DAT_BUS_WIDTH; /*!< Shows the currently defined data bus width */ + __IO uint8_t SECURED_MODE; /*!< Card is in secured mode of operation */ + __IO uint16_t SD_CARD_TYPE; /*!< Carries information about card type */ + __IO uint32_t SIZE_OF_PROTECTED_AREA; /*!< Carries information about the capacity of protected area */ + __IO uint8_t SPEED_CLASS; /*!< Carries information about the speed class of the card */ + __IO uint8_t PERFORMANCE_MOVE; /*!< Carries information about the card's performance move */ + __IO uint8_t AU_SIZE; /*!< Carries information about the card's allocation unit size */ + __IO uint16_t ERASE_SIZE; /*!< Determines the number of AUs to be erased in one operation */ + __IO uint8_t ERASE_TIMEOUT; /*!< Determines the timeout for any number of AU erase */ + __IO uint8_t ERASE_OFFSET; /*!< Carries information about the erase offset */ + +}HAL_SD_CardStatusTypedef; +/** + * @} + */ + +/** @defgroup SD_Exported_Types_Group5 SD Card information structure + * @{ + */ +typedef struct +{ + HAL_SD_CSDTypedef SD_csd; /*!< SD card specific data register */ + HAL_SD_CIDTypedef SD_cid; /*!< SD card identification number register */ + uint64_t CardCapacity; /*!< Card capacity */ + uint32_t CardBlockSize; /*!< Card block size */ + uint16_t RCA; /*!< SD relative card address */ + uint8_t CardType; /*!< SD card type */ + +}HAL_SD_CardInfoTypedef; +/** + * @} + */ + +/** @defgroup SD_Exported_Types_Group6 SD Error status enumeration Structure definition + * @{ + */ +typedef enum +{ +/** + * @brief SD specific error defines + */ + SD_CMD_CRC_FAIL = (1), /*!< Command response received (but CRC check failed) */ + SD_DATA_CRC_FAIL = (2), /*!< Data block sent/received (CRC check failed) */ + SD_CMD_RSP_TIMEOUT = (3), /*!< Command response timeout */ + SD_DATA_TIMEOUT = (4), /*!< Data timeout */ + SD_TX_UNDERRUN = (5), /*!< Transmit FIFO underrun */ + SD_RX_OVERRUN = (6), /*!< Receive FIFO overrun */ + SD_START_BIT_ERR = (7), /*!< Start bit not detected on all data signals in wide bus mode */ + SD_CMD_OUT_OF_RANGE = (8), /*!< Command's argument was out of range. */ + SD_ADDR_MISALIGNED = (9), /*!< Misaligned address */ + SD_BLOCK_LEN_ERR = (10), /*!< Transferred block length is not allowed for the card or the number of transferred bytes does not match the block length */ + SD_ERASE_SEQ_ERR = (11), /*!< An error in the sequence of erase command occurs. */ + SD_BAD_ERASE_PARAM = (12), /*!< An invalid selection for erase groups */ + SD_WRITE_PROT_VIOLATION = (13), /*!< Attempt to program a write protect block */ + SD_LOCK_UNLOCK_FAILED = (14), /*!< Sequence or password error has been detected in unlock command or if there was an attempt to access a locked card */ + SD_COM_CRC_FAILED = (15), /*!< CRC check of the previous command failed */ + SD_ILLEGAL_CMD = (16), /*!< Command is not legal for the card state */ + SD_CARD_ECC_FAILED = (17), /*!< Card internal ECC was applied but failed to correct the data */ + SD_CC_ERROR = (18), /*!< Internal card controller error */ + SD_GENERAL_UNKNOWN_ERROR = (19), /*!< General or unknown error */ + SD_STREAM_READ_UNDERRUN = (20), /*!< The card could not sustain data transfer in stream read operation. */ + SD_STREAM_WRITE_OVERRUN = (21), /*!< The card could not sustain data programming in stream mode */ + SD_CID_CSD_OVERWRITE = (22), /*!< CID/CSD overwrite error */ + SD_WP_ERASE_SKIP = (23), /*!< Only partial address space was erased */ + SD_CARD_ECC_DISABLED = (24), /*!< Command has been executed without using internal ECC */ + SD_ERASE_RESET = (25), /*!< Erase sequence was cleared before executing because an out of erase sequence command was received */ + SD_AKE_SEQ_ERROR = (26), /*!< Error in sequence of authentication. */ + SD_INVALID_VOLTRANGE = (27), + SD_ADDR_OUT_OF_RANGE = (28), + SD_SWITCH_ERROR = (29), + SD_SDIO_DISABLED = (30), + SD_SDIO_FUNCTION_BUSY = (31), + SD_SDIO_FUNCTION_FAILED = (32), + SD_SDIO_UNKNOWN_FUNCTION = (33), + +/** + * @brief Standard error defines + */ + SD_INTERNAL_ERROR = (34), + SD_NOT_CONFIGURED = (35), + SD_REQUEST_PENDING = (36), + SD_REQUEST_NOT_APPLICABLE = (37), + SD_INVALID_PARAMETER = (38), + SD_UNSUPPORTED_FEATURE = (39), + SD_UNSUPPORTED_HW = (40), + SD_ERROR = (41), + SD_OK = (0) + +}HAL_SD_ErrorTypedef; +/** + * @} + */ + +/** @defgroup SD_Exported_Types_Group7 SD Transfer state enumeration structure + * @{ + */ +typedef enum +{ + SD_TRANSFER_OK = 0, /*!< Transfer success */ + SD_TRANSFER_BUSY = 1, /*!< Transfer is occurring */ + SD_TRANSFER_ERROR = 2 /*!< Transfer failed */ + +}HAL_SD_TransferStateTypedef; +/** + * @} + */ + +/** @defgroup SD_Exported_Types_Group8 SD Card State enumeration structure + * @{ + */ +typedef enum +{ + SD_CARD_READY = ((uint32_t)0x00000001), /*!< Card state is ready */ + SD_CARD_IDENTIFICATION = ((uint32_t)0x00000002), /*!< Card is in identification state */ + SD_CARD_STANDBY = ((uint32_t)0x00000003), /*!< Card is in standby state */ + SD_CARD_TRANSFER = ((uint32_t)0x00000004), /*!< Card is in transfer state */ + SD_CARD_SENDING = ((uint32_t)0x00000005), /*!< Card is sending an operation */ + SD_CARD_RECEIVING = ((uint32_t)0x00000006), /*!< Card is receiving operation information */ + SD_CARD_PROGRAMMING = ((uint32_t)0x00000007), /*!< Card is in programming state */ + SD_CARD_DISCONNECTED = ((uint32_t)0x00000008), /*!< Card is disconnected */ + SD_CARD_ERROR = ((uint32_t)0x000000FF) /*!< Card is in error state */ + +}HAL_SD_CardStateTypedef; +/** + * @} + */ + +/** @defgroup SD_Exported_Types_Group9 SD Operation enumeration structure + * @{ + */ +typedef enum +{ + SD_READ_SINGLE_BLOCK = 0, /*!< Read single block operation */ + SD_READ_MULTIPLE_BLOCK = 1, /*!< Read multiple blocks operation */ + SD_WRITE_SINGLE_BLOCK = 2, /*!< Write single block operation */ + SD_WRITE_MULTIPLE_BLOCK = 3 /*!< Write multiple blocks operation */ + +}HAL_SD_OperationTypedef; +/** + * @} + */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SD_Exported_Constants SD Exported Constants + * @{ + */ + +/** + * @brief SD Commands Index + */ +#define SD_CMD_GO_IDLE_STATE ((uint8_t)0) /*!< Resets the SD memory card. */ +#define SD_CMD_SEND_OP_COND ((uint8_t)1) /*!< Sends host capacity support information and activates the card's initialization process. */ +#define SD_CMD_ALL_SEND_CID ((uint8_t)2) /*!< Asks any card connected to the host to send the CID numbers on the CMD line. */ +#define SD_CMD_SET_REL_ADDR ((uint8_t)3) /*!< Asks the card to publish a new relative address (RCA). */ +#define SD_CMD_SET_DSR ((uint8_t)4) /*!< Programs the DSR of all cards. */ +#define SD_CMD_SDIO_SEN_OP_COND ((uint8_t)5) /*!< Sends host capacity support information (HCS) and asks the accessed card to send its + operating condition register (OCR) content in the response on the CMD line. */ +#define SD_CMD_HS_SWITCH ((uint8_t)6) /*!< Checks switchable function (mode 0) and switch card function (mode 1). */ +#define SD_CMD_SEL_DESEL_CARD ((uint8_t)7) /*!< Selects the card by its own relative address and gets deselected by any other address */ +#define SD_CMD_HS_SEND_EXT_CSD ((uint8_t)8) /*!< Sends SD Memory Card interface condition, which includes host supply voltage information + and asks the card whether card supports voltage. */ +#define SD_CMD_SEND_CSD ((uint8_t)9) /*!< Addressed card sends its card specific data (CSD) on the CMD line. */ +#define SD_CMD_SEND_CID ((uint8_t)10) /*!< Addressed card sends its card identification (CID) on the CMD line. */ +#define SD_CMD_READ_DAT_UNTIL_STOP ((uint8_t)11) /*!< SD card doesn't support it. */ +#define SD_CMD_STOP_TRANSMISSION ((uint8_t)12) /*!< Forces the card to stop transmission. */ +#define SD_CMD_SEND_STATUS ((uint8_t)13) /*!< Addressed card sends its status register. */ +#define SD_CMD_HS_BUSTEST_READ ((uint8_t)14) +#define SD_CMD_GO_INACTIVE_STATE ((uint8_t)15) /*!< Sends an addressed card into the inactive state. */ +#define SD_CMD_SET_BLOCKLEN ((uint8_t)16) /*!< Sets the block length (in bytes for SDSC) for all following block commands + (read, write, lock). Default block length is fixed to 512 Bytes. Not effective + for SDHS and SDXC. */ +#define SD_CMD_READ_SINGLE_BLOCK ((uint8_t)17) /*!< Reads single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of + fixed 512 bytes in case of SDHC and SDXC. */ +#define SD_CMD_READ_MULT_BLOCK ((uint8_t)18) /*!< Continuously transfers data blocks from card to host until interrupted by + STOP_TRANSMISSION command. */ +#define SD_CMD_HS_BUSTEST_WRITE ((uint8_t)19) /*!< 64 bytes tuning pattern is sent for SDR50 and SDR104. */ +#define SD_CMD_WRITE_DAT_UNTIL_STOP ((uint8_t)20) /*!< Speed class control command. */ +#define SD_CMD_SET_BLOCK_COUNT ((uint8_t)23) /*!< Specify block count for CMD18 and CMD25. */ +#define SD_CMD_WRITE_SINGLE_BLOCK ((uint8_t)24) /*!< Writes single block of size selected by SET_BLOCKLEN in case of SDSC, and a block of + fixed 512 bytes in case of SDHC and SDXC. */ +#define SD_CMD_WRITE_MULT_BLOCK ((uint8_t)25) /*!< Continuously writes blocks of data until a STOP_TRANSMISSION follows. */ +#define SD_CMD_PROG_CID ((uint8_t)26) /*!< Reserved for manufacturers. */ +#define SD_CMD_PROG_CSD ((uint8_t)27) /*!< Programming of the programmable bits of the CSD. */ +#define SD_CMD_SET_WRITE_PROT ((uint8_t)28) /*!< Sets the write protection bit of the addressed group. */ +#define SD_CMD_CLR_WRITE_PROT ((uint8_t)29) /*!< Clears the write protection bit of the addressed group. */ +#define SD_CMD_SEND_WRITE_PROT ((uint8_t)30) /*!< Asks the card to send the status of the write protection bits. */ +#define SD_CMD_SD_ERASE_GRP_START ((uint8_t)32) /*!< Sets the address of the first write block to be erased. (For SD card only). */ +#define SD_CMD_SD_ERASE_GRP_END ((uint8_t)33) /*!< Sets the address of the last write block of the continuous range to be erased. */ +#define SD_CMD_ERASE_GRP_START ((uint8_t)35) /*!< Sets the address of the first write block to be erased. Reserved for each command + system set by switch function command (CMD6). */ +#define SD_CMD_ERASE_GRP_END ((uint8_t)36) /*!< Sets the address of the last write block of the continuous range to be erased. + Reserved for each command system set by switch function command (CMD6). */ +#define SD_CMD_ERASE ((uint8_t)38) /*!< Reserved for SD security applications. */ +#define SD_CMD_FAST_IO ((uint8_t)39) /*!< SD card doesn't support it (Reserved). */ +#define SD_CMD_GO_IRQ_STATE ((uint8_t)40) /*!< SD card doesn't support it (Reserved). */ +#define SD_CMD_LOCK_UNLOCK ((uint8_t)42) /*!< Sets/resets the password or lock/unlock the card. The size of the data block is set by + the SET_BLOCK_LEN command. */ +#define SD_CMD_APP_CMD ((uint8_t)55) /*!< Indicates to the card that the next command is an application specific command rather + than a standard command. */ +#define SD_CMD_GEN_CMD ((uint8_t)56) /*!< Used either to transfer a data block to the card or to get a data block from the card + for general purpose/application specific commands. */ +#define SD_CMD_NO_CMD ((uint8_t)64) + +/** + * @brief Following commands are SD Card Specific commands. + * SDIO_APP_CMD should be sent before sending these commands. + */ +#define SD_CMD_APP_SD_SET_BUSWIDTH ((uint8_t)6) /*!< (ACMD6) Defines the data bus width to be used for data transfer. The allowed data bus + widths are given in SCR register. */ +#define SD_CMD_SD_APP_STATUS ((uint8_t)13) /*!< (ACMD13) Sends the SD status. */ +#define SD_CMD_SD_APP_SEND_NUM_WRITE_BLOCKS ((uint8_t)22) /*!< (ACMD22) Sends the number of the written (without errors) write blocks. Responds with + 32bit+CRC data block. */ +#define SD_CMD_SD_APP_OP_COND ((uint8_t)41) /*!< (ACMD41) Sends host capacity support information (HCS) and asks the accessed card to + send its operating condition register (OCR) content in the response on the CMD line. */ +#define SD_CMD_SD_APP_SET_CLR_CARD_DETECT ((uint8_t)42) /*!< (ACMD42) Connects/Disconnects the 50 KOhm pull-up resistor on CD/DAT3 (pin 1) of the card. */ +#define SD_CMD_SD_APP_SEND_SCR ((uint8_t)51) /*!< Reads the SD Configuration Register (SCR). */ +#define SD_CMD_SDIO_RW_DIRECT ((uint8_t)52) /*!< For SD I/O card only, reserved for security specification. */ +#define SD_CMD_SDIO_RW_EXTENDED ((uint8_t)53) /*!< For SD I/O card only, reserved for security specification. */ + +/** + * @brief Following commands are SD Card Specific security commands. + * SD_CMD_APP_CMD should be sent before sending these commands. + */ +#define SD_CMD_SD_APP_GET_MKB ((uint8_t)43) /*!< For SD card only */ +#define SD_CMD_SD_APP_GET_MID ((uint8_t)44) /*!< For SD card only */ +#define SD_CMD_SD_APP_SET_CER_RN1 ((uint8_t)45) /*!< For SD card only */ +#define SD_CMD_SD_APP_GET_CER_RN2 ((uint8_t)46) /*!< For SD card only */ +#define SD_CMD_SD_APP_SET_CER_RES2 ((uint8_t)47) /*!< For SD card only */ +#define SD_CMD_SD_APP_GET_CER_RES1 ((uint8_t)48) /*!< For SD card only */ +#define SD_CMD_SD_APP_SECURE_READ_MULTIPLE_BLOCK ((uint8_t)18) /*!< For SD card only */ +#define SD_CMD_SD_APP_SECURE_WRITE_MULTIPLE_BLOCK ((uint8_t)25) /*!< For SD card only */ +#define SD_CMD_SD_APP_SECURE_ERASE ((uint8_t)38) /*!< For SD card only */ +#define SD_CMD_SD_APP_CHANGE_SECURE_AREA ((uint8_t)49) /*!< For SD card only */ +#define SD_CMD_SD_APP_SECURE_WRITE_MKB ((uint8_t)48) /*!< For SD card only */ + +/** + * @brief Supported SD Memory Cards + */ +#define STD_CAPACITY_SD_CARD_V1_1 ((uint32_t)0x00000000) +#define STD_CAPACITY_SD_CARD_V2_0 ((uint32_t)0x00000001) +#define HIGH_CAPACITY_SD_CARD ((uint32_t)0x00000002) +#define MULTIMEDIA_CARD ((uint32_t)0x00000003) +#define SECURE_DIGITAL_IO_CARD ((uint32_t)0x00000004) +#define HIGH_SPEED_MULTIMEDIA_CARD ((uint32_t)0x00000005) +#define SECURE_DIGITAL_IO_COMBO_CARD ((uint32_t)0x00000006) +#define HIGH_CAPACITY_MMC_CARD ((uint32_t)0x00000007) +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup SD_Exported_macros SD Exported Macros + * @brief macros to handle interrupts and specific clock configurations + * @{ + */ + +/** + * @brief Enable the SD device. + * @retval None + */ +#define __HAL_SD_SDIO_ENABLE() __SDIO_ENABLE() + +/** + * @brief Disable the SD device. + * @retval None + */ +#define __HAL_SD_SDIO_DISABLE() __SDIO_DISABLE() + +/** + * @brief Enable the SDIO DMA transfer. + * @retval None + */ +#define __HAL_SD_SDIO_DMA_ENABLE() __SDIO_DMA_ENABLE() + +/** + * @brief Disable the SDIO DMA transfer. + * @retval None + */ +#define __HAL_SD_SDIO_DMA_DISABLE() __SDIO_DMA_DISABLE() + +/** + * @brief Enable the SD device interrupt. + * @param __HANDLE__: SD Handle + * @param __INTERRUPT__: specifies the SDIO interrupt sources to be enabled. + * This parameter can be one or a combination of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt + * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt + * @arg SDIO_IT_TXACT: Data transmit in progress interrupt + * @arg SDIO_IT_RXACT: Data receive in progress interrupt + * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt + * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt + * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt + * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt + * @retval None + */ +#define __HAL_SD_SDIO_ENABLE_IT(__HANDLE__, __INTERRUPT__) __SDIO_ENABLE_IT((__HANDLE__)->Instance, (__INTERRUPT__)) + +/** + * @brief Disable the SD device interrupt. + * @param __HANDLE__: SD Handle + * @param __INTERRUPT__: specifies the SDIO interrupt sources to be disabled. + * This parameter can be one or a combination of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt + * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt + * @arg SDIO_IT_TXACT: Data transmit in progress interrupt + * @arg SDIO_IT_RXACT: Data receive in progress interrupt + * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt + * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt + * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt + * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt + * @retval None + */ +#define __HAL_SD_SDIO_DISABLE_IT(__HANDLE__, __INTERRUPT__) __SDIO_DISABLE_IT((__HANDLE__)->Instance, (__INTERRUPT__)) + +/** + * @brief Check whether the specified SD flag is set or not. + * @param __HANDLE__: SD Handle + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed) + * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) + * @arg SDIO_FLAG_CTIMEOUT: Command response timeout + * @arg SDIO_FLAG_DTIMEOUT: Data timeout + * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error + * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error + * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed) + * @arg SDIO_FLAG_CMDSENT: Command sent (no response required) + * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero) + * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide bus mode. + * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed) + * @arg SDIO_FLAG_CMDACT: Command transfer in progress + * @arg SDIO_FLAG_TXACT: Data transmit in progress + * @arg SDIO_FLAG_RXACT: Data receive in progress + * @arg SDIO_FLAG_TXFIFOHE: Transmit FIFO Half Empty + * @arg SDIO_FLAG_RXFIFOHF: Receive FIFO Half Full + * @arg SDIO_FLAG_TXFIFOF: Transmit FIFO full + * @arg SDIO_FLAG_RXFIFOF: Receive FIFO full + * @arg SDIO_FLAG_TXFIFOE: Transmit FIFO empty + * @arg SDIO_FLAG_RXFIFOE: Receive FIFO empty + * @arg SDIO_FLAG_TXDAVL: Data available in transmit FIFO + * @arg SDIO_FLAG_RXDAVL: Data available in receive FIFO + * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received + * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61 + * @retval The new state of SD FLAG (SET or RESET). + */ +#define __HAL_SD_SDIO_GET_FLAG(__HANDLE__, __FLAG__) __SDIO_GET_FLAG((__HANDLE__)->Instance, (__FLAG__)) + +/** + * @brief Clear the SD's pending flags. + * @param __HANDLE__: SD Handle + * @param __FLAG__: specifies the flag to clear. + * This parameter can be one or a combination of the following values: + * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed) + * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) + * @arg SDIO_FLAG_CTIMEOUT: Command response timeout + * @arg SDIO_FLAG_DTIMEOUT: Data timeout + * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error + * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error + * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed) + * @arg SDIO_FLAG_CMDSENT: Command sent (no response required) + * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero) + * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide bus mode + * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed) + * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received + * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61 + * @retval None + */ +#define __HAL_SD_SDIO_CLEAR_FLAG(__HANDLE__, __FLAG__) __SDIO_CLEAR_FLAG((__HANDLE__)->Instance, (__FLAG__)) + +/** + * @brief Check whether the specified SD interrupt has occurred or not. + * @param __HANDLE__: SD Handle + * @param __INTERRUPT__: specifies the SDIO interrupt source to check. + * This parameter can be one of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt + * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt + * @arg SDIO_IT_TXACT: Data transmit in progress interrupt + * @arg SDIO_IT_RXACT: Data receive in progress interrupt + * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt + * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt + * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt + * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt + * @retval The new state of SD IT (SET or RESET). + */ +#define __HAL_SD_SDIO_GET_IT (__HANDLE__, __INTERRUPT__) __SDIO_GET_IT ((__HANDLE__)->Instance, __INTERRUPT__) + +/** + * @brief Clear the SD's interrupt pending bits. + * @param __HANDLE__ : SD Handle + * @param __INTERRUPT__: specifies the interrupt pending bit to clear. + * This parameter can be one or a combination of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIO_DCOUNT, is zero) interrupt + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 + * @retval None + */ +#define __HAL_SD_SDIO_CLEAR_IT(__HANDLE__, __INTERRUPT__) __SDIO_CLEAR_IT((__HANDLE__)->Instance, (__INTERRUPT__)) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SD_Exported_Functions SD Exported Functions + * @{ + */ + +/** @defgroup SD_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +HAL_SD_ErrorTypedef HAL_SD_Init(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *SDCardInfo); +HAL_StatusTypeDef HAL_SD_DeInit (SD_HandleTypeDef *hsd); +void HAL_SD_MspInit(SD_HandleTypeDef *hsd); +void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd); +/** + * @} + */ + +/** @defgroup SD_Exported_Functions_Group2 I/O operation functions + * @{ + */ +/* Blocking mode: Polling */ +HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks); +HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks); +HAL_SD_ErrorTypedef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint64_t startaddr, uint64_t endaddr); + +/* Non-Blocking mode: Interrupt */ +void HAL_SD_IRQHandler(SD_HandleTypeDef *hsd); + +/* Callback in non blocking modes (DMA) */ +void HAL_SD_DMA_RxCpltCallback(DMA_HandleTypeDef *hdma); +void HAL_SD_DMA_RxErrorCallback(DMA_HandleTypeDef *hdma); +void HAL_SD_DMA_TxCpltCallback(DMA_HandleTypeDef *hdma); +void HAL_SD_DMA_TxErrorCallback(DMA_HandleTypeDef *hdma); +void HAL_SD_XferCpltCallback(SD_HandleTypeDef *hsd); +void HAL_SD_XferErrorCallback(SD_HandleTypeDef *hsd); + +/* Non-Blocking mode: DMA */ +HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks); +HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks); +HAL_SD_ErrorTypedef HAL_SD_CheckWriteOperation(SD_HandleTypeDef *hsd, uint32_t Timeout); +HAL_SD_ErrorTypedef HAL_SD_CheckReadOperation(SD_HandleTypeDef *hsd, uint32_t Timeout); +/** + * @} + */ + +/** @defgroup SD_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ +HAL_SD_ErrorTypedef HAL_SD_Get_CardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *pCardInfo); +HAL_SD_ErrorTypedef HAL_SD_WideBusOperation_Config(SD_HandleTypeDef *hsd, uint32_t WideMode); +HAL_SD_ErrorTypedef HAL_SD_StopTransfer(SD_HandleTypeDef *hsd); +HAL_SD_ErrorTypedef HAL_SD_HighSpeed (SD_HandleTypeDef *hsd); +/** + * @} + */ + +/* Peripheral State functions ************************************************/ +/** @defgroup SD_Exported_Functions_Group4 Peripheral State functions + * @{ + */ +HAL_SD_ErrorTypedef HAL_SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus); +HAL_SD_ErrorTypedef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypedef *pCardStatus); +HAL_SD_TransferStateTypedef HAL_SD_GetStatus(SD_HandleTypeDef *hsd); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/** @defgroup SD_Private_Types SD Private Types + * @{ + */ + +/** + * @} + */ + +/* Private defines -----------------------------------------------------------*/ +/** @defgroup SD_Private_Defines SD Private Defines + * @{ + */ + +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup SD_Private_Variables SD Private Variables + * @{ + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup SD_Private_Constants SD Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup SD_Private_Macros SD Private Macros + * @{ + */ + +/** + * @} + */ + +/* Private functions prototypes ----------------------------------------------*/ +/** @defgroup SD_Private_Functions_Prototypes SD Private Functions Prototypes + * @{ + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup SD_Private_Functions SD Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_SD_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sdram.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sdram.h new file mode 100644 index 0000000..ab7782e --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sdram.h @@ -0,0 +1,196 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_sdram.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of SDRAM HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_SDRAM_H +#define __STM32F4xx_HAL_SDRAM_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_ll_fmc.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup SDRAM + * @{ + */ + +/* Exported typedef ----------------------------------------------------------*/ +/** @defgroup SDRAM_Exported_Types SDRAM Exported Types + * @{ + */ + +/** + * @brief HAL SDRAM State structure definition + */ +typedef enum +{ + HAL_SDRAM_STATE_RESET = 0x00, /*!< SDRAM not yet initialized or disabled */ + HAL_SDRAM_STATE_READY = 0x01, /*!< SDRAM initialized and ready for use */ + HAL_SDRAM_STATE_BUSY = 0x02, /*!< SDRAM internal process is ongoing */ + HAL_SDRAM_STATE_ERROR = 0x03, /*!< SDRAM error state */ + HAL_SDRAM_STATE_WRITE_PROTECTED = 0x04, /*!< SDRAM device write protected */ + HAL_SDRAM_STATE_PRECHARGED = 0x05 /*!< SDRAM device precharged */ + +}HAL_SDRAM_StateTypeDef; + +/** + * @brief SDRAM handle Structure definition + */ +typedef struct +{ + FMC_SDRAM_TypeDef *Instance; /*!< Register base address */ + + FMC_SDRAM_InitTypeDef Init; /*!< SDRAM device configuration parameters */ + + __IO HAL_SDRAM_StateTypeDef State; /*!< SDRAM access state */ + + HAL_LockTypeDef Lock; /*!< SDRAM locking object */ + + DMA_HandleTypeDef *hdma; /*!< Pointer DMA handler */ + +}SDRAM_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup SDRAM_Exported_Macros SDRAM Exported Macros + * @{ + */ + +/** @brief Reset SDRAM handle state + * @param __HANDLE__: specifies the SDRAM handle. + * @retval None + */ +#define __HAL_SDRAM_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SDRAM_STATE_RESET) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SDRAM_Exported_Functions SDRAM Exported Functions + * @{ + */ + +/** @addtogroup SDRAM_Exported_Functions_Group1 + * @{ + */ + +/* Initialization/de-initialization functions *********************************/ +HAL_StatusTypeDef HAL_SDRAM_Init(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_TimingTypeDef *Timing); +HAL_StatusTypeDef HAL_SDRAM_DeInit(SDRAM_HandleTypeDef *hsdram); +void HAL_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram); +void HAL_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram); + +void HAL_SDRAM_IRQHandler(SDRAM_HandleTypeDef *hsdram); +void HAL_SDRAM_RefreshErrorCallback(SDRAM_HandleTypeDef *hsdram); +void HAL_SDRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma); +void HAL_SDRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/** @addtogroup SDRAM_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions ****************************************************/ +HAL_StatusTypeDef HAL_SDRAM_Read_8b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint8_t *pDstBuffer, uint32_t BufferSize); +HAL_StatusTypeDef HAL_SDRAM_Write_8b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint8_t *pSrcBuffer, uint32_t BufferSize); +HAL_StatusTypeDef HAL_SDRAM_Read_16b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint16_t *pDstBuffer, uint32_t BufferSize); +HAL_StatusTypeDef HAL_SDRAM_Write_16b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint16_t *pSrcBuffer, uint32_t BufferSize); +HAL_StatusTypeDef HAL_SDRAM_Read_32b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize); +HAL_StatusTypeDef HAL_SDRAM_Write_32b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize); + +HAL_StatusTypeDef HAL_SDRAM_Read_DMA(SDRAM_HandleTypeDef *hsdram, uint32_t * pAddress, uint32_t *pDstBuffer, uint32_t BufferSize); +HAL_StatusTypeDef HAL_SDRAM_Write_DMA(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize); +/** + * @} + */ + +/** @addtogroup SDRAM_Exported_Functions_Group3 + * @{ + */ +/* SDRAM Control functions *****************************************************/ +HAL_StatusTypeDef HAL_SDRAM_WriteProtection_Enable(SDRAM_HandleTypeDef *hsdram); +HAL_StatusTypeDef HAL_SDRAM_WriteProtection_Disable(SDRAM_HandleTypeDef *hsdram); +HAL_StatusTypeDef HAL_SDRAM_SendCommand(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command, uint32_t Timeout); +HAL_StatusTypeDef HAL_SDRAM_ProgramRefreshRate(SDRAM_HandleTypeDef *hsdram, uint32_t RefreshRate); +HAL_StatusTypeDef HAL_SDRAM_SetAutoRefreshNumber(SDRAM_HandleTypeDef *hsdram, uint32_t AutoRefreshNumber); +uint32_t HAL_SDRAM_GetModeStatus(SDRAM_HandleTypeDef *hsdram); +/** + * @} + */ + +/** @addtogroup SDRAM_Exported_Functions_Group4 + * @{ + */ +/* SDRAM State functions ********************************************************/ +HAL_SDRAM_StateTypeDef HAL_SDRAM_GetState(SDRAM_HandleTypeDef *hsdram); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_SDRAM_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_smartcard.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_smartcard.h new file mode 100644 index 0000000..43fec1f --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_smartcard.h @@ -0,0 +1,620 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_smartcard.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of SMARTCARD HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_SMARTCARD_H +#define __STM32F4xx_HAL_SMARTCARD_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup SMARTCARD + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SMARTCARD_Exported_Types SMARTCARD Exported Types + * @{ + */ + +/** + * @brief SMARTCARD Init Structure definition + */ +typedef struct +{ + uint32_t BaudRate; /*!< This member configures the SmartCard communication baud rate. + The baud rate is computed using the following formula: + - IntegerDivider = ((PCLKx) / (8 * (hirda->Init.BaudRate))) + - FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 8) + 0.5 */ + + uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref SMARTCARD_Word_Length */ + + uint32_t StopBits; /*!< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref SMARTCARD_Stop_Bits */ + + uint32_t Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref SMARTCARD_Parity + @note When parity is enabled, the computed parity is inserted + at the MSB position of the transmitted data (9th bit when + the word length is set to 9 data bits; 8th bit when the + word length is set to 8 data bits).*/ + + uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. + This parameter can be a value of @ref SMARTCARD_Mode */ + + uint32_t CLKPolarity; /*!< Specifies the steady state of the serial clock. + This parameter can be a value of @ref SMARTCARD_Clock_Polarity */ + + uint32_t CLKPhase; /*!< Specifies the clock transition on which the bit capture is made. + This parameter can be a value of @ref SMARTCARD_Clock_Phase */ + + uint32_t CLKLastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted + data bit (MSB) has to be output on the SCLK pin in synchronous mode. + This parameter can be a value of @ref SMARTCARD_Last_Bit */ + + uint32_t Prescaler; /*!< Specifies the SmartCard Prescaler value used for dividing the system clock + to provide the smartcard clock + This parameter can be a value of @ref SMARTCARD_Prescaler */ + + uint32_t GuardTime; /*!< Specifies the SmartCard Guard Time value in terms of number of baud clocks + The value given in the register (5 significant bits) is multiplied by 2 + to give the division factor of the source clock frequency */ + + uint32_t NACKState; /*!< Specifies the SmartCard NACK Transmission state. + This parameter can be a value of @ref SmartCard_NACK_State */ +}SMARTCARD_InitTypeDef; + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_SMARTCARD_STATE_RESET = 0x00, /*!< Peripheral is not yet Initialized */ + HAL_SMARTCARD_STATE_READY = 0x01, /*!< Peripheral Initialized and ready for use */ + HAL_SMARTCARD_STATE_BUSY = 0x02, /*!< an internal process is ongoing */ + HAL_SMARTCARD_STATE_BUSY_TX = 0x12, /*!< Data Transmission process is ongoing */ + HAL_SMARTCARD_STATE_BUSY_RX = 0x22, /*!< Data Reception process is ongoing */ + HAL_SMARTCARD_STATE_BUSY_TX_RX = 0x32, /*!< Data Transmission and Reception process is ongoing */ + HAL_SMARTCARD_STATE_TIMEOUT = 0x03, /*!< Timeout state */ + HAL_SMARTCARD_STATE_ERROR = 0x04 /*!< Error */ +}HAL_SMARTCARD_StateTypeDef; + +/** + * @brief SMARTCARD handle Structure definition + */ +typedef struct +{ + USART_TypeDef *Instance; /* USART registers base address */ + + SMARTCARD_InitTypeDef Init; /* SmartCard communication parameters */ + + uint8_t *pTxBuffPtr; /* Pointer to SmartCard Tx transfer Buffer */ + + uint16_t TxXferSize; /* SmartCard Tx Transfer size */ + + uint16_t TxXferCount; /* SmartCard Tx Transfer Counter */ + + uint8_t *pRxBuffPtr; /* Pointer to SmartCard Rx transfer Buffer */ + + uint16_t RxXferSize; /* SmartCard Rx Transfer size */ + + uint16_t RxXferCount; /* SmartCard Rx Transfer Counter */ + + DMA_HandleTypeDef *hdmatx; /* SmartCard Tx DMA Handle parameters */ + + DMA_HandleTypeDef *hdmarx; /* SmartCard Rx DMA Handle parameters */ + + HAL_LockTypeDef Lock; /* Locking object */ + + __IO HAL_SMARTCARD_StateTypeDef State; /* SmartCard communication state */ + + __IO uint32_t ErrorCode; /* SmartCard Error code */ + +}SMARTCARD_HandleTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SMARTCARD_Exported_Constants SMARTCARD Exported constants + * @{ + */ +/** @defgroup SMARTCARD_Error_Code SMARTCARD Error Code + * @brief SMARTCARD Error Code + * @{ + */ +#define HAL_SMARTCARD_ERROR_NONE ((uint32_t)0x00000000) /*!< No error */ +#define HAL_SMARTCARD_ERROR_PE ((uint32_t)0x00000001) /*!< Parity error */ +#define HAL_SMARTCARD_ERROR_NE ((uint32_t)0x00000002) /*!< Noise error */ +#define HAL_SMARTCARD_ERROR_FE ((uint32_t)0x00000004) /*!< Frame error */ +#define HAL_SMARTCARD_ERROR_ORE ((uint32_t)0x00000008) /*!< Overrun error */ +#define HAL_SMARTCARD_ERROR_DMA ((uint32_t)0x00000010) /*!< DMA transfer error */ +/** + * @} + */ + +/** @defgroup SMARTCARD_Word_Length SMARTCARD Word Length + * @{ + */ +#define SMARTCARD_WORDLENGTH_9B ((uint32_t)USART_CR1_M) +/** + * @} + */ + +/** @defgroup SMARTCARD_Stop_Bits SMARTCARD Number of Stop Bits + * @{ + */ +#define SMARTCARD_STOPBITS_0_5 ((uint32_t)USART_CR2_STOP_0) +#define SMARTCARD_STOPBITS_1_5 ((uint32_t)(USART_CR2_STOP_0 | USART_CR2_STOP_1)) +/** + * @} + */ + +/** @defgroup SMARTCARD_Parity SMARTCARD Parity + * @{ + */ +#define SMARTCARD_PARITY_EVEN ((uint32_t)USART_CR1_PCE) +#define SMARTCARD_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS)) +/** + * @} + */ + +/** @defgroup SMARTCARD_Mode SMARTCARD Mode + * @{ + */ +#define SMARTCARD_MODE_RX ((uint32_t)USART_CR1_RE) +#define SMARTCARD_MODE_TX ((uint32_t)USART_CR1_TE) +#define SMARTCARD_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE)) +/** + * @} + */ + +/** @defgroup SMARTCARD_Clock_Polarity SMARTCARD Clock Polarity + * @{ + */ +#define SMARTCARD_POLARITY_LOW ((uint32_t)0x00000000) +#define SMARTCARD_POLARITY_HIGH ((uint32_t)USART_CR2_CPOL) +/** + * @} + */ + +/** @defgroup SMARTCARD_Clock_Phase SMARTCARD Clock Phase + * @{ + */ +#define SMARTCARD_PHASE_1EDGE ((uint32_t)0x00000000) +#define SMARTCARD_PHASE_2EDGE ((uint32_t)USART_CR2_CPHA) +/** + * @} + */ + +/** @defgroup SMARTCARD_Last_Bit SMARTCARD Last Bit + * @{ + */ +#define SMARTCARD_LASTBIT_DISABLE ((uint32_t)0x00000000) +#define SMARTCARD_LASTBIT_ENABLE ((uint32_t)USART_CR2_LBCL) +/** + * @} + */ + +/** @defgroup SmartCard_NACK_State SMARTCARD NACK State + * @{ + */ +#define SMARTCARD_NACK_ENABLE ((uint32_t)USART_CR3_NACK) +#define SMARTCARD_NACK_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup SmartCard_DMA_Requests SMARTCARD DMA requests + * @{ + */ +#define SMARTCARD_DMAREQ_TX ((uint32_t)USART_CR3_DMAT) +#define SMARTCARD_DMAREQ_RX ((uint32_t)USART_CR3_DMAR) +/** + * @} + */ + +/** @defgroup SMARTCARD_Prescaler SMARTCARD Prescaler + * @{ + */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV2 ((uint32_t)0x00000001) /*!< SYSCLK divided by 2 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV4 ((uint32_t)0x00000002) /*!< SYSCLK divided by 4 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV6 ((uint32_t)0x00000003) /*!< SYSCLK divided by 6 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV8 ((uint32_t)0x00000004) /*!< SYSCLK divided by 8 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV10 ((uint32_t)0x00000005) /*!< SYSCLK divided by 10 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV12 ((uint32_t)0x00000006) /*!< SYSCLK divided by 12 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV14 ((uint32_t)0x00000007) /*!< SYSCLK divided by 14 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV16 ((uint32_t)0x00000008) /*!< SYSCLK divided by 16 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV18 ((uint32_t)0x00000009) /*!< SYSCLK divided by 18 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV20 ((uint32_t)0x0000000A) /*!< SYSCLK divided by 20 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV22 ((uint32_t)0x0000000B) /*!< SYSCLK divided by 22 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV24 ((uint32_t)0x0000000C) /*!< SYSCLK divided by 24 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV26 ((uint32_t)0x0000000D) /*!< SYSCLK divided by 26 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV28 ((uint32_t)0x0000000E) /*!< SYSCLK divided by 28 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV30 ((uint32_t)0x0000000F) /*!< SYSCLK divided by 30 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV32 ((uint32_t)0x00000010) /*!< SYSCLK divided by 32 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV34 ((uint32_t)0x00000011) /*!< SYSCLK divided by 34 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV36 ((uint32_t)0x00000012) /*!< SYSCLK divided by 36 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV38 ((uint32_t)0x00000013) /*!< SYSCLK divided by 38 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV40 ((uint32_t)0x00000014) /*!< SYSCLK divided by 40 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV42 ((uint32_t)0x00000015) /*!< SYSCLK divided by 42 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV44 ((uint32_t)0x00000016) /*!< SYSCLK divided by 44 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV46 ((uint32_t)0x00000017) /*!< SYSCLK divided by 46 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV48 ((uint32_t)0x00000018) /*!< SYSCLK divided by 48 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV50 ((uint32_t)0x00000019) /*!< SYSCLK divided by 50 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV52 ((uint32_t)0x0000001A) /*!< SYSCLK divided by 52 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV54 ((uint32_t)0x0000001B) /*!< SYSCLK divided by 54 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV56 ((uint32_t)0x0000001C) /*!< SYSCLK divided by 56 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV58 ((uint32_t)0x0000001D) /*!< SYSCLK divided by 58 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV60 ((uint32_t)0x0000001E) /*!< SYSCLK divided by 60 */ +#define SMARTCARD_PRESCALER_SYSCLK_DIV62 ((uint32_t)0x0000001F) /*!< SYSCLK divided by 62 */ +/** + * @} + */ + +/** @defgroup SmartCard_Flags SMARTCARD Flags + * Elements values convention: 0xXXXX + * - 0xXXXX : Flag mask in the SR register + * @{ + */ +#define SMARTCARD_FLAG_TXE ((uint32_t)0x00000080) +#define SMARTCARD_FLAG_TC ((uint32_t)0x00000040) +#define SMARTCARD_FLAG_RXNE ((uint32_t)0x00000020) +#define SMARTCARD_FLAG_IDLE ((uint32_t)0x00000010) +#define SMARTCARD_FLAG_ORE ((uint32_t)0x00000008) +#define SMARTCARD_FLAG_NE ((uint32_t)0x00000004) +#define SMARTCARD_FLAG_FE ((uint32_t)0x00000002) +#define SMARTCARD_FLAG_PE ((uint32_t)0x00000001) +/** + * @} + */ + +/** @defgroup SmartCard_Interrupt_definition SMARTCARD Interrupts Definition + * Elements values convention: 0xY000XXXX + * - XXXX : Interrupt mask in the XX register + * - Y : Interrupt source register (2bits) + * - 01: CR1 register + * - 10: CR3 register + * @{ + */ +#define SMARTCARD_IT_PE ((uint32_t)(SMARTCARD_CR1_REG_INDEX << 28 | USART_CR1_PEIE)) +#define SMARTCARD_IT_TXE ((uint32_t)(SMARTCARD_CR1_REG_INDEX << 28 | USART_CR1_TXEIE)) +#define SMARTCARD_IT_TC ((uint32_t)(SMARTCARD_CR1_REG_INDEX << 28 | USART_CR1_TCIE)) +#define SMARTCARD_IT_RXNE ((uint32_t)(SMARTCARD_CR1_REG_INDEX << 28 | USART_CR1_RXNEIE)) +#define SMARTCARD_IT_IDLE ((uint32_t)(SMARTCARD_CR1_REG_INDEX << 28 | USART_CR1_IDLEIE)) +#define SMARTCARD_IT_ERR ((uint32_t)(SMARTCARD_CR3_REG_INDEX << 28 | USART_CR3_EIE)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup SMARTCARD_Exported_Macros SMARTCARD Exported Macros + * @{ + */ + +/** @brief Reset SMARTCARD handle state + * @param __HANDLE__: specifies the SMARTCARD Handle. + * @retval None + */ +#define __HAL_SMARTCARD_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SMARTCARD_STATE_RESET) + +/** @brief Flushs the Smartcard DR register + * @param __HANDLE__: specifies the SMARTCARD Handle. + */ +#define __HAL_SMARTCARD_FLUSH_DRREGISTER(__HANDLE__) ((__HANDLE__)->Instance->DR) + +/** @brief Checks whether the specified Smartcard flag is set or not. + * @param __HANDLE__: specifies the SMARTCARD Handle. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg SMARTCARD_FLAG_TXE: Transmit data register empty flag + * @arg SMARTCARD_FLAG_TC: Transmission Complete flag + * @arg SMARTCARD_FLAG_RXNE: Receive data register not empty flag + * @arg SMARTCARD_FLAG_IDLE: Idle Line detection flag + * @arg SMARTCARD_FLAG_ORE: Overrun Error flag + * @arg SMARTCARD_FLAG_NE: Noise Error flag + * @arg SMARTCARD_FLAG_FE: Framing Error flag + * @arg SMARTCARD_FLAG_PE: Parity Error flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_SMARTCARD_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__)) + +/** @brief Clears the specified Smartcard pending flags. + * @param __HANDLE__: specifies the SMARTCARD Handle. + * @param __FLAG__: specifies the flag to check. + * This parameter can be any combination of the following values: + * @arg SMARTCARD_FLAG_TC: Transmission Complete flag. + * @arg SMARTCARD_FLAG_RXNE: Receive data register not empty flag. + * + * @note PE (Parity error), FE (Framing error), NE (Noise error) and ORE (Overrun + * error) flags are cleared by software sequence: a read operation to + * USART_SR register followed by a read operation to USART_DR register. + * @note RXNE flag can be also cleared by a read to the USART_DR register. + * @note TC flag can be also cleared by software sequence: a read operation to + * USART_SR register followed by a write operation to USART_DR register. + * @note TXE flag is cleared only by a write to the USART_DR register. + */ +#define __HAL_SMARTCARD_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__)) + +/** @brief Clear the SMARTCARD PE pending flag. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__) \ + do{ \ + __IO uint32_t tmpreg; \ + tmpreg = (__HANDLE__)->Instance->SR; \ + tmpreg = (__HANDLE__)->Instance->DR; \ + UNUSED(tmpreg); \ + } while(0) + +/** @brief Clear the SMARTCARD FE pending flag. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_SMARTCARD_CLEAR_FEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__) + +/** @brief Clear the SMARTCARD NE pending flag. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_SMARTCARD_CLEAR_NEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__) + +/** @brief Clear the SMARTCARD ORE pending flag. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_SMARTCARD_CLEAR_OREFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__) + +/** @brief Clear the SMARTCARD IDLE pending flag. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_SMARTCARD_CLEAR_IDLEFLAG(__HANDLE__) __HAL_SMARTCARD_CLEAR_PEFLAG(__HANDLE__) + + +/** @brief Enables or disables the specified SmartCard interrupts. + * @param __HANDLE__: specifies the SMARTCARD Handle. + * @param __INTERRUPT__: specifies the SMARTCARD interrupt source to check. + * This parameter can be one of the following values: + * @arg SMARTCARD_IT_TXE: Transmit Data Register empty interrupt + * @arg SMARTCARD_IT_TC: Transmission complete interrupt + * @arg SMARTCARD_IT_RXNE: Receive Data register not empty interrupt + * @arg SMARTCARD_IT_IDLE: Idle line detection interrupt + * @arg SMARTCARD_IT_PE: Parity Error interrupt + * @arg SMARTCARD_IT_ERR: Error interrupt(Frame error, noise error, overrun error) + */ +#define __HAL_SMARTCARD_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28) == 1)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & SMARTCARD_IT_MASK)): \ + ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & SMARTCARD_IT_MASK))) +#define __HAL_SMARTCARD_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28) == 1)? ((__HANDLE__)->Instance->CR1 &= ~((__INTERRUPT__) & SMARTCARD_IT_MASK)): \ + ((__HANDLE__)->Instance->CR3 &= ~ ((__INTERRUPT__) & SMARTCARD_IT_MASK))) + +/** @brief Checks whether the specified SmartCard interrupt has occurred or not. + * @param __HANDLE__: specifies the SmartCard Handle. + * @param __IT__: specifies the SMARTCARD interrupt source to check. + * This parameter can be one of the following values: + * @arg SMARTCARD_IT_TXE: Transmit Data Register empty interrupt + * @arg SMARTCARD_IT_TC: Transmission complete interrupt + * @arg SMARTCARD_IT_RXNE: Receive Data register not empty interrupt + * @arg SMARTCARD_IT_IDLE: Idle line detection interrupt + * @arg SMARTCARD_IT_ERR: Error interrupt + * @arg SMARTCARD_IT_PE: Parity Error interrupt + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_SMARTCARD_GET_IT_SOURCE(__HANDLE__, __IT__) (((((__IT__) >> 28) == 1)? (__HANDLE__)->Instance->CR1: (__HANDLE__)->Instance->CR3) & (((uint32_t)(__IT__)) & SMARTCARD_IT_MASK)) + +/** @brief Macro to enable the SMARTCARD's one bit sample method + * @param __HANDLE__: specifies the SMARTCARD Handle. + * @retval None + */ +#define __HAL_SMARTCARD_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT) + +/** @brief Macro to disable the SMARTCARD's one bit sample method + * @param __HANDLE__: specifies the SMARTCARD Handle. + * @retval None + */ +#define __HAL_SMARTCARD_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_ONEBIT)) + +/** @brief Enable the USART associated to the SMARTCARD Handle + * @param __HANDLE__: specifies the SMARTCARD Handle. + * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device). + * @retval None + */ +#define __HAL_SMARTCARD_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE) + +/** @brief Disable the USART associated to the SMARTCARD Handle + * @param __HANDLE__: specifies the SMARTCARD Handle. + * SMARTCARD Handle selects the USARTx peripheral (USART availability and x value depending on device). + * @retval None + */ +#define __HAL_SMARTCARD_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE) + +/** @brief Macros to enable or disable the SmartCard DMA request. + * @param __HANDLE__: specifies the SmartCard Handle. + * @param __REQUEST__: specifies the SmartCard DMA request. + * This parameter can be one of the following values: + * @arg SMARTCARD_DMAREQ_TX: SmartCard DMA transmit request + * @arg SMARTCARD_DMAREQ_RX: SmartCard DMA receive request + */ +#define __HAL_SMARTCARD_DMA_REQUEST_ENABLE(__HANDLE__, __REQUEST__) ((__HANDLE__)->Instance->CR3 |= (__REQUEST__)) +#define __HAL_SMARTCARD_DMA_REQUEST_DISABLE(__HANDLE__, __REQUEST__) ((__HANDLE__)->Instance->CR3 &= ~(__REQUEST__)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SMARTCARD_Exported_Functions + * @{ + */ + +/** @addtogroup SMARTCARD_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions **********************************/ +HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc); +HAL_StatusTypeDef HAL_SMARTCARD_ReInit(SMARTCARD_HandleTypeDef *hsc); +HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsc); +void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsc); +void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsc); +/** + * @} + */ + +/** @addtogroup SMARTCARD_Exported_Functions_Group2 + * @{ + */ +/* IO operation functions *******************************************************/ +HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size); +void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc); +void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsc); +void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsc); +void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsc); +/** + * @} + */ + +/** @addtogroup SMARTCARD_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State functions **************************************************/ +HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(SMARTCARD_HandleTypeDef *hsc); +uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsc); + +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup SMARTCARD_Private_Constants SMARTCARD Private Constants + * @{ + */ + +/** @brief SMARTCARD interruptions flag mask + * + */ +#define SMARTCARD_IT_MASK ((uint32_t) USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE | USART_CR1_RXNEIE | \ + USART_CR1_IDLEIE | USART_CR3_EIE ) +#define SMARTCARD_DIV(_PCLK_, _BAUD_) (((_PCLK_)*25)/(4*(_BAUD_))) +#define SMARTCARD_DIVMANT(_PCLK_, _BAUD_) (SMARTCARD_DIV((_PCLK_), (_BAUD_))/100) +#define SMARTCARD_DIVFRAQ(_PCLK_, _BAUD_) (((SMARTCARD_DIV((_PCLK_), (_BAUD_)) - (SMARTCARD_DIVMANT((_PCLK_), (_BAUD_)) * 100)) * 16 + 50) / 100) +#define SMARTCARD_BRR(_PCLK_, _BAUD_) ((SMARTCARD_DIVMANT((_PCLK_), (_BAUD_)) << 4)|(SMARTCARD_DIVFRAQ((_PCLK_), (_BAUD_)) & 0x0F)) + +#define SMARTCARD_CR1_REG_INDEX 1 +#define SMARTCARD_CR3_REG_INDEX 3 +/** + * @} + */ + +/* Private macros --------------------------------------------------------*/ +/** @defgroup SMARTCARD_Private_Macros SMARTCARD Private Macros + * @{ + */ +#define IS_SMARTCARD_WORD_LENGTH(LENGTH) ((LENGTH) == SMARTCARD_WORDLENGTH_9B) +#define IS_SMARTCARD_STOPBITS(STOPBITS) (((STOPBITS) == SMARTCARD_STOPBITS_0_5) || \ + ((STOPBITS) == SMARTCARD_STOPBITS_1_5)) +#define IS_SMARTCARD_PARITY(PARITY) (((PARITY) == SMARTCARD_PARITY_EVEN) || \ + ((PARITY) == SMARTCARD_PARITY_ODD)) +#define IS_SMARTCARD_MODE(MODE) ((((MODE) & (uint32_t)0x0000FFF3) == 0x00) && ((MODE) != (uint32_t)0x000000)) +#define IS_SMARTCARD_POLARITY(CPOL) (((CPOL) == SMARTCARD_POLARITY_LOW) || ((CPOL) == SMARTCARD_POLARITY_HIGH)) +#define IS_SMARTCARD_PHASE(CPHA) (((CPHA) == SMARTCARD_PHASE_1EDGE) || ((CPHA) == SMARTCARD_PHASE_2EDGE)) +#define IS_SMARTCARD_LASTBIT(LASTBIT) (((LASTBIT) == SMARTCARD_LASTBIT_DISABLE) || \ + ((LASTBIT) == SMARTCARD_LASTBIT_ENABLE)) +#define IS_SMARTCARD_NACK_STATE(NACK) (((NACK) == SMARTCARD_NACK_ENABLE) || \ + ((NACK) == SMARTCARD_NACK_DISABLE)) +#define IS_SMARTCARD_BAUDRATE(BAUDRATE) ((BAUDRATE) < 10500001) +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup SMARTCARD_Private_Functions SMARTCARD Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_SMARTCARD_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spdifrx.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spdifrx.h new file mode 100644 index 0000000..c0d84bc --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spdifrx.h @@ -0,0 +1,559 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_spdifrx.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of SPDIFRX HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_SPDIFRX_H +#define __STM32F4xx_HAL_SPDIFRX_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F446xx) + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup SPDIFRX + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SPDIFRX_Exported_Types SPDIFRX Exported Types + * @{ + */ + +/** + * @brief SPDIFRX Init structure definition + */ +typedef struct +{ + uint32_t InputSelection; /*!< Specifies the SPDIF input selection. + This parameter can be a value of @ref SPDIFRX_Input_Selection */ + + uint32_t Retries; /*!< Specifies the Maximum allowed re-tries during synchronization phase. + This parameter can be a value of @ref SPDIFRX_Max_Retries */ + + uint32_t WaitForActivity; /*!< Specifies the wait for activity on SPDIF selected input. + This parameter can be a value of @ref SPDIFRX_Wait_For_Activity. */ + + uint32_t ChannelSelection; /*!< Specifies whether the control flow will take the channel status from channel A or B. + This parameter can be a value of @ref SPDIFRX_Channel_Selection */ + + uint32_t DataFormat; /*!< Specifies the Data samples format (LSB, MSB, ...). + This parameter can be a value of @ref SPDIFRX_Data_Format */ + + uint32_t StereoMode; /*!< Specifies whether the peripheral is in stereo or mono mode. + This parameter can be a value of @ref SPDIFRX_Stereo_Mode */ + + uint32_t PreambleTypeMask; /*!< Specifies whether The preamble type bits are copied or not into the received frame. + This parameter can be a value of @ref SPDIFRX_PT_Mask */ + + uint32_t ChannelStatusMask; /*!< Specifies whether the channel status and user bits are copied or not into the received frame. + This parameter can be a value of @ref SPDIFRX_ChannelStatus_Mask */ + + uint32_t ValidityBitMask; /*!< Specifies whether the validity bit is copied or not into the received frame. + This parameter can be a value of @ref SPDIFRX_V_Mask */ + + uint32_t ParityErrorMask; /*!< Specifies whether the parity error bit is copied or not into the received frame. + This parameter can be a value of @ref SPDIFRX_PE_Mask */ + +}SPDIFRX_InitTypeDef; + +/** + * @brief SPDIFRX SetDataFormat structure definition + */ +typedef struct +{ + uint32_t DataFormat; /*!< Specifies the Data samples format (LSB, MSB, ...). + This parameter can be a value of @ref SPDIFRX_Data_Format */ + + uint32_t StereoMode; /*!< Specifies whether the peripheral is in stereo or mono mode. + This parameter can be a value of @ref SPDIFRX_Stereo_Mode */ + + uint32_t PreambleTypeMask; /*!< Specifies whether The preamble type bits are copied or not into the received frame. + This parameter can be a value of @ref SPDIFRX_PT_Mask */ + + uint32_t ChannelStatusMask; /*!< Specifies whether the channel status and user bits are copied or not into the received frame. + This parameter can be a value of @ref SPDIFRX_ChannelStatus_Mask */ + + uint32_t ValidityBitMask; /*!< Specifies whether the validity bit is copied or not into the received frame. + This parameter can be a value of @ref SPDIFRX_V_Mask */ + + uint32_t ParityErrorMask; /*!< Specifies whether the parity error bit is copied or not into the received frame. + This parameter can be a value of @ref SPDIFRX_PE_Mask */ + +}SPDIFRX_SetDataFormatTypeDef; + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_SPDIFRX_STATE_RESET = 0x00, /*!< SPDIFRX not yet initialized or disabled */ + HAL_SPDIFRX_STATE_READY = 0x01, /*!< SPDIFRX initialized and ready for use */ + HAL_SPDIFRX_STATE_BUSY = 0x02, /*!< SPDIFRX internal process is ongoing */ + HAL_SPDIFRX_STATE_BUSY_RX = 0x03, /*!< SPDIFRX internal Data Flow RX process is ongoing */ + HAL_SPDIFRX_STATE_BUSY_CX = 0x04, /*!< SPDIFRX internal Control Flow RX process is ongoing */ + HAL_SPDIFRX_STATE_ERROR = 0x07 /*!< SPDIFRX error state */ +}HAL_SPDIFRX_StateTypeDef; + +/** + * @brief SPDIFRX handle Structure definition + */ +typedef struct +{ + SPDIFRX_TypeDef *Instance; /* SPDIFRX registers base address */ + + SPDIFRX_InitTypeDef Init; /* SPDIFRX communication parameters */ + + uint32_t *pRxBuffPtr; /* Pointer to SPDIFRX Rx transfer buffer */ + + uint32_t *pCsBuffPtr; /* Pointer to SPDIFRX Cx transfer buffer */ + + __IO uint16_t RxXferSize; /* SPDIFRX Rx transfer size */ + + __IO uint16_t RxXferCount; /* SPDIFRX Rx transfer counter + (This field is initialized at the + same value as transfer size at the + beginning of the transfer and + decremented when a sample is received. + NbSamplesReceived = RxBufferSize-RxBufferCount) */ + + __IO uint16_t CsXferSize; /* SPDIFRX Rx transfer size */ + + __IO uint16_t CsXferCount; /* SPDIFRX Rx transfer counter + (This field is initialized at the + same value as transfer size at the + beginning of the transfer and + decremented when a sample is received. + NbSamplesReceived = RxBufferSize-RxBufferCount) */ + + DMA_HandleTypeDef *hdmaCsRx; /* SPDIFRX EC60958_channel_status and user_information DMA handle parameters */ + + DMA_HandleTypeDef *hdmaDrRx; /* SPDIFRX Rx DMA handle parameters */ + + __IO HAL_LockTypeDef Lock; /* SPDIFRX locking object */ + + __IO HAL_SPDIFRX_StateTypeDef State; /* SPDIFRX communication state */ + + __IO uint32_t ErrorCode; /* SPDIFRX Error code */ + +}SPDIFRX_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SPDIFRX_Exported_Constants SPDIFRX Exported Constants + * @{ + */ +/** @defgroup SPDIFRX_ErrorCode SPDIFRX Error Code + * @{ + */ +#define HAL_SPDIFRX_ERROR_NONE ((uint32_t)0x00000000) /*!< No error */ +#define HAL_SPDIFRX_ERROR_TIMEOUT ((uint32_t)0x00000001) /*!< Timeout error */ +#define HAL_SPDIFRX_ERROR_OVR ((uint32_t)0x00000002) /*!< OVR error */ +#define HAL_SPDIFRX_ERROR_PE ((uint32_t)0x00000004) /*!< Parity error */ +#define HAL_SPDIFRX_ERROR_DMA ((uint32_t)0x00000008) /*!< DMA transfer error */ +#define HAL_SPDIFRX_ERROR_UNKNOWN ((uint32_t)0x00000010) /*!< Unknown Error error */ +/** + * @} + */ + +/** @defgroup SPDIFRX_Input_Selection SPDIFRX Input Selection + * @{ + */ +#define SPDIFRX_INPUT_IN0 ((uint32_t)0x00000000) +#define SPDIFRX_INPUT_IN1 ((uint32_t)0x00010000) +#define SPDIFRX_INPUT_IN2 ((uint32_t)0x00020000) +#define SPDIFRX_INPUT_IN3 ((uint32_t)0x00030000) +/** + * @} + */ + +/** @defgroup SPDIFRX_Max_Retries SPDIFRX Maximum Retries + * @{ + */ +#define SPDIFRX_MAXRETRIES_NONE ((uint32_t)0x00000000) +#define SPDIFRX_MAXRETRIES_3 ((uint32_t)0x00001000) +#define SPDIFRX_MAXRETRIES_15 ((uint32_t)0x00002000) +#define SPDIFRX_MAXRETRIES_63 ((uint32_t)0x00003000) +/** + * @} + */ + +/** @defgroup SPDIFRX_Wait_For_Activity SPDIFRX Wait For Activity + * @{ + */ +#define SPDIFRX_WAITFORACTIVITY_OFF ((uint32_t)0x00000000) +#define SPDIFRX_WAITFORACTIVITY_ON ((uint32_t)SPDIFRX_CR_WFA) +/** + * @} + */ + +/** @defgroup SPDIFRX_PT_Mask SPDIFRX Preamble Type Mask +* @{ +*/ +#define SPDIFRX_PREAMBLETYPEMASK_OFF ((uint32_t)0x00000000) +#define SPDIFRX_PREAMBLETYPEMASK_ON ((uint32_t)SPDIFRX_CR_PTMSK) +/** + * @} + */ + +/** @defgroup SPDIFRX_ChannelStatus_Mask SPDIFRX Channel Status Mask +* @{ +*/ +#define SPDIFRX_CHANNELSTATUS_OFF ((uint32_t)0x00000000) /* The channel status and user bits are copied into the SPDIF_DR */ +#define SPDIFRX_CHANNELSTATUS_ON ((uint32_t)SPDIFRX_CR_CUMSK) /* The channel status and user bits are not copied into the SPDIF_DR, zeros are written instead*/ +/** + * @} + */ + +/** @defgroup SPDIFRX_V_Mask SPDIFRX Validity Mask +* @{ +*/ +#define SPDIFRX_VALIDITYMASK_OFF ((uint32_t)0x00000000) +#define SPDIFRX_VALIDITYMASK_ON ((uint32_t)SPDIFRX_CR_VMSK) +/** + * @} + */ + +/** @defgroup SPDIFRX_PE_Mask SPDIFRX Parity Error Mask +* @{ +*/ +#define SPDIFRX_PARITYERRORMASK_OFF ((uint32_t)0x00000000) +#define SPDIFRX_PARITYERRORMASK_ON ((uint32_t)SPDIFRX_CR_PMSK) +/** + * @} + */ + +/** @defgroup SPDIFRX_Channel_Selection SPDIFRX Channel Selection + * @{ + */ +#define SPDIFRX_CHANNEL_A ((uint32_t)0x00000000) +#define SPDIFRX_CHANNEL_B ((uint32_t)SPDIFRX_CR_CHSEL) +/** + * @} + */ + +/** @defgroup SPDIFRX_Data_Format SPDIFRX Data Format + * @{ + */ +#define SPDIFRX_DATAFORMAT_LSB ((uint32_t)0x00000000) +#define SPDIFRX_DATAFORMAT_MSB ((uint32_t)0x00000010) +#define SPDIFRX_DATAFORMAT_32BITS ((uint32_t)0x00000020) +/** + * @} + */ + +/** @defgroup SPDIFRX_Stereo_Mode SPDIFRX Stereo Mode + * @{ + */ +#define SPDIFRX_STEREOMODE_DISABLE ((uint32_t)0x00000000) +#define SPDIFRX_STEREOMODE_ENABLE ((uint32_t)SPDIFRX_CR_RXSTEO) +/** + * @} + */ + +/** @defgroup SPDIFRX_State SPDIFRX State + * @{ + */ + +#define SPDIFRX_STATE_IDLE ((uint32_t)0xFFFFFFFC) +#define SPDIFRX_STATE_SYNC ((uint32_t)0x00000001) +#define SPDIFRX_STATE_RCV ((uint32_t)SPDIFRX_CR_SPDIFEN) +/** + * @} + */ + +/** @defgroup SPDIFRX_Interrupts_Definition SPDIFRX Interrupts Definition + * @{ + */ +#define SPDIFRX_IT_RXNE ((uint32_t)SPDIFRX_IMR_RXNEIE) +#define SPDIFRX_IT_CSRNE ((uint32_t)SPDIFRX_IMR_CSRNEIE) +#define SPDIFRX_IT_PERRIE ((uint32_t)SPDIFRX_IMR_PERRIE) +#define SPDIFRX_IT_OVRIE ((uint32_t)SPDIFRX_IMR_OVRIE) +#define SPDIFRX_IT_SBLKIE ((uint32_t)SPDIFRX_IMR_SBLKIE) +#define SPDIFRX_IT_SYNCDIE ((uint32_t)SPDIFRX_IMR_SYNCDIE) +#define SPDIFRX_IT_IFEIE ((uint32_t)SPDIFRX_IMR_IFEIE ) +/** + * @} + */ + +/** @defgroup SPDIFRX_Flags_Definition SPDIFRX Flags Definition + * @{ + */ +#define SPDIFRX_FLAG_RXNE ((uint32_t)SPDIFRX_SR_RXNE) +#define SPDIFRX_FLAG_CSRNE ((uint32_t)SPDIFRX_SR_CSRNE) +#define SPDIFRX_FLAG_PERR ((uint32_t)SPDIFRX_SR_PERR) +#define SPDIFRX_FLAG_OVR ((uint32_t)SPDIFRX_SR_OVR) +#define SPDIFRX_FLAG_SBD ((uint32_t)SPDIFRX_SR_SBD) +#define SPDIFRX_FLAG_SYNCD ((uint32_t)SPDIFRX_SR_SYNCD) +#define SPDIFRX_FLAG_FERR ((uint32_t)SPDIFRX_SR_FERR) +#define SPDIFRX_FLAG_SERR ((uint32_t)SPDIFRX_SR_SERR) +#define SPDIFRX_FLAG_TERR ((uint32_t)SPDIFRX_SR_TERR) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup SPDIFRX_Exported_macros SPDIFRX Exported Macros + * @{ + */ + +/** @brief Reset SPDIFRX handle state + * @param __HANDLE__: SPDIFRX handle. + * @retval None + */ +#define __HAL_SPDIFRX_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = (uint16_t)SPDIFRX_CR_SPDIFEN) + +/** @brief Disable the specified SPDIFRX peripheral (IDLE State). + * @param __HANDLE__: specifies the SPDIFRX Handle. + * @retval None + */ +#define __HAL_SPDIFRX_IDLE(__HANDLE__) ((__HANDLE__)->Instance->CR &= SPDIFRX_STATE_IDLE) + +/** @brief Enable the specified SPDIFRX peripheral (SYNC State). + * @param __HANDLE__: specifies the SPDIFRX Handle. + * @retval None + */ +#define __HAL_SPDIFRX_SYNC(__HANDLE__) ((__HANDLE__)->Instance->CR |= SPDIFRX_STATE_SYNC) + + +/** @brief Enable the specified SPDIFRX peripheral (RCV State). + * @param __HANDLE__: specifies the SPDIFRX Handle. + * @retval None + */ +#define __HAL_SPDIFRX_RCV(__HANDLE__) ((__HANDLE__)->Instance->CR |= SPDIFRX_STATE_RCV) + + +/** @brief Enable or disable the specified SPDIFRX interrupts. + * @param __HANDLE__: specifies the SPDIFRX Handle. + * @param __INTERRUPT__: specifies the interrupt source to enable or disable. + * This parameter can be one of the following values: + * @arg SPDIFRX_IT_RXNE + * @arg SPDIFRX_IT_CSRNE + * @arg SPDIFRX_IT_PERRIE + * @arg SPDIFRX_IT_OVRIE + * @arg SPDIFRX_IT_SBLKIE + * @arg SPDIFRX_IT_SYNCDIE + * @arg SPDIFRX_IT_IFEIE + * @retval None + */ +#define __HAL_SPDIFRX_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IMR |= (__INTERRUPT__)) +#define __HAL_SPDIFRX_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IMR &= (uint16_t)(~(__INTERRUPT__))) + +/** @brief Checks if the specified SPDIFRX interrupt source is enabled or disabled. + * @param __HANDLE__: specifies the SPDIFRX Handle. + * @param __INTERRUPT__: specifies the SPDIFRX interrupt source to check. + * This parameter can be one of the following values: + * @arg SPDIFRX_IT_RXNE + * @arg SPDIFRX_IT_CSRNE + * @arg SPDIFRX_IT_PERRIE + * @arg SPDIFRX_IT_OVRIE + * @arg SPDIFRX_IT_SBLKIE + * @arg SPDIFRX_IT_SYNCDIE + * @arg SPDIFRX_IT_IFEIE + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_SPDIFRX_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->IMR & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Checks whether the specified SPDIFRX flag is set or not. + * @param __HANDLE__: specifies the SPDIFRX Handle. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg SPDIFRX_FLAG_RXNE + * @arg SPDIFRX_FLAG_CSRNE + * @arg SPDIFRX_FLAG_PERR + * @arg SPDIFRX_FLAG_OVR + * @arg SPDIFRX_FLAG_SBD + * @arg SPDIFRX_FLAG_SYNCD + * @arg SPDIFRX_FLAG_FERR + * @arg SPDIFRX_FLAG_SERR + * @arg SPDIFRX_FLAG_TERR + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_SPDIFRX_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__)) + +/** @brief Clears the specified SPDIFRX SR flag, in setting the proper IFCR register bit. + * @param __HANDLE__: specifies the USART Handle. + * @param __IT_CLEAR__: specifies the interrupt clear register flag that needs to be set + * to clear the corresponding interrupt + * This parameter can be one of the following values: + * @arg SPDIFRX_FLAG_PERR + * @arg SPDIFRX_FLAG_OVR + * @arg SPDIFRX_SR_SBD + * @arg SPDIFRX_SR_SYNCD + * @retval None + */ +#define __HAL_SPDIFRX_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->IFCR = (uint32_t)(__IT_CLEAR__)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SPDIFRX_Exported_Functions + * @{ + */ + +/** @addtogroup SPDIFRX_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions **********************************/ +HAL_StatusTypeDef HAL_SPDIFRX_Init(SPDIFRX_HandleTypeDef *hspdif); +HAL_StatusTypeDef HAL_SPDIFRX_DeInit (SPDIFRX_HandleTypeDef *hspdif); +void HAL_SPDIFRX_MspInit(SPDIFRX_HandleTypeDef *hspdif); +void HAL_SPDIFRX_MspDeInit(SPDIFRX_HandleTypeDef *hspdif); +HAL_StatusTypeDef HAL_SPDIFRX_SetDataFormat(SPDIFRX_HandleTypeDef *hspdif, SPDIFRX_SetDataFormatTypeDef sDataFormat); +/** + * @} + */ + +/** @addtogroup SPDIFRX_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions ***************************************************/ + /* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size, uint32_t Timeout); + + /* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size); +void HAL_SPDIFRX_IRQHandler(SPDIFRX_HandleTypeDef *hspdif); + +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size); + +HAL_StatusTypeDef HAL_SPDIFRX_DMAStop(SPDIFRX_HandleTypeDef *hspdif); + +/* Callbacks used in non blocking modes (Interrupt and DMA) *******************/ +void HAL_SPDIFRX_RxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif); +void HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef *hspdif); +void HAL_SPDIFRX_ErrorCallback(SPDIFRX_HandleTypeDef *hspdif); +void HAL_SPDIFRX_CxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif); +void HAL_SPDIFRX_CxCpltCallback(SPDIFRX_HandleTypeDef *hspdif); +/** + * @} + */ + +/** @addtogroup SPDIFRX_Exported_Functions_Group3 + * @{ + */ +/* Peripheral Control and State functions ************************************/ +HAL_SPDIFRX_StateTypeDef HAL_SPDIFRX_GetState(SPDIFRX_HandleTypeDef *hspdif); +uint32_t HAL_SPDIFRX_GetError(SPDIFRX_HandleTypeDef *hspdif); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup SPDIFRX_Private_Macros SPDIFRX Private Macros + * @{ + */ +#define IS_SPDIFRX_INPUT_SELECT(INPUT) (((INPUT) == SPDIFRX_INPUT_IN1) || \ + ((INPUT) == SPDIFRX_INPUT_IN2) || \ + ((INPUT) == SPDIFRX_INPUT_IN3) || \ + ((INPUT) == SPDIFRX_INPUT_IN0)) +#define IS_SPDIFRX_MAX_RETRIES(RET) (((RET) == SPDIFRX_MAXRETRIES_NONE) || \ + ((RET) == SPDIFRX_MAXRETRIES_3) || \ + ((RET) == SPDIFRX_MAXRETRIES_15) || \ + ((RET) == SPDIFRX_MAXRETRIES_63)) +#define IS_SPDIFRX_WAIT_FOR_ACTIVITY(VAL) (((VAL) == SPDIFRX_WAITFORACTIVITY_ON) || \ + ((VAL) == SPDIFRX_WAITFORACTIVITY_OFF)) +#define IS_PREAMBLE_TYPE_MASK(VAL) (((VAL) == SPDIFRX_PREAMBLETYPEMASK_ON) || \ + ((VAL) == SPDIFRX_PREAMBLETYPEMASK_OFF)) +#define IS_VALIDITY_MASK(VAL) (((VAL) == SPDIFRX_VALIDITYMASK_OFF) || \ + ((VAL) == SPDIFRX_VALIDITYMASK_ON)) +#define IS_PARITY_ERROR_MASK(VAL) (((VAL) == SPDIFRX_PARITYERRORMASK_OFF) || \ + ((VAL) == SPDIFRX_PARITYERRORMASK_ON)) +#define IS_SPDIFRX_CHANNEL(CHANNEL) (((CHANNEL) == SPDIFRX_CHANNEL_A) || \ + ((CHANNEL) == SPDIFRX_CHANNEL_B)) +#define IS_SPDIFRX_DATA_FORMAT(FORMAT) (((FORMAT) == SPDIFRX_DATAFORMAT_LSB) || \ + ((FORMAT) == SPDIFRX_DATAFORMAT_MSB) || \ + ((FORMAT) == SPDIFRX_DATAFORMAT_32BITS)) +#define IS_STEREO_MODE(MODE) (((MODE) == SPDIFRX_STEREOMODE_DISABLE) || \ + ((MODE) == SPDIFRX_STEREOMODE_ENABLE)) + +#define IS_CHANNEL_STATUS_MASK(VAL) (((VAL) == SPDIFRX_CHANNELSTATUS_ON) || \ + ((VAL) == SPDIFRX_CHANNELSTATUS_OFF)) +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup SPDIFRX_Private_Functions SPDIFRX Private Functions + * @{ + */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F446xx */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F4xx_HAL_SPDIFRX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h new file mode 100644 index 0000000..6f4a142 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h @@ -0,0 +1,580 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_spi.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of SPI HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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. + * + ****************************************************************************** + * + * Modifications by Robert Fisk + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_SPI_H +#define __STM32F4xx_HAL_SPI_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup SPI + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SPI_Exported_Types SPI Exported Types + * @{ + */ + +/** + * @brief SPI Configuration Structure definition + */ +typedef struct +{ + uint32_t Mode; /*!< Specifies the SPI operating mode. + This parameter can be a value of @ref SPI_mode */ + + uint32_t Direction; /*!< Specifies the SPI Directional mode state. + This parameter can be a value of @ref SPI_Direction_mode */ + + uint32_t DataSize; /*!< Specifies the SPI data size. + This parameter can be a value of @ref SPI_data_size */ + + uint32_t CLKPolarity; /*!< Specifies the serial clock steady state. + This parameter can be a value of @ref SPI_Clock_Polarity */ + + uint32_t CLKPhase; /*!< Specifies the clock active edge for the bit capture. + This parameter can be a value of @ref SPI_Clock_Phase */ + + uint32_t NSS; /*!< Specifies whether the NSS signal is managed by + hardware (NSS pin) or by software using the SSI bit. + This parameter can be a value of @ref SPI_Slave_Select_management */ + + uint32_t BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be + used to configure the transmit and receive SCK clock. + This parameter can be a value of @ref SPI_BaudRate_Prescaler + @note The communication clock is derived from the master + clock. The slave clock does not need to be set */ + + uint32_t FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit. + This parameter can be a value of @ref SPI_MSB_LSB_transmission */ + + uint32_t TIMode; /*!< Specifies if the TI mode is enabled or not. + This parameter can be a value of @ref SPI_TI_mode */ + + uint32_t CRCCalculation; /*!< Specifies if the CRC calculation is enabled or not. + This parameter can be a value of @ref SPI_CRC_Calculation */ + + uint32_t CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation. + This parameter must be a number between Min_Data = 0 and Max_Data = 65535 */ + +}SPI_InitTypeDef; + +/** + * @brief HAL SPI State structure definition + */ +typedef enum +{ + HAL_SPI_STATE_RESET = 0x00, /*!< SPI not yet initialized or disabled */ + HAL_SPI_STATE_READY = 0x01, /*!< SPI initialized and ready for use */ + HAL_SPI_STATE_BUSY = 0x02, /*!< SPI process is ongoing */ + HAL_SPI_STATE_BUSY_TX = 0x12, /*!< Data Transmission process is ongoing */ + HAL_SPI_STATE_BUSY_RX = 0x22, /*!< Data Reception process is ongoing */ + HAL_SPI_STATE_BUSY_TX_RX = 0x32, /*!< Data Transmission and Reception process is ongoing */ + HAL_SPI_STATE_ERROR = 0x03 /*!< SPI error state */ + +}HAL_SPI_StateTypeDef; + +/** + * @brief SPI handle Structure definition + */ +typedef struct __SPI_HandleTypeDef +{ + SPI_TypeDef *Instance; /* SPI registers base address */ + + SPI_InitTypeDef Init; /* SPI communication parameters */ + + uint8_t *pTxBuffPtr; /* Pointer to SPI Tx transfer Buffer */ + + uint16_t TxXferSize; /* SPI Tx transfer size */ + + uint16_t TxXferCount; /* SPI Tx Transfer Counter */ + + uint8_t *pRxBuffPtr; /* Pointer to SPI Rx transfer Buffer */ + + uint16_t RxXferSize; /* SPI Rx transfer size */ + + uint16_t RxXferCount; /* SPI Rx Transfer Counter */ + + DMA_HandleTypeDef *hdmatx; /* SPI Tx DMA handle parameters */ + + DMA_HandleTypeDef *hdmarx; /* SPI Rx DMA handle parameters */ + + void (*RxISR)(struct __SPI_HandleTypeDef * hspi); /* function pointer on Rx ISR */ + + void (*TxISR)(struct __SPI_HandleTypeDef * hspi); /* function pointer on Tx ISR */ + + HAL_LockTypeDef Lock; /* SPI locking object */ + + __IO HAL_SPI_StateTypeDef State; /* SPI communication state */ + + __IO uint32_t ErrorCode; /* SPI Error code */ + +}SPI_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SPI_Exported_Constants SPI Exported Constants + * @{ + */ + +/** @defgroup SPI_Error_Code SPI Error Code + * @brief SPI Error Code + * @{ + */ +#define HAL_SPI_ERROR_NONE ((uint32_t)0x00000000) /*!< No error */ +#define HAL_SPI_ERROR_MODF ((uint32_t)0x00000001) /*!< MODF error */ +#define HAL_SPI_ERROR_CRC ((uint32_t)0x00000002) /*!< CRC error */ +#define HAL_SPI_ERROR_OVR ((uint32_t)0x00000004) /*!< OVR error */ +#define HAL_SPI_ERROR_FRE ((uint32_t)0x00000008) /*!< FRE error */ +#define HAL_SPI_ERROR_DMA ((uint32_t)0x00000010) /*!< DMA transfer error */ +#define HAL_SPI_ERROR_FLAG ((uint32_t)0x00000020) /*!< Flag: RXNE,TXE, BSY */ +/** + * @} + */ + +/** @defgroup SPI_mode SPI Mode + * @{ + */ +#define SPI_MODE_SLAVE ((uint32_t)0x00000000) +#define SPI_MODE_MASTER (SPI_CR1_MSTR | SPI_CR1_SSI) +/** + * @} + */ + +/** @defgroup SPI_Direction_mode SPI Direction Mode + * @{ + */ +#define SPI_DIRECTION_2LINES ((uint32_t)0x00000000) +#define SPI_DIRECTION_2LINES_RXONLY SPI_CR1_RXONLY +#define SPI_DIRECTION_1LINE SPI_CR1_BIDIMODE +/** + * @} + */ + +/** @defgroup SPI_data_size SPI Data Size + * @{ + */ +#define SPI_DATASIZE_8BIT ((uint32_t)0x00000000) +#define SPI_DATASIZE_16BIT SPI_CR1_DFF +/** + * @} + */ + +/** @defgroup SPI_Clock_Polarity SPI Clock Polarity + * @{ + */ +#define SPI_POLARITY_LOW ((uint32_t)0x00000000) +#define SPI_POLARITY_HIGH SPI_CR1_CPOL +/** + * @} + */ + +/** @defgroup SPI_Clock_Phase SPI Clock Phase + * @{ + */ +#define SPI_PHASE_1EDGE ((uint32_t)0x00000000) +#define SPI_PHASE_2EDGE SPI_CR1_CPHA +/** + * @} + */ + +/** @defgroup SPI_Slave_Select_management SPI Slave Select Management + * @{ + */ +#define SPI_NSS_SOFT SPI_CR1_SSM +#define SPI_NSS_HARD_INPUT ((uint32_t)0x00000000) +#define SPI_NSS_HARD_OUTPUT ((uint32_t)0x00040000) +/** + * @} + */ + +/** @defgroup SPI_BaudRate_Prescaler SPI BaudRate Prescaler + * @{ + */ +#define SPI_BAUDRATEPRESCALER_2 ((uint32_t)0x00000000) +#define SPI_BAUDRATEPRESCALER_4 ((uint32_t)0x00000008) +#define SPI_BAUDRATEPRESCALER_8 ((uint32_t)0x00000010) +#define SPI_BAUDRATEPRESCALER_16 ((uint32_t)0x00000018) +#define SPI_BAUDRATEPRESCALER_32 ((uint32_t)0x00000020) +#define SPI_BAUDRATEPRESCALER_64 ((uint32_t)0x00000028) +#define SPI_BAUDRATEPRESCALER_128 ((uint32_t)0x00000030) +#define SPI_BAUDRATEPRESCALER_256 ((uint32_t)0x00000038) +/** + * @} + */ + +/** @defgroup SPI_MSB_LSB_transmission SPI MSB LSB Transsmission + * @{ + */ +#define SPI_FIRSTBIT_MSB ((uint32_t)0x00000000) +#define SPI_FIRSTBIT_LSB SPI_CR1_LSBFIRST +/** + * @} + */ + +/** @defgroup SPI_TI_mode SPI TI Mode + * @{ + */ +#define SPI_TIMODE_DISABLE ((uint32_t)0x00000000) +#define SPI_TIMODE_ENABLE SPI_CR2_FRF +/** + * @} + */ + +/** @defgroup SPI_CRC_Calculation SPI CRC Calculation + * @{ + */ +#define SPI_CRCCALCULATION_DISABLE ((uint32_t)0x00000000) +#define SPI_CRCCALCULATION_ENABLE SPI_CR1_CRCEN + +#define SPI_CRC_DEFAULTPOLYNOMIAL 0x07 + +/** + * @} + */ + +/** @defgroup SPI_Interrupt_definition SPI Interrupt Definition + * @{ + */ +#define SPI_IT_TXE SPI_CR2_TXEIE +#define SPI_IT_RXNE SPI_CR2_RXNEIE +#define SPI_IT_ERR SPI_CR2_ERRIE +/** + * @} + */ + +/** @defgroup SPI_Flags_definition SPI Flags Definition + * @{ + */ +#define SPI_FLAG_RXNE SPI_SR_RXNE +#define SPI_FLAG_TXE SPI_SR_TXE +#define SPI_FLAG_CRCERR SPI_SR_CRCERR +#define SPI_FLAG_MODF SPI_SR_MODF +#define SPI_FLAG_OVR SPI_SR_OVR +#define SPI_FLAG_BSY SPI_SR_BSY +#define SPI_FLAG_FRE SPI_SR_FRE +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup SPI_Exported_Macros SPI Exported Macros + * @{ + */ +/** @brief Reset SPI handle state + * @param __HANDLE__: specifies the SPI handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define __HAL_SPI_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SPI_STATE_RESET) + +/** @brief Enable or disable the specified SPI interrupts. + * @param __HANDLE__: specifies the SPI handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @param __INTERRUPT__: specifies the interrupt source to enable or disable. + * This parameter can be one of the following values: + * @arg SPI_IT_TXE: Tx buffer empty interrupt enable + * @arg SPI_IT_RXNE: RX buffer not empty interrupt enable + * @arg SPI_IT_ERR: Error interrupt enable + * @retval None + */ +#define __HAL_SPI_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 |= (__INTERRUPT__)) +#define __HAL_SPI_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 &= (~(__INTERRUPT__))) + +/** @brief Check if the specified SPI interrupt source is enabled or disabled. + * @param __HANDLE__: specifies the SPI handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @param __INTERRUPT__: specifies the SPI interrupt source to check. + * This parameter can be one of the following values: + * @arg SPI_IT_TXE: Tx buffer empty interrupt enable + * @arg SPI_IT_RXNE: RX buffer not empty interrupt enable + * @arg SPI_IT_ERR: Error interrupt enable + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_SPI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Check whether the specified SPI flag is set or not. + * @param __HANDLE__: specifies the SPI handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg SPI_FLAG_RXNE: Receive buffer not empty flag + * @arg SPI_FLAG_TXE: Transmit buffer empty flag + * @arg SPI_FLAG_CRCERR: CRC error flag + * @arg SPI_FLAG_MODF: Mode fault flag + * @arg SPI_FLAG_OVR: Overrun flag + * @arg SPI_FLAG_BSY: Busy flag + * @arg SPI_FLAG_FRE: Frame format error flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_SPI_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the SPI CRCERR pending flag. + * @param __HANDLE__: specifies the SPI handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define __HAL_SPI_CLEAR_CRCERRFLAG(__HANDLE__) ((__HANDLE__)->Instance->SR = ~(SPI_FLAG_CRCERR)) + +/** @brief Clear the SPI MODF pending flag. + * @param __HANDLE__: specifies the SPI handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define __HAL_SPI_CLEAR_MODFFLAG(__HANDLE__) \ + do{ \ + __IO uint32_t tmpreg; \ + tmpreg = (__HANDLE__)->Instance->SR; \ + (__HANDLE__)->Instance->CR1 &= (~SPI_CR1_SPE); \ + UNUSED(tmpreg); \ + } while(0) + +/** @brief Clear the SPI OVR pending flag. + * @param __HANDLE__: specifies the SPI handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define __HAL_SPI_CLEAR_OVRFLAG(__HANDLE__) \ + do{ \ + __IO uint32_t tmpreg; \ + tmpreg = (__HANDLE__)->Instance->DR; \ + tmpreg = (__HANDLE__)->Instance->SR; \ + UNUSED(tmpreg); \ + } while(0) + +/** @brief Clear the SPI FRE pending flag. + * @param __HANDLE__: specifies the SPI handle. + * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. + * @retval None + */ +#define __HAL_SPI_CLEAR_FREFLAG(__HANDLE__) \ + do{ \ + __IO uint32_t tmpreg; \ + tmpreg = (__HANDLE__)->Instance->SR; \ + UNUSED(tmpreg); \ + }while(0) + +/** @brief Enable SPI + * @param __HANDLE__: specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= SPI_CR1_SPE) + +/** @brief Disable SPI + * @param __HANDLE__: specifies the SPI Handle. + * @retval None + */ +#define __HAL_SPI_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~SPI_CR1_SPE) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SPI_Exported_Functions + * @{ + */ + +/** @addtogroup SPI_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions **********************************/ +HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi); +HAL_StatusTypeDef HAL_SPI_DeInit (SPI_HandleTypeDef *hspi); +void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi); +void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi); +/** + * @} + */ + +/** @addtogroup SPI_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions *****************************************************/ +HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size); +HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size); +HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi); +HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi); +HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi); + +void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi); +void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi); +/** + * @} + */ + +/** @addtogroup SPI_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State and Control functions **************************************/ +HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi); +uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi); + +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup SPI_Private_Constants SPI Private Constants + * @{ + */ +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup SPI_Private_Macros SPI Private Macros + * @{ + */ + +#define IS_SPI_MODE(MODE) (((MODE) == SPI_MODE_SLAVE) || \ + ((MODE) == SPI_MODE_MASTER)) + + +#define IS_SPI_DIRECTION_MODE(MODE) (((MODE) == SPI_DIRECTION_2LINES) || \ + ((MODE) == SPI_DIRECTION_2LINES_RXONLY) || \ + ((MODE) == SPI_DIRECTION_1LINE)) + +#define IS_SPI_DIRECTION_2LINES_OR_1LINE(MODE) (((MODE) == SPI_DIRECTION_2LINES) || \ + ((MODE) == SPI_DIRECTION_1LINE)) + +#define IS_SPI_DIRECTION_2LINES(MODE) ((MODE) == SPI_DIRECTION_2LINES) + +#define IS_SPI_DATASIZE(DATASIZE) (((DATASIZE) == SPI_DATASIZE_16BIT) || \ + ((DATASIZE) == SPI_DATASIZE_8BIT)) + +#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_POLARITY_LOW) || \ + ((CPOL) == SPI_POLARITY_HIGH)) + +#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_PHASE_1EDGE) || \ + ((CPHA) == SPI_PHASE_2EDGE)) + +#define IS_SPI_NSS(NSS) (((NSS) == SPI_NSS_SOFT) || \ + ((NSS) == SPI_NSS_HARD_INPUT) || \ + ((NSS) == SPI_NSS_HARD_OUTPUT)) + +#define IS_SPI_BAUDRATE_PRESCALER(PRESCALER) (((PRESCALER) == SPI_BAUDRATEPRESCALER_2) || \ + ((PRESCALER) == SPI_BAUDRATEPRESCALER_4) || \ + ((PRESCALER) == SPI_BAUDRATEPRESCALER_8) || \ + ((PRESCALER) == SPI_BAUDRATEPRESCALER_16) || \ + ((PRESCALER) == SPI_BAUDRATEPRESCALER_32) || \ + ((PRESCALER) == SPI_BAUDRATEPRESCALER_64) || \ + ((PRESCALER) == SPI_BAUDRATEPRESCALER_128) || \ + ((PRESCALER) == SPI_BAUDRATEPRESCALER_256)) + +#define IS_SPI_FIRST_BIT(BIT) (((BIT) == SPI_FIRSTBIT_MSB) || \ + ((BIT) == SPI_FIRSTBIT_LSB)) + +#define IS_SPI_TIMODE(MODE) (((MODE) == SPI_TIMODE_DISABLE) || \ + ((MODE) == SPI_TIMODE_ENABLE)) + +#define IS_SPI_CRC_CALCULATION(CALCULATION) (((CALCULATION) == SPI_CRCCALCULATION_DISABLE) || \ + ((CALCULATION) == SPI_CRCCALCULATION_ENABLE)) + +#define IS_SPI_CRC_POLYNOMIAL(POLYNOMIAL) (((POLYNOMIAL) >= 0x1) && ((POLYNOMIAL) <= 0xFFFF)) + +#define SPI_1LINE_TX(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= SPI_CR1_BIDIOE) + +#define SPI_1LINE_RX(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~SPI_CR1_BIDIOE) + +#define SPI_RESET_CRC(__HANDLE__) do{(__HANDLE__)->Instance->CR1 &= (~SPI_CR1_CRCEN);\ + (__HANDLE__)->Instance->CR1 |= SPI_CR1_CRCEN;}while(0) +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup SPI_Private_Functions SPI Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_SPI_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sram.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sram.h new file mode 100644 index 0000000..a77d4c8 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_sram.h @@ -0,0 +1,202 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_sram.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of SRAM HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_SRAM_H +#define __STM32F4xx_HAL_SRAM_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) + #include "stm32f4xx_ll_fsmc.h" +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) || defined(STM32F446xx) + #include "stm32f4xx_ll_fmc.h" +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ + + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F446xx) +/** @addtogroup SRAM + * @{ + */ + +/* Exported typedef ----------------------------------------------------------*/ + +/** @defgroup SRAM_Exported_Types SRAM Exported Types + * @{ + */ +/** + * @brief HAL SRAM State structures definition + */ +typedef enum +{ + HAL_SRAM_STATE_RESET = 0x00, /*!< SRAM not yet initialized or disabled */ + HAL_SRAM_STATE_READY = 0x01, /*!< SRAM initialized and ready for use */ + HAL_SRAM_STATE_BUSY = 0x02, /*!< SRAM internal process is ongoing */ + HAL_SRAM_STATE_ERROR = 0x03, /*!< SRAM error state */ + HAL_SRAM_STATE_PROTECTED = 0x04 /*!< SRAM peripheral NORSRAM device write protected */ + +}HAL_SRAM_StateTypeDef; + +/** + * @brief SRAM handle Structure definition + */ +typedef struct +{ + FMC_NORSRAM_TypeDef *Instance; /*!< Register base address */ + + FMC_NORSRAM_EXTENDED_TypeDef *Extended; /*!< Extended mode register base address */ + + FMC_NORSRAM_InitTypeDef Init; /*!< SRAM device control configuration parameters */ + + HAL_LockTypeDef Lock; /*!< SRAM locking object */ + + __IO HAL_SRAM_StateTypeDef State; /*!< SRAM device access state */ + + DMA_HandleTypeDef *hdma; /*!< Pointer DMA handler */ + +}SRAM_HandleTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup SRAM_Exported_Macros SRAM Exported Macros + * @{ + */ +/** @brief Reset SRAM handle state + * @param __HANDLE__: SRAM handle + * @retval None + */ +#define __HAL_SRAM_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SRAM_STATE_RESET) + +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup SRAM_Exported_Functions + * @{ + */ + +/** @addtogroup SRAM_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions **********************************/ +HAL_StatusTypeDef HAL_SRAM_Init(SRAM_HandleTypeDef *hsram, FMC_NORSRAM_TimingTypeDef *Timing, FMC_NORSRAM_TimingTypeDef *ExtTiming); +HAL_StatusTypeDef HAL_SRAM_DeInit(SRAM_HandleTypeDef *hsram); +void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram); +void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef *hsram); + +void HAL_SRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma); +void HAL_SRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/** @addtogroup SRAM_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions *****************************************************/ +HAL_StatusTypeDef HAL_SRAM_Read_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pDstBuffer, uint32_t BufferSize); +HAL_StatusTypeDef HAL_SRAM_Write_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pSrcBuffer, uint32_t BufferSize); +HAL_StatusTypeDef HAL_SRAM_Read_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pDstBuffer, uint32_t BufferSize); +HAL_StatusTypeDef HAL_SRAM_Write_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pSrcBuffer, uint32_t BufferSize); +HAL_StatusTypeDef HAL_SRAM_Read_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize); +HAL_StatusTypeDef HAL_SRAM_Write_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize); +HAL_StatusTypeDef HAL_SRAM_Read_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize); +HAL_StatusTypeDef HAL_SRAM_Write_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize); +/** + * @} + */ + +/** @addtogroup SRAM_Exported_Functions_Group3 + * @{ + */ +/* SRAM Control functions ******************************************************/ +HAL_StatusTypeDef HAL_SRAM_WriteOperation_Enable(SRAM_HandleTypeDef *hsram); +HAL_StatusTypeDef HAL_SRAM_WriteOperation_Disable(SRAM_HandleTypeDef *hsram); +/** + * @} + */ + +/** @addtogroup SRAM_Exported_Functions_Group4 + * @{ + */ +/* SRAM State functions *********************************************************/ +HAL_SRAM_StateTypeDef HAL_SRAM_GetState(SRAM_HandleTypeDef *hsram); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** + * @} + */ + +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_SRAM_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h new file mode 100644 index 0000000..e607825 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h @@ -0,0 +1,1608 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_tim.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of TIM HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_TIM_H +#define __STM32F4xx_HAL_TIM_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup TIM + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup TIM_Exported_Types TIM Exported Types + * @{ + */ + +/** + * @brief TIM Time base Configuration Structure definition + */ +typedef struct +{ + uint32_t Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ + + uint32_t CounterMode; /*!< Specifies the counter mode. + This parameter can be a value of @ref TIM_Counter_Mode */ + + uint32_t Period; /*!< Specifies the period value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */ + + uint32_t ClockDivision; /*!< Specifies the clock division. + This parameter can be a value of @ref TIM_ClockDivision */ + + uint32_t RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter + reaches zero, an update event is generated and counting restarts + from the RCR value (N). + This means in PWM mode that (N+1) corresponds to: + - the number of PWM periods in edge-aligned mode + - the number of half PWM period in center-aligned mode + This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. + @note This parameter is valid only for TIM1 and TIM8. */ +} TIM_Base_InitTypeDef; + +/** + * @brief TIM Output Compare Configuration Structure definition + */ + +typedef struct +{ + uint32_t OCMode; /*!< Specifies the TIM mode. + This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ + + uint32_t Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ + + uint32_t OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_Output_Compare_Polarity */ + + uint32_t OCNPolarity; /*!< Specifies the complementary output polarity. + This parameter can be a value of @ref TIM_Output_Compare_N_Polarity + @note This parameter is valid only for TIM1 and TIM8. */ + + uint32_t OCFastMode; /*!< Specifies the Fast mode state. + This parameter can be a value of @ref TIM_Output_Fast_State + @note This parameter is valid only in PWM1 and PWM2 mode. */ + + + uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_Idle_State + @note This parameter is valid only for TIM1 and TIM8. */ + + uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State + @note This parameter is valid only for TIM1 and TIM8. */ +} TIM_OC_InitTypeDef; + +/** + * @brief TIM One Pulse Mode Configuration Structure definition + */ +typedef struct +{ + uint32_t OCMode; /*!< Specifies the TIM mode. + This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ + + uint32_t Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ + + uint32_t OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_Output_Compare_Polarity */ + + uint32_t OCNPolarity; /*!< Specifies the complementary output polarity. + This parameter can be a value of @ref TIM_Output_Compare_N_Polarity + @note This parameter is valid only for TIM1 and TIM8. */ + + uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_Idle_State + @note This parameter is valid only for TIM1 and TIM8. */ + + uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State + @note This parameter is valid only for TIM1 and TIM8. */ + + uint32_t ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint32_t ICSelection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t ICFilter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_OnePulse_InitTypeDef; + + +/** + * @brief TIM Input Capture Configuration Structure definition + */ + +typedef struct +{ + uint32_t ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint32_t ICSelection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t ICPrescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t ICFilter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_IC_InitTypeDef; + +/** + * @brief TIM Encoder Configuration Structure definition + */ + +typedef struct +{ + uint32_t EncoderMode; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Encoder_Mode */ + + uint32_t IC1Polarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint32_t IC1Selection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t IC1Prescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t IC1Filter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + + uint32_t IC2Polarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint32_t IC2Selection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t IC2Prescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t IC2Filter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_Encoder_InitTypeDef; + +/** + * @brief Clock Configuration Handle Structure definition + */ +typedef struct +{ + uint32_t ClockSource; /*!< TIM clock sources. + This parameter can be a value of @ref TIM_Clock_Source */ + uint32_t ClockPolarity; /*!< TIM clock polarity. + This parameter can be a value of @ref TIM_Clock_Polarity */ + uint32_t ClockPrescaler; /*!< TIM clock prescaler. + This parameter can be a value of @ref TIM_Clock_Prescaler */ + uint32_t ClockFilter; /*!< TIM clock filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +}TIM_ClockConfigTypeDef; + +/** + * @brief Clear Input Configuration Handle Structure definition + */ +typedef struct +{ + uint32_t ClearInputState; /*!< TIM clear Input state. + This parameter can be ENABLE or DISABLE */ + uint32_t ClearInputSource; /*!< TIM clear Input sources. + This parameter can be a value of @ref TIM_ClearInput_Source */ + uint32_t ClearInputPolarity; /*!< TIM Clear Input polarity. + This parameter can be a value of @ref TIM_ClearInput_Polarity */ + uint32_t ClearInputPrescaler; /*!< TIM Clear Input prescaler. + This parameter can be a value of @ref TIM_ClearInput_Prescaler */ + uint32_t ClearInputFilter; /*!< TIM Clear Input filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +}TIM_ClearInputConfigTypeDef; + +/** + * @brief TIM Slave configuration Structure definition + */ +typedef struct { + uint32_t SlaveMode; /*!< Slave mode selection + This parameter can be a value of @ref TIM_Slave_Mode */ + uint32_t InputTrigger; /*!< Input Trigger source + This parameter can be a value of @ref TIM_Trigger_Selection */ + uint32_t TriggerPolarity; /*!< Input Trigger polarity + This parameter can be a value of @ref TIM_Trigger_Polarity */ + uint32_t TriggerPrescaler; /*!< Input trigger prescaler + This parameter can be a value of @ref TIM_Trigger_Prescaler */ + uint32_t TriggerFilter; /*!< Input trigger filter + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + +}TIM_SlaveConfigTypeDef; + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_TIM_STATE_RESET = 0x00, /*!< Peripheral not yet initialized or disabled */ + HAL_TIM_STATE_READY = 0x01, /*!< Peripheral Initialized and ready for use */ + HAL_TIM_STATE_BUSY = 0x02, /*!< An internal process is ongoing */ + HAL_TIM_STATE_TIMEOUT = 0x03, /*!< Timeout state */ + HAL_TIM_STATE_ERROR = 0x04 /*!< Reception process is ongoing */ +}HAL_TIM_StateTypeDef; + +/** + * @brief HAL Active channel structures definition + */ +typedef enum +{ + HAL_TIM_ACTIVE_CHANNEL_1 = 0x01, /*!< The active channel is 1 */ + HAL_TIM_ACTIVE_CHANNEL_2 = 0x02, /*!< The active channel is 2 */ + HAL_TIM_ACTIVE_CHANNEL_3 = 0x04, /*!< The active channel is 3 */ + HAL_TIM_ACTIVE_CHANNEL_4 = 0x08, /*!< The active channel is 4 */ + HAL_TIM_ACTIVE_CHANNEL_CLEARED = 0x00 /*!< All active channels cleared */ +}HAL_TIM_ActiveChannel; + +/** + * @brief TIM Time Base Handle Structure definition + */ +typedef struct +{ + TIM_TypeDef *Instance; /*!< Register base address */ + TIM_Base_InitTypeDef Init; /*!< TIM Time Base required parameters */ + HAL_TIM_ActiveChannel Channel; /*!< Active channel */ + DMA_HandleTypeDef *hdma[7]; /*!< DMA Handlers array + This array is accessed by a @ref DMA_Handle_index */ + HAL_LockTypeDef Lock; /*!< Locking object */ + __IO HAL_TIM_StateTypeDef State; /*!< TIM operation state */ +}TIM_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup TIM_Exported_Constants TIM Exported Constants + * @{ + */ + +/** @defgroup TIM_Input_Channel_Polarity TIM Input Channel Polarity + * @{ + */ +#define TIM_INPUTCHANNELPOLARITY_RISING ((uint32_t)0x00000000) /*!< Polarity for TIx source */ +#define TIM_INPUTCHANNELPOLARITY_FALLING (TIM_CCER_CC1P) /*!< Polarity for TIx source */ +#define TIM_INPUTCHANNELPOLARITY_BOTHEDGE (TIM_CCER_CC1P | TIM_CCER_CC1NP) /*!< Polarity for TIx source */ +/** + * @} + */ + +/** @defgroup TIM_ETR_Polarity TIM ETR Polarity + * @{ + */ +#define TIM_ETRPOLARITY_INVERTED (TIM_SMCR_ETP) /*!< Polarity for ETR source */ +#define TIM_ETRPOLARITY_NONINVERTED ((uint32_t)0x0000) /*!< Polarity for ETR source */ +/** + * @} + */ + +/** @defgroup TIM_ETR_Prescaler TIM ETR Prescaler + * @{ + */ +#define TIM_ETRPRESCALER_DIV1 ((uint32_t)0x0000) /*!< No prescaler is used */ +#define TIM_ETRPRESCALER_DIV2 (TIM_SMCR_ETPS_0) /*!< ETR input source is divided by 2 */ +#define TIM_ETRPRESCALER_DIV4 (TIM_SMCR_ETPS_1) /*!< ETR input source is divided by 4 */ +#define TIM_ETRPRESCALER_DIV8 (TIM_SMCR_ETPS) /*!< ETR input source is divided by 8 */ +/** + * @} + */ + +/** @defgroup TIM_Counter_Mode TIM Counter Mode + * @{ + */ +#define TIM_COUNTERMODE_UP ((uint32_t)0x0000) +#define TIM_COUNTERMODE_DOWN TIM_CR1_DIR +#define TIM_COUNTERMODE_CENTERALIGNED1 TIM_CR1_CMS_0 +#define TIM_COUNTERMODE_CENTERALIGNED2 TIM_CR1_CMS_1 +#define TIM_COUNTERMODE_CENTERALIGNED3 TIM_CR1_CMS +/** + * @} + */ + +/** @defgroup TIM_ClockDivision TIM Clock Division + * @{ + */ +#define TIM_CLOCKDIVISION_DIV1 ((uint32_t)0x0000) +#define TIM_CLOCKDIVISION_DIV2 (TIM_CR1_CKD_0) +#define TIM_CLOCKDIVISION_DIV4 (TIM_CR1_CKD_1) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_and_PWM_modes TIM Output Compare and PWM modes + * @{ + */ +#define TIM_OCMODE_TIMING ((uint32_t)0x0000) +#define TIM_OCMODE_ACTIVE (TIM_CCMR1_OC1M_0) +#define TIM_OCMODE_INACTIVE (TIM_CCMR1_OC1M_1) +#define TIM_OCMODE_TOGGLE (TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1) +#define TIM_OCMODE_PWM1 (TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2) +#define TIM_OCMODE_PWM2 (TIM_CCMR1_OC1M) +#define TIM_OCMODE_FORCED_ACTIVE (TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_2) +#define TIM_OCMODE_FORCED_INACTIVE (TIM_CCMR1_OC1M_2) + +/** + * @} + */ + +/** @defgroup TIM_Output_Fast_State TIM Output Fast State + * @{ + */ +#define TIM_OCFAST_DISABLE ((uint32_t)0x0000) +#define TIM_OCFAST_ENABLE (TIM_CCMR1_OC1FE) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Polarity TIM Output Compare Polarity + * @{ + */ +#define TIM_OCPOLARITY_HIGH ((uint32_t)0x0000) +#define TIM_OCPOLARITY_LOW (TIM_CCER_CC1P) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Polarity TIM Output CompareN Polarity + * @{ + */ +#define TIM_OCNPOLARITY_HIGH ((uint32_t)0x0000) +#define TIM_OCNPOLARITY_LOW (TIM_CCER_CC1NP) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Idle_State TIM Output Compare Idle State + * @{ + */ +#define TIM_OCIDLESTATE_SET (TIM_CR2_OIS1) +#define TIM_OCIDLESTATE_RESET ((uint32_t)0x0000) +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Idle_State TIM Output Compare N Idle State + * @{ + */ +#define TIM_OCNIDLESTATE_SET (TIM_CR2_OIS1N) +#define TIM_OCNIDLESTATE_RESET ((uint32_t)0x0000) +/** + * @} + */ + +/** @defgroup TIM_Channel TIM Channel + * @{ + */ +#define TIM_CHANNEL_1 ((uint32_t)0x0000) +#define TIM_CHANNEL_2 ((uint32_t)0x0004) +#define TIM_CHANNEL_3 ((uint32_t)0x0008) +#define TIM_CHANNEL_4 ((uint32_t)0x000C) +#define TIM_CHANNEL_ALL ((uint32_t)0x0018) + +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Polarity TIM Input Capture Polarity + * @{ + */ +#define TIM_ICPOLARITY_RISING TIM_INPUTCHANNELPOLARITY_RISING +#define TIM_ICPOLARITY_FALLING TIM_INPUTCHANNELPOLARITY_FALLING +#define TIM_ICPOLARITY_BOTHEDGE TIM_INPUTCHANNELPOLARITY_BOTHEDGE +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Selection TIM Input Capture Selection + * @{ + */ +#define TIM_ICSELECTION_DIRECTTI (TIM_CCMR1_CC1S_0) /*!< TIM Input 1, 2, 3 or 4 is selected to be + connected to IC1, IC2, IC3 or IC4, respectively */ +#define TIM_ICSELECTION_INDIRECTTI (TIM_CCMR1_CC1S_1) /*!< TIM Input 1, 2, 3 or 4 is selected to be + connected to IC2, IC1, IC4 or IC3, respectively */ +#define TIM_ICSELECTION_TRC (TIM_CCMR1_CC1S) /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC */ + +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Prescaler TIM Input Capture Prescaler + * @{ + */ +#define TIM_ICPSC_DIV1 ((uint32_t)0x0000) /*!< Capture performed each time an edge is detected on the capture input */ +#define TIM_ICPSC_DIV2 (TIM_CCMR1_IC1PSC_0) /*!< Capture performed once every 2 events */ +#define TIM_ICPSC_DIV4 (TIM_CCMR1_IC1PSC_1) /*!< Capture performed once every 4 events */ +#define TIM_ICPSC_DIV8 (TIM_CCMR1_IC1PSC) /*!< Capture performed once every 8 events */ +/** + * @} + */ + +/** @defgroup TIM_One_Pulse_Mode TIM One Pulse Mode + * @{ + */ +#define TIM_OPMODE_SINGLE (TIM_CR1_OPM) +#define TIM_OPMODE_REPETITIVE ((uint32_t)0x0000) +/** + * @} + */ + +/** @defgroup TIM_Encoder_Mode TIM Encoder Mode + * @{ + */ +#define TIM_ENCODERMODE_TI1 (TIM_SMCR_SMS_0) +#define TIM_ENCODERMODE_TI2 (TIM_SMCR_SMS_1) +#define TIM_ENCODERMODE_TI12 (TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0) + +/** + * @} + */ + +/** @defgroup TIM_Interrupt_definition TIM Interrupt definition + * @{ + */ +#define TIM_IT_UPDATE (TIM_DIER_UIE) +#define TIM_IT_CC1 (TIM_DIER_CC1IE) +#define TIM_IT_CC2 (TIM_DIER_CC2IE) +#define TIM_IT_CC3 (TIM_DIER_CC3IE) +#define TIM_IT_CC4 (TIM_DIER_CC4IE) +#define TIM_IT_COM (TIM_DIER_COMIE) +#define TIM_IT_TRIGGER (TIM_DIER_TIE) +#define TIM_IT_BREAK (TIM_DIER_BIE) +/** + * @} + */ + +/** @defgroup TIM_Commutation_Source TIM Commutation Source + * @{ + */ +#define TIM_COMMUTATION_TRGI (TIM_CR2_CCUS) +#define TIM_COMMUTATION_SOFTWARE ((uint32_t)0x0000) +/** + * @} + */ + +/** @defgroup TIM_DMA_sources TIM DMA sources + * @{ + */ +#define TIM_DMA_UPDATE (TIM_DIER_UDE) +#define TIM_DMA_CC1 (TIM_DIER_CC1DE) +#define TIM_DMA_CC2 (TIM_DIER_CC2DE) +#define TIM_DMA_CC3 (TIM_DIER_CC3DE) +#define TIM_DMA_CC4 (TIM_DIER_CC4DE) +#define TIM_DMA_COM (TIM_DIER_COMDE) +#define TIM_DMA_TRIGGER (TIM_DIER_TDE) +/** + * @} + */ + +/** @defgroup TIM_Event_Source TIM Event Source + * @{ + */ +#define TIM_EVENTSOURCE_UPDATE TIM_EGR_UG +#define TIM_EVENTSOURCE_CC1 TIM_EGR_CC1G +#define TIM_EVENTSOURCE_CC2 TIM_EGR_CC2G +#define TIM_EVENTSOURCE_CC3 TIM_EGR_CC3G +#define TIM_EVENTSOURCE_CC4 TIM_EGR_CC4G +#define TIM_EVENTSOURCE_COM TIM_EGR_COMG +#define TIM_EVENTSOURCE_TRIGGER TIM_EGR_TG +#define TIM_EVENTSOURCE_BREAK TIM_EGR_BG + +/** + * @} + */ + +/** @defgroup TIM_Flag_definition TIM Flag definition + * @{ + */ +#define TIM_FLAG_UPDATE (TIM_SR_UIF) +#define TIM_FLAG_CC1 (TIM_SR_CC1IF) +#define TIM_FLAG_CC2 (TIM_SR_CC2IF) +#define TIM_FLAG_CC3 (TIM_SR_CC3IF) +#define TIM_FLAG_CC4 (TIM_SR_CC4IF) +#define TIM_FLAG_COM (TIM_SR_COMIF) +#define TIM_FLAG_TRIGGER (TIM_SR_TIF) +#define TIM_FLAG_BREAK (TIM_SR_BIF) +#define TIM_FLAG_CC1OF (TIM_SR_CC1OF) +#define TIM_FLAG_CC2OF (TIM_SR_CC2OF) +#define TIM_FLAG_CC3OF (TIM_SR_CC3OF) +#define TIM_FLAG_CC4OF (TIM_SR_CC4OF) +/** + * @} + */ + +/** @defgroup TIM_Clock_Source TIM Clock Source + * @{ + */ +#define TIM_CLOCKSOURCE_ETRMODE2 (TIM_SMCR_ETPS_1) +#define TIM_CLOCKSOURCE_INTERNAL (TIM_SMCR_ETPS_0) +#define TIM_CLOCKSOURCE_ITR0 ((uint32_t)0x0000) +#define TIM_CLOCKSOURCE_ITR1 (TIM_SMCR_TS_0) +#define TIM_CLOCKSOURCE_ITR2 (TIM_SMCR_TS_1) +#define TIM_CLOCKSOURCE_ITR3 (TIM_SMCR_TS_0 | TIM_SMCR_TS_1) +#define TIM_CLOCKSOURCE_TI1ED (TIM_SMCR_TS_2) +#define TIM_CLOCKSOURCE_TI1 (TIM_SMCR_TS_0 | TIM_SMCR_TS_2) +#define TIM_CLOCKSOURCE_TI2 (TIM_SMCR_TS_1 | TIM_SMCR_TS_2) +#define TIM_CLOCKSOURCE_ETRMODE1 (TIM_SMCR_TS) +/** + * @} + */ + +/** @defgroup TIM_Clock_Polarity TIM Clock Polarity + * @{ + */ +#define TIM_CLOCKPOLARITY_INVERTED TIM_ETRPOLARITY_INVERTED /*!< Polarity for ETRx clock sources */ +#define TIM_CLOCKPOLARITY_NONINVERTED TIM_ETRPOLARITY_NONINVERTED /*!< Polarity for ETRx clock sources */ +#define TIM_CLOCKPOLARITY_RISING TIM_INPUTCHANNELPOLARITY_RISING /*!< Polarity for TIx clock sources */ +#define TIM_CLOCKPOLARITY_FALLING TIM_INPUTCHANNELPOLARITY_FALLING /*!< Polarity for TIx clock sources */ +#define TIM_CLOCKPOLARITY_BOTHEDGE TIM_INPUTCHANNELPOLARITY_BOTHEDGE /*!< Polarity for TIx clock sources */ +/** + * @} + */ + +/** @defgroup TIM_Clock_Prescaler TIM Clock Prescaler + * @{ + */ +#define TIM_CLOCKPRESCALER_DIV1 TIM_ETRPRESCALER_DIV1 /*!< No prescaler is used */ +#define TIM_CLOCKPRESCALER_DIV2 TIM_ETRPRESCALER_DIV2 /*!< Prescaler for External ETR Clock: Capture performed once every 2 events. */ +#define TIM_CLOCKPRESCALER_DIV4 TIM_ETRPRESCALER_DIV4 /*!< Prescaler for External ETR Clock: Capture performed once every 4 events. */ +#define TIM_CLOCKPRESCALER_DIV8 TIM_ETRPRESCALER_DIV8 /*!< Prescaler for External ETR Clock: Capture performed once every 8 events. */ +/** + * @} + */ + +/** @defgroup TIM_ClearInput_Source TIM Clear Input Source + * @{ + */ +#define TIM_CLEARINPUTSOURCE_ETR ((uint32_t)0x0001) +#define TIM_CLEARINPUTSOURCE_NONE ((uint32_t)0x0000) +/** + * @} + */ + +/** @defgroup TIM_ClearInput_Polarity TIM Clear Input Polarity + * @{ + */ +#define TIM_CLEARINPUTPOLARITY_INVERTED TIM_ETRPOLARITY_INVERTED /*!< Polarity for ETRx pin */ +#define TIM_CLEARINPUTPOLARITY_NONINVERTED TIM_ETRPOLARITY_NONINVERTED /*!< Polarity for ETRx pin */ +/** + * @} + */ + +/** @defgroup TIM_ClearInput_Prescaler TIM Clear Input Prescaler + * @{ + */ +#define TIM_CLEARINPUTPRESCALER_DIV1 TIM_ETRPRESCALER_DIV1 /*!< No prescaler is used */ +#define TIM_CLEARINPUTPRESCALER_DIV2 TIM_ETRPRESCALER_DIV2 /*!< Prescaler for External ETR pin: Capture performed once every 2 events. */ +#define TIM_CLEARINPUTPRESCALER_DIV4 TIM_ETRPRESCALER_DIV4 /*!< Prescaler for External ETR pin: Capture performed once every 4 events. */ +#define TIM_CLEARINPUTPRESCALER_DIV8 TIM_ETRPRESCALER_DIV8 /*!< Prescaler for External ETR pin: Capture performed once every 8 events. */ +/** + * @} + */ + +/** @defgroup TIM_OSSR_Off_State_Selection_for_Run_mode_state TIM OSSR OffState Selection for Run mode state + * @{ + */ +#define TIM_OSSR_ENABLE (TIM_BDTR_OSSR) +#define TIM_OSSR_DISABLE ((uint32_t)0x0000) +/** + * @} + */ + +/** @defgroup TIM_OSSI_Off_State_Selection_for_Idle_mode_state TIM OSSI OffState Selection for Idle mode state + * @{ + */ +#define TIM_OSSI_ENABLE (TIM_BDTR_OSSI) +#define TIM_OSSI_DISABLE ((uint32_t)0x0000) +/** + * @} + */ + +/** @defgroup TIM_Lock_level TIM Lock level + * @{ + */ +#define TIM_LOCKLEVEL_OFF ((uint32_t)0x0000) +#define TIM_LOCKLEVEL_1 (TIM_BDTR_LOCK_0) +#define TIM_LOCKLEVEL_2 (TIM_BDTR_LOCK_1) +#define TIM_LOCKLEVEL_3 (TIM_BDTR_LOCK) +/** + * @} + */ +/** @defgroup TIM_Break_Input_enable_disable TIM Break Input State + * @{ + */ +#define TIM_BREAK_ENABLE (TIM_BDTR_BKE) +#define TIM_BREAK_DISABLE ((uint32_t)0x0000) +/** + * @} + */ + +/** @defgroup TIM_Break_Polarity TIM Break Polarity + * @{ + */ +#define TIM_BREAKPOLARITY_LOW ((uint32_t)0x0000) +#define TIM_BREAKPOLARITY_HIGH (TIM_BDTR_BKP) +/** + * @} + */ + +/** @defgroup TIM_AOE_Bit_Set_Reset TIM AOE Bit State + * @{ + */ +#define TIM_AUTOMATICOUTPUT_ENABLE (TIM_BDTR_AOE) +#define TIM_AUTOMATICOUTPUT_DISABLE ((uint32_t)0x0000) +/** + * @} + */ + +/** @defgroup TIM_Master_Mode_Selection TIM Master Mode Selection + * @{ + */ +#define TIM_TRGO_RESET ((uint32_t)0x0000) +#define TIM_TRGO_ENABLE (TIM_CR2_MMS_0) +#define TIM_TRGO_UPDATE (TIM_CR2_MMS_1) +#define TIM_TRGO_OC1 ((TIM_CR2_MMS_1 | TIM_CR2_MMS_0)) +#define TIM_TRGO_OC1REF (TIM_CR2_MMS_2) +#define TIM_TRGO_OC2REF ((TIM_CR2_MMS_2 | TIM_CR2_MMS_0)) +#define TIM_TRGO_OC3REF ((TIM_CR2_MMS_2 | TIM_CR2_MMS_1)) +#define TIM_TRGO_OC4REF ((TIM_CR2_MMS_2 | TIM_CR2_MMS_1 | TIM_CR2_MMS_0)) +/** + * @} + */ + +/** @defgroup TIM_Slave_Mode TIM Slave Mode + * @{ + */ +#define TIM_SLAVEMODE_DISABLE ((uint32_t)0x0000) +#define TIM_SLAVEMODE_RESET ((uint32_t)0x0004) +#define TIM_SLAVEMODE_GATED ((uint32_t)0x0005) +#define TIM_SLAVEMODE_TRIGGER ((uint32_t)0x0006) +#define TIM_SLAVEMODE_EXTERNAL1 ((uint32_t)0x0007) +/** + * @} + */ + +/** @defgroup TIM_Master_Slave_Mode TIM Master Slave Mode + * @{ + */ +#define TIM_MASTERSLAVEMODE_ENABLE ((uint32_t)0x0080) +#define TIM_MASTERSLAVEMODE_DISABLE ((uint32_t)0x0000) +/** + * @} + */ + +/** @defgroup TIM_Trigger_Selection TIM Trigger Selection + * @{ + */ +#define TIM_TS_ITR0 ((uint32_t)0x0000) +#define TIM_TS_ITR1 ((uint32_t)0x0010) +#define TIM_TS_ITR2 ((uint32_t)0x0020) +#define TIM_TS_ITR3 ((uint32_t)0x0030) +#define TIM_TS_TI1F_ED ((uint32_t)0x0040) +#define TIM_TS_TI1FP1 ((uint32_t)0x0050) +#define TIM_TS_TI2FP2 ((uint32_t)0x0060) +#define TIM_TS_ETRF ((uint32_t)0x0070) +#define TIM_TS_NONE ((uint32_t)0xFFFF) +/** + * @} + */ + +/** @defgroup TIM_Trigger_Polarity TIM Trigger Polarity + * @{ + */ +#define TIM_TRIGGERPOLARITY_INVERTED TIM_ETRPOLARITY_INVERTED /*!< Polarity for ETRx trigger sources */ +#define TIM_TRIGGERPOLARITY_NONINVERTED TIM_ETRPOLARITY_NONINVERTED /*!< Polarity for ETRx trigger sources */ +#define TIM_TRIGGERPOLARITY_RISING TIM_INPUTCHANNELPOLARITY_RISING /*!< Polarity for TIxFPx or TI1_ED trigger sources */ +#define TIM_TRIGGERPOLARITY_FALLING TIM_INPUTCHANNELPOLARITY_FALLING /*!< Polarity for TIxFPx or TI1_ED trigger sources */ +#define TIM_TRIGGERPOLARITY_BOTHEDGE TIM_INPUTCHANNELPOLARITY_BOTHEDGE /*!< Polarity for TIxFPx or TI1_ED trigger sources */ +/** + * @} + */ + +/** @defgroup TIM_Trigger_Prescaler TIM Trigger Prescaler + * @{ + */ +#define TIM_TRIGGERPRESCALER_DIV1 TIM_ETRPRESCALER_DIV1 /*!< No prescaler is used */ +#define TIM_TRIGGERPRESCALER_DIV2 TIM_ETRPRESCALER_DIV2 /*!< Prescaler for External ETR Trigger: Capture performed once every 2 events. */ +#define TIM_TRIGGERPRESCALER_DIV4 TIM_ETRPRESCALER_DIV4 /*!< Prescaler for External ETR Trigger: Capture performed once every 4 events. */ +#define TIM_TRIGGERPRESCALER_DIV8 TIM_ETRPRESCALER_DIV8 /*!< Prescaler for External ETR Trigger: Capture performed once every 8 events. */ +/** + * @} + */ + + +/** @defgroup TIM_TI1_Selection TIM TI1 Selection + * @{ + */ +#define TIM_TI1SELECTION_CH1 ((uint32_t)0x0000) +#define TIM_TI1SELECTION_XORCOMBINATION (TIM_CR2_TI1S) +/** + * @} + */ + +/** @defgroup TIM_DMA_Base_address TIM DMA Base address + * @{ + */ +#define TIM_DMABASE_CR1 (0x00000000) +#define TIM_DMABASE_CR2 (0x00000001) +#define TIM_DMABASE_SMCR (0x00000002) +#define TIM_DMABASE_DIER (0x00000003) +#define TIM_DMABASE_SR (0x00000004) +#define TIM_DMABASE_EGR (0x00000005) +#define TIM_DMABASE_CCMR1 (0x00000006) +#define TIM_DMABASE_CCMR2 (0x00000007) +#define TIM_DMABASE_CCER (0x00000008) +#define TIM_DMABASE_CNT (0x00000009) +#define TIM_DMABASE_PSC (0x0000000A) +#define TIM_DMABASE_ARR (0x0000000B) +#define TIM_DMABASE_RCR (0x0000000C) +#define TIM_DMABASE_CCR1 (0x0000000D) +#define TIM_DMABASE_CCR2 (0x0000000E) +#define TIM_DMABASE_CCR3 (0x0000000F) +#define TIM_DMABASE_CCR4 (0x00000010) +#define TIM_DMABASE_BDTR (0x00000011) +#define TIM_DMABASE_DCR (0x00000012) +#define TIM_DMABASE_OR (0x00000013) +/** + * @} + */ + +/** @defgroup TIM_DMA_Burst_Length TIM DMA Burst Length + * @{ + */ +#define TIM_DMABURSTLENGTH_1TRANSFER (0x00000000) +#define TIM_DMABURSTLENGTH_2TRANSFERS (0x00000100) +#define TIM_DMABURSTLENGTH_3TRANSFERS (0x00000200) +#define TIM_DMABURSTLENGTH_4TRANSFERS (0x00000300) +#define TIM_DMABURSTLENGTH_5TRANSFERS (0x00000400) +#define TIM_DMABURSTLENGTH_6TRANSFERS (0x00000500) +#define TIM_DMABURSTLENGTH_7TRANSFERS (0x00000600) +#define TIM_DMABURSTLENGTH_8TRANSFERS (0x00000700) +#define TIM_DMABURSTLENGTH_9TRANSFERS (0x00000800) +#define TIM_DMABURSTLENGTH_10TRANSFERS (0x00000900) +#define TIM_DMABURSTLENGTH_11TRANSFERS (0x00000A00) +#define TIM_DMABURSTLENGTH_12TRANSFERS (0x00000B00) +#define TIM_DMABURSTLENGTH_13TRANSFERS (0x00000C00) +#define TIM_DMABURSTLENGTH_14TRANSFERS (0x00000D00) +#define TIM_DMABURSTLENGTH_15TRANSFERS (0x00000E00) +#define TIM_DMABURSTLENGTH_16TRANSFERS (0x00000F00) +#define TIM_DMABURSTLENGTH_17TRANSFERS (0x00001000) +#define TIM_DMABURSTLENGTH_18TRANSFERS (0x00001100) +/** + * @} + */ + +/** @defgroup DMA_Handle_index DMA Handle index + * @{ + */ +#define TIM_DMA_ID_UPDATE ((uint16_t) 0x0) /*!< Index of the DMA handle used for Update DMA requests */ +#define TIM_DMA_ID_CC1 ((uint16_t) 0x1) /*!< Index of the DMA handle used for Capture/Compare 1 DMA requests */ +#define TIM_DMA_ID_CC2 ((uint16_t) 0x2) /*!< Index of the DMA handle used for Capture/Compare 2 DMA requests */ +#define TIM_DMA_ID_CC3 ((uint16_t) 0x3) /*!< Index of the DMA handle used for Capture/Compare 3 DMA requests */ +#define TIM_DMA_ID_CC4 ((uint16_t) 0x4) /*!< Index of the DMA handle used for Capture/Compare 4 DMA requests */ +#define TIM_DMA_ID_COMMUTATION ((uint16_t) 0x5) /*!< Index of the DMA handle used for Commutation DMA requests */ +#define TIM_DMA_ID_TRIGGER ((uint16_t) 0x6) /*!< Index of the DMA handle used for Trigger DMA requests */ +/** + * @} + */ + +/** @defgroup Channel_CC_State Channel CC State + * @{ + */ +#define TIM_CCx_ENABLE ((uint32_t)0x0001) +#define TIM_CCx_DISABLE ((uint32_t)0x0000) +#define TIM_CCxN_ENABLE ((uint32_t)0x0004) +#define TIM_CCxN_DISABLE ((uint32_t)0x0000) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup TIM_Exported_Macros TIM Exported Macros + * @{ + */ +/** @brief Reset TIM handle state + * @param __HANDLE__: TIM handle + * @retval None + */ +#define __HAL_TIM_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_TIM_STATE_RESET) + +/** + * @brief Enable the TIM peripheral. + * @param __HANDLE__: TIM handle + * @retval None + */ +#define __HAL_TIM_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1|=(TIM_CR1_CEN)) + +/** + * @brief Enable the TIM main Output. + * @param __HANDLE__: TIM handle + * @retval None + */ +#define __HAL_TIM_MOE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->BDTR|=(TIM_BDTR_MOE)) + + +/** + * @brief Disable the TIM peripheral. + * @param __HANDLE__: TIM handle + * @retval None + */ +#define __HAL_TIM_DISABLE(__HANDLE__) \ + do { \ + if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0) \ + { \ + if(((__HANDLE__)->Instance->CCER & TIM_CCER_CCxNE_MASK) == 0) \ + { \ + (__HANDLE__)->Instance->CR1 &= ~(TIM_CR1_CEN); \ + } \ + } \ + } while(0) + +/* The Main Output of a timer instance is disabled only if all the CCx and CCxN + channels have been disabled */ +/** + * @brief Disable the TIM main Output. + * @param __HANDLE__: TIM handle + * @retval None + */ +#define __HAL_TIM_MOE_DISABLE(__HANDLE__) \ + do { \ + if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0) \ + { \ + if(((__HANDLE__)->Instance->CCER & TIM_CCER_CCxNE_MASK) == 0) \ + { \ + (__HANDLE__)->Instance->BDTR &= ~(TIM_BDTR_MOE); \ + } \ + } \ + } while(0) + +#define __HAL_TIM_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DIER |= (__INTERRUPT__)) +#define __HAL_TIM_ENABLE_DMA(__HANDLE__, __DMA__) ((__HANDLE__)->Instance->DIER |= (__DMA__)) +#define __HAL_TIM_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DIER &= ~(__INTERRUPT__)) +#define __HAL_TIM_DISABLE_DMA(__HANDLE__, __DMA__) ((__HANDLE__)->Instance->DIER &= ~(__DMA__)) +#define __HAL_TIM_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR &(__FLAG__)) == (__FLAG__)) +#define __HAL_TIM_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__)) + +#define __HAL_TIM_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->DIER & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) +#define __HAL_TIM_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->SR = ~(__INTERRUPT__)) + +#define __HAL_TIM_IS_TIM_COUNTING_DOWN(__HANDLE__) (((__HANDLE__)->Instance->CR1 &(TIM_CR1_DIR)) == (TIM_CR1_DIR)) +#define __HAL_TIM_SET_PRESCALER(__HANDLE__, __PRESC__) ((__HANDLE__)->Instance->PSC = (__PRESC__)) + +#define TIM_SET_ICPRESCALERVALUE(__HANDLE__, __CHANNEL__, __ICPSC__) \ +(((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= (__ICPSC__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 |= ((__ICPSC__) << 8)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 |= (__ICPSC__)) :\ + ((__HANDLE__)->Instance->CCMR2 |= ((__ICPSC__) << 8))) + +#define TIM_RESET_ICPRESCALERVALUE(__HANDLE__, __CHANNEL__) \ +(((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 &= (uint16_t)~TIM_CCMR1_IC1PSC) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 &= (uint16_t)~TIM_CCMR1_IC2PSC) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 &= (uint16_t)~TIM_CCMR2_IC3PSC) :\ + ((__HANDLE__)->Instance->CCMR2 &= (uint16_t)~TIM_CCMR2_IC4PSC)) + +#define TIM_SET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__, __POLARITY__) \ +(((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER |= (__POLARITY__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCER |= ((__POLARITY__) << 4)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCER |= ((__POLARITY__) << 8)) :\ + ((__HANDLE__)->Instance->CCER |= (((__POLARITY__) << 12) & TIM_CCER_CC4P))) + +#define TIM_RESET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__) \ +(((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER &= (uint16_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCER &= (uint16_t)~(TIM_CCER_CC2P | TIM_CCER_CC2NP)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCER &= (uint16_t)~(TIM_CCER_CC3P | TIM_CCER_CC3NP)) :\ + ((__HANDLE__)->Instance->CCER &= (uint16_t)~TIM_CCER_CC4P)) + +/** + * @brief Sets the TIM Capture Compare Register value on runtime without + * calling another time ConfigChannel function. + * @param __HANDLE__: TIM handle. + * @param __CHANNEL__ : TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param __COMPARE__: specifies the Capture Compare register new value. + * @retval None + */ +#define __HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__) \ +(*(__IO uint32_t *)(&((__HANDLE__)->Instance->CCR1) + ((__CHANNEL__) >> 2)) = (__COMPARE__)) + +/** + * @brief Gets the TIM Capture Compare Register value on runtime + * @param __HANDLE__: TIM handle. + * @param __CHANNEL__ : TIM Channel associated with the capture compare register + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: get capture/compare 1 register value + * @arg TIM_CHANNEL_2: get capture/compare 2 register value + * @arg TIM_CHANNEL_3: get capture/compare 3 register value + * @arg TIM_CHANNEL_4: get capture/compare 4 register value + * @retval None + */ +#define __HAL_TIM_GET_COMPARE(__HANDLE__, __CHANNEL__) \ + (*(__IO uint32_t *)(&((__HANDLE__)->Instance->CCR1) + ((__CHANNEL__) >> 2))) + +/** + * @brief Sets the TIM Counter Register value on runtime. + * @param __HANDLE__: TIM handle. + * @param __COUNTER__: specifies the Counter register new value. + * @retval None + */ +#define __HAL_TIM_SET_COUNTER(__HANDLE__, __COUNTER__) ((__HANDLE__)->Instance->CNT = (__COUNTER__)) + +/** + * @brief Gets the TIM Counter Register value on runtime. + * @param __HANDLE__: TIM handle. + * @retval None + */ +#define __HAL_TIM_GET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->CNT) + +/** + * @brief Sets the TIM Autoreload Register value on runtime without calling + * another time any Init function. + * @param __HANDLE__: TIM handle. + * @param __AUTORELOAD__: specifies the Counter register new value. + * @retval None + */ +#define __HAL_TIM_SET_AUTORELOAD(__HANDLE__, __AUTORELOAD__) \ + do{ \ + (__HANDLE__)->Instance->ARR = (__AUTORELOAD__); \ + (__HANDLE__)->Init.Period = (__AUTORELOAD__); \ + } while(0) +/** + * @brief Gets the TIM Autoreload Register value on runtime + * @param __HANDLE__: TIM handle. + * @retval None + */ +#define __HAL_TIM_GET_AUTORELOAD(__HANDLE__) ((__HANDLE__)->Instance->ARR) + +/** + * @brief Sets the TIM Clock Division value on runtime without calling + * another time any Init function. + * @param __HANDLE__: TIM handle. + * @param __CKD__: specifies the clock division value. + * This parameter can be one of the following value: + * @arg TIM_CLOCKDIVISION_DIV1 + * @arg TIM_CLOCKDIVISION_DIV2 + * @arg TIM_CLOCKDIVISION_DIV4 + * @retval None + */ +#define __HAL_TIM_SET_CLOCKDIVISION(__HANDLE__, __CKD__) \ + do{ \ + (__HANDLE__)->Instance->CR1 &= (uint16_t)(~TIM_CR1_CKD); \ + (__HANDLE__)->Instance->CR1 |= (__CKD__); \ + (__HANDLE__)->Init.ClockDivision = (__CKD__); \ + } while(0) +/** + * @brief Gets the TIM Clock Division value on runtime + * @param __HANDLE__: TIM handle. + * @retval None + */ +#define __HAL_TIM_GET_CLOCKDIVISION(__HANDLE__) ((__HANDLE__)->Instance->CR1 & TIM_CR1_CKD) + +/** + * @brief Sets the TIM Input Capture prescaler on runtime without calling + * another time HAL_TIM_IC_ConfigChannel() function. + * @param __HANDLE__: TIM handle. + * @param __CHANNEL__ : TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param __ICPSC__: specifies the Input Capture4 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +#define __HAL_TIM_SET_ICPRESCALER(__HANDLE__, __CHANNEL__, __ICPSC__) \ + do{ \ + TIM_RESET_ICPRESCALERVALUE((__HANDLE__), (__CHANNEL__)); \ + TIM_SET_ICPRESCALERVALUE((__HANDLE__), (__CHANNEL__), (__ICPSC__)); \ + } while(0) + +/** + * @brief Gets the TIM Input Capture prescaler on runtime + * @param __HANDLE__: TIM handle. + * @param __CHANNEL__ : TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: get input capture 1 prescaler value + * @arg TIM_CHANNEL_2: get input capture 2 prescaler value + * @arg TIM_CHANNEL_3: get input capture 3 prescaler value + * @arg TIM_CHANNEL_4: get input capture 4 prescaler value + * @retval None + */ +#define __HAL_TIM_GET_ICPRESCALER(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 & TIM_CCMR1_IC1PSC) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? (((__HANDLE__)->Instance->CCMR1 & TIM_CCMR1_IC2PSC) >> 8) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 & TIM_CCMR2_IC3PSC) :\ + (((__HANDLE__)->Instance->CCMR2 & TIM_CCMR2_IC4PSC)) >> 8) + +/** + * @brief Set the Update Request Source (URS) bit of the TIMx_CR1 register + * @param __HANDLE__: TIM handle. + * @note When the USR bit of the TIMx_CR1 register is set, only counter + * overflow/underflow generates an update interrupt or DMA request (if + * enabled) + * @retval None + */ +#define __HAL_TIM_URS_ENABLE(__HANDLE__) \ + ((__HANDLE__)->Instance->CR1|= (TIM_CR1_URS)) + +/** + * @brief Reset the Update Request Source (URS) bit of the TIMx_CR1 register + * @param __HANDLE__: TIM handle. + * @note When the USR bit of the TIMx_CR1 register is reset, any of the + * following events generate an update interrupt or DMA request (if + * enabled): + * – Counter overflow/underflow + * – Setting the UG bit + * – Update generation through the slave mode controller + * @retval None + */ +#define __HAL_TIM_URS_DISABLE(__HANDLE__) \ + ((__HANDLE__)->Instance->CR1&=~(TIM_CR1_URS)) + +/** + * @brief Sets the TIM Capture x input polarity on runtime. + * @param __HANDLE__: TIM handle. + * @param __CHANNEL__: TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param __POLARITY__: Polarity for TIx source + * @arg TIM_INPUTCHANNELPOLARITY_RISING: Rising Edge + * @arg TIM_INPUTCHANNELPOLARITY_FALLING: Falling Edge + * @arg TIM_INPUTCHANNELPOLARITY_BOTHEDGE: Rising and Falling Edge + * @note The polarity TIM_INPUTCHANNELPOLARITY_BOTHEDGE is not authorized for TIM Channel 4. + * @retval None + */ +#define __HAL_TIM_SET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__, __POLARITY__) \ + do{ \ + TIM_RESET_CAPTUREPOLARITY((__HANDLE__), (__CHANNEL__)); \ + TIM_SET_CAPTUREPOLARITY((__HANDLE__), (__CHANNEL__), (__POLARITY__)); \ + }while(0) +/** + * @} + */ + +/* Include TIM HAL Extension module */ +#include "stm32f4xx_hal_tim_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup TIM_Exported_Functions + * @{ + */ + +/** @addtogroup TIM_Exported_Functions_Group1 + * @{ + */ + +/* Time Base functions ********************************************************/ +HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIM_Base_Stop_DMA(TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group2 + * @{ + */ +/* Timer Output Compare functions **********************************************/ +HAL_StatusTypeDef HAL_TIM_OC_Init(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_OC_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_OC_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_OC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_OC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_OC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIM_OC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); + +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group3 + * @{ + */ +/* Timer PWM functions *********************************************************/ +HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_PWM_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIM_PWM_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); + +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group4 + * @{ + */ +/* Timer Input Capture functions ***********************************************/ +HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_IC_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_IC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIM_IC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); + +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group5 + * @{ + */ +/* Timer One Pulse functions ***************************************************/ +HAL_StatusTypeDef HAL_TIM_OnePulse_Init(TIM_HandleTypeDef *htim, uint32_t OnePulseMode); +HAL_StatusTypeDef HAL_TIM_OnePulse_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_OnePulse_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_OnePulse_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +HAL_StatusTypeDef HAL_TIM_OnePulse_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel); + +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +HAL_StatusTypeDef HAL_TIM_OnePulse_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); + +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group6 + * @{ + */ +/* Timer Encoder functions *****************************************************/ +HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim, TIM_Encoder_InitTypeDef* sConfig); +HAL_StatusTypeDef HAL_TIM_Encoder_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef *htim); + /* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_Encoder_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData1, uint32_t *pData2, uint16_t Length); +HAL_StatusTypeDef HAL_TIM_Encoder_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); + +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group7 + * @{ + */ +/* Interrupt Handler functions **********************************************/ +void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim); + +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group8 + * @{ + */ +/* Control functions *********************************************************/ +HAL_StatusTypeDef HAL_TIM_OC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef* sConfig, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef* sConfig, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_IC_InitTypeDef* sConfig, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_OnePulse_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OnePulse_InitTypeDef* sConfig, uint32_t OutputChannel, uint32_t InputChannel); +HAL_StatusTypeDef HAL_TIM_ConfigOCrefClear(TIM_HandleTypeDef *htim, TIM_ClearInputConfigTypeDef * sClearInputConfig, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_ConfigClockSource(TIM_HandleTypeDef *htim, TIM_ClockConfigTypeDef * sClockSourceConfig); +HAL_StatusTypeDef HAL_TIM_ConfigTI1Input(TIM_HandleTypeDef *htim, uint32_t TI1_Selection); +HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchronization(TIM_HandleTypeDef *htim, TIM_SlaveConfigTypeDef * sSlaveConfig); +HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchronization_IT(TIM_HandleTypeDef *htim, TIM_SlaveConfigTypeDef * sSlaveConfig); +HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, uint32_t BurstRequestSrc, \ + uint32_t *BurstBuffer, uint32_t BurstLength); +HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc); +HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, uint32_t BurstRequestSrc, \ + uint32_t *BurstBuffer, uint32_t BurstLength); +HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc); +HAL_StatusTypeDef HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, uint32_t EventSource); +uint32_t HAL_TIM_ReadCapturedValue(TIM_HandleTypeDef *htim, uint32_t Channel); + +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group9 + * @{ + */ +/* Callback in non blocking modes (Interrupt and DMA) *************************/ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_ErrorCallback(TIM_HandleTypeDef *htim); + +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group10 + * @{ + */ +/* Peripheral State functions **************************************************/ +HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_OC_GetState(TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_PWM_GetState(TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_IC_GetState(TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_OnePulse_GetState(TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_Encoder_GetState(TIM_HandleTypeDef *htim); + +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup TIM_Private_Macros TIM Private Macros + * @{ + */ + +/** @defgroup TIM_IS_TIM_Definitions TIM Private macros to check input parameters + * @{ + */ +#define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_COUNTERMODE_UP) || \ + ((MODE) == TIM_COUNTERMODE_DOWN) || \ + ((MODE) == TIM_COUNTERMODE_CENTERALIGNED1) || \ + ((MODE) == TIM_COUNTERMODE_CENTERALIGNED2) || \ + ((MODE) == TIM_COUNTERMODE_CENTERALIGNED3)) + +#define IS_TIM_CLOCKDIVISION_DIV(DIV) (((DIV) == TIM_CLOCKDIVISION_DIV1) || \ + ((DIV) == TIM_CLOCKDIVISION_DIV2) || \ + ((DIV) == TIM_CLOCKDIVISION_DIV4)) + +#define IS_TIM_PWM_MODE(MODE) (((MODE) == TIM_OCMODE_PWM1) || \ + ((MODE) == TIM_OCMODE_PWM2)) + +#define IS_TIM_OC_MODE(MODE) (((MODE) == TIM_OCMODE_TIMING) || \ + ((MODE) == TIM_OCMODE_ACTIVE) || \ + ((MODE) == TIM_OCMODE_INACTIVE) || \ + ((MODE) == TIM_OCMODE_TOGGLE) || \ + ((MODE) == TIM_OCMODE_FORCED_ACTIVE) || \ + ((MODE) == TIM_OCMODE_FORCED_INACTIVE)) + +#define IS_TIM_FAST_STATE(STATE) (((STATE) == TIM_OCFAST_DISABLE) || \ + ((STATE) == TIM_OCFAST_ENABLE)) + +#define IS_TIM_OC_POLARITY(POLARITY) (((POLARITY) == TIM_OCPOLARITY_HIGH) || \ + ((POLARITY) == TIM_OCPOLARITY_LOW)) + +#define IS_TIM_OCN_POLARITY(POLARITY) (((POLARITY) == TIM_OCNPOLARITY_HIGH) || \ + ((POLARITY) == TIM_OCNPOLARITY_LOW)) + +#define IS_TIM_OCIDLE_STATE(STATE) (((STATE) == TIM_OCIDLESTATE_SET) || \ + ((STATE) == TIM_OCIDLESTATE_RESET)) + +#define IS_TIM_OCNIDLE_STATE(STATE) (((STATE) == TIM_OCNIDLESTATE_SET) || \ + ((STATE) == TIM_OCNIDLESTATE_RESET)) + +#define IS_TIM_CHANNELS(CHANNEL) (((CHANNEL) == TIM_CHANNEL_1) || \ + ((CHANNEL) == TIM_CHANNEL_2) || \ + ((CHANNEL) == TIM_CHANNEL_3) || \ + ((CHANNEL) == TIM_CHANNEL_4) || \ + ((CHANNEL) == TIM_CHANNEL_ALL)) + +#define IS_TIM_OPM_CHANNELS(CHANNEL) (((CHANNEL) == TIM_CHANNEL_1) || \ + ((CHANNEL) == TIM_CHANNEL_2)) + +#define IS_TIM_COMPLEMENTARY_CHANNELS(CHANNEL) (((CHANNEL) == TIM_CHANNEL_1) || \ + ((CHANNEL) == TIM_CHANNEL_2) || \ + ((CHANNEL) == TIM_CHANNEL_3)) + +#define IS_TIM_IC_POLARITY(POLARITY) (((POLARITY) == TIM_ICPOLARITY_RISING) || \ + ((POLARITY) == TIM_ICPOLARITY_FALLING) || \ + ((POLARITY) == TIM_ICPOLARITY_BOTHEDGE)) + +#define IS_TIM_IC_SELECTION(SELECTION) (((SELECTION) == TIM_ICSELECTION_DIRECTTI) || \ + ((SELECTION) == TIM_ICSELECTION_INDIRECTTI) || \ + ((SELECTION) == TIM_ICSELECTION_TRC)) + +#define IS_TIM_IC_PRESCALER(PRESCALER) (((PRESCALER) == TIM_ICPSC_DIV1) || \ + ((PRESCALER) == TIM_ICPSC_DIV2) || \ + ((PRESCALER) == TIM_ICPSC_DIV4) || \ + ((PRESCALER) == TIM_ICPSC_DIV8)) + +#define IS_TIM_OPM_MODE(MODE) (((MODE) == TIM_OPMODE_SINGLE) || \ + ((MODE) == TIM_OPMODE_REPETITIVE)) + +#define IS_TIM_DMA_SOURCE(SOURCE) ((((SOURCE) & 0xFFFF80FF) == 0x00000000) && ((SOURCE) != 0x00000000)) + +#define IS_TIM_ENCODER_MODE(MODE) (((MODE) == TIM_ENCODERMODE_TI1) || \ + ((MODE) == TIM_ENCODERMODE_TI2) || \ + ((MODE) == TIM_ENCODERMODE_TI12)) + +#define IS_TIM_EVENT_SOURCE(SOURCE) ((((SOURCE) & 0xFFFFFF00) == 0x00000000) && ((SOURCE) != 0x00000000)) + +#define IS_TIM_CLOCKSOURCE(CLOCK) (((CLOCK) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((CLOCK) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((CLOCK) == TIM_CLOCKSOURCE_ITR0) || \ + ((CLOCK) == TIM_CLOCKSOURCE_ITR1) || \ + ((CLOCK) == TIM_CLOCKSOURCE_ITR2) || \ + ((CLOCK) == TIM_CLOCKSOURCE_ITR3) || \ + ((CLOCK) == TIM_CLOCKSOURCE_TI1ED) || \ + ((CLOCK) == TIM_CLOCKSOURCE_TI1) || \ + ((CLOCK) == TIM_CLOCKSOURCE_TI2) || \ + ((CLOCK) == TIM_CLOCKSOURCE_ETRMODE1)) + +#define IS_TIM_CLOCKPOLARITY(POLARITY) (((POLARITY) == TIM_CLOCKPOLARITY_INVERTED) || \ + ((POLARITY) == TIM_CLOCKPOLARITY_NONINVERTED) || \ + ((POLARITY) == TIM_CLOCKPOLARITY_RISING) || \ + ((POLARITY) == TIM_CLOCKPOLARITY_FALLING) || \ + ((POLARITY) == TIM_CLOCKPOLARITY_BOTHEDGE)) + +#define IS_TIM_CLOCKPRESCALER(PRESCALER) (((PRESCALER) == TIM_CLOCKPRESCALER_DIV1) || \ + ((PRESCALER) == TIM_CLOCKPRESCALER_DIV2) || \ + ((PRESCALER) == TIM_CLOCKPRESCALER_DIV4) || \ + ((PRESCALER) == TIM_CLOCKPRESCALER_DIV8)) + +#define IS_TIM_CLOCKFILTER(ICFILTER) ((ICFILTER) <= 0xF) + +#define IS_TIM_CLEARINPUT_SOURCE(SOURCE) (((SOURCE) == TIM_CLEARINPUTSOURCE_NONE) || \ + ((SOURCE) == TIM_CLEARINPUTSOURCE_ETR)) + +#define IS_TIM_CLEARINPUT_POLARITY(POLARITY) (((POLARITY) == TIM_CLEARINPUTPOLARITY_INVERTED) || \ + ((POLARITY) == TIM_CLEARINPUTPOLARITY_NONINVERTED)) + +#define IS_TIM_CLEARINPUT_PRESCALER(PRESCALER) (((PRESCALER) == TIM_CLEARINPUTPRESCALER_DIV1) || \ + ((PRESCALER) == TIM_CLEARINPUTPRESCALER_DIV2) || \ + ((PRESCALER) == TIM_CLEARINPUTPRESCALER_DIV4) || \ + ((PRESCALER) == TIM_CLEARINPUTPRESCALER_DIV8)) + +#define IS_TIM_CLEARINPUT_FILTER(ICFILTER) ((ICFILTER) <= 0xF) + +#define IS_TIM_OSSR_STATE(STATE) (((STATE) == TIM_OSSR_ENABLE) || \ + ((STATE) == TIM_OSSR_DISABLE)) + +#define IS_TIM_OSSI_STATE(STATE) (((STATE) == TIM_OSSI_ENABLE) || \ + ((STATE) == TIM_OSSI_DISABLE)) + +#define IS_TIM_LOCK_LEVEL(LEVEL) (((LEVEL) == TIM_LOCKLEVEL_OFF) || \ + ((LEVEL) == TIM_LOCKLEVEL_1) || \ + ((LEVEL) == TIM_LOCKLEVEL_2) || \ + ((LEVEL) == TIM_LOCKLEVEL_3)) + +#define IS_TIM_BREAK_STATE(STATE) (((STATE) == TIM_BREAK_ENABLE) || \ + ((STATE) == TIM_BREAK_DISABLE)) + +#define IS_TIM_BREAK_POLARITY(POLARITY) (((POLARITY) == TIM_BREAKPOLARITY_LOW) || \ + ((POLARITY) == TIM_BREAKPOLARITY_HIGH)) + +#define IS_TIM_AUTOMATIC_OUTPUT_STATE(STATE) (((STATE) == TIM_AUTOMATICOUTPUT_ENABLE) || \ + ((STATE) == TIM_AUTOMATICOUTPUT_DISABLE)) + +#define IS_TIM_TRGO_SOURCE(SOURCE) (((SOURCE) == TIM_TRGO_RESET) || \ + ((SOURCE) == TIM_TRGO_ENABLE) || \ + ((SOURCE) == TIM_TRGO_UPDATE) || \ + ((SOURCE) == TIM_TRGO_OC1) || \ + ((SOURCE) == TIM_TRGO_OC1REF) || \ + ((SOURCE) == TIM_TRGO_OC2REF) || \ + ((SOURCE) == TIM_TRGO_OC3REF) || \ + ((SOURCE) == TIM_TRGO_OC4REF)) + +#define IS_TIM_SLAVE_MODE(MODE) (((MODE) == TIM_SLAVEMODE_DISABLE) || \ + ((MODE) == TIM_SLAVEMODE_GATED) || \ + ((MODE) == TIM_SLAVEMODE_RESET) || \ + ((MODE) == TIM_SLAVEMODE_TRIGGER) || \ + ((MODE) == TIM_SLAVEMODE_EXTERNAL1)) + +#define IS_TIM_MSM_STATE(STATE) (((STATE) == TIM_MASTERSLAVEMODE_ENABLE) || \ + ((STATE) == TIM_MASTERSLAVEMODE_DISABLE)) + +#define IS_TIM_TRIGGER_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ + ((SELECTION) == TIM_TS_ITR1) || \ + ((SELECTION) == TIM_TS_ITR2) || \ + ((SELECTION) == TIM_TS_ITR3) || \ + ((SELECTION) == TIM_TS_TI1F_ED) || \ + ((SELECTION) == TIM_TS_TI1FP1) || \ + ((SELECTION) == TIM_TS_TI2FP2) || \ + ((SELECTION) == TIM_TS_ETRF)) + +#define IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(SELECTION) (((SELECTION) == TIM_TS_ITR0) || \ + ((SELECTION) == TIM_TS_ITR1) || \ + ((SELECTION) == TIM_TS_ITR2) || \ + ((SELECTION) == TIM_TS_ITR3) || \ + ((SELECTION) == TIM_TS_NONE)) +#define IS_TIM_TRIGGERPOLARITY(POLARITY) (((POLARITY) == TIM_TRIGGERPOLARITY_INVERTED ) || \ + ((POLARITY) == TIM_TRIGGERPOLARITY_NONINVERTED) || \ + ((POLARITY) == TIM_TRIGGERPOLARITY_RISING ) || \ + ((POLARITY) == TIM_TRIGGERPOLARITY_FALLING ) || \ + ((POLARITY) == TIM_TRIGGERPOLARITY_BOTHEDGE )) + +#define IS_TIM_TRIGGERPRESCALER(PRESCALER) (((PRESCALER) == TIM_TRIGGERPRESCALER_DIV1) || \ + ((PRESCALER) == TIM_TRIGGERPRESCALER_DIV2) || \ + ((PRESCALER) == TIM_TRIGGERPRESCALER_DIV4) || \ + ((PRESCALER) == TIM_TRIGGERPRESCALER_DIV8)) + +#define IS_TIM_TRIGGERFILTER(ICFILTER) ((ICFILTER) <= 0xF) + +#define IS_TIM_TI1SELECTION(TI1SELECTION) (((TI1SELECTION) == TIM_TI1SELECTION_CH1) || \ + ((TI1SELECTION) == TIM_TI1SELECTION_XORCOMBINATION)) + +#define IS_TIM_DMA_BASE(BASE) (((BASE) == TIM_DMABASE_CR1) || \ + ((BASE) == TIM_DMABASE_CR2) || \ + ((BASE) == TIM_DMABASE_SMCR) || \ + ((BASE) == TIM_DMABASE_DIER) || \ + ((BASE) == TIM_DMABASE_SR) || \ + ((BASE) == TIM_DMABASE_EGR) || \ + ((BASE) == TIM_DMABASE_CCMR1) || \ + ((BASE) == TIM_DMABASE_CCMR2) || \ + ((BASE) == TIM_DMABASE_CCER) || \ + ((BASE) == TIM_DMABASE_CNT) || \ + ((BASE) == TIM_DMABASE_PSC) || \ + ((BASE) == TIM_DMABASE_ARR) || \ + ((BASE) == TIM_DMABASE_RCR) || \ + ((BASE) == TIM_DMABASE_CCR1) || \ + ((BASE) == TIM_DMABASE_CCR2) || \ + ((BASE) == TIM_DMABASE_CCR3) || \ + ((BASE) == TIM_DMABASE_CCR4) || \ + ((BASE) == TIM_DMABASE_BDTR) || \ + ((BASE) == TIM_DMABASE_DCR) || \ + ((BASE) == TIM_DMABASE_OR)) + +#define IS_TIM_DMA_LENGTH(LENGTH) (((LENGTH) == TIM_DMABURSTLENGTH_1TRANSFER) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_2TRANSFERS) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_3TRANSFERS) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_4TRANSFERS) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_5TRANSFERS) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_6TRANSFERS) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_7TRANSFERS) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_8TRANSFERS) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_9TRANSFERS) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_10TRANSFERS) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_11TRANSFERS) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_12TRANSFERS) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_13TRANSFERS) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_14TRANSFERS) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_15TRANSFERS) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_16TRANSFERS) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_17TRANSFERS) || \ + ((LENGTH) == TIM_DMABURSTLENGTH_18TRANSFERS)) + +#define IS_TIM_IC_FILTER(ICFILTER) ((ICFILTER) <= 0xF) +/** + * @} + */ + +/** @defgroup TIM_Mask_Definitions TIM Mask Definition + * @{ + */ +/* The counter of a timer instance is disabled only if all the CCx and CCxN + channels have been disabled */ +#define TIM_CCER_CCxE_MASK ((uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E)) +#define TIM_CCER_CCxNE_MASK ((uint32_t)(TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup TIM_Private_Functions TIM Private Functions + * @{ + */ +void TIM_Base_SetConfig(TIM_TypeDef *TIMx, TIM_Base_InitTypeDef *Structure); +void TIM_TI1_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, uint32_t TIM_ICFilter); +void TIM_OC2_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config); +void TIM_DMADelayPulseCplt(DMA_HandleTypeDef *hdma); +void TIM_DMAError(DMA_HandleTypeDef *hdma); +void TIM_DMACaptureCplt(DMA_HandleTypeDef *hdma); +void TIM_CCxChannelCmd(TIM_TypeDef* TIMx, uint32_t Channel, uint32_t ChannelState); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_TIM_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h new file mode 100644 index 0000000..81cf076 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim_ex.h @@ -0,0 +1,325 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_tim_ex.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of TIM HAL Extension module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_TIM_EX_H +#define __STM32F4xx_HAL_TIM_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup TIMEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Types TIM Exported Types + * @{ + */ + +/** + * @brief TIM Hall sensor Configuration Structure definition + */ + +typedef struct +{ + + uint32_t IC1Polarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint32_t IC1Prescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t IC1Filter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + uint32_t Commutation_Delay; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ +} TIM_HallSensor_InitTypeDef; + +/** + * @brief TIM Master configuration Structure definition + */ +typedef struct { + uint32_t MasterOutputTrigger; /*!< Trigger output (TRGO) selection. + This parameter can be a value of @ref TIM_Master_Mode_Selection */ + uint32_t MasterSlaveMode; /*!< Master/slave mode selection. + This parameter can be a value of @ref TIM_Master_Slave_Mode */ +}TIM_MasterConfigTypeDef; + +/** + * @brief TIM Break and Dead time configuration Structure definition + */ +typedef struct +{ + uint32_t OffStateRunMode; /*!< TIM off state in run mode. + This parameter can be a value of @ref TIM_OSSR_Off_State_Selection_for_Run_mode_state */ + uint32_t OffStateIDLEMode; /*!< TIM off state in IDLE mode. + This parameter can be a value of @ref TIM_OSSI_Off_State_Selection_for_Idle_mode_state */ + uint32_t LockLevel; /*!< TIM Lock level. + This parameter can be a value of @ref TIM_Lock_level */ + uint32_t DeadTime; /*!< TIM dead Time. + This parameter can be a number between Min_Data = 0x00 and Max_Data = 0xFF */ + uint32_t BreakState; /*!< TIM Break State. + This parameter can be a value of @ref TIM_Break_Input_enable_disable */ + uint32_t BreakPolarity; /*!< TIM Break input polarity. + This parameter can be a value of @ref TIM_Break_Polarity */ + uint32_t AutomaticOutput; /*!< TIM Automatic Output Enable state. + This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */ +}TIM_BreakDeadTimeConfigTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Constants TIM Exported Constants + * @{ + */ + +/** @defgroup TIMEx_Remap TIM Remap + * @{ + */ +#define TIM_TIM2_TIM8_TRGO (0x00000000) +#define TIM_TIM2_ETH_PTP (0x00000400) +#define TIM_TIM2_USBFS_SOF (0x00000800) +#define TIM_TIM2_USBHS_SOF (0x00000C00) +#define TIM_TIM5_GPIO (0x00000000) +#define TIM_TIM5_LSI (0x00000040) +#define TIM_TIM5_LSE (0x00000080) +#define TIM_TIM5_RTC (0x000000C0) +#define TIM_TIM11_GPIO (0x00000000) +#define TIM_TIM11_HSE (0x00000002) + +#if defined (STM32F446xx) +#define TIM_TIM11_SPDIFRX (0x00000001) +#endif /* STM32F446xx */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup TIMEx_Exported_Functions + * @{ + */ + +/** @addtogroup TIMEx_Exported_Functions_Group1 + * @{ + */ +/* Timer Hall Sensor functions **********************************************/ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef* htim, TIM_HallSensor_InitTypeDef* sConfig); +HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef* htim); + +void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef* htim); +void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef* htim); + + /* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef* htim); +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef* htim); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef* htim); +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef* htim); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef* htim, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef* htim); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group2 + * @{ + */ +/* Timer Complementary Output Compare functions *****************************/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef* htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef* htim, uint32_t Channel); + +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef* htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef* htim, uint32_t Channel); + +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef* htim, uint32_t Channel, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef* htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group3 + * @{ + */ +/* Timer Complementary PWM functions ****************************************/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef* htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef* htim, uint32_t Channel); + +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef* htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef* htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef* htim, uint32_t Channel, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef* htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group4 + * @{ + */ +/* Timer Complementary One Pulse functions **********************************/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef* htim, uint32_t OutputChannel); +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef* htim, uint32_t OutputChannel); + +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef* htim, uint32_t OutputChannel); +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef* htim, uint32_t OutputChannel); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group5 + * @{ + */ +/* Extension Control functions ************************************************/ +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent(TIM_HandleTypeDef* htim, uint32_t InputTrigger, uint32_t CommutationSource); +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent_IT(TIM_HandleTypeDef* htim, uint32_t InputTrigger, uint32_t CommutationSource); +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent_DMA(TIM_HandleTypeDef* htim, uint32_t InputTrigger, uint32_t CommutationSource); +HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef* htim, TIM_MasterConfigTypeDef * sMasterConfig); +HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef* htim, TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig); +HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef* htim, uint32_t Remap); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group6 + * @{ + */ +/* Extension Callback *********************************************************/ +void HAL_TIMEx_CommutationCallback(TIM_HandleTypeDef* htim); +void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef* htim); +void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group7 + * @{ + */ +/* Extension Peripheral State functions **************************************/ +HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(TIM_HandleTypeDef* htim); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup TIMEx_Private_Macros TIM Private Macros + * @{ + */ +#if defined (STM32F446xx) +#define IS_TIM_REMAP(TIM_REMAP) (((TIM_REMAP) == TIM_TIM2_TIM8_TRGO)||\ + ((TIM_REMAP) == TIM_TIM2_ETH_PTP)||\ + ((TIM_REMAP) == TIM_TIM2_USBFS_SOF)||\ + ((TIM_REMAP) == TIM_TIM2_USBHS_SOF)||\ + ((TIM_REMAP) == TIM_TIM5_GPIO)||\ + ((TIM_REMAP) == TIM_TIM5_LSI)||\ + ((TIM_REMAP) == TIM_TIM5_LSE)||\ + ((TIM_REMAP) == TIM_TIM5_RTC)||\ + ((TIM_REMAP) == TIM_TIM11_GPIO)||\ + ((TIM_REMAP) == TIM_TIM11_SPDIFRX)||\ + ((TIM_REMAP) == TIM_TIM11_HSE)) +#else +#define IS_TIM_REMAP(TIM_REMAP) (((TIM_REMAP) == TIM_TIM2_TIM8_TRGO)||\ + ((TIM_REMAP) == TIM_TIM2_ETH_PTP)||\ + ((TIM_REMAP) == TIM_TIM2_USBFS_SOF)||\ + ((TIM_REMAP) == TIM_TIM2_USBHS_SOF)||\ + ((TIM_REMAP) == TIM_TIM5_GPIO)||\ + ((TIM_REMAP) == TIM_TIM5_LSI)||\ + ((TIM_REMAP) == TIM_TIM5_LSE)||\ + ((TIM_REMAP) == TIM_TIM5_RTC)||\ + ((TIM_REMAP) == TIM_TIM11_GPIO)||\ + ((TIM_REMAP) == TIM_TIM11_HSE)) +#endif /* STM32F446xx */ + + +#define IS_TIM_DEADTIME(DEADTIME) ((DEADTIME) <= 0xFF) +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup TIMEx_Private_Functions TIM Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_TIM_EX_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h new file mode 100644 index 0000000..f3f8c0a --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h @@ -0,0 +1,722 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_uart.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of UART HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_UART_H +#define __STM32F4xx_HAL_UART_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup UART + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup UART_Exported_Types UART Exported Types + * @{ + */ + +/** + * @brief UART Init Structure definition + */ +typedef struct +{ + uint32_t BaudRate; /*!< This member configures the UART communication baud rate. + The baud rate is computed using the following formula: + - IntegerDivider = ((PCLKx) / (8 * (OVR8+1) * (huart->Init.BaudRate))) + - FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 8 * (OVR8+1)) + 0.5 + Where OVR8 is the "oversampling by 8 mode" configuration bit in the CR1 register. */ + + uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref UART_Word_Length */ + + uint32_t StopBits; /*!< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref UART_Stop_Bits */ + + uint32_t Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref UART_Parity + @note When parity is enabled, the computed parity is inserted + at the MSB position of the transmitted data (9th bit when + the word length is set to 9 data bits; 8th bit when the + word length is set to 8 data bits). */ + + uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. + This parameter can be a value of @ref UART_Mode */ + + uint32_t HwFlowCtl; /*!< Specifies whether the hardware flow control mode is enabled + or disabled. + This parameter can be a value of @ref UART_Hardware_Flow_Control */ + + uint32_t OverSampling; /*!< Specifies whether the Over sampling 8 is enabled or disabled, to achieve higher speed (up to fPCLK/8). + This parameter can be a value of @ref UART_Over_Sampling */ +}UART_InitTypeDef; + +/** + * @brief HAL UART State structures definition + */ +typedef enum +{ + HAL_UART_STATE_RESET = 0x00, /*!< Peripheral is not yet Initialized */ + HAL_UART_STATE_READY = 0x01, /*!< Peripheral Initialized and ready for use */ + HAL_UART_STATE_BUSY = 0x02, /*!< an internal process is ongoing */ + HAL_UART_STATE_BUSY_TX = 0x12, /*!< Data Transmission process is ongoing */ + HAL_UART_STATE_BUSY_RX = 0x22, /*!< Data Reception process is ongoing */ + HAL_UART_STATE_BUSY_TX_RX = 0x32, /*!< Data Transmission and Reception process is ongoing */ + HAL_UART_STATE_TIMEOUT = 0x03, /*!< Timeout state */ + HAL_UART_STATE_ERROR = 0x04 /*!< Error */ +}HAL_UART_StateTypeDef; + +/** + * @brief UART handle Structure definition + */ +typedef struct +{ + USART_TypeDef *Instance; /*!< UART registers base address */ + + UART_InitTypeDef Init; /*!< UART communication parameters */ + + uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */ + + uint16_t TxXferSize; /*!< UART Tx Transfer size */ + + uint16_t TxXferCount; /*!< UART Tx Transfer Counter */ + + uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */ + + uint16_t RxXferSize; /*!< UART Rx Transfer size */ + + uint16_t RxXferCount; /*!< UART Rx Transfer Counter */ + + DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */ + + HAL_LockTypeDef Lock; /*!< Locking object */ + + __IO HAL_UART_StateTypeDef State; /*!< UART communication state */ + + __IO uint32_t ErrorCode; /*!< UART Error code */ + +}UART_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup UART_Exported_Constants UART Exported constants + * @{ + */ + +/** @defgroup UART_Error_Code UART Error Code + * @brief UART Error Code + * @{ + */ +#define HAL_UART_ERROR_NONE ((uint32_t)0x00000000) /*!< No error */ +#define HAL_UART_ERROR_PE ((uint32_t)0x00000001) /*!< Parity error */ +#define HAL_UART_ERROR_NE ((uint32_t)0x00000002) /*!< Noise error */ +#define HAL_UART_ERROR_FE ((uint32_t)0x00000004) /*!< Frame error */ +#define HAL_UART_ERROR_ORE ((uint32_t)0x00000008) /*!< Overrun error */ +#define HAL_UART_ERROR_DMA ((uint32_t)0x00000010) /*!< DMA transfer error */ +/** + * @} + */ + +/** @defgroup UART_Word_Length UART Word Length + * @{ + */ +#define UART_WORDLENGTH_8B ((uint32_t)0x00000000) +#define UART_WORDLENGTH_9B ((uint32_t)USART_CR1_M) +/** + * @} + */ + +/** @defgroup UART_Stop_Bits UART Number of Stop Bits + * @{ + */ +#define UART_STOPBITS_1 ((uint32_t)0x00000000) +#define UART_STOPBITS_2 ((uint32_t)USART_CR2_STOP_1) +/** + * @} + */ + +/** @defgroup UART_Parity UART Parity + * @{ + */ +#define UART_PARITY_NONE ((uint32_t)0x00000000) +#define UART_PARITY_EVEN ((uint32_t)USART_CR1_PCE) +#define UART_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS)) +/** + * @} + */ + +/** @defgroup UART_Hardware_Flow_Control UART Hardware Flow Control + * @{ + */ +#define UART_HWCONTROL_NONE ((uint32_t)0x00000000) +#define UART_HWCONTROL_RTS ((uint32_t)USART_CR3_RTSE) +#define UART_HWCONTROL_CTS ((uint32_t)USART_CR3_CTSE) +#define UART_HWCONTROL_RTS_CTS ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE)) +/** + * @} + */ + +/** @defgroup UART_Mode UART Transfer Mode + * @{ + */ +#define UART_MODE_RX ((uint32_t)USART_CR1_RE) +#define UART_MODE_TX ((uint32_t)USART_CR1_TE) +#define UART_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE)) +/** + * @} + */ + + /** @defgroup UART_State UART State + * @{ + */ +#define UART_STATE_DISABLE ((uint32_t)0x00000000) +#define UART_STATE_ENABLE ((uint32_t)USART_CR1_UE) +/** + * @} + */ + +/** @defgroup UART_Over_Sampling UART Over Sampling + * @{ + */ +#define UART_OVERSAMPLING_16 ((uint32_t)0x00000000) +#define UART_OVERSAMPLING_8 ((uint32_t)USART_CR1_OVER8) +/** + * @} + */ + +/** @defgroup UART_LIN_Break_Detection_Length UART LIN Break Detection Length + * @{ + */ +#define UART_LINBREAKDETECTLENGTH_10B ((uint32_t)0x00000000) +#define UART_LINBREAKDETECTLENGTH_11B ((uint32_t)0x00000020) +/** + * @} + */ + +/** @defgroup UART_WakeUp_functions UART Wakeup Functions + * @{ + */ +#define UART_WAKEUPMETHOD_IDLELINE ((uint32_t)0x00000000) +#define UART_WAKEUPMETHOD_ADDRESSMARK ((uint32_t)0x00000800) +/** + * @} + */ + +/** @defgroup UART_Flags UART FLags + * Elements values convention: 0xXXXX + * - 0xXXXX : Flag mask in the SR register + * @{ + */ +#define UART_FLAG_CTS ((uint32_t)USART_SR_CTS) +#define UART_FLAG_LBD ((uint32_t)USART_SR_LBD) +#define UART_FLAG_TXE ((uint32_t)USART_SR_TXE) +#define UART_FLAG_TC ((uint32_t)USART_SR_TC) +#define UART_FLAG_RXNE ((uint32_t)USART_SR_RXNE) +#define UART_FLAG_IDLE ((uint32_t)USART_SR_IDLE) +#define UART_FLAG_ORE ((uint32_t)USART_SR_ORE) +#define UART_FLAG_NE ((uint32_t)USART_SR_NE) +#define UART_FLAG_FE ((uint32_t)USART_SR_FE) +#define UART_FLAG_PE ((uint32_t)USART_SR_PE) +/** + * @} + */ + +/** @defgroup UART_Interrupt_definition UART Interrupt Definitions + * Elements values convention: 0xY000XXXX + * - XXXX : Interrupt mask (16 bits) in the Y register + * - Y : Interrupt source register (2bits) + * - 0001: CR1 register + * - 0010: CR2 register + * - 0011: CR3 register + * + * @{ + */ + +#define UART_IT_PE ((uint32_t)(UART_CR1_REG_INDEX << 28 | USART_CR1_PEIE)) +#define UART_IT_TXE ((uint32_t)(UART_CR1_REG_INDEX << 28 | USART_CR1_TXEIE)) +#define UART_IT_TC ((uint32_t)(UART_CR1_REG_INDEX << 28 | USART_CR1_TCIE)) +#define UART_IT_RXNE ((uint32_t)(UART_CR1_REG_INDEX << 28 | USART_CR1_RXNEIE)) +#define UART_IT_IDLE ((uint32_t)(UART_CR1_REG_INDEX << 28 | USART_CR1_IDLEIE)) + +#define UART_IT_LBD ((uint32_t)(UART_CR2_REG_INDEX << 28 | USART_CR2_LBDIE)) + +#define UART_IT_CTS ((uint32_t)(UART_CR3_REG_INDEX << 28 | USART_CR3_CTSIE)) +#define UART_IT_ERR ((uint32_t)(UART_CR3_REG_INDEX << 28 | USART_CR3_EIE)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup UART_Exported_Macros UART Exported Macros + * @{ + */ + +/** @brief Reset UART handle state + * @param __HANDLE__: specifies the UART Handle. + * This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_UART_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_UART_STATE_RESET) + +/** @brief Flushes the UART DR register + * @param __HANDLE__: specifies the UART Handle. + */ +#define __HAL_UART_FLUSH_DRREGISTER(__HANDLE__) ((__HANDLE__)->Instance->DR) + +/** @brief Checks whether the specified UART flag is set or not. + * @param __HANDLE__: specifies the UART Handle. + * This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg UART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5) + * @arg UART_FLAG_LBD: LIN Break detection flag + * @arg UART_FLAG_TXE: Transmit data register empty flag + * @arg UART_FLAG_TC: Transmission Complete flag + * @arg UART_FLAG_RXNE: Receive data register not empty flag + * @arg UART_FLAG_IDLE: Idle Line detection flag + * @arg UART_FLAG_ORE: Overrun Error flag + * @arg UART_FLAG_NE: Noise Error flag + * @arg UART_FLAG_FE: Framing Error flag + * @arg UART_FLAG_PE: Parity Error flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ + +#define __HAL_UART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__)) + +/** @brief Clears the specified UART pending flag. + * @param __HANDLE__: specifies the UART Handle. + * This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @param __FLAG__: specifies the flag to check. + * This parameter can be any combination of the following values: + * @arg UART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5). + * @arg UART_FLAG_LBD: LIN Break detection flag. + * @arg UART_FLAG_TC: Transmission Complete flag. + * @arg UART_FLAG_RXNE: Receive data register not empty flag. + * + * @note PE (Parity error), FE (Framing error), NE (Noise error), ORE (Overrun + * error) and IDLE (Idle line detected) flags are cleared by software + * sequence: a read operation to USART_SR register followed by a read + * operation to USART_DR register. + * @note RXNE flag can be also cleared by a read to the USART_DR register. + * @note TC flag can be also cleared by software sequence: a read operation to + * USART_SR register followed by a write operation to USART_DR register. + * @note TXE flag is cleared only by a write to the USART_DR register. + * + * @retval None + */ +#define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__)) + +/** @brief Clear the UART PE pending flag. + * @param __HANDLE__: specifies the UART Handle. + * This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_UART_CLEAR_PEFLAG(__HANDLE__) \ + do{ \ + __IO uint32_t tmpreg; \ + tmpreg = (__HANDLE__)->Instance->SR; \ + tmpreg = (__HANDLE__)->Instance->DR; \ + UNUSED(tmpreg); \ + } while(0) + +/** @brief Clear the UART FE pending flag. + * @param __HANDLE__: specifies the UART Handle. + * This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_UART_CLEAR_FEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__) + +/** @brief Clear the UART NE pending flag. + * @param __HANDLE__: specifies the UART Handle. + * This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_UART_CLEAR_NEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__) + +/** @brief Clear the UART ORE pending flag. + * @param __HANDLE__: specifies the UART Handle. + * This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_UART_CLEAR_OREFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__) + +/** @brief Clear the UART IDLE pending flag. + * @param __HANDLE__: specifies the UART Handle. + * This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @retval None + */ +#define __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__) + +/** @brief Enable the specified UART interrupt. + * @param __HANDLE__: specifies the UART Handle. + * This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @param __INTERRUPT__: specifies the UART interrupt source to enable. + * This parameter can be one of the following values: + * @arg UART_IT_CTS: CTS change interrupt + * @arg UART_IT_LBD: LIN Break detection interrupt + * @arg UART_IT_TXE: Transmit Data Register empty interrupt + * @arg UART_IT_TC: Transmission complete interrupt + * @arg UART_IT_RXNE: Receive Data register not empty interrupt + * @arg UART_IT_IDLE: Idle line detection interrupt + * @arg UART_IT_PE: Parity Error interrupt + * @arg UART_IT_ERR: Error interrupt(Frame error, noise error, overrun error) + * @retval None + */ +#define UART_IT_MASK ((uint32_t)0x0000FFFF) +#define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28) == 1)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & UART_IT_MASK)): \ + (((__INTERRUPT__) >> 28) == 2)? ((__HANDLE__)->Instance->CR2 |= ((__INTERRUPT__) & UART_IT_MASK)): \ + ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & UART_IT_MASK))) +/** @brief Disable the specified UART interrupt. + * @param __HANDLE__: specifies the UART Handle. + * This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @param __INTERRUPT__: specifies the UART interrupt source to disable. + * This parameter can be one of the following values: + * @arg UART_IT_CTS: CTS change interrupt + * @arg UART_IT_LBD: LIN Break detection interrupt + * @arg UART_IT_TXE: Transmit Data Register empty interrupt + * @arg UART_IT_TC: Transmission complete interrupt + * @arg UART_IT_RXNE: Receive Data register not empty interrupt + * @arg UART_IT_IDLE: Idle line detection interrupt + * @arg UART_IT_PE: Parity Error interrupt + * @arg UART_IT_ERR: Error interrupt(Frame error, noise error, overrun error) + * @retval None + */ +#define __HAL_UART_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28) == 1)? ((__HANDLE__)->Instance->CR1 &= ~((__INTERRUPT__) & UART_IT_MASK)): \ + (((__INTERRUPT__) >> 28) == 2)? ((__HANDLE__)->Instance->CR2 &= ~((__INTERRUPT__) & UART_IT_MASK)): \ + ((__HANDLE__)->Instance->CR3 &= ~ ((__INTERRUPT__) & UART_IT_MASK))) + +/** @brief Checks whether the specified UART interrupt has occurred or not. + * @param __HANDLE__: specifies the UART Handle. + * This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or + * UART peripheral. + * @param __IT__: specifies the UART interrupt source to check. + * This parameter can be one of the following values: + * @arg UART_IT_CTS: CTS change interrupt (not available for UART4 and UART5) + * @arg UART_IT_LBD: LIN Break detection interrupt + * @arg UART_IT_TXE: Transmit Data Register empty interrupt + * @arg UART_IT_TC: Transmission complete interrupt + * @arg UART_IT_RXNE: Receive Data register not empty interrupt + * @arg UART_IT_IDLE: Idle line detection interrupt + * @arg USART_IT_ERR: Error interrupt + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_UART_GET_IT_SOURCE(__HANDLE__, __IT__) (((((__IT__) >> 28) == 1)? (__HANDLE__)->Instance->CR1:(((((uint32_t)(__IT__)) >> 28) == 2)? \ + (__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & (((uint32_t)(__IT__)) & UART_IT_MASK)) + +/** @brief Enable CTS flow control + * This macro allows to enable CTS hardware flow control for a given UART instance, + * without need to call HAL_UART_Init() function. + * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. + * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need + * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : + * - UART instance should have already been initialised (through call of HAL_UART_Init() ) + * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__)) + * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)). + * @param __HANDLE__: specifies the UART Handle. + * The Handle Instance can be USART1, USART2 or LPUART. + * @retval None + */ +#define __HAL_UART_HWCONTROL_CTS_ENABLE(__HANDLE__) \ + do{ \ + SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \ + (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_CTSE; \ + } while(0) + +/** @brief Disable CTS flow control + * This macro allows to disable CTS hardware flow control for a given UART instance, + * without need to call HAL_UART_Init() function. + * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. + * @note As macro is expected to be used for modifying CTS Hw flow control feature activation, without need + * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : + * - UART instance should have already been initialised (through call of HAL_UART_Init() ) + * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__)) + * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)). + * @param __HANDLE__: specifies the UART Handle. + * The Handle Instance can be USART1, USART2 or LPUART. + * @retval None + */ +#define __HAL_UART_HWCONTROL_CTS_DISABLE(__HANDLE__) \ + do{ \ + CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_CTSE); \ + (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_CTSE); \ + } while(0) + +/** @brief Enable RTS flow control + * This macro allows to enable RTS hardware flow control for a given UART instance, + * without need to call HAL_UART_Init() function. + * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. + * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need + * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : + * - UART instance should have already been initialised (through call of HAL_UART_Init() ) + * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__)) + * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)). + * @param __HANDLE__: specifies the UART Handle. + * The Handle Instance can be USART1, USART2 or LPUART. + * @retval None + */ +#define __HAL_UART_HWCONTROL_RTS_ENABLE(__HANDLE__) \ + do{ \ + SET_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE); \ + (__HANDLE__)->Init.HwFlowCtl |= USART_CR3_RTSE; \ + } while(0) + +/** @brief Disable RTS flow control + * This macro allows to disable RTS hardware flow control for a given UART instance, + * without need to call HAL_UART_Init() function. + * As involving direct access to UART registers, usage of this macro should be fully endorsed by user. + * @note As macro is expected to be used for modifying RTS Hw flow control feature activation, without need + * for USART instance Deinit/Init, following conditions for macro call should be fulfilled : + * - UART instance should have already been initialised (through call of HAL_UART_Init() ) + * - macro could only be called when corresponding UART instance is disabled (i.e __HAL_UART_DISABLE(__HANDLE__)) + * and should be followed by an Enable macro (i.e __HAL_UART_ENABLE(__HANDLE__)). + * @param __HANDLE__: specifies the UART Handle. + * The Handle Instance can be USART1, USART2 or LPUART. + * @retval None + */ +#define __HAL_UART_HWCONTROL_RTS_DISABLE(__HANDLE__) \ + do{ \ + CLEAR_BIT((__HANDLE__)->Instance->CR3, USART_CR3_RTSE);\ + (__HANDLE__)->Init.HwFlowCtl &= ~(USART_CR3_RTSE); \ + } while(0) + +/** @brief macros to enables the UART's one bit sample method + * @param __HANDLE__: specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT) + +/** @brief macros to disables the UART's one bit sample method + * @param __HANDLE__: specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_ONEBIT)) + +/** @brief Enable UART + * @param __HANDLE__: specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE) + +/** @brief Disable UART + * @param __HANDLE__: specifies the UART Handle. + * @retval None + */ +#define __HAL_UART_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE) +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup UART_Exported_Functions + * @{ + */ + +/** @addtogroup UART_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions **********************************/ +HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength); +HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod); +HAL_StatusTypeDef HAL_UART_DeInit (UART_HandleTypeDef *huart); +void HAL_UART_MspInit(UART_HandleTypeDef *huart); +void HAL_UART_MspDeInit(UART_HandleTypeDef *huart); +/** + * @} + */ + +/** @addtogroup UART_Exported_Functions_Group2 + * @{ + */ +/* IO operation functions *******************************************************/ +HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart); +void HAL_UART_IRQHandler(UART_HandleTypeDef *huart); +void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); +void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart); +void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); +void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart); +void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart); +/** + * @} + */ + +/** @addtogroup UART_Exported_Functions_Group3 + * @{ + */ +/* Peripheral Control functions ************************************************/ +HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart); +HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart); +/** + * @} + */ + +/** @addtogroup UART_Exported_Functions_Group4 + * @{ + */ +/* Peripheral State functions **************************************************/ +HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart); +uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup UART_Private_Constants UART Private Constants + * @{ + */ +/** @brief UART interruptions flag mask + * + */ +#define UART_CR1_REG_INDEX 1 +#define UART_CR2_REG_INDEX 2 +#define UART_CR3_REG_INDEX 3 +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup UART_Private_Macros UART Private Macros + * @{ + */ +#define IS_UART_WORD_LENGTH(LENGTH) (((LENGTH) == UART_WORDLENGTH_8B) || \ + ((LENGTH) == UART_WORDLENGTH_9B)) +#define IS_UART_LIN_WORD_LENGTH(LENGTH) (((LENGTH) == UART_WORDLENGTH_8B)) +#define IS_UART_STOPBITS(STOPBITS) (((STOPBITS) == UART_STOPBITS_1) || \ + ((STOPBITS) == UART_STOPBITS_2)) +#define IS_UART_PARITY(PARITY) (((PARITY) == UART_PARITY_NONE) || \ + ((PARITY) == UART_PARITY_EVEN) || \ + ((PARITY) == UART_PARITY_ODD)) +#define IS_UART_HARDWARE_FLOW_CONTROL(CONTROL)\ + (((CONTROL) == UART_HWCONTROL_NONE) || \ + ((CONTROL) == UART_HWCONTROL_RTS) || \ + ((CONTROL) == UART_HWCONTROL_CTS) || \ + ((CONTROL) == UART_HWCONTROL_RTS_CTS)) +#define IS_UART_MODE(MODE) ((((MODE) & (uint32_t)0x0000FFF3) == 0x00) && ((MODE) != (uint32_t)0x000000)) +#define IS_UART_STATE(STATE) (((STATE) == UART_STATE_DISABLE) || \ + ((STATE) == UART_STATE_ENABLE)) +#define IS_UART_OVERSAMPLING(SAMPLING) (((SAMPLING) == UART_OVERSAMPLING_16) || \ + ((SAMPLING) == UART_OVERSAMPLING_8)) +#define IS_UART_LIN_OVERSAMPLING(SAMPLING) (((SAMPLING) == UART_OVERSAMPLING_16)) +#define IS_UART_LIN_BREAK_DETECT_LENGTH(LENGTH) (((LENGTH) == UART_LINBREAKDETECTLENGTH_10B) || \ + ((LENGTH) == UART_LINBREAKDETECTLENGTH_11B)) +#define IS_UART_WAKEUPMETHOD(WAKEUP) (((WAKEUP) == UART_WAKEUPMETHOD_IDLELINE) || \ + ((WAKEUP) == UART_WAKEUPMETHOD_ADDRESSMARK)) +#define IS_UART_BAUDRATE(BAUDRATE) ((BAUDRATE) < 10500001) +#define IS_UART_ADDRESS(ADDRESS) ((ADDRESS) <= 0xF) + +#define UART_DIV_SAMPLING16(_PCLK_, _BAUD_) (((_PCLK_)*25)/(4*(_BAUD_))) +#define UART_DIVMANT_SAMPLING16(_PCLK_, _BAUD_) (UART_DIV_SAMPLING16((_PCLK_), (_BAUD_))/100) +#define UART_DIVFRAQ_SAMPLING16(_PCLK_, _BAUD_) (((UART_DIV_SAMPLING16((_PCLK_), (_BAUD_)) - (UART_DIVMANT_SAMPLING16((_PCLK_), (_BAUD_)) * 100)) * 16 + 50) / 100) +#define UART_BRR_SAMPLING16(_PCLK_, _BAUD_) ((UART_DIVMANT_SAMPLING16((_PCLK_), (_BAUD_)) << 4)|(UART_DIVFRAQ_SAMPLING16((_PCLK_), (_BAUD_)) & 0x0F)) + +#define UART_DIV_SAMPLING8(_PCLK_, _BAUD_) (((_PCLK_)*25)/(2*(_BAUD_))) +#define UART_DIVMANT_SAMPLING8(_PCLK_, _BAUD_) (UART_DIV_SAMPLING8((_PCLK_), (_BAUD_))/100) +#define UART_DIVFRAQ_SAMPLING8(_PCLK_, _BAUD_) (((UART_DIV_SAMPLING8((_PCLK_), (_BAUD_)) - (UART_DIVMANT_SAMPLING8((_PCLK_), (_BAUD_)) * 100)) * 16 + 50) / 100) +#define UART_BRR_SAMPLING8(_PCLK_, _BAUD_) ((UART_DIVMANT_SAMPLING8((_PCLK_), (_BAUD_)) << 4)|(UART_DIVFRAQ_SAMPLING8((_PCLK_), (_BAUD_)) & 0x0F)) + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup UART_Private_Functions UART Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_UART_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_usart.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_usart.h new file mode 100644 index 0000000..f6a135a --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_usart.h @@ -0,0 +1,588 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_usart.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of USART HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_USART_H +#define __STM32F4xx_HAL_USART_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup USART + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup USART_Exported_Types USART Exported Types + * @{ + */ + +/** + * @brief USART Init Structure definition + */ +typedef struct +{ + uint32_t BaudRate; /*!< This member configures the Usart communication baud rate. + The baud rate is computed using the following formula: + - IntegerDivider = ((PCLKx) / (8 * (husart->Init.BaudRate))) + - FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 8) + 0.5 */ + + uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame. + This parameter can be a value of @ref USART_Word_Length */ + + uint32_t StopBits; /*!< Specifies the number of stop bits transmitted. + This parameter can be a value of @ref USART_Stop_Bits */ + + uint32_t Parity; /*!< Specifies the parity mode. + This parameter can be a value of @ref USART_Parity + @note When parity is enabled, the computed parity is inserted + at the MSB position of the transmitted data (9th bit when + the word length is set to 9 data bits; 8th bit when the + word length is set to 8 data bits). */ + + uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled. + This parameter can be a value of @ref USART_Mode */ + + uint32_t CLKPolarity; /*!< Specifies the steady state of the serial clock. + This parameter can be a value of @ref USART_Clock_Polarity */ + + uint32_t CLKPhase; /*!< Specifies the clock transition on which the bit capture is made. + This parameter can be a value of @ref USART_Clock_Phase */ + + uint32_t CLKLastBit; /*!< Specifies whether the clock pulse corresponding to the last transmitted + data bit (MSB) has to be output on the SCLK pin in synchronous mode. + This parameter can be a value of @ref USART_Last_Bit */ +}USART_InitTypeDef; + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_USART_STATE_RESET = 0x00, /*!< Peripheral is not yet Initialized */ + HAL_USART_STATE_READY = 0x01, /*!< Peripheral Initialized and ready for use */ + HAL_USART_STATE_BUSY = 0x02, /*!< an internal process is ongoing */ + HAL_USART_STATE_BUSY_TX = 0x12, /*!< Data Transmission process is ongoing */ + HAL_USART_STATE_BUSY_RX = 0x22, /*!< Data Reception process is ongoing */ + HAL_USART_STATE_BUSY_TX_RX = 0x32, /*!< Data Transmission Reception process is ongoing */ + HAL_USART_STATE_TIMEOUT = 0x03, /*!< Timeout state */ + HAL_USART_STATE_ERROR = 0x04 /*!< Error */ +}HAL_USART_StateTypeDef; + +/** + * @brief USART handle Structure definition + */ +typedef struct +{ + USART_TypeDef *Instance; /* USART registers base address */ + + USART_InitTypeDef Init; /* Usart communication parameters */ + + uint8_t *pTxBuffPtr; /* Pointer to Usart Tx transfer Buffer */ + + uint16_t TxXferSize; /* Usart Tx Transfer size */ + + __IO uint16_t TxXferCount; /* Usart Tx Transfer Counter */ + + uint8_t *pRxBuffPtr; /* Pointer to Usart Rx transfer Buffer */ + + uint16_t RxXferSize; /* Usart Rx Transfer size */ + + __IO uint16_t RxXferCount; /* Usart Rx Transfer Counter */ + + DMA_HandleTypeDef *hdmatx; /* Usart Tx DMA Handle parameters */ + + DMA_HandleTypeDef *hdmarx; /* Usart Rx DMA Handle parameters */ + + HAL_LockTypeDef Lock; /* Locking object */ + + __IO HAL_USART_StateTypeDef State; /* Usart communication state */ + + __IO uint32_t ErrorCode; /* USART Error code */ + +}USART_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup USART_Exported_Constants USART Exported Constants + * @{ + */ + +/** @defgroup USART_Error_Code USART Error Code + * @brief USART Error Code + * @{ + */ +#define HAL_USART_ERROR_NONE ((uint32_t)0x00000000) /*!< No error */ +#define HAL_USART_ERROR_PE ((uint32_t)0x00000001) /*!< Parity error */ +#define HAL_USART_ERROR_NE ((uint32_t)0x00000002) /*!< Noise error */ +#define HAL_USART_ERROR_FE ((uint32_t)0x00000004) /*!< Frame error */ +#define HAL_USART_ERROR_ORE ((uint32_t)0x00000008) /*!< Overrun error */ +#define HAL_USART_ERROR_DMA ((uint32_t)0x00000010) /*!< DMA transfer error */ +/** + * @} + */ + +/** @defgroup USART_Word_Length USART Word Length + * @{ + */ +#define USART_WORDLENGTH_8B ((uint32_t)0x00000000) +#define USART_WORDLENGTH_9B ((uint32_t)USART_CR1_M) +/** + * @} + */ + +/** @defgroup USART_Stop_Bits USART Number of Stop Bits + * @{ + */ +#define USART_STOPBITS_1 ((uint32_t)0x00000000) +#define USART_STOPBITS_0_5 ((uint32_t)USART_CR2_STOP_0) +#define USART_STOPBITS_2 ((uint32_t)USART_CR2_STOP_1) +#define USART_STOPBITS_1_5 ((uint32_t)(USART_CR2_STOP_0 | USART_CR2_STOP_1)) +/** + * @} + */ + +/** @defgroup USART_Parity USART Parity + * @{ + */ +#define USART_PARITY_NONE ((uint32_t)0x00000000) +#define USART_PARITY_EVEN ((uint32_t)USART_CR1_PCE) +#define USART_PARITY_ODD ((uint32_t)(USART_CR1_PCE | USART_CR1_PS)) +/** + * @} + */ + +/** @defgroup USART_Mode USART Mode + * @{ + */ +#define USART_MODE_RX ((uint32_t)USART_CR1_RE) +#define USART_MODE_TX ((uint32_t)USART_CR1_TE) +#define USART_MODE_TX_RX ((uint32_t)(USART_CR1_TE |USART_CR1_RE)) +/** + * @} + */ + +/** @defgroup USART_Clock USART Clock + * @{ + */ +#define USART_CLOCK_DISABLE ((uint32_t)0x00000000) +#define USART_CLOCK_ENABLE ((uint32_t)USART_CR2_CLKEN) +/** + * @} + */ + +/** @defgroup USART_Clock_Polarity USART Clock Polarity + * @{ + */ +#define USART_POLARITY_LOW ((uint32_t)0x00000000) +#define USART_POLARITY_HIGH ((uint32_t)USART_CR2_CPOL) +/** + * @} + */ + +/** @defgroup USART_Clock_Phase USART Clock Phase + * @{ + */ +#define USART_PHASE_1EDGE ((uint32_t)0x00000000) +#define USART_PHASE_2EDGE ((uint32_t)USART_CR2_CPHA) +/** + * @} + */ + +/** @defgroup USART_Last_Bit USART Last Bit + * @{ + */ +#define USART_LASTBIT_DISABLE ((uint32_t)0x00000000) +#define USART_LASTBIT_ENABLE ((uint32_t)USART_CR2_LBCL) +/** + * @} + */ + +/** @defgroup USART_NACK_State USART NACK State + * @{ + */ +#define USART_NACK_ENABLE ((uint32_t)USART_CR3_NACK) +#define USART_NACK_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup USART_Flags USART Flags + * Elements values convention: 0xXXXX + * - 0xXXXX : Flag mask in the SR register + * @{ + */ +#define USART_FLAG_TXE ((uint32_t)0x00000080) +#define USART_FLAG_TC ((uint32_t)0x00000040) +#define USART_FLAG_RXNE ((uint32_t)0x00000020) +#define USART_FLAG_IDLE ((uint32_t)0x00000010) +#define USART_FLAG_ORE ((uint32_t)0x00000008) +#define USART_FLAG_NE ((uint32_t)0x00000004) +#define USART_FLAG_FE ((uint32_t)0x00000002) +#define USART_FLAG_PE ((uint32_t)0x00000001) +/** + * @} + */ + +/** @defgroup USART_Interrupt_definition USART Interrupts Definition + * Elements values convention: 0xY000XXXX + * - XXXX : Interrupt mask in the XX register + * - Y : Interrupt source register (2bits) + * - 01: CR1 register + * - 10: CR2 register + * - 11: CR3 register + * + * @{ + */ +#define USART_IT_PE ((uint32_t)(USART_CR1_REG_INDEX << 28 | USART_CR1_PEIE)) +#define USART_IT_TXE ((uint32_t)(USART_CR1_REG_INDEX << 28 | USART_CR1_TXEIE)) +#define USART_IT_TC ((uint32_t)(USART_CR1_REG_INDEX << 28 | USART_CR1_TCIE)) +#define USART_IT_RXNE ((uint32_t)(USART_CR1_REG_INDEX << 28 | USART_CR1_RXNEIE)) +#define USART_IT_IDLE ((uint32_t)(USART_CR1_REG_INDEX << 28 | USART_CR1_IDLEIE)) + +#define USART_IT_LBD ((uint32_t)(USART_CR2_REG_INDEX << 28 | USART_CR2_LBDIE)) + +#define USART_IT_CTS ((uint32_t)(USART_CR3_REG_INDEX << 28 | USART_CR3_CTSIE)) +#define USART_IT_ERR ((uint32_t)(USART_CR3_REG_INDEX << 28 | USART_CR3_EIE)) +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup USART_Exported_Macros USART Exported Macros + * @{ + */ + +/** @brief Reset USART handle state + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3 or 6 to select the USART peripheral. + * @retval None + */ +#define __HAL_USART_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_USART_STATE_RESET) + +/** @brief Checks whether the specified Smartcard flag is set or not. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3 or 6 to select the USART peripheral. + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg USART_FLAG_TXE: Transmit data register empty flag + * @arg USART_FLAG_TC: Transmission Complete flag + * @arg USART_FLAG_RXNE: Receive data register not empty flag + * @arg USART_FLAG_IDLE: Idle Line detection flag + * @arg USART_FLAG_ORE: Overrun Error flag + * @arg USART_FLAG_NE: Noise Error flag + * @arg USART_FLAG_FE: Framing Error flag + * @arg USART_FLAG_PE: Parity Error flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_USART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__)) + +/** @brief Clears the specified Smartcard pending flags. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3 or 6 to select the USART peripheral. + * @param __FLAG__: specifies the flag to check. + * This parameter can be any combination of the following values: + * @arg USART_FLAG_TC: Transmission Complete flag. + * @arg USART_FLAG_RXNE: Receive data register not empty flag. + * + * @note PE (Parity error), FE (Framing error), NE (Noise error), ORE (Overrun + * error) and IDLE (Idle line detected) flags are cleared by software + * sequence: a read operation to USART_SR register followed by a read + * operation to USART_DR register. + * @note RXNE flag can be also cleared by a read to the USART_DR register. + * @note TC flag can be also cleared by software sequence: a read operation to + * USART_SR register followed by a write operation to USART_DR register. + * @note TXE flag is cleared only by a write to the USART_DR register. + * + * @retval None + */ +#define __HAL_USART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__)) + +/** @brief Clear the USART PE pending flag. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3 or 6 to select the USART peripheral. + * @retval None + */ +#define __HAL_USART_CLEAR_PEFLAG(__HANDLE__) \ + do{ \ + __IO uint32_t tmpreg; \ + tmpreg = (__HANDLE__)->Instance->SR; \ + tmpreg = (__HANDLE__)->Instance->DR; \ + UNUSED(tmpreg); \ + } while(0) + +/** @brief Clear the USART FE pending flag. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3 or 6 to select the USART peripheral. + * @retval None + */ +#define __HAL_USART_CLEAR_FEFLAG(__HANDLE__) __HAL_USART_CLEAR_PEFLAG(__HANDLE__) + +/** @brief Clear the USART NE pending flag. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3 or 6 to select the USART peripheral. + * @retval None + */ +#define __HAL_USART_CLEAR_NEFLAG(__HANDLE__) __HAL_USART_CLEAR_PEFLAG(__HANDLE__) + +/** @brief Clear the UART ORE pending flag. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3 or 6 to select the USART peripheral. + * @retval None + */ +#define __HAL_USART_CLEAR_OREFLAG(__HANDLE__) __HAL_USART_CLEAR_PEFLAG(__HANDLE__) + +/** @brief Clear the USART IDLE pending flag. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3 or 6 to select the USART peripheral. + * @retval None + */ +#define __HAL_USART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_USART_CLEAR_PEFLAG(__HANDLE__) + +/** @brief Enables or disables the specified USART interrupts. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3 or 6 to select the USART peripheral. + * @param __INTERRUPT__: specifies the USART interrupt source to check. + * This parameter can be one of the following values: + * @arg USART_IT_TXE: Transmit Data Register empty interrupt + * @arg USART_IT_TC: Transmission complete interrupt + * @arg USART_IT_RXNE: Receive Data register not empty interrupt + * @arg USART_IT_IDLE: Idle line detection interrupt + * @arg USART_IT_PE: Parity Error interrupt + * @arg USART_IT_ERR: Error interrupt(Frame error, noise error, overrun error) + * This parameter can be: ENABLE or DISABLE. + * @retval None + */ +#define __HAL_USART_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28) == 1)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & USART_IT_MASK)): \ + (((__INTERRUPT__) >> 28) == 2)? ((__HANDLE__)->Instance->CR2 |= ((__INTERRUPT__) & USART_IT_MASK)): \ + ((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & USART_IT_MASK))) +#define __HAL_USART_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28) == 1)? ((__HANDLE__)->Instance->CR1 &= ~((__INTERRUPT__) & USART_IT_MASK)): \ + (((__INTERRUPT__) >> 28) == 2)? ((__HANDLE__)->Instance->CR2 &= ~((__INTERRUPT__) & USART_IT_MASK)): \ + ((__HANDLE__)->Instance->CR3 &= ~ ((__INTERRUPT__) & USART_IT_MASK))) + +/** @brief Checks whether the specified USART interrupt has occurred or not. + * @param __HANDLE__: specifies the USART Handle. + * This parameter can be USARTx where x: 1, 2, 3 or 6 to select the USART peripheral. + * @param __IT__: specifies the USART interrupt source to check. + * This parameter can be one of the following values: + * @arg USART_IT_TXE: Transmit Data Register empty interrupt + * @arg USART_IT_TC: Transmission complete interrupt + * @arg USART_IT_RXNE: Receive Data register not empty interrupt + * @arg USART_IT_IDLE: Idle line detection interrupt + * @arg USART_IT_ERR: Error interrupt + * @arg USART_IT_PE: Parity Error interrupt + * @retval The new state of __IT__ (TRUE or FALSE). + */ +#define __HAL_USART_GET_IT_SOURCE(__HANDLE__, __IT__) (((((__IT__) >> 28) == 1)? (__HANDLE__)->Instance->CR1:(((((uint32_t)(__IT__)) >> 28) == 2)? \ + (__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & (((uint32_t)(__IT__)) & USART_IT_MASK)) + +/** @brief Macro to enable the USART's one bit sample method + * @param __HANDLE__: specifies the USART Handle. + * @retval None + */ +#define __HAL_USART_ONE_BIT_SAMPLE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3|= USART_CR3_ONEBIT) + +/** @brief Macro to disable the USART's one bit sample method + * @param __HANDLE__: specifies the USART Handle. + * @retval None + */ +#define __HAL_USART_ONE_BIT_SAMPLE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_ONEBIT)) + +/** @brief Enable USART + * @param __HANDLE__: specifies the USART Handle. + * USART Handle selects the USARTx peripheral (USART availability and x value depending on device). + * @retval None + */ +#define __HAL_USART_ENABLE(__HANDLE__) ( (__HANDLE__)->Instance->CR1 |= USART_CR1_UE) + +/** @brief Disable USART + * @param __HANDLE__: specifies the USART Handle. + * USART Handle selects the USARTx peripheral (USART availability and x value depending on device). + * @retval None + */ +#define __HAL_USART_DISABLE(__HANDLE__) ( (__HANDLE__)->Instance->CR1 &= ~USART_CR1_UE) + +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup USART_Exported_Functions + * @{ + */ + +/** @addtogroup USART_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions **********************************/ +HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart); +HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart); +void HAL_USART_MspInit(USART_HandleTypeDef *husart); +void HAL_USART_MspDeInit(USART_HandleTypeDef *husart); +/** + * @} + */ + +/** @addtogroup USART_Exported_Functions_Group2 + * @{ + */ +/* IO operation functions *******************************************************/ +HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size); +HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size); +HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size); +HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size); +HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size); +HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size); +HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart); +HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart); +HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart); +void HAL_USART_IRQHandler(USART_HandleTypeDef *husart); +void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart); +void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart); +void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart); +void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart); +void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart); +void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart); +/** + * @} + */ + +/** @addtogroup USART_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State functions ************************************************/ +HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart); +uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup USART_Private_Constants USART Private Constants + * @{ + */ +/** @brief USART interruptions flag mask + * + */ +#define USART_IT_MASK ((uint32_t) USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE | USART_CR1_RXNEIE | \ + USART_CR1_IDLEIE | USART_CR2_LBDIE | USART_CR3_CTSIE | USART_CR3_EIE ) + + +#define USART_CR1_REG_INDEX 1 +#define USART_CR2_REG_INDEX 2 +#define USART_CR3_REG_INDEX 3 +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup USART_Private_Macros USART Private Macros + * @{ + */ +#define IS_USART_NACK_STATE(NACK) (((NACK) == USART_NACK_ENABLE) || \ + ((NACK) == USART_NACK_DISABLE)) +#define IS_USART_LASTBIT(LASTBIT) (((LASTBIT) == USART_LASTBIT_DISABLE) || \ + ((LASTBIT) == USART_LASTBIT_ENABLE)) +#define IS_USART_PHASE(CPHA) (((CPHA) == USART_PHASE_1EDGE) || ((CPHA) == USART_PHASE_2EDGE)) +#define IS_USART_POLARITY(CPOL) (((CPOL) == USART_POLARITY_LOW) || ((CPOL) == USART_POLARITY_HIGH)) +#define IS_USART_CLOCK(CLOCK) (((CLOCK) == USART_CLOCK_DISABLE) || \ + ((CLOCK) == USART_CLOCK_ENABLE)) +#define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WORDLENGTH_8B) || \ + ((LENGTH) == USART_WORDLENGTH_9B)) +#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_STOPBITS_1) || \ + ((STOPBITS) == USART_STOPBITS_0_5) || \ + ((STOPBITS) == USART_STOPBITS_1_5) || \ + ((STOPBITS) == USART_STOPBITS_2)) +#define IS_USART_PARITY(PARITY) (((PARITY) == USART_PARITY_NONE) || \ + ((PARITY) == USART_PARITY_EVEN) || \ + ((PARITY) == USART_PARITY_ODD)) +#define IS_USART_MODE(MODE) ((((MODE) & (uint32_t)0xFFF3) == 0x00) && ((MODE) != (uint32_t)0x00)) +#define IS_USART_BAUDRATE(BAUDRATE) ((BAUDRATE) < 10500001) + +#define USART_DIV(_PCLK_, _BAUD_) (((_PCLK_)*25)/(2*(_BAUD_))) +#define USART_DIVMANT(_PCLK_, _BAUD_) (USART_DIV((_PCLK_), (_BAUD_))/100) +#define USART_DIVFRAQ(_PCLK_, _BAUD_) (((USART_DIV((_PCLK_), (_BAUD_)) - (USART_DIVMANT((_PCLK_), (_BAUD_)) * 100)) * 16 + 50) / 100) +#define USART_BRR(_PCLK_, _BAUD_) ((USART_DIVMANT((_PCLK_), (_BAUD_)) << 4)|(USART_DIVFRAQ((_PCLK_), (_BAUD_)) & 0x0F)) +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup USART_Private_Functions USART Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_USART_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_wwdg.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_wwdg.h new file mode 100644 index 0000000..37d9942 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_wwdg.h @@ -0,0 +1,349 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_wwdg.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of WWDG HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_WWDG_H +#define __STM32F4xx_HAL_WWDG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup WWDG + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup WWDG_Exported_Types WWDG Exported Types + * @{ + */ + +/** + * @brief WWDG HAL State Structure definition + */ +typedef enum +{ + HAL_WWDG_STATE_RESET = 0x00, /*!< WWDG not yet initialized or disabled */ + HAL_WWDG_STATE_READY = 0x01, /*!< WWDG initialized and ready for use */ + HAL_WWDG_STATE_BUSY = 0x02, /*!< WWDG internal process is ongoing */ + HAL_WWDG_STATE_TIMEOUT = 0x03, /*!< WWDG timeout state */ + HAL_WWDG_STATE_ERROR = 0x04 /*!< WWDG error state */ +}HAL_WWDG_StateTypeDef; + +/** + * @brief WWDG Init structure definition + */ +typedef struct +{ + uint32_t Prescaler; /*!< Specifies the prescaler value of the WWDG. + This parameter can be a value of @ref WWDG_Prescaler */ + + uint32_t Window; /*!< Specifies the WWDG window value to be compared to the downcounter. + This parameter must be a number lower than Max_Data = 0x80 */ + + uint32_t Counter; /*!< Specifies the WWDG free-running downcounter value. + This parameter must be a number between Min_Data = 0x40 and Max_Data = 0x7F */ + +}WWDG_InitTypeDef; + +/** + * @brief WWDG handle Structure definition + */ +typedef struct +{ + WWDG_TypeDef *Instance; /*!< Register base address */ + + WWDG_InitTypeDef Init; /*!< WWDG required parameters */ + + HAL_LockTypeDef Lock; /*!< WWDG locking object */ + + __IO HAL_WWDG_StateTypeDef State; /*!< WWDG communication state */ + +}WWDG_HandleTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup WWDG_Exported_Constants WWDG Exported Constants + * @{ + */ + +/** @defgroup WWDG_Interrupt_definition WWDG Interrupt definition + * @{ + */ +#define WWDG_IT_EWI WWDG_CFR_EWI /*!< Early wakeup interrupt */ +/** + * @} + */ + +/** @defgroup WWDG_Flag_definition WWDG Flag definition + * @brief WWDG Flag definition + * @{ + */ +#define WWDG_FLAG_EWIF WWDG_SR_EWIF /*!< Early wakeup interrupt flag */ +/** + * @} + */ + +/** @defgroup WWDG_Prescaler WWDG Prescaler + * @{ + */ +#define WWDG_PRESCALER_1 ((uint32_t)0x00000000) /*!< WWDG counter clock = (PCLK1/4096)/1 */ +#define WWDG_PRESCALER_2 WWDG_CFR_WDGTB0 /*!< WWDG counter clock = (PCLK1/4096)/2 */ +#define WWDG_PRESCALER_4 WWDG_CFR_WDGTB1 /*!< WWDG counter clock = (PCLK1/4096)/4 */ +#define WWDG_PRESCALER_8 WWDG_CFR_WDGTB /*!< WWDG counter clock = (PCLK1/4096)/8 */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup WWDG_Exported_Macros WWDG Exported Macros + * @{ + */ + +/** @brief Reset WWDG handle state + * @param __HANDLE__: WWDG handle + * @retval None + */ +#define __HAL_WWDG_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_WWDG_STATE_RESET) + +/** + * @brief Enables the WWDG peripheral. + * @param __HANDLE__: WWDG handle + * @retval None + */ +#define __HAL_WWDG_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR, WWDG_CR_WDGA) + +/** + * @brief Disables the WWDG peripheral. + * @param __HANDLE__: WWDG handle + * @note WARNING: This is a dummy macro for HAL code alignment. + * Once enable, WWDG Peripheral cannot be disabled except by a system reset. + * @retval None + */ +#define __HAL_WWDG_DISABLE(__HANDLE__) /* dummy macro */ + +/** + * @brief Gets the selected WWDG's it status. + * @param __HANDLE__: WWDG handle + * @param __INTERRUPT__: specifies the it to check. + * This parameter can be one of the following values: + * @arg WWDG_FLAG_EWIF: Early wakeup interrupt IT + * @retval The new state of WWDG_FLAG (SET or RESET). + */ +#define __HAL_WWDG_GET_IT(__HANDLE__, __INTERRUPT__) __HAL_WWDG_GET_FLAG((__HANDLE__),(__INTERRUPT__)) + +/** @brief Clear the WWDG's interrupt pending bits + * bits to clear the selected interrupt pending bits. + * @param __HANDLE__: WWDG handle + * @param __INTERRUPT__: specifies the interrupt pending bit to clear. + * This parameter can be one of the following values: + * @arg WWDG_FLAG_EWIF: Early wakeup interrupt flag + */ +#define __HAL_WWDG_CLEAR_IT(__HANDLE__, __INTERRUPT__) __HAL_WWDG_CLEAR_FLAG((__HANDLE__), (__INTERRUPT__)) + +/** + * @brief Enables the WWDG early wakeup interrupt. + * @param __HANDLE__: WWDG handle + * @param __INTERRUPT__: specifies the interrupt to enable. + * This parameter can be one of the following values: + * @arg WWDG_IT_EWI: Early wakeup interrupt + * @note Once enabled this interrupt cannot be disabled except by a system reset. + * @retval None + */ +#define __HAL_WWDG_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CFR, (__INTERRUPT__)) + +/** + * @brief Disables the WWDG early wakeup interrupt. + * @param __HANDLE__: WWDG handle + * @param __INTERRUPT__: specifies the interrupt to disable. + * This parameter can be one of the following values: + * @arg WWDG_IT_EWI: Early wakeup interrupt + * @note WARNING: This is a dummy macro for HAL code alignment. + * Once enabled this interrupt cannot be disabled except by a system reset. + * @retval None + */ +#define __HAL_WWDG_DISABLE_IT(__HANDLE__, __INTERRUPT__) /* dummy macro */ + +/** + * @brief Gets the selected WWDG's flag status. + * @param __HANDLE__: WWDG handle + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg WWDG_FLAG_EWIF: Early wakeup interrupt flag + * @retval The new state of WWDG_FLAG (SET or RESET). + */ +#define __HAL_WWDG_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__)) + +/** + * @brief Clears the WWDG's pending flags. + * @param __HANDLE__: WWDG handle + * @param __FLAG__: specifies the flag to clear. + * This parameter can be one of the following values: + * @arg WWDG_FLAG_EWIF: Early wakeup interrupt flag + * @retval None + */ +#define __HAL_WWDG_CLEAR_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR) = ~(__FLAG__)) + +/** @brief Checks if the specified WWDG interrupt source is enabled or disabled. + * @param __HANDLE__: WWDG Handle. + * @param __INTERRUPT__: specifies the WWDG interrupt source to check. + * This parameter can be one of the following values: + * @arg WWDG_IT_EWI: Early Wakeup Interrupt + * @retval state of __INTERRUPT__ (TRUE or FALSE). + */ +#define __HAL_WWDG_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->CFR & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup WWDG_Exported_Functions + * @{ + */ + +/** @addtogroup WWDG_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions **********************************/ +HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg); +HAL_StatusTypeDef HAL_WWDG_DeInit(WWDG_HandleTypeDef *hwwdg); +void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg); +void HAL_WWDG_MspDeInit(WWDG_HandleTypeDef *hwwdg); +void HAL_WWDG_WakeupCallback(WWDG_HandleTypeDef* hwwdg); +/** + * @} + */ + +/** @addtogroup WWDG_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions ******************************************************/ +HAL_StatusTypeDef HAL_WWDG_Start(WWDG_HandleTypeDef *hwwdg); +HAL_StatusTypeDef HAL_WWDG_Start_IT(WWDG_HandleTypeDef *hwwdg); +HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg, uint32_t Counter); +void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg); +/** + * @} + */ + +/** @addtogroup WWDG_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State functions **************************************************/ +HAL_WWDG_StateTypeDef HAL_WWDG_GetState(WWDG_HandleTypeDef *hwwdg); +/** + * @} + */ + +/** + * @} + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup WWDG_Private_Constants WWDG Private Constants + * @{ + */ +/** @defgroup WWDG_BitAddress_AliasRegion WWDG BitAddress + * @brief WWDG registers bit address in the alias region + * @{ + */ + +/* --- CFR Register ---*/ +/* Alias word address of EWI bit */ +#define WWDG_CFR_BASE (uint32_t)(WWDG_BASE + 0x04) + +/** + * @} + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup WWDG_Private_Macros WWDG Private Macros + * @{ + */ +#define IS_WWDG_PRESCALER(__PRESCALER__) (((__PRESCALER__) == WWDG_PRESCALER_1) || \ + ((__PRESCALER__) == WWDG_PRESCALER_2) || \ + ((__PRESCALER__) == WWDG_PRESCALER_4) || \ + ((__PRESCALER__) == WWDG_PRESCALER_8)) +#define IS_WWDG_WINDOW(__WINDOW__) ((__WINDOW__) <= 0x7F) +#define IS_WWDG_COUNTER(__COUNTER__) (((__COUNTER__) >= 0x40) && ((__COUNTER__) <= 0x7F)) +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup WWDG_Private_Functions WWDG Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_WWDG_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_fmc.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_fmc.h new file mode 100644 index 0000000..3386a27 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_fmc.h @@ -0,0 +1,1421 @@ +/** + ****************************************************************************** + * @file stm32f4xx_ll_fmc.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of FMC HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_LL_FMC_H +#define __STM32F4xx_LL_FMC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup FMC_LL + * @{ + */ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) +/* Private types -------------------------------------------------------------*/ +/** @defgroup FMC_LL_Private_Types FMC Private Types + * @{ + */ + +/** + * @brief FMC NORSRAM Configuration Structure definition + */ +typedef struct +{ + uint32_t NSBank; /*!< Specifies the NORSRAM memory device that will be used. + This parameter can be a value of @ref FMC_NORSRAM_Bank */ + + uint32_t DataAddressMux; /*!< Specifies whether the address and data values are + multiplexed on the data bus or not. + This parameter can be a value of @ref FMC_Data_Address_Bus_Multiplexing */ + + uint32_t MemoryType; /*!< Specifies the type of external memory attached to + the corresponding memory device. + This parameter can be a value of @ref FMC_Memory_Type */ + + uint32_t MemoryDataWidth; /*!< Specifies the external memory device width. + This parameter can be a value of @ref FMC_NORSRAM_Data_Width */ + + uint32_t BurstAccessMode; /*!< Enables or disables the burst access mode for Flash memory, + valid only with synchronous burst Flash memories. + This parameter can be a value of @ref FMC_Burst_Access_Mode */ + + uint32_t WaitSignalPolarity; /*!< Specifies the wait signal polarity, valid only when accessing + the Flash memory in burst mode. + This parameter can be a value of @ref FMC_Wait_Signal_Polarity */ + + uint32_t WrapMode; /*!< Enables or disables the Wrapped burst access mode for Flash + memory, valid only when accessing Flash memories in burst mode. + This parameter can be a value of @ref FMC_Wrap_Mode + This mode is not available for the STM32F446xx devices */ + + uint32_t WaitSignalActive; /*!< Specifies if the wait signal is asserted by the memory one + clock cycle before the wait state or during the wait state, + valid only when accessing memories in burst mode. + This parameter can be a value of @ref FMC_Wait_Timing */ + + uint32_t WriteOperation; /*!< Enables or disables the write operation in the selected device by the FMC. + This parameter can be a value of @ref FMC_Write_Operation */ + + uint32_t WaitSignal; /*!< Enables or disables the wait state insertion via wait + signal, valid for Flash memory access in burst mode. + This parameter can be a value of @ref FMC_Wait_Signal */ + + uint32_t ExtendedMode; /*!< Enables or disables the extended mode. + This parameter can be a value of @ref FMC_Extended_Mode */ + + uint32_t AsynchronousWait; /*!< Enables or disables wait signal during asynchronous transfers, + valid only with asynchronous Flash memories. + This parameter can be a value of @ref FMC_AsynchronousWait */ + + uint32_t WriteBurst; /*!< Enables or disables the write burst operation. + This parameter can be a value of @ref FMC_Write_Burst */ + + uint32_t ContinuousClock; /*!< Enables or disables the FMC clock output to external memory devices. + This parameter is only enabled through the FMC_BCR1 register, and don't care + through FMC_BCR2..4 registers. + This parameter can be a value of @ref FMC_Continous_Clock */ + + uint32_t WriteFifo; /*!< Enables or disables the write FIFO used by the FMC controller. + This parameter is only enabled through the FMC_BCR1 register, and don't care + through FMC_BCR2..4 registers. + This parameter can be a value of @ref FMC_Write_FIFO + This mode is available only for the STM32F446xx devices */ + + uint32_t PageSize; /*!< Specifies the memory page size. + This parameter can be a value of @ref FMC_Page_Size + This mode is available only for the STM32F446xx devices */ + +}FMC_NORSRAM_InitTypeDef; + +/** + * @brief FMC NORSRAM Timing parameters structure definition + */ +typedef struct +{ + uint32_t AddressSetupTime; /*!< Defines the number of HCLK cycles to configure + the duration of the address setup time. + This parameter can be a value between Min_Data = 0 and Max_Data = 15. + @note This parameter is not used with synchronous NOR Flash memories. */ + + uint32_t AddressHoldTime; /*!< Defines the number of HCLK cycles to configure + the duration of the address hold time. + This parameter can be a value between Min_Data = 1 and Max_Data = 15. + @note This parameter is not used with synchronous NOR Flash memories. */ + + uint32_t DataSetupTime; /*!< Defines the number of HCLK cycles to configure + the duration of the data setup time. + This parameter can be a value between Min_Data = 1 and Max_Data = 255. + @note This parameter is used for SRAMs, ROMs and asynchronous multiplexed + NOR Flash memories. */ + + uint32_t BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure + the duration of the bus turnaround. + This parameter can be a value between Min_Data = 0 and Max_Data = 15. + @note This parameter is only used for multiplexed NOR Flash memories. */ + + uint32_t CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of + HCLK cycles. This parameter can be a value between Min_Data = 2 and Max_Data = 16. + @note This parameter is not used for asynchronous NOR Flash, SRAM or ROM + accesses. */ + + uint32_t DataLatency; /*!< Defines the number of memory clock cycles to issue + to the memory before getting the first data. + The parameter value depends on the memory type as shown below: + - It must be set to 0 in case of a CRAM + - It is don't care in asynchronous NOR, SRAM or ROM accesses + - It may assume a value between Min_Data = 2 and Max_Data = 17 in NOR Flash memories + with synchronous burst mode enable */ + + uint32_t AccessMode; /*!< Specifies the asynchronous access mode. + This parameter can be a value of @ref FMC_Access_Mode */ +}FMC_NORSRAM_TimingTypeDef; + +/** + * @brief FMC NAND Configuration Structure definition + */ +typedef struct +{ + uint32_t NandBank; /*!< Specifies the NAND memory device that will be used. + This parameter can be a value of @ref FMC_NAND_Bank */ + + uint32_t Waitfeature; /*!< Enables or disables the Wait feature for the NAND Memory device. + This parameter can be any value of @ref FMC_Wait_feature */ + + uint32_t MemoryDataWidth; /*!< Specifies the external memory device width. + This parameter can be any value of @ref FMC_NAND_Data_Width */ + + uint32_t EccComputation; /*!< Enables or disables the ECC computation. + This parameter can be any value of @ref FMC_ECC */ + + uint32_t ECCPageSize; /*!< Defines the page size for the extended ECC. + This parameter can be any value of @ref FMC_ECC_Page_Size */ + + uint32_t TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between CLE low and RE low. + This parameter can be a value between Min_Data = 0 and Max_Data = 255 */ + + uint32_t TARSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between ALE low and RE low. + This parameter can be a number between Min_Data = 0 and Max_Data = 255 */ +}FMC_NAND_InitTypeDef; + +/** + * @brief FMC NAND/PCCARD Timing parameters structure definition + */ +typedef struct +{ + uint32_t SetupTime; /*!< Defines the number of HCLK cycles to setup address before + the command assertion for NAND-Flash read or write access + to common/Attribute or I/O memory space (depending on + the memory space timing to be configured). + This parameter can be a value between Min_Data = 0 and Max_Data = 255 */ + + uint32_t WaitSetupTime; /*!< Defines the minimum number of HCLK cycles to assert the + command for NAND-Flash read or write access to + common/Attribute or I/O memory space (depending on the + memory space timing to be configured). + This parameter can be a number between Min_Data = 0 and Max_Data = 255 */ + + uint32_t HoldSetupTime; /*!< Defines the number of HCLK clock cycles to hold address + (and data for write access) after the command de-assertion + for NAND-Flash read or write access to common/Attribute + or I/O memory space (depending on the memory space timing + to be configured). + This parameter can be a number between Min_Data = 0 and Max_Data = 255 */ + + uint32_t HiZSetupTime; /*!< Defines the number of HCLK clock cycles during which the + data bus is kept in HiZ after the start of a NAND-Flash + write access to common/Attribute or I/O memory space (depending + on the memory space timing to be configured). + This parameter can be a number between Min_Data = 0 and Max_Data = 255 */ +}FMC_NAND_PCC_TimingTypeDef; + +/** + * @brief FMC NAND Configuration Structure definition + */ +typedef struct +{ + uint32_t Waitfeature; /*!< Enables or disables the Wait feature for the PCCARD Memory device. + This parameter can be any value of @ref FMC_Wait_feature */ + + uint32_t TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between CLE low and RE low. + This parameter can be a value between Min_Data = 0 and Max_Data = 255 */ + + uint32_t TARSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between ALE low and RE low. + This parameter can be a number between Min_Data = 0 and Max_Data = 255 */ +}FMC_PCCARD_InitTypeDef; + +/** + * @brief FMC SDRAM Configuration Structure definition + */ +typedef struct +{ + uint32_t SDBank; /*!< Specifies the SDRAM memory device that will be used. + This parameter can be a value of @ref FMC_SDRAM_Bank */ + + uint32_t ColumnBitsNumber; /*!< Defines the number of bits of column address. + This parameter can be a value of @ref FMC_SDRAM_Column_Bits_number. */ + + uint32_t RowBitsNumber; /*!< Defines the number of bits of column address. + This parameter can be a value of @ref FMC_SDRAM_Row_Bits_number. */ + + uint32_t MemoryDataWidth; /*!< Defines the memory device width. + This parameter can be a value of @ref FMC_SDRAM_Memory_Bus_Width. */ + + uint32_t InternalBankNumber; /*!< Defines the number of the device's internal banks. + This parameter can be of @ref FMC_SDRAM_Internal_Banks_Number. */ + + uint32_t CASLatency; /*!< Defines the SDRAM CAS latency in number of memory clock cycles. + This parameter can be a value of @ref FMC_SDRAM_CAS_Latency. */ + + uint32_t WriteProtection; /*!< Enables the SDRAM device to be accessed in write mode. + This parameter can be a value of @ref FMC_SDRAM_Write_Protection. */ + + uint32_t SDClockPeriod; /*!< Define the SDRAM Clock Period for both SDRAM devices and they allow + to disable the clock before changing frequency. + This parameter can be a value of @ref FMC_SDRAM_Clock_Period. */ + + uint32_t ReadBurst; /*!< This bit enable the SDRAM controller to anticipate the next read + commands during the CAS latency and stores data in the Read FIFO. + This parameter can be a value of @ref FMC_SDRAM_Read_Burst. */ + + uint32_t ReadPipeDelay; /*!< Define the delay in system clock cycles on read data path. + This parameter can be a value of @ref FMC_SDRAM_Read_Pipe_Delay. */ +}FMC_SDRAM_InitTypeDef; + +/** + * @brief FMC SDRAM Timing parameters structure definition + */ +typedef struct +{ + uint32_t LoadToActiveDelay; /*!< Defines the delay between a Load Mode Register command and + an active or Refresh command in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t ExitSelfRefreshDelay; /*!< Defines the delay from releasing the self refresh command to + issuing the Activate command in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t SelfRefreshTime; /*!< Defines the minimum Self Refresh period in number of memory clock + cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t RowCycleDelay; /*!< Defines the delay between the Refresh command and the Activate command + and the delay between two consecutive Refresh commands in number of + memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t WriteRecoveryTime; /*!< Defines the Write recovery Time in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t RPDelay; /*!< Defines the delay between a Precharge Command and an other command + in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t RCDDelay; /*!< Defines the delay between the Activate Command and a Read/Write + command in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ +}FMC_SDRAM_TimingTypeDef; + +/** + * @brief SDRAM command parameters structure definition + */ +typedef struct +{ + uint32_t CommandMode; /*!< Defines the command issued to the SDRAM device. + This parameter can be a value of @ref FMC_SDRAM_Command_Mode. */ + + uint32_t CommandTarget; /*!< Defines which device (1 or 2) the command will be issued to. + This parameter can be a value of @ref FMC_SDRAM_Command_Target. */ + + uint32_t AutoRefreshNumber; /*!< Defines the number of consecutive auto refresh command issued + in auto refresh mode. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + uint32_t ModeRegisterDefinition; /*!< Defines the SDRAM Mode register content */ +}FMC_SDRAM_CommandTypeDef; +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup FMC_LL_Private_Constants FMC Private Constants + * @{ + */ + +/** @defgroup FMC_LL_NOR_SRAM_Controller FMC NOR/SRAM Controller + * @{ + */ +/** @defgroup FMC_NORSRAM_Bank FMC NOR/SRAM Bank + * @{ + */ +#define FMC_NORSRAM_BANK1 ((uint32_t)0x00000000) +#define FMC_NORSRAM_BANK2 ((uint32_t)0x00000002) +#define FMC_NORSRAM_BANK3 ((uint32_t)0x00000004) +#define FMC_NORSRAM_BANK4 ((uint32_t)0x00000006) +/** + * @} + */ + +/** @defgroup FMC_Data_Address_Bus_Multiplexing FMC Data Address Bus Multiplexing + * @{ + */ +#define FMC_DATA_ADDRESS_MUX_DISABLE ((uint32_t)0x00000000) +#define FMC_DATA_ADDRESS_MUX_ENABLE ((uint32_t)0x00000002) +/** + * @} + */ + +/** @defgroup FMC_Memory_Type FMC Memory Type + * @{ + */ +#define FMC_MEMORY_TYPE_SRAM ((uint32_t)0x00000000) +#define FMC_MEMORY_TYPE_PSRAM ((uint32_t)0x00000004) +#define FMC_MEMORY_TYPE_NOR ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup FMC_NORSRAM_Data_Width FMC NORSRAM Data Width + * @{ + */ +#define FMC_NORSRAM_MEM_BUS_WIDTH_8 ((uint32_t)0x00000000) +#define FMC_NORSRAM_MEM_BUS_WIDTH_16 ((uint32_t)0x00000010) +#define FMC_NORSRAM_MEM_BUS_WIDTH_32 ((uint32_t)0x00000020) +/** + * @} + */ + +/** @defgroup FMC_NORSRAM_Flash_Access FMC NOR/SRAM Flash Access + * @{ + */ +#define FMC_NORSRAM_FLASH_ACCESS_ENABLE ((uint32_t)0x00000040) +#define FMC_NORSRAM_FLASH_ACCESS_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup FMC_Burst_Access_Mode FMC Burst Access Mode + * @{ + */ +#define FMC_BURST_ACCESS_MODE_DISABLE ((uint32_t)0x00000000) +#define FMC_BURST_ACCESS_MODE_ENABLE ((uint32_t)0x00000100) +/** + * @} + */ + +/** @defgroup FMC_Wait_Signal_Polarity FMC Wait Signal Polarity + * @{ + */ +#define FMC_WAIT_SIGNAL_POLARITY_LOW ((uint32_t)0x00000000) +#define FMC_WAIT_SIGNAL_POLARITY_HIGH ((uint32_t)0x00000200) +/** + * @} + */ + +/** @defgroup FMC_Wrap_Mode FMC Wrap Mode + * @{ + */ +/** @note This mode is not available for the STM32F446xx devices + */ +#define FMC_WRAP_MODE_DISABLE ((uint32_t)0x00000000) +#define FMC_WRAP_MODE_ENABLE ((uint32_t)0x00000400) +/** + * @} + */ + +/** @defgroup FMC_Wait_Timing FMC Wait Timing + * @{ + */ +#define FMC_WAIT_TIMING_BEFORE_WS ((uint32_t)0x00000000) +#define FMC_WAIT_TIMING_DURING_WS ((uint32_t)0x00000800) +/** + * @} + */ + +/** @defgroup FMC_Write_Operation FMC Write Operation + * @{ + */ +#define FMC_WRITE_OPERATION_DISABLE ((uint32_t)0x00000000) +#define FMC_WRITE_OPERATION_ENABLE ((uint32_t)0x00001000) +/** + * @} + */ + +/** @defgroup FMC_Wait_Signal FMC Wait Signal + * @{ + */ +#define FMC_WAIT_SIGNAL_DISABLE ((uint32_t)0x00000000) +#define FMC_WAIT_SIGNAL_ENABLE ((uint32_t)0x00002000) +/** + * @} + */ + +/** @defgroup FMC_Extended_Mode FMC Extended Mode + * @{ + */ +#define FMC_EXTENDED_MODE_DISABLE ((uint32_t)0x00000000) +#define FMC_EXTENDED_MODE_ENABLE ((uint32_t)0x00004000) +/** + * @} + */ + +/** @defgroup FMC_AsynchronousWait FMC Asynchronous Wait + * @{ + */ +#define FMC_ASYNCHRONOUS_WAIT_DISABLE ((uint32_t)0x00000000) +#define FMC_ASYNCHRONOUS_WAIT_ENABLE ((uint32_t)0x00008000) +/** + * @} + */ + +/** @defgroup FMC_Page_Size FMC Page Size + * @note These values are available only for the STM32F446xx devices. + * @{ + */ +#define FMC_PAGE_SIZE_NONE ((uint32_t)0x00000000) +#define FMC_PAGE_SIZE_128 ((uint32_t)FMC_BCR1_CPSIZE_0) +#define FMC_PAGE_SIZE_256 ((uint32_t)FMC_BCR1_CPSIZE_1) +#define FMC_PAGE_SIZE_1024 ((uint32_t)FMC_BCR1_CPSIZE_2) +/** + * @} + */ + +/** @defgroup FMC_Write_FIFO FMC Write FIFO + * @note These values are available only for the STM32F446xx devices. + * @{ + */ +#define FMC_WRITE_FIFO_DISABLE ((uint32_t)0x00000000) +#define FMC_WRITE_FIFO_ENABLE ((uint32_t)FMC_BCR1_WFDIS) +/** + * @} + */ + +/** @defgroup FMC_Write_Burst FMC Write Burst + * @{ + */ +#define FMC_WRITE_BURST_DISABLE ((uint32_t)0x00000000) +#define FMC_WRITE_BURST_ENABLE ((uint32_t)0x00080000) +/** + * @} + */ + +/** @defgroup FMC_Continous_Clock FMC Continuous Clock + * @{ + */ +#define FMC_CONTINUOUS_CLOCK_SYNC_ONLY ((uint32_t)0x00000000) +#define FMC_CONTINUOUS_CLOCK_SYNC_ASYNC ((uint32_t)0x00100000) +/** + * @} + */ + +/** @defgroup FMC_Access_Mode FMC Access Mode + * @{ + */ +#define FMC_ACCESS_MODE_A ((uint32_t)0x00000000) +#define FMC_ACCESS_MODE_B ((uint32_t)0x10000000) +#define FMC_ACCESS_MODE_C ((uint32_t)0x20000000) +#define FMC_ACCESS_MODE_D ((uint32_t)0x30000000) +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup FMC_LL_NAND_Controller FMC NAND Controller + * @{ + */ +/** @defgroup FMC_NAND_Bank FMC NAND Bank + * @{ + */ +#define FMC_NAND_BANK2 ((uint32_t)0x00000010) +#define FMC_NAND_BANK3 ((uint32_t)0x00000100) +/** + * @} + */ + +/** @defgroup FMC_Wait_feature FMC Wait feature + * @{ + */ +#define FMC_NAND_PCC_WAIT_FEATURE_DISABLE ((uint32_t)0x00000000) +#define FMC_NAND_PCC_WAIT_FEATURE_ENABLE ((uint32_t)0x00000002) +/** + * @} + */ + +/** @defgroup FMC_PCR_Memory_Type FMC PCR Memory Type + * @{ + */ +#define FMC_PCR_MEMORY_TYPE_PCCARD ((uint32_t)0x00000000) +#define FMC_PCR_MEMORY_TYPE_NAND ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup FMC_NAND_Data_Width FMC NAND Data Width + * @{ + */ +#define FMC_NAND_PCC_MEM_BUS_WIDTH_8 ((uint32_t)0x00000000) +#define FMC_NAND_PCC_MEM_BUS_WIDTH_16 ((uint32_t)0x00000010) +/** + * @} + */ + +/** @defgroup FMC_ECC FMC ECC + * @{ + */ +#define FMC_NAND_ECC_DISABLE ((uint32_t)0x00000000) +#define FMC_NAND_ECC_ENABLE ((uint32_t)0x00000040) +/** + * @} + */ + +/** @defgroup FMC_ECC_Page_Size FMC ECC Page Size + * @{ + */ +#define FMC_NAND_ECC_PAGE_SIZE_256BYTE ((uint32_t)0x00000000) +#define FMC_NAND_ECC_PAGE_SIZE_512BYTE ((uint32_t)0x00020000) +#define FMC_NAND_ECC_PAGE_SIZE_1024BYTE ((uint32_t)0x00040000) +#define FMC_NAND_ECC_PAGE_SIZE_2048BYTE ((uint32_t)0x00060000) +#define FMC_NAND_ECC_PAGE_SIZE_4096BYTE ((uint32_t)0x00080000) +#define FMC_NAND_ECC_PAGE_SIZE_8192BYTE ((uint32_t)0x000A0000) +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup FMC_LL_SDRAM_Controller FMC SDRAM Controller + * @{ + */ +/** @defgroup FMC_SDRAM_Bank FMC SDRAM Bank + * @{ + */ +#define FMC_SDRAM_BANK1 ((uint32_t)0x00000000) +#define FMC_SDRAM_BANK2 ((uint32_t)0x00000001) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Column_Bits_number FMC SDRAM Column Bits number + * @{ + */ +#define FMC_SDRAM_COLUMN_BITS_NUM_8 ((uint32_t)0x00000000) +#define FMC_SDRAM_COLUMN_BITS_NUM_9 ((uint32_t)0x00000001) +#define FMC_SDRAM_COLUMN_BITS_NUM_10 ((uint32_t)0x00000002) +#define FMC_SDRAM_COLUMN_BITS_NUM_11 ((uint32_t)0x00000003) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Row_Bits_number FMC SDRAM Row Bits number + * @{ + */ +#define FMC_SDRAM_ROW_BITS_NUM_11 ((uint32_t)0x00000000) +#define FMC_SDRAM_ROW_BITS_NUM_12 ((uint32_t)0x00000004) +#define FMC_SDRAM_ROW_BITS_NUM_13 ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Memory_Bus_Width FMC SDRAM Memory Bus Width + * @{ + */ +#define FMC_SDRAM_MEM_BUS_WIDTH_8 ((uint32_t)0x00000000) +#define FMC_SDRAM_MEM_BUS_WIDTH_16 ((uint32_t)0x00000010) +#define FMC_SDRAM_MEM_BUS_WIDTH_32 ((uint32_t)0x00000020) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Internal_Banks_Number FMC SDRAM Internal Banks Number + * @{ + */ +#define FMC_SDRAM_INTERN_BANKS_NUM_2 ((uint32_t)0x00000000) +#define FMC_SDRAM_INTERN_BANKS_NUM_4 ((uint32_t)0x00000040) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_CAS_Latency FMC SDRAM CAS Latency + * @{ + */ +#define FMC_SDRAM_CAS_LATENCY_1 ((uint32_t)0x00000080) +#define FMC_SDRAM_CAS_LATENCY_2 ((uint32_t)0x00000100) +#define FMC_SDRAM_CAS_LATENCY_3 ((uint32_t)0x00000180) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Write_Protection FMC SDRAM Write Protection + * @{ + */ +#define FMC_SDRAM_WRITE_PROTECTION_DISABLE ((uint32_t)0x00000000) +#define FMC_SDRAM_WRITE_PROTECTION_ENABLE ((uint32_t)0x00000200) + +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Clock_Period FMC SDRAM Clock Period + * @{ + */ +#define FMC_SDRAM_CLOCK_DISABLE ((uint32_t)0x00000000) +#define FMC_SDRAM_CLOCK_PERIOD_2 ((uint32_t)0x00000800) +#define FMC_SDRAM_CLOCK_PERIOD_3 ((uint32_t)0x00000C00) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Read_Burst FMC SDRAM Read Burst + * @{ + */ +#define FMC_SDRAM_RBURST_DISABLE ((uint32_t)0x00000000) +#define FMC_SDRAM_RBURST_ENABLE ((uint32_t)0x00001000) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Read_Pipe_Delay FMC SDRAM Read Pipe Delay + * @{ + */ +#define FMC_SDRAM_RPIPE_DELAY_0 ((uint32_t)0x00000000) +#define FMC_SDRAM_RPIPE_DELAY_1 ((uint32_t)0x00002000) +#define FMC_SDRAM_RPIPE_DELAY_2 ((uint32_t)0x00004000) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Command_Mode FMC SDRAM Command Mode + * @{ + */ +#define FMC_SDRAM_CMD_NORMAL_MODE ((uint32_t)0x00000000) +#define FMC_SDRAM_CMD_CLK_ENABLE ((uint32_t)0x00000001) +#define FMC_SDRAM_CMD_PALL ((uint32_t)0x00000002) +#define FMC_SDRAM_CMD_AUTOREFRESH_MODE ((uint32_t)0x00000003) +#define FMC_SDRAM_CMD_LOAD_MODE ((uint32_t)0x00000004) +#define FMC_SDRAM_CMD_SELFREFRESH_MODE ((uint32_t)0x00000005) +#define FMC_SDRAM_CMD_POWERDOWN_MODE ((uint32_t)0x00000006) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Command_Target FMC SDRAM Command Target + * @{ + */ +#define FMC_SDRAM_CMD_TARGET_BANK2 FMC_SDCMR_CTB2 +#define FMC_SDRAM_CMD_TARGET_BANK1 FMC_SDCMR_CTB1 +#define FMC_SDRAM_CMD_TARGET_BANK1_2 ((uint32_t)0x00000018) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Mode_Status FMC SDRAM Mode Status + * @{ + */ +#define FMC_SDRAM_NORMAL_MODE ((uint32_t)0x00000000) +#define FMC_SDRAM_SELF_REFRESH_MODE FMC_SDSR_MODES1_0 +#define FMC_SDRAM_POWER_DOWN_MODE FMC_SDSR_MODES1_1 +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup FMC_LL_Interrupt_definition FMC Interrupt definition + * @{ + */ +#define FMC_IT_RISING_EDGE ((uint32_t)0x00000008) +#define FMC_IT_LEVEL ((uint32_t)0x00000010) +#define FMC_IT_FALLING_EDGE ((uint32_t)0x00000020) +#define FMC_IT_REFRESH_ERROR ((uint32_t)0x00004000) +/** + * @} + */ + +/** @defgroup FMC_LL_Flag_definition FMC Flag definition + * @{ + */ +#define FMC_FLAG_RISING_EDGE ((uint32_t)0x00000001) +#define FMC_FLAG_LEVEL ((uint32_t)0x00000002) +#define FMC_FLAG_FALLING_EDGE ((uint32_t)0x00000004) +#define FMC_FLAG_FEMPT ((uint32_t)0x00000040) +#define FMC_SDRAM_FLAG_REFRESH_IT FMC_SDSR_RE +#define FMC_SDRAM_FLAG_BUSY FMC_SDSR_BUSY +#define FMC_SDRAM_FLAG_REFRESH_ERROR FMC_SDRTR_CRE +/** + * @} + */ + +/** @defgroup FMC_LL_Alias_definition FMC Alias definition + * @{ + */ +#if defined(STM32F446xx) + #define FMC_NAND_TypeDef FMC_Bank3_TypeDef +#else + #define FMC_NAND_TypeDef FMC_Bank2_3_TypeDef + #define FMC_PCCARD_TypeDef FMC_Bank4_TypeDef +#endif /* defined(STM32F446xx) */ + #define FMC_NORSRAM_TypeDef FMC_Bank1_TypeDef + #define FMC_NORSRAM_EXTENDED_TypeDef FMC_Bank1E_TypeDef + #define FMC_SDRAM_TypeDef FMC_Bank5_6_TypeDef + + +#if defined(STM32F446xx) + #define FMC_NAND_DEVICE FMC_Bank3 +#else + #define FMC_NAND_DEVICE FMC_Bank2_3 + #define FMC_PCCARD_DEVICE FMC_Bank4 +#endif /* defined(STM32F446xx) */ + #define FMC_NORSRAM_DEVICE FMC_Bank1 + #define FMC_NORSRAM_EXTENDED_DEVICE FMC_Bank1E + #define FMC_SDRAM_DEVICE FMC_Bank5_6 +/** + * @} + */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup FMC_LL_Private_Macros FMC Private Macros + * @{ + */ + +/** @defgroup FMC_LL_NOR_Macros FMC NOR/SRAM Macros + * @brief macros to handle NOR device enable/disable and read/write operations + * @{ + */ +/** + * @brief Enable the NORSRAM device access. + * @param __INSTANCE__: FMC_NORSRAM Instance + * @param __BANK__: FMC_NORSRAM Bank + * @retval None + */ +#define __FMC_NORSRAM_ENABLE(__INSTANCE__, __BANK__) ((__INSTANCE__)->BTCR[(__BANK__)] |= FMC_BCR1_MBKEN) + +/** + * @brief Disable the NORSRAM device access. + * @param __INSTANCE__: FMC_NORSRAM Instance + * @param __BANK__: FMC_NORSRAM Bank + * @retval None + */ +#define __FMC_NORSRAM_DISABLE(__INSTANCE__, __BANK__) ((__INSTANCE__)->BTCR[(__BANK__)] &= ~FMC_BCR1_MBKEN) +/** + * @} + */ + +/** @defgroup FMC_LL_NAND_Macros FMC NAND Macros + * @brief macros to handle NAND device enable/disable + * @{ + */ +#if defined(STM32F446xx) +/** + * @brief Enable the NAND device access. + * @param __INSTANCE__: FMC_NAND Instance + * @param __BANK__: FMC_NAND Bank + * @retval None + */ +#define __FMC_NAND_ENABLE(__INSTANCE__, __BANK__) ((__INSTANCE__)->PCR |= FMC_PCR_PBKEN) + +/** + * @brief Disable the NAND device access. + * @param __INSTANCE__: FMC_NAND Instance + * @param __BANK__: FMC_NAND Bank + * @retval None + */ +#define __FMC_NAND_DISABLE(__INSTANCE__, __BANK__) ((__INSTANCE__)->PCR &= ~FMC_PCR_PBKEN) +#else /* defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) */ +/** + * @brief Enable the NAND device access. + * @param __INSTANCE__: FMC_NAND Instance + * @param __BANK__: FMC_NAND Bank + * @retval None + */ +#define __FMC_NAND_ENABLE(__INSTANCE__, __BANK__) (((__BANK__) == FMC_NAND_BANK2)? ((__INSTANCE__)->PCR2 |= FMC_PCR2_PBKEN): \ + ((__INSTANCE__)->PCR3 |= FMC_PCR3_PBKEN)) + +/** + * @brief Disable the NAND device access. + * @param __INSTANCE__: FMC_NAND Instance + * @param __BANK__: FMC_NAND Bank + * @retval None + */ +#define __FMC_NAND_DISABLE(__INSTANCE__, __BANK__) (((__BANK__) == FMC_NAND_BANK2)? ((__INSTANCE__)->PCR2 &= ~FMC_PCR2_PBKEN): \ + ((__INSTANCE__)->PCR3 &= ~FMC_PCR3_PBKEN)) + +#endif /* defined(STM32F446xx)*/ +/** + * @} + */ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) +/** @defgroup FMC_LL_PCCARD_Macros FMC PCCARD Macros + * @brief macros to handle SRAM read/write operations + * @{ + */ +/** + * @brief Enable the PCCARD device access. + * @param __INSTANCE__: FMC_PCCARD Instance + * @retval None + */ +#define __FMC_PCCARD_ENABLE(__INSTANCE__) ((__INSTANCE__)->PCR4 |= FMC_PCR4_PBKEN) + +/** + * @brief Disable the PCCARD device access. + * @param __INSTANCE__: FMC_PCCARD Instance + * @retval None + */ +#define __FMC_PCCARD_DISABLE(__INSTANCE__) ((__INSTANCE__)->PCR4 &= ~FMC_PCR4_PBKEN) +/** + * @} + */ +#endif /* defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) */ + +/** @defgroup FMC_LL_Flag_Interrupt_Macros FMC Flag&Interrupt Macros + * @brief macros to handle FMC flags and interrupts + * @{ + */ +#if defined(STM32F446xx) +/** + * @brief Enable the NAND device interrupt. + * @param __INSTANCE__: FMC_NAND instance + * @param __BANK__: FMC_NAND Bank + * @param __INTERRUPT__: FMC_NAND interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_RISING_EDGE: Interrupt rising edge. + * @arg FMC_IT_LEVEL: Interrupt level. + * @arg FMC_IT_FALLING_EDGE: Interrupt falling edge. + * @retval None + */ +#define __FMC_NAND_ENABLE_IT(__INSTANCE__, __BANK__, __INTERRUPT__) ((__INSTANCE__)->SR |= (__INTERRUPT__)) + +/** + * @brief Disable the NAND device interrupt. + * @param __INSTANCE__: FMC_NAND Instance + * @param __BANK__: FMC_NAND Bank + * @param __INTERRUPT__: FMC_NAND interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_RISING_EDGE: Interrupt rising edge. + * @arg FMC_IT_LEVEL: Interrupt level. + * @arg FMC_IT_FALLING_EDGE: Interrupt falling edge. + * @retval None + */ +#define __FMC_NAND_DISABLE_IT(__INSTANCE__, __BANK__, __INTERRUPT__) ((__INSTANCE__)->SR &= ~(__INTERRUPT__)) + +/** + * @brief Get flag status of the NAND device. + * @param __INSTANCE__: FMC_NAND Instance + * @param __BANK__: FMC_NAND Bank + * @param __FLAG__: FMC_NAND flag + * This parameter can be any combination of the following values: + * @arg FMC_FLAG_RISING_EDGE: Interrupt rising edge flag. + * @arg FMC_FLAG_LEVEL: Interrupt level edge flag. + * @arg FMC_FLAG_FALLING_EDGE: Interrupt falling edge flag. + * @arg FMC_FLAG_FEMPT: FIFO empty flag. + * @retval The state of FLAG (SET or RESET). + */ +#define __FMC_NAND_GET_FLAG(__INSTANCE__, __BANK__, __FLAG__) (((__INSTANCE__)->SR &(__FLAG__)) == (__FLAG__)) +/** + * @brief Clear flag status of the NAND device. + * @param __INSTANCE__: FMC_NAND Instance + * @param __BANK__: FMC_NAND Bank + * @param __FLAG__: FMC_NAND flag + * This parameter can be any combination of the following values: + * @arg FMC_FLAG_RISING_EDGE: Interrupt rising edge flag. + * @arg FMC_FLAG_LEVEL: Interrupt level edge flag. + * @arg FMC_FLAG_FALLING_EDGE: Interrupt falling edge flag. + * @arg FMC_FLAG_FEMPT: FIFO empty flag. + * @retval None + */ +#define __FMC_NAND_CLEAR_FLAG(__INSTANCE__, __BANK__, __FLAG__) ((__INSTANCE__)->SR &= ~(__FLAG__)) +#else /* defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) */ +/** + * @brief Enable the NAND device interrupt. + * @param __INSTANCE__: FMC_NAND instance + * @param __BANK__: FMC_NAND Bank + * @param __INTERRUPT__: FMC_NAND interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_RISING_EDGE: Interrupt rising edge. + * @arg FMC_IT_LEVEL: Interrupt level. + * @arg FMC_IT_FALLING_EDGE: Interrupt falling edge. + * @retval None + */ +#define __FMC_NAND_ENABLE_IT(__INSTANCE__, __BANK__, __INTERRUPT__) (((__BANK__) == FMC_NAND_BANK2)? ((__INSTANCE__)->SR2 |= (__INTERRUPT__)): \ + ((__INSTANCE__)->SR3 |= (__INTERRUPT__))) + +/** + * @brief Disable the NAND device interrupt. + * @param __INSTANCE__: FMC_NAND Instance + * @param __BANK__: FMC_NAND Bank + * @param __INTERRUPT__: FMC_NAND interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_RISING_EDGE: Interrupt rising edge. + * @arg FMC_IT_LEVEL: Interrupt level. + * @arg FMC_IT_FALLING_EDGE: Interrupt falling edge. + * @retval None + */ +#define __FMC_NAND_DISABLE_IT(__INSTANCE__, __BANK__, __INTERRUPT__) (((__BANK__) == FMC_NAND_BANK2)? ((__INSTANCE__)->SR2 &= ~(__INTERRUPT__)): \ + ((__INSTANCE__)->SR3 &= ~(__INTERRUPT__))) + +/** + * @brief Get flag status of the NAND device. + * @param __INSTANCE__: FMC_NAND Instance + * @param __BANK__: FMC_NAND Bank + * @param __FLAG__: FMC_NAND flag + * This parameter can be any combination of the following values: + * @arg FMC_FLAG_RISING_EDGE: Interrupt rising edge flag. + * @arg FMC_FLAG_LEVEL: Interrupt level edge flag. + * @arg FMC_FLAG_FALLING_EDGE: Interrupt falling edge flag. + * @arg FMC_FLAG_FEMPT: FIFO empty flag. + * @retval The state of FLAG (SET or RESET). + */ +#define __FMC_NAND_GET_FLAG(__INSTANCE__, __BANK__, __FLAG__) (((__BANK__) == FMC_NAND_BANK2)? (((__INSTANCE__)->SR2 &(__FLAG__)) == (__FLAG__)): \ + (((__INSTANCE__)->SR3 &(__FLAG__)) == (__FLAG__))) +/** + * @brief Clear flag status of the NAND device. + * @param __INSTANCE__: FMC_NAND Instance + * @param __BANK__: FMC_NAND Bank + * @param __FLAG__: FMC_NAND flag + * This parameter can be any combination of the following values: + * @arg FMC_FLAG_RISING_EDGE: Interrupt rising edge flag. + * @arg FMC_FLAG_LEVEL: Interrupt level edge flag. + * @arg FMC_FLAG_FALLING_EDGE: Interrupt falling edge flag. + * @arg FMC_FLAG_FEMPT: FIFO empty flag. + * @retval None + */ +#define __FMC_NAND_CLEAR_FLAG(__INSTANCE__, __BANK__, __FLAG__) (((__BANK__) == FMC_NAND_BANK2)? ((__INSTANCE__)->SR2 &= ~(__FLAG__)): \ + ((__INSTANCE__)->SR3 &= ~(__FLAG__))) +#endif /* defined(STM32F446xx) */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) +/** + * @brief Enable the PCCARD device interrupt. + * @param __INSTANCE__: FMC_PCCARD instance + * @param __INTERRUPT__: FMC_PCCARD interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_RISING_EDGE: Interrupt rising edge. + * @arg FMC_IT_LEVEL: Interrupt level. + * @arg FMC_IT_FALLING_EDGE: Interrupt falling edge. + * @retval None + */ +#define __FMC_PCCARD_ENABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SR4 |= (__INTERRUPT__)) + +/** + * @brief Disable the PCCARD device interrupt. + * @param __INSTANCE__: FMC_PCCARD instance + * @param __INTERRUPT__: FMC_PCCARD interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_RISING_EDGE: Interrupt rising edge. + * @arg FMC_IT_LEVEL: Interrupt level. + * @arg FMC_IT_FALLING_EDGE: Interrupt falling edge. + * @retval None + */ +#define __FMC_PCCARD_DISABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SR4 &= ~(__INTERRUPT__)) + +/** + * @brief Get flag status of the PCCARD device. + * @param __INSTANCE__: FMC_PCCARD instance + * @param __FLAG__: FMC_PCCARD flag + * This parameter can be any combination of the following values: + * @arg FMC_FLAG_RISING_EDGE: Interrupt rising edge flag. + * @arg FMC_FLAG_LEVEL: Interrupt level edge flag. + * @arg FMC_FLAG_FALLING_EDGE: Interrupt falling edge flag. + * @arg FMC_FLAG_FEMPT: FIFO empty flag. + * @retval The state of FLAG (SET or RESET). + */ +#define __FMC_PCCARD_GET_FLAG(__INSTANCE__, __FLAG__) (((__INSTANCE__)->SR4 &(__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear flag status of the PCCARD device. + * @param __INSTANCE__: FMC_PCCARD instance + * @param __FLAG__: FMC_PCCARD flag + * This parameter can be any combination of the following values: + * @arg FMC_FLAG_RISING_EDGE: Interrupt rising edge flag. + * @arg FMC_FLAG_LEVEL: Interrupt level edge flag. + * @arg FMC_FLAG_FALLING_EDGE: Interrupt falling edge flag. + * @arg FMC_FLAG_FEMPT: FIFO empty flag. + * @retval None + */ +#define __FMC_PCCARD_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->SR4 &= ~(__FLAG__)) +#endif /* defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) */ + +/** + * @brief Enable the SDRAM device interrupt. + * @param __INSTANCE__: FMC_SDRAM instance + * @param __INTERRUPT__: FMC_SDRAM interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_REFRESH_ERROR: Interrupt refresh error + * @retval None + */ +#define __FMC_SDRAM_ENABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SDRTR |= (__INTERRUPT__)) + +/** + * @brief Disable the SDRAM device interrupt. + * @param __INSTANCE__: FMC_SDRAM instance + * @param __INTERRUPT__: FMC_SDRAM interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_REFRESH_ERROR: Interrupt refresh error + * @retval None + */ +#define __FMC_SDRAM_DISABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SDRTR &= ~(__INTERRUPT__)) + +/** + * @brief Get flag status of the SDRAM device. + * @param __INSTANCE__: FMC_SDRAM instance + * @param __FLAG__: FMC_SDRAM flag + * This parameter can be any combination of the following values: + * @arg FMC_SDRAM_FLAG_REFRESH_IT: Interrupt refresh error. + * @arg FMC_SDRAM_FLAG_BUSY: SDRAM busy flag. + * @arg FMC_SDRAM_FLAG_REFRESH_ERROR: Refresh error flag. + * @retval The state of FLAG (SET or RESET). + */ +#define __FMC_SDRAM_GET_FLAG(__INSTANCE__, __FLAG__) (((__INSTANCE__)->SDSR &(__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear flag status of the SDRAM device. + * @param __INSTANCE__: FMC_SDRAM instance + * @param __FLAG__: FMC_SDRAM flag + * This parameter can be any combination of the following values: + * @arg FMC_SDRAM_FLAG_REFRESH_ERROR + * @retval None + */ +#define __FMC_SDRAM_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->SDRTR |= (__FLAG__)) +/** + * @} + */ + +/** @defgroup FSMC_LL_Assert_Macros FSMC Assert Macros + * @{ + */ +#define IS_FMC_NORSRAM_BANK(BANK) (((BANK) == FMC_NORSRAM_BANK1) || \ + ((BANK) == FMC_NORSRAM_BANK2) || \ + ((BANK) == FMC_NORSRAM_BANK3) || \ + ((BANK) == FMC_NORSRAM_BANK4)) + +#define IS_FMC_MUX(__MUX__) (((__MUX__) == FMC_DATA_ADDRESS_MUX_DISABLE) || \ + ((__MUX__) == FMC_DATA_ADDRESS_MUX_ENABLE)) + +#define IS_FMC_MEMORY(__MEMORY__) (((__MEMORY__) == FMC_MEMORY_TYPE_SRAM) || \ + ((__MEMORY__) == FMC_MEMORY_TYPE_PSRAM)|| \ + ((__MEMORY__) == FMC_MEMORY_TYPE_NOR)) + +#define IS_FMC_NORSRAM_MEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FMC_NORSRAM_MEM_BUS_WIDTH_8) || \ + ((__WIDTH__) == FMC_NORSRAM_MEM_BUS_WIDTH_16) || \ + ((__WIDTH__) == FMC_NORSRAM_MEM_BUS_WIDTH_32)) + +#define IS_FMC_ACCESS_MODE(__MODE__) (((__MODE__) == FMC_ACCESS_MODE_A) || \ + ((__MODE__) == FMC_ACCESS_MODE_B) || \ + ((__MODE__) == FMC_ACCESS_MODE_C) || \ + ((__MODE__) == FMC_ACCESS_MODE_D)) + +#define IS_FMC_NAND_BANK(BANK) (((BANK) == FMC_NAND_BANK2) || \ + ((BANK) == FMC_NAND_BANK3)) + +#define IS_FMC_WAIT_FEATURE(FEATURE) (((FEATURE) == FMC_NAND_PCC_WAIT_FEATURE_DISABLE) || \ + ((FEATURE) == FMC_NAND_PCC_WAIT_FEATURE_ENABLE)) + +#define IS_FMC_NAND_MEMORY_WIDTH(WIDTH) (((WIDTH) == FMC_NAND_PCC_MEM_BUS_WIDTH_8) || \ + ((WIDTH) == FMC_NAND_PCC_MEM_BUS_WIDTH_16)) + +#define IS_FMC_ECC_STATE(STATE) (((STATE) == FMC_NAND_ECC_DISABLE) || \ + ((STATE) == FMC_NAND_ECC_ENABLE)) + +#define IS_FMC_ECCPAGE_SIZE(SIZE) (((SIZE) == FMC_NAND_ECC_PAGE_SIZE_256BYTE) || \ + ((SIZE) == FMC_NAND_ECC_PAGE_SIZE_512BYTE) || \ + ((SIZE) == FMC_NAND_ECC_PAGE_SIZE_1024BYTE) || \ + ((SIZE) == FMC_NAND_ECC_PAGE_SIZE_2048BYTE) || \ + ((SIZE) == FMC_NAND_ECC_PAGE_SIZE_4096BYTE) || \ + ((SIZE) == FMC_NAND_ECC_PAGE_SIZE_8192BYTE)) + +#define IS_FMC_TCLR_TIME(TIME) ((TIME) <= 255) + +#define IS_FMC_TAR_TIME(TIME) ((TIME) <= 255) + +#define IS_FMC_SETUP_TIME(TIME) ((TIME) <= 255) + +#define IS_FMC_WAIT_TIME(TIME) ((TIME) <= 255) + +#define IS_FMC_HOLD_TIME(TIME) ((TIME) <= 255) + +#define IS_FMC_HIZ_TIME(TIME) ((TIME) <= 255) + +#define IS_FMC_NORSRAM_DEVICE(__INSTANCE__) ((__INSTANCE__) == FMC_NORSRAM_DEVICE) + +#define IS_FMC_NORSRAM_EXTENDED_DEVICE(__INSTANCE__) ((__INSTANCE__) == FMC_NORSRAM_EXTENDED_DEVICE) + +#define IS_FMC_NAND_DEVICE(__INSTANCE__) ((__INSTANCE__) == FMC_NAND_DEVICE) + +#define IS_FMC_PCCARD_DEVICE(__INSTANCE__) ((__INSTANCE__) == FMC_PCCARD_DEVICE) + +#define IS_FMC_BURSTMODE(__STATE__) (((__STATE__) == FMC_BURST_ACCESS_MODE_DISABLE) || \ + ((__STATE__) == FMC_BURST_ACCESS_MODE_ENABLE)) + +#define IS_FMC_WAIT_POLARITY(__POLARITY__) (((__POLARITY__) == FMC_WAIT_SIGNAL_POLARITY_LOW) || \ + ((__POLARITY__) == FMC_WAIT_SIGNAL_POLARITY_HIGH)) + +#if !defined (STM32F446xx) +#define IS_FMC_WRAP_MODE(__MODE__) (((__MODE__) == FMC_WRAP_MODE_DISABLE) || \ + ((__MODE__) == FMC_WRAP_MODE_ENABLE)) +#endif /* !defined (STM32F446xx) */ + +#define IS_FMC_WAIT_SIGNAL_ACTIVE(__ACTIVE__) (((__ACTIVE__) == FMC_WAIT_TIMING_BEFORE_WS) || \ + ((__ACTIVE__) == FMC_WAIT_TIMING_DURING_WS)) + +#define IS_FMC_WRITE_OPERATION(__OPERATION__) (((__OPERATION__) == FMC_WRITE_OPERATION_DISABLE) || \ + ((__OPERATION__) == FMC_WRITE_OPERATION_ENABLE)) + +#define IS_FMC_WAITE_SIGNAL(__SIGNAL__) (((__SIGNAL__) == FMC_WAIT_SIGNAL_DISABLE) || \ + ((__SIGNAL__) == FMC_WAIT_SIGNAL_ENABLE)) + +#define IS_FMC_EXTENDED_MODE(__MODE__) (((__MODE__) == FMC_EXTENDED_MODE_DISABLE) || \ + ((__MODE__) == FMC_EXTENDED_MODE_ENABLE)) + +#define IS_FMC_ASYNWAIT(__STATE__) (((__STATE__) == FMC_ASYNCHRONOUS_WAIT_DISABLE) || \ + ((__STATE__) == FMC_ASYNCHRONOUS_WAIT_ENABLE)) + +#define IS_FMC_WRITE_BURST(__BURST__) (((__BURST__) == FMC_WRITE_BURST_DISABLE) || \ + ((__BURST__) == FMC_WRITE_BURST_ENABLE)) + +#define IS_FMC_CONTINOUS_CLOCK(CCLOCK) (((CCLOCK) == FMC_CONTINUOUS_CLOCK_SYNC_ONLY) || \ + ((CCLOCK) == FMC_CONTINUOUS_CLOCK_SYNC_ASYNC)) + +#define IS_FMC_ADDRESS_SETUP_TIME(__TIME__) ((__TIME__) <= 15) + +#define IS_FMC_ADDRESS_HOLD_TIME(__TIME__) (((__TIME__) > 0) && ((__TIME__) <= 15)) + +#define IS_FMC_DATASETUP_TIME(__TIME__) (((__TIME__) > 0) && ((__TIME__) <= 255)) + +#define IS_FMC_TURNAROUND_TIME(__TIME__) ((__TIME__) <= 15) + +#define IS_FMC_DATA_LATENCY(__LATENCY__) (((__LATENCY__) > 1) && ((__LATENCY__) <= 17)) + +#define IS_FMC_CLK_DIV(DIV) (((DIV) > 1) && ((DIV) <= 16)) + +#define IS_FMC_SDRAM_BANK(BANK) (((BANK) == FMC_SDRAM_BANK1) || \ + ((BANK) == FMC_SDRAM_BANK2)) + +#define IS_FMC_COLUMNBITS_NUMBER(COLUMN) (((COLUMN) == FMC_SDRAM_COLUMN_BITS_NUM_8) || \ + ((COLUMN) == FMC_SDRAM_COLUMN_BITS_NUM_9) || \ + ((COLUMN) == FMC_SDRAM_COLUMN_BITS_NUM_10) || \ + ((COLUMN) == FMC_SDRAM_COLUMN_BITS_NUM_11)) + +#define IS_FMC_ROWBITS_NUMBER(ROW) (((ROW) == FMC_SDRAM_ROW_BITS_NUM_11) || \ + ((ROW) == FMC_SDRAM_ROW_BITS_NUM_12) || \ + ((ROW) == FMC_SDRAM_ROW_BITS_NUM_13)) + +#define IS_FMC_SDMEMORY_WIDTH(WIDTH) (((WIDTH) == FMC_SDRAM_MEM_BUS_WIDTH_8) || \ + ((WIDTH) == FMC_SDRAM_MEM_BUS_WIDTH_16) || \ + ((WIDTH) == FMC_SDRAM_MEM_BUS_WIDTH_32)) + +#define IS_FMC_INTERNALBANK_NUMBER(NUMBER) (((NUMBER) == FMC_SDRAM_INTERN_BANKS_NUM_2) || \ + ((NUMBER) == FMC_SDRAM_INTERN_BANKS_NUM_4)) + + +#define IS_FMC_CAS_LATENCY(LATENCY) (((LATENCY) == FMC_SDRAM_CAS_LATENCY_1) || \ + ((LATENCY) == FMC_SDRAM_CAS_LATENCY_2) || \ + ((LATENCY) == FMC_SDRAM_CAS_LATENCY_3)) + +#define IS_FMC_SDCLOCK_PERIOD(PERIOD) (((PERIOD) == FMC_SDRAM_CLOCK_DISABLE) || \ + ((PERIOD) == FMC_SDRAM_CLOCK_PERIOD_2) || \ + ((PERIOD) == FMC_SDRAM_CLOCK_PERIOD_3)) + +#define IS_FMC_READ_BURST(RBURST) (((RBURST) == FMC_SDRAM_RBURST_DISABLE) || \ + ((RBURST) == FMC_SDRAM_RBURST_ENABLE)) + + +#define IS_FMC_READPIPE_DELAY(DELAY) (((DELAY) == FMC_SDRAM_RPIPE_DELAY_0) || \ + ((DELAY) == FMC_SDRAM_RPIPE_DELAY_1) || \ + ((DELAY) == FMC_SDRAM_RPIPE_DELAY_2)) + +#define IS_FMC_LOADTOACTIVE_DELAY(DELAY) (((DELAY) > 0) && ((DELAY) <= 16)) + +#define IS_FMC_EXITSELFREFRESH_DELAY(DELAY) (((DELAY) > 0) && ((DELAY) <= 16)) + +#define IS_FMC_SELFREFRESH_TIME(TIME) (((TIME) > 0) && ((TIME) <= 16)) + +#define IS_FMC_ROWCYCLE_DELAY(DELAY) (((DELAY) > 0) && ((DELAY) <= 16)) + +#define IS_FMC_WRITE_RECOVERY_TIME(TIME) (((TIME) > 0) && ((TIME) <= 16)) + +#define IS_FMC_RP_DELAY(DELAY) (((DELAY) > 0) && ((DELAY) <= 16)) + +#define IS_FMC_RCD_DELAY(DELAY) (((DELAY) > 0) && ((DELAY) <= 16)) + +#define IS_FMC_COMMAND_MODE(COMMAND) (((COMMAND) == FMC_SDRAM_CMD_NORMAL_MODE) || \ + ((COMMAND) == FMC_SDRAM_CMD_CLK_ENABLE) || \ + ((COMMAND) == FMC_SDRAM_CMD_PALL) || \ + ((COMMAND) == FMC_SDRAM_CMD_AUTOREFRESH_MODE) || \ + ((COMMAND) == FMC_SDRAM_CMD_LOAD_MODE) || \ + ((COMMAND) == FMC_SDRAM_CMD_SELFREFRESH_MODE) || \ + ((COMMAND) == FMC_SDRAM_CMD_POWERDOWN_MODE)) + +#define IS_FMC_COMMAND_TARGET(TARGET) (((TARGET) == FMC_SDRAM_CMD_TARGET_BANK1) || \ + ((TARGET) == FMC_SDRAM_CMD_TARGET_BANK2) || \ + ((TARGET) == FMC_SDRAM_CMD_TARGET_BANK1_2)) + +#define IS_FMC_AUTOREFRESH_NUMBER(NUMBER) (((NUMBER) > 0) && ((NUMBER) <= 16)) + +#define IS_FMC_MODE_REGISTER(CONTENT) ((CONTENT) <= 8191) + +#define IS_FMC_REFRESH_RATE(RATE) ((RATE) <= 8191) + +#define IS_FMC_SDRAM_DEVICE(INSTANCE) ((INSTANCE) == FMC_SDRAM_DEVICE) + +#define IS_FMC_WRITE_PROTECTION(WRITE) (((WRITE) == FMC_SDRAM_WRITE_PROTECTION_DISABLE) || \ + ((WRITE) == FMC_SDRAM_WRITE_PROTECTION_ENABLE)) + +#if defined (STM32F446xx) +#define IS_FMC_PAGESIZE(SIZE) (((SIZE) == FMC_PAGE_SIZE_NONE) || \ + ((SIZE) == FMC_PAGE_SIZE_128) || \ + ((SIZE) == FMC_PAGE_SIZE_256) || \ + ((SIZE) == FMC_PAGE_SIZE_1024)) + +#define IS_FMC_WRITE_FIFO(FIFO) (((FIFO) == FMC_WRITE_FIFO_DISABLE) || \ + ((FIFO) == FMC_WRITE_FIFO_ENABLE)) +#endif /* defined (STM32F446xx) */ + +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup FMC_LL_Private_Functions FMC LL Private Functions + * @{ + */ + +/** @defgroup FMC_LL_NORSRAM NOR SRAM + * @{ + */ +/** @defgroup FMC_LL_NORSRAM_Private_Functions_Group1 NOR SRAM Initialization/de-initialization functions + * @{ + */ +HAL_StatusTypeDef FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_InitTypeDef *Init); +HAL_StatusTypeDef FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank); +HAL_StatusTypeDef FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef *Device, FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, uint32_t ExtendedMode); +HAL_StatusTypeDef FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank); +/** + * @} + */ + +/** @defgroup FMC_LL_NORSRAM_Private_Functions_Group2 NOR SRAM Control functions + * @{ + */ +HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank); +/** + * @} + */ +/** + * @} + */ + +/** @defgroup FMC_LL_NAND NAND + * @{ + */ +/** @defgroup FMC_LL_NAND_Private_Functions_Group1 NAND Initialization/de-initialization functions + * @{ + */ +HAL_StatusTypeDef FMC_NAND_Init(FMC_NAND_TypeDef *Device, FMC_NAND_InitTypeDef *Init); +HAL_StatusTypeDef FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank); +HAL_StatusTypeDef FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank); +HAL_StatusTypeDef FMC_NAND_DeInit(FMC_NAND_TypeDef *Device, uint32_t Bank); +/** + * @} + */ + +/** @defgroup FMC_LL_NAND_Private_Functions_Group2 NAND Control functions + * @{ + */ +HAL_StatusTypeDef FMC_NAND_ECC_Enable(FMC_NAND_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FMC_NAND_ECC_Disable(FMC_NAND_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FMC_NAND_GetECC(FMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, uint32_t Timeout); + +/** + * @} + */ +/** + * @} + */ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) +/** @defgroup FMC_LL_PCCARD PCCARD + * @{ + */ +/** @defgroup FMC_LL_PCCARD_Private_Functions_Group1 PCCARD Initialization/de-initialization functions + * @{ + */ +HAL_StatusTypeDef FMC_PCCARD_Init(FMC_PCCARD_TypeDef *Device, FMC_PCCARD_InitTypeDef *Init); +HAL_StatusTypeDef FMC_PCCARD_CommonSpace_Timing_Init(FMC_PCCARD_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing); +HAL_StatusTypeDef FMC_PCCARD_AttributeSpace_Timing_Init(FMC_PCCARD_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing); +HAL_StatusTypeDef FMC_PCCARD_IOSpace_Timing_Init(FMC_PCCARD_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing); +HAL_StatusTypeDef FMC_PCCARD_DeInit(FMC_PCCARD_TypeDef *Device); +/** + * @} + */ +/** + * @} + */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +/** @defgroup FMC_LL_SDRAM SDRAM + * @{ + */ +/** @defgroup FMC_LL_SDRAM_Private_Functions_Group1 SDRAM Initialization/de-initialization functions + * @{ + */ +HAL_StatusTypeDef FMC_SDRAM_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_InitTypeDef *Init); +HAL_StatusTypeDef FMC_SDRAM_Timing_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_TimingTypeDef *Timing, uint32_t Bank); +HAL_StatusTypeDef FMC_SDRAM_DeInit(FMC_SDRAM_TypeDef *Device, uint32_t Bank); +/** + * @} + */ + +/** @defgroup FMC_LL_SDRAM_Private_Functions_Group2 SDRAM Control functions + * @{ + */ +HAL_StatusTypeDef FMC_SDRAM_WriteProtection_Enable(FMC_SDRAM_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FMC_SDRAM_WriteProtection_Disable(FMC_SDRAM_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FMC_SDRAM_SendCommand(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_CommandTypeDef *Command, uint32_t Timeout); +HAL_StatusTypeDef FMC_SDRAM_ProgramRefreshRate(FMC_SDRAM_TypeDef *Device, uint32_t RefreshRate); +HAL_StatusTypeDef FMC_SDRAM_SetAutoRefreshNumber(FMC_SDRAM_TypeDef *Device, uint32_t AutoRefreshNumber); +uint32_t FMC_SDRAM_GetModeStatus(FMC_SDRAM_TypeDef *Device, uint32_t Bank); +/** + * @} + */ +/** + * @} + */ + +/** + * @} + */ + +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_LL_FMC_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_fsmc.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_fsmc.h new file mode 100644 index 0000000..56b3ebd --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_fsmc.h @@ -0,0 +1,978 @@ +/** + ****************************************************************************** + * @file stm32f4xx_ll_fsmc.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of FSMC HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_LL_FSMC_H +#define __STM32F4xx_LL_FSMC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup FSMC_LL + * @{ + */ + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) +/* Private types -------------------------------------------------------------*/ +/** @defgroup FSMC_LL_Private_Types FSMC Private Types + * @{ + */ + +/** + * @brief FSMC NORSRAM Configuration Structure definition + */ +typedef struct +{ + uint32_t NSBank; /*!< Specifies the NORSRAM memory device that will be used. + This parameter can be a value of @ref FSMC_NORSRAM_Bank */ + + uint32_t DataAddressMux; /*!< Specifies whether the address and data values are + multiplexed on the data bus or not. + This parameter can be a value of @ref FSMC_Data_Address_Bus_Multiplexing */ + + uint32_t MemoryType; /*!< Specifies the type of external memory attached to + the corresponding memory device. + This parameter can be a value of @ref FSMC_Memory_Type */ + + uint32_t MemoryDataWidth; /*!< Specifies the external memory device width. + This parameter can be a value of @ref FSMC_NORSRAM_Data_Width */ + + uint32_t BurstAccessMode; /*!< Enables or disables the burst access mode for Flash memory, + valid only with synchronous burst Flash memories. + This parameter can be a value of @ref FSMC_Burst_Access_Mode */ + + uint32_t WaitSignalPolarity; /*!< Specifies the wait signal polarity, valid only when accessing + the Flash memory in burst mode. + This parameter can be a value of @ref FSMC_Wait_Signal_Polarity */ + + uint32_t WrapMode; /*!< Enables or disables the Wrapped burst access mode for Flash + memory, valid only when accessing Flash memories in burst mode. + This parameter can be a value of @ref FSMC_Wrap_Mode */ + + uint32_t WaitSignalActive; /*!< Specifies if the wait signal is asserted by the memory one + clock cycle before the wait state or during the wait state, + valid only when accessing memories in burst mode. + This parameter can be a value of @ref FSMC_Wait_Timing */ + + uint32_t WriteOperation; /*!< Enables or disables the write operation in the selected device by the FSMC. + This parameter can be a value of @ref FSMC_Write_Operation */ + + uint32_t WaitSignal; /*!< Enables or disables the wait state insertion via wait + signal, valid for Flash memory access in burst mode. + This parameter can be a value of @ref FSMC_Wait_Signal */ + + uint32_t ExtendedMode; /*!< Enables or disables the extended mode. + This parameter can be a value of @ref FSMC_Extended_Mode */ + + uint32_t AsynchronousWait; /*!< Enables or disables wait signal during asynchronous transfers, + valid only with asynchronous Flash memories. + This parameter can be a value of @ref FSMC_AsynchronousWait */ + + uint32_t WriteBurst; /*!< Enables or disables the write burst operation. + This parameter can be a value of @ref FSMC_Write_Burst */ + +}FSMC_NORSRAM_InitTypeDef; + +/** + * @brief FSMC NORSRAM Timing parameters structure definition + */ +typedef struct +{ + uint32_t AddressSetupTime; /*!< Defines the number of HCLK cycles to configure + the duration of the address setup time. + This parameter can be a value between Min_Data = 0 and Max_Data = 15. + @note This parameter is not used with synchronous NOR Flash memories. */ + + uint32_t AddressHoldTime; /*!< Defines the number of HCLK cycles to configure + the duration of the address hold time. + This parameter can be a value between Min_Data = 1 and Max_Data = 15. + @note This parameter is not used with synchronous NOR Flash memories. */ + + uint32_t DataSetupTime; /*!< Defines the number of HCLK cycles to configure + the duration of the data setup time. + This parameter can be a value between Min_Data = 1 and Max_Data = 255. + @note This parameter is used for SRAMs, ROMs and asynchronous multiplexed + NOR Flash memories. */ + + uint32_t BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure + the duration of the bus turnaround. + This parameter can be a value between Min_Data = 0 and Max_Data = 15. + @note This parameter is only used for multiplexed NOR Flash memories. */ + + uint32_t CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of + HCLK cycles. This parameter can be a value between Min_Data = 2 and Max_Data = 16. + @note This parameter is not used for asynchronous NOR Flash, SRAM or ROM + accesses. */ + + uint32_t DataLatency; /*!< Defines the number of memory clock cycles to issue + to the memory before getting the first data. + The parameter value depends on the memory type as shown below: + - It must be set to 0 in case of a CRAM + - It is don't care in asynchronous NOR, SRAM or ROM accesses + - It may assume a value between Min_Data = 2 and Max_Data = 17 in NOR Flash memories + with synchronous burst mode enable */ + + uint32_t AccessMode; /*!< Specifies the asynchronous access mode. + This parameter can be a value of @ref FSMC_Access_Mode */ + +}FSMC_NORSRAM_TimingTypeDef; + +/** + * @brief FSMC NAND Configuration Structure definition + */ +typedef struct +{ + uint32_t NandBank; /*!< Specifies the NAND memory device that will be used. + This parameter can be a value of @ref FSMC_NAND_Bank */ + + uint32_t Waitfeature; /*!< Enables or disables the Wait feature for the NAND Memory device. + This parameter can be any value of @ref FSMC_Wait_feature */ + + uint32_t MemoryDataWidth; /*!< Specifies the external memory device width. + This parameter can be any value of @ref FSMC_NAND_Data_Width */ + + uint32_t EccComputation; /*!< Enables or disables the ECC computation. + This parameter can be any value of @ref FSMC_ECC */ + + uint32_t ECCPageSize; /*!< Defines the page size for the extended ECC. + This parameter can be any value of @ref FSMC_ECC_Page_Size */ + + uint32_t TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between CLE low and RE low. + This parameter can be a value between Min_Data = 0 and Max_Data = 255 */ + + uint32_t TARSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between ALE low and RE low. + This parameter can be a number between Min_Data = 0 and Max_Data = 255 */ + +}FSMC_NAND_InitTypeDef; + +/** + * @brief FSMC NAND/PCCARD Timing parameters structure definition + */ +typedef struct +{ + uint32_t SetupTime; /*!< Defines the number of HCLK cycles to setup address before + the command assertion for NAND-Flash read or write access + to common/Attribute or I/O memory space (depending on + the memory space timing to be configured). + This parameter can be a value between Min_Data = 0 and Max_Data = 255 */ + + uint32_t WaitSetupTime; /*!< Defines the minimum number of HCLK cycles to assert the + command for NAND-Flash read or write access to + common/Attribute or I/O memory space (depending on the + memory space timing to be configured). + This parameter can be a number between Min_Data = 0 and Max_Data = 255 */ + + uint32_t HoldSetupTime; /*!< Defines the number of HCLK clock cycles to hold address + (and data for write access) after the command de-assertion + for NAND-Flash read or write access to common/Attribute + or I/O memory space (depending on the memory space timing + to be configured). + This parameter can be a number between Min_Data = 0 and Max_Data = 255 */ + + uint32_t HiZSetupTime; /*!< Defines the number of HCLK clock cycles during which the + data bus is kept in HiZ after the start of a NAND-Flash + write access to common/Attribute or I/O memory space (depending + on the memory space timing to be configured). + This parameter can be a number between Min_Data = 0 and Max_Data = 255 */ + +}FSMC_NAND_PCC_TimingTypeDef; + +/** + * @brief FSMC NAND Configuration Structure definition + */ +typedef struct +{ + uint32_t Waitfeature; /*!< Enables or disables the Wait feature for the PCCARD Memory device. + This parameter can be any value of @ref FSMC_Wait_feature */ + + uint32_t TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between CLE low and RE low. + This parameter can be a value between Min_Data = 0 and Max_Data = 255 */ + + uint32_t TARSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between ALE low and RE low. + This parameter can be a number between Min_Data = 0 and Max_Data = 255 */ + +}FSMC_PCCARD_InitTypeDef; +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup FSMC_LL_Private_Constants FSMC Private Constants + * @{ + */ + +/** @defgroup FSMC_LL_NOR_SRAM_Controller FSMC NOR/SRAM Controller + * @{ + */ +/** @defgroup FSMC_NORSRAM_Bank FSMC NOR/SRAM Bank + * @{ + */ +#define FSMC_NORSRAM_BANK1 ((uint32_t)0x00000000) +#define FSMC_NORSRAM_BANK2 ((uint32_t)0x00000002) +#define FSMC_NORSRAM_BANK3 ((uint32_t)0x00000004) +#define FSMC_NORSRAM_BANK4 ((uint32_t)0x00000006) +/** + * @} + */ + +/** @defgroup FSMC_Data_Address_Bus_Multiplexing FSMC Data Address Bus Multiplexing + * @{ + */ +#define FSMC_DATA_ADDRESS_MUX_DISABLE ((uint32_t)0x00000000) +#define FSMC_DATA_ADDRESS_MUX_ENABLE ((uint32_t)0x00000002) +/** + * @} + */ + +/** @defgroup FSMC_Memory_Type FSMC Memory Type + * @{ + */ +#define FSMC_MEMORY_TYPE_SRAM ((uint32_t)0x00000000) +#define FSMC_MEMORY_TYPE_PSRAM ((uint32_t)0x00000004) +#define FSMC_MEMORY_TYPE_NOR ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup FSMC_NORSRAM_Data_Width FSMC NOR/SRAM Data Width + * @{ + */ +#define FSMC_NORSRAM_MEM_BUS_WIDTH_8 ((uint32_t)0x00000000) +#define FSMC_NORSRAM_MEM_BUS_WIDTH_16 ((uint32_t)0x00000010) +#define FSMC_NORSRAM_MEM_BUS_WIDTH_32 ((uint32_t)0x00000020) +/** + * @} + */ + +/** @defgroup FSMC_NORSRAM_Flash_Access FSMC NOR/SRAM Flash Access + * @{ + */ +#define FSMC_NORSRAM_FLASH_ACCESS_ENABLE ((uint32_t)0x00000040) +#define FSMC_NORSRAM_FLASH_ACCESS_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup FSMC_Burst_Access_Mode FSMC Burst Access Mode + * @{ + */ +#define FSMC_BURST_ACCESS_MODE_DISABLE ((uint32_t)0x00000000) +#define FSMC_BURST_ACCESS_MODE_ENABLE ((uint32_t)0x00000100) +/** + * @} + */ + +/** @defgroup FSMC_Wait_Signal_Polarity FSMC Wait Signal Polarity + * @{ + */ +#define FSMC_WAIT_SIGNAL_POLARITY_LOW ((uint32_t)0x00000000) +#define FSMC_WAIT_SIGNAL_POLARITY_HIGH ((uint32_t)0x00000200) +/** + * @} + */ + +/** @defgroup FSMC_Wrap_Mode FSMC Wrap Mode + * @{ + */ +#define FSMC_WRAP_MODE_DISABLE ((uint32_t)0x00000000) +#define FSMC_WRAP_MODE_ENABLE ((uint32_t)0x00000400) +/** + * @} + */ + +/** @defgroup FSMC_Wait_Timing FSMC Wait Timing + * @{ + */ +#define FSMC_WAIT_TIMING_BEFORE_WS ((uint32_t)0x00000000) +#define FSMC_WAIT_TIMING_DURING_WS ((uint32_t)0x00000800) +/** + * @} + */ + +/** @defgroup FSMC_Write_Operation FSMC Write Operation + * @{ + */ +#define FSMC_WRITE_OPERATION_DISABLE ((uint32_t)0x00000000) +#define FSMC_WRITE_OPERATION_ENABLE ((uint32_t)0x00001000) +/** + * @} + */ + +/** @defgroup FSMC_Wait_Signal FSMC Wait Signal + * @{ + */ +#define FSMC_WAIT_SIGNAL_DISABLE ((uint32_t)0x00000000) +#define FSMC_WAIT_SIGNAL_ENABLE ((uint32_t)0x00002000) +/** + * @} + */ + +/** @defgroup FSMC_Extended_Mode FSMC Extended Mode + * @{ + */ +#define FSMC_EXTENDED_MODE_DISABLE ((uint32_t)0x00000000) +#define FSMC_EXTENDED_MODE_ENABLE ((uint32_t)0x00004000) +/** + * @} + */ + +/** @defgroup FSMC_AsynchronousWait FSMC Asynchronous Wait + * @{ + */ +#define FSMC_ASYNCHRONOUS_WAIT_DISABLE ((uint32_t)0x00000000) +#define FSMC_ASYNCHRONOUS_WAIT_ENABLE ((uint32_t)0x00008000) +/** + * @} + */ + +/** @defgroup FSMC_Write_Burst FSMC Write Burst + * @{ + */ +#define FSMC_WRITE_BURST_DISABLE ((uint32_t)0x00000000) +#define FSMC_WRITE_BURST_ENABLE ((uint32_t)0x00080000) +/** + * @} + */ + +/** @defgroup FSMC_Continous_Clock FSMC Continous Clock + * @{ + */ +#define FSMC_CONTINUOUS_CLOCK_SYNC_ONLY ((uint32_t)0x00000000) +#define FSMC_CONTINUOUS_CLOCK_SYNC_ASYNC ((uint32_t)0x00100000) +/** + * @} + */ + +/** @defgroup FSMC_Access_Mode FSMC Access Mode + * @{ + */ +#define FSMC_ACCESS_MODE_A ((uint32_t)0x00000000) +#define FSMC_ACCESS_MODE_B ((uint32_t)0x10000000) +#define FSMC_ACCESS_MODE_C ((uint32_t)0x20000000) +#define FSMC_ACCESS_MODE_D ((uint32_t)0x30000000) +/** + * @} + */ +/** + * @} + */ + +/** @defgroup FSMC_LL_NAND_Controller FSMC NAND and PCCARD Controller + * @{ + */ +/** @defgroup FSMC_NAND_Bank FSMC NAND Bank + * @{ + */ +#define FSMC_NAND_BANK2 ((uint32_t)0x00000010) +#define FSMC_NAND_BANK3 ((uint32_t)0x00000100) +/** + * @} + */ + +/** @defgroup FSMC_Wait_feature FSMC Wait feature + * @{ + */ +#define FSMC_NAND_PCC_WAIT_FEATURE_DISABLE ((uint32_t)0x00000000) +#define FSMC_NAND_PCC_WAIT_FEATURE_ENABLE ((uint32_t)0x00000002) +/** + * @} + */ + +/** @defgroup FSMC_PCR_Memory_Type FSMC PCR Memory Type + * @{ + */ +#define FSMC_PCR_MEMORY_TYPE_PCCARD ((uint32_t)0x00000000) +#define FSMC_PCR_MEMORY_TYPE_NAND ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup FSMC_NAND_Data_Width FSMC NAND Data Width + * @{ + */ +#define FSMC_NAND_PCC_MEM_BUS_WIDTH_8 ((uint32_t)0x00000000) +#define FSMC_NAND_PCC_MEM_BUS_WIDTH_16 ((uint32_t)0x00000010) +/** + * @} + */ + +/** @defgroup FSMC_ECC FSMC ECC + * @{ + */ +#define FSMC_NAND_ECC_DISABLE ((uint32_t)0x00000000) +#define FSMC_NAND_ECC_ENABLE ((uint32_t)0x00000040) +/** + * @} + */ + +/** @defgroup FSMC_ECC_Page_Size FSMC ECC Page Size + * @{ + */ +#define FSMC_NAND_ECC_PAGE_SIZE_256BYTE ((uint32_t)0x00000000) +#define FSMC_NAND_ECC_PAGE_SIZE_512BYTE ((uint32_t)0x00020000) +#define FSMC_NAND_ECC_PAGE_SIZE_1024BYTE ((uint32_t)0x00040000) +#define FSMC_NAND_ECC_PAGE_SIZE_2048BYTE ((uint32_t)0x00060000) +#define FSMC_NAND_ECC_PAGE_SIZE_4096BYTE ((uint32_t)0x00080000) +#define FSMC_NAND_ECC_PAGE_SIZE_8192BYTE ((uint32_t)0x000A0000) +/** + * @} + */ +/** + * @} + */ + +/** @defgroup FSMC_LL_Interrupt_definition FSMC Interrupt definition + * @{ + */ +#define FSMC_IT_RISING_EDGE ((uint32_t)0x00000008) +#define FSMC_IT_LEVEL ((uint32_t)0x00000010) +#define FSMC_IT_FALLING_EDGE ((uint32_t)0x00000020) +#define FSMC_IT_REFRESH_ERROR ((uint32_t)0x00004000) +/** + * @} + */ + +/** @defgroup FSMC_LL_Flag_definition FSMC Flag definition + * @{ + */ +#define FSMC_FLAG_RISING_EDGE ((uint32_t)0x00000001) +#define FSMC_FLAG_LEVEL ((uint32_t)0x00000002) +#define FSMC_FLAG_FALLING_EDGE ((uint32_t)0x00000004) +#define FSMC_FLAG_FEMPT ((uint32_t)0x00000040) +/** + * @} + */ + +/** @defgroup FSMC_LL_Alias_definition FSMC Alias definition + * @{ + */ +#define FSMC_NORSRAM_TypeDef FSMC_Bank1_TypeDef +#define FSMC_NORSRAM_EXTENDED_TypeDef FSMC_Bank1E_TypeDef +#define FSMC_NAND_TypeDef FSMC_Bank2_3_TypeDef +#define FSMC_PCCARD_TypeDef FSMC_Bank4_TypeDef + +#define FSMC_NORSRAM_DEVICE FSMC_Bank1 +#define FSMC_NORSRAM_EXTENDED_DEVICE FSMC_Bank1E +#define FSMC_NAND_DEVICE FSMC_Bank2_3 +#define FSMC_PCCARD_DEVICE FSMC_Bank4 + +#define FMC_NORSRAM_TypeDef FSMC_NORSRAM_TypeDef +#define FMC_NORSRAM_EXTENDED_TypeDef FSMC_NORSRAM_EXTENDED_TypeDef +#define FMC_NORSRAM_InitTypeDef FSMC_NORSRAM_InitTypeDef +#define FMC_NORSRAM_TimingTypeDef FSMC_NORSRAM_TimingTypeDef + +#define FMC_NORSRAM_Init FSMC_NORSRAM_Init +#define FMC_NORSRAM_Timing_Init FSMC_NORSRAM_Timing_Init +#define FMC_NORSRAM_Extended_Timing_Init FSMC_NORSRAM_Extended_Timing_Init +#define FMC_NORSRAM_DeInit FSMC_NORSRAM_DeInit +#define FMC_NORSRAM_WriteOperation_Enable FSMC_NORSRAM_WriteOperation_Enable +#define FMC_NORSRAM_WriteOperation_Disable FSMC_NORSRAM_WriteOperation_Disable + +#define __FMC_NORSRAM_ENABLE __FSMC_NORSRAM_ENABLE +#define __FMC_NORSRAM_DISABLE __FSMC_NORSRAM_DISABLE + +#define FMC_NAND_InitTypeDef FSMC_NAND_InitTypeDef +#define FMC_PCCARD_InitTypeDef FSMC_PCCARD_InitTypeDef +#define FMC_NAND_PCC_TimingTypeDef FSMC_NAND_PCC_TimingTypeDef + +#define FMC_NAND_Init FSMC_NAND_Init +#define FMC_NAND_CommonSpace_Timing_Init FSMC_NAND_CommonSpace_Timing_Init +#define FMC_NAND_AttributeSpace_Timing_Init FSMC_NAND_AttributeSpace_Timing_Init +#define FMC_NAND_DeInit FSMC_NAND_DeInit +#define FMC_NAND_ECC_Enable FSMC_NAND_ECC_Enable +#define FMC_NAND_ECC_Disable FSMC_NAND_ECC_Disable +#define FMC_NAND_GetECC FSMC_NAND_GetECC +#define FMC_PCCARD_Init FSMC_PCCARD_Init +#define FMC_PCCARD_CommonSpace_Timing_Init FSMC_PCCARD_CommonSpace_Timing_Init +#define FMC_PCCARD_AttributeSpace_Timing_Init FSMC_PCCARD_AttributeSpace_Timing_Init +#define FMC_PCCARD_IOSpace_Timing_Init FSMC_PCCARD_IOSpace_Timing_Init +#define FMC_PCCARD_DeInit FSMC_PCCARD_DeInit + +#define __FMC_NAND_ENABLE __FSMC_NAND_ENABLE +#define __FMC_NAND_DISABLE __FSMC_NAND_DISABLE +#define __FMC_PCCARD_ENABLE __FSMC_PCCARD_ENABLE +#define __FMC_PCCARD_DISABLE __FSMC_PCCARD_DISABLE +#define __FMC_NAND_ENABLE_IT __FSMC_NAND_ENABLE_IT +#define __FMC_NAND_DISABLE_IT __FSMC_NAND_DISABLE_IT +#define __FMC_NAND_GET_FLAG __FSMC_NAND_GET_FLAG +#define __FMC_NAND_CLEAR_FLAG __FSMC_NAND_CLEAR_FLAG +#define __FMC_PCCARD_ENABLE_IT __FSMC_PCCARD_ENABLE_IT +#define __FMC_PCCARD_DISABLE_IT __FSMC_PCCARD_DISABLE_IT +#define __FMC_PCCARD_GET_FLAG __FSMC_PCCARD_GET_FLAG +#define __FMC_PCCARD_CLEAR_FLAG __FSMC_PCCARD_CLEAR_FLAG + +#define FMC_NORSRAM_TypeDef FSMC_NORSRAM_TypeDef +#define FMC_NORSRAM_EXTENDED_TypeDef FSMC_NORSRAM_EXTENDED_TypeDef +#define FMC_NAND_TypeDef FSMC_NAND_TypeDef +#define FMC_PCCARD_TypeDef FSMC_PCCARD_TypeDef + +#define FMC_NORSRAM_DEVICE FSMC_NORSRAM_DEVICE +#define FMC_NORSRAM_EXTENDED_DEVICE FSMC_NORSRAM_EXTENDED_DEVICE +#define FMC_NAND_DEVICE FSMC_NAND_DEVICE +#define FMC_PCCARD_DEVICE FSMC_PCCARD_DEVICE + +#define FMC_NAND_BANK2 FSMC_NAND_BANK2 + +#define FMC_NORSRAM_BANK1 FSMC_NORSRAM_BANK1 +#define FMC_NORSRAM_BANK2 FSMC_NORSRAM_BANK2 +#define FMC_NORSRAM_BANK3 FSMC_NORSRAM_BANK3 + +#define FMC_IT_RISING_EDGE FSMC_IT_RISING_EDGE +#define FMC_IT_LEVEL FSMC_IT_LEVEL +#define FMC_IT_FALLING_EDGE FSMC_IT_FALLING_EDGE +#define FMC_IT_REFRESH_ERROR FSMC_IT_REFRESH_ERROR + +#define FMC_FLAG_RISING_EDGE FSMC_FLAG_RISING_EDGE +#define FMC_FLAG_LEVEL FSMC_FLAG_LEVEL +#define FMC_FLAG_FALLING_EDGE FSMC_FLAG_FALLING_EDGE +#define FMC_FLAG_FEMPT FSMC_FLAG_FEMPT +/** + * @} + */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup FSMC_LL_Private_Macros FSMC Private Macros + * @{ + */ + +/** @defgroup FSMC_LL_NOR_Macros FSMC NOR/SRAM Exported Macros + * @brief macros to handle NOR device enable/disable and read/write operations + * @{ + */ +/** + * @brief Enable the NORSRAM device access. + * @param __INSTANCE__: FSMC_NORSRAM Instance + * @param __BANK__: FSMC_NORSRAM Bank + * @retval none + */ +#define __FSMC_NORSRAM_ENABLE(__INSTANCE__, __BANK__) ((__INSTANCE__)->BTCR[(__BANK__)] |= FSMC_BCR1_MBKEN) + +/** + * @brief Disable the NORSRAM device access. + * @param __INSTANCE__: FSMC_NORSRAM Instance + * @param __BANK__: FSMC_NORSRAM Bank + * @retval none + */ +#define __FSMC_NORSRAM_DISABLE(__INSTANCE__, __BANK__) ((__INSTANCE__)->BTCR[(__BANK__)] &= ~FSMC_BCR1_MBKEN) +/** + * @} + */ + +/** @defgroup FSMC_LL_NAND_Macros FSMC NAND Macros + * @brief macros to handle NAND device enable/disable + * @{ + */ +/** + * @brief Enable the NAND device access. + * @param __INSTANCE__: FSMC_NAND Instance + * @param __BANK__: FSMC_NAND Bank + * @retval none + */ +#define __FSMC_NAND_ENABLE(__INSTANCE__, __BANK__) (((__BANK__) == FSMC_NAND_BANK2)? ((__INSTANCE__)->PCR2 |= FSMC_PCR2_PBKEN): \ + ((__INSTANCE__)->PCR3 |= FSMC_PCR3_PBKEN)) + +/** + * @brief Disable the NAND device access. + * @param __INSTANCE__: FSMC_NAND Instance + * @param __BANK__: FSMC_NAND Bank + * @retval none + */ +#define __FSMC_NAND_DISABLE(__INSTANCE__, __BANK__) (((__BANK__) == FSMC_NAND_BANK2)? ((__INSTANCE__)->PCR2 &= ~FSMC_PCR2_PBKEN): \ + ((__INSTANCE__)->PCR3 &= ~FSMC_PCR3_PBKEN)) +/** + * @} + */ + +/** @defgroup FSMC_LL_PCCARD_Macros FSMC PCCARD Macros + * @brief macros to handle SRAM read/write operations + * @{ + */ +/** + * @brief Enable the PCCARD device access. + * @param __INSTANCE__: FSMC_PCCARD Instance + * @retval none + */ +#define __FSMC_PCCARD_ENABLE(__INSTANCE__) ((__INSTANCE__)->PCR4 |= FSMC_PCR4_PBKEN) + +/** + * @brief Disable the PCCARD device access. + * @param __INSTANCE__: FSMC_PCCARD Instance + * @retval none + */ +#define __FSMC_PCCARD_DISABLE(__INSTANCE__) ((__INSTANCE__)->PCR4 &= ~FSMC_PCR4_PBKEN) +/** + * @} + */ + +/** @defgroup FSMC_LL_Flag_Interrupt_Macros FSMC Flag&Interrupt Macros + * @brief macros to handle FSMC flags and interrupts + * @{ + */ +/** + * @brief Enable the NAND device interrupt. + * @param __INSTANCE__: FSMC_NAND Instance + * @param __BANK__: FSMC_NAND Bank + * @param __INTERRUPT__: FSMC_NAND interrupt + * This parameter can be any combination of the following values: + * @arg FSMC_IT_RISING_EDGE: Interrupt rising edge. + * @arg FSMC_IT_LEVEL: Interrupt level. + * @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge. + * @retval None + */ +#define __FSMC_NAND_ENABLE_IT(__INSTANCE__, __BANK__, __INTERRUPT__) (((__BANK__) == FSMC_NAND_BANK2)? ((__INSTANCE__)->SR2 |= (__INTERRUPT__)): \ + ((__INSTANCE__)->SR3 |= (__INTERRUPT__))) + +/** + * @brief Disable the NAND device interrupt. + * @param __INSTANCE__: FSMC_NAND Instance + * @param __BANK__: FSMC_NAND Bank + * @param __INTERRUPT__: FSMC_NAND interrupt + * This parameter can be any combination of the following values: + * @arg FSMC_IT_RISING_EDGE: Interrupt rising edge. + * @arg FSMC_IT_LEVEL: Interrupt level. + * @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge. + * @retval None + */ +#define __FSMC_NAND_DISABLE_IT(__INSTANCE__, __BANK__, __INTERRUPT__) (((__BANK__) == FSMC_NAND_BANK2)? ((__INSTANCE__)->SR2 &= ~(__INTERRUPT__)): \ + ((__INSTANCE__)->SR3 &= ~(__INTERRUPT__))) + +/** + * @brief Get flag status of the NAND device. + * @param __INSTANCE__: FSMC_NAND Instance + * @param __BANK__ : FSMC_NAND Bank + * @param __FLAG__ : FSMC_NAND flag + * This parameter can be any combination of the following values: + * @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag. + * @arg FSMC_FLAG_LEVEL: Interrupt level edge flag. + * @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag. + * @arg FSMC_FLAG_FEMPT: FIFO empty flag. + * @retval The state of FLAG (SET or RESET). + */ +#define __FSMC_NAND_GET_FLAG(__INSTANCE__, __BANK__, __FLAG__) (((__BANK__) == FSMC_NAND_BANK2)? (((__INSTANCE__)->SR2 &(__FLAG__)) == (__FLAG__)): \ + (((__INSTANCE__)->SR3 &(__FLAG__)) == (__FLAG__))) +/** + * @brief Clear flag status of the NAND device. + * @param __INSTANCE__: FSMC_NAND Instance + * @param __BANK__: FSMC_NAND Bank + * @param __FLAG__: FSMC_NAND flag + * This parameter can be any combination of the following values: + * @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag. + * @arg FSMC_FLAG_LEVEL: Interrupt level edge flag. + * @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag. + * @arg FSMC_FLAG_FEMPT: FIFO empty flag. + * @retval None + */ +#define __FSMC_NAND_CLEAR_FLAG(__INSTANCE__, __BANK__, __FLAG__) (((__BANK__) == FSMC_NAND_BANK2)? ((__INSTANCE__)->SR2 &= ~(__FLAG__)): \ + ((__INSTANCE__)->SR3 &= ~(__FLAG__))) +/** + * @brief Enable the PCCARD device interrupt. + * @param __INSTANCE__: FSMC_PCCARD Instance + * @param __INTERRUPT__: FSMC_PCCARD interrupt + * This parameter can be any combination of the following values: + * @arg FSMC_IT_RISING_EDGE: Interrupt rising edge. + * @arg FSMC_IT_LEVEL: Interrupt level. + * @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge. + * @retval None + */ +#define __FSMC_PCCARD_ENABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SR4 |= (__INTERRUPT__)) + +/** + * @brief Disable the PCCARD device interrupt. + * @param __INSTANCE__: FSMC_PCCARD Instance + * @param __INTERRUPT__: FSMC_PCCARD interrupt + * This parameter can be any combination of the following values: + * @arg FSMC_IT_RISING_EDGE: Interrupt rising edge. + * @arg FSMC_IT_LEVEL: Interrupt level. + * @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge. + * @retval None + */ +#define __FSMC_PCCARD_DISABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SR4 &= ~(__INTERRUPT__)) + +/** + * @brief Get flag status of the PCCARD device. + * @param __INSTANCE__: FSMC_PCCARD Instance + * @param __FLAG__: FSMC_PCCARD flag + * This parameter can be any combination of the following values: + * @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag. + * @arg FSMC_FLAG_LEVEL: Interrupt level edge flag. + * @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag. + * @arg FSMC_FLAG_FEMPT: FIFO empty flag. + * @retval The state of FLAG (SET or RESET). + */ +#define __FSMC_PCCARD_GET_FLAG(__INSTANCE__, __FLAG__) (((__INSTANCE__)->SR4 &(__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear flag status of the PCCARD device. + * @param __INSTANCE__: FSMC_PCCARD Instance + * @param __FLAG__: FSMC_PCCARD flag + * This parameter can be any combination of the following values: + * @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag. + * @arg FSMC_FLAG_LEVEL: Interrupt level edge flag. + * @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag. + * @arg FSMC_FLAG_FEMPT: FIFO empty flag. + * @retval None + */ +#define __FSMC_PCCARD_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->SR4 &= ~(__FLAG__)) +/** + * @} + */ + +/** @defgroup FSMC_LL_Assert_Macros FSMC Assert Macros + * @{ + */ +#define IS_FSMC_NORSRAM_BANK(__BANK__) (((__BANK__) == FSMC_NORSRAM_BANK1) || \ + ((__BANK__) == FSMC_NORSRAM_BANK2) || \ + ((__BANK__) == FSMC_NORSRAM_BANK3) || \ + ((__BANK__) == FSMC_NORSRAM_BANK4)) + +#define IS_FSMC_MUX(__MUX__) (((__MUX__) == FSMC_DATA_ADDRESS_MUX_DISABLE) || \ + ((__MUX__) == FSMC_DATA_ADDRESS_MUX_ENABLE)) + +#define IS_FSMC_MEMORY(__MEMORY__) (((__MEMORY__) == FSMC_MEMORY_TYPE_SRAM) || \ + ((__MEMORY__) == FSMC_MEMORY_TYPE_PSRAM)|| \ + ((__MEMORY__) == FSMC_MEMORY_TYPE_NOR)) + +#define IS_FSMC_NORSRAM_MEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_8) || \ + ((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_16) || \ + ((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_32)) + +#define IS_FSMC_ACCESS_MODE(__MODE__) (((__MODE__) == FSMC_ACCESS_MODE_A) || \ + ((__MODE__) == FSMC_ACCESS_MODE_B) || \ + ((__MODE__) == FSMC_ACCESS_MODE_C) || \ + ((__MODE__) == FSMC_ACCESS_MODE_D)) + +#define IS_FSMC_NAND_BANK(BANK) (((BANK) == FSMC_NAND_BANK2) || \ + ((BANK) == FSMC_NAND_BANK3)) + +#define IS_FSMC_WAIT_FEATURE(FEATURE) (((FEATURE) == FSMC_NAND_PCC_WAIT_FEATURE_DISABLE) || \ + ((FEATURE) == FSMC_NAND_PCC_WAIT_FEATURE_ENABLE)) + +#define IS_FSMC_NAND_MEMORY_WIDTH(WIDTH) (((WIDTH) == FSMC_NAND_PCC_MEM_BUS_WIDTH_8) || \ + ((WIDTH) == FSMC_NAND_PCC_MEM_BUS_WIDTH_16)) + +#define IS_FSMC_ECC_STATE(STATE) (((STATE) == FSMC_NAND_ECC_DISABLE) || \ + ((STATE) == FSMC_NAND_ECC_ENABLE)) + +#define IS_FSMC_ECCPAGE_SIZE(SIZE) (((SIZE) == FSMC_NAND_ECC_PAGE_SIZE_256BYTE) || \ + ((SIZE) == FSMC_NAND_ECC_PAGE_SIZE_512BYTE) || \ + ((SIZE) == FSMC_NAND_ECC_PAGE_SIZE_1024BYTE) || \ + ((SIZE) == FSMC_NAND_ECC_PAGE_SIZE_2048BYTE) || \ + ((SIZE) == FSMC_NAND_ECC_PAGE_SIZE_4096BYTE) || \ + ((SIZE) == FSMC_NAND_ECC_PAGE_SIZE_8192BYTE)) + +#define IS_FSMC_TCLR_TIME(TIME) ((TIME) <= 255) + +#define IS_FSMC_TAR_TIME(TIME) ((TIME) <= 255) + +#define IS_FSMC_SETUP_TIME(TIME) ((TIME) <= 255) + +#define IS_FSMC_WAIT_TIME(TIME) ((TIME) <= 255) + +#define IS_FSMC_HOLD_TIME(TIME) ((TIME) <= 255) + +#define IS_FSMC_HIZ_TIME(TIME) ((TIME) <= 255) + +#define IS_FSMC_NORSRAM_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_NORSRAM_DEVICE) + +#define IS_FSMC_NORSRAM_EXTENDED_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_NORSRAM_EXTENDED_DEVICE) + +#define IS_FSMC_NAND_DEVICE(INSTANCE) ((INSTANCE) == FSMC_NAND_DEVICE) + +#define IS_FSMC_PCCARD_DEVICE(INSTANCE) ((INSTANCE) == FSMC_PCCARD_DEVICE) + +#define IS_FSMC_BURSTMODE(__STATE__) (((__STATE__) == FSMC_BURST_ACCESS_MODE_DISABLE) || \ + ((__STATE__) == FSMC_BURST_ACCESS_MODE_ENABLE)) + +#define IS_FSMC_WAIT_POLARITY(__POLARITY__) (((__POLARITY__) == FSMC_WAIT_SIGNAL_POLARITY_LOW) || \ + ((__POLARITY__) == FSMC_WAIT_SIGNAL_POLARITY_HIGH)) + +#define IS_FSMC_WRAP_MODE(__MODE__) (((__MODE__) == FSMC_WRAP_MODE_DISABLE) || \ + ((__MODE__) == FSMC_WRAP_MODE_ENABLE)) + +#define IS_FSMC_WAIT_SIGNAL_ACTIVE(__ACTIVE__) (((__ACTIVE__) == FSMC_WAIT_TIMING_BEFORE_WS) || \ + ((__ACTIVE__) == FSMC_WAIT_TIMING_DURING_WS)) + +#define IS_FSMC_WRITE_OPERATION(__OPERATION__) (((__OPERATION__) == FSMC_WRITE_OPERATION_DISABLE) || \ + ((__OPERATION__) == FSMC_WRITE_OPERATION_ENABLE)) + +#define IS_FSMC_WAITE_SIGNAL(__SIGNAL__) (((__SIGNAL__) == FSMC_WAIT_SIGNAL_DISABLE) || \ + ((__SIGNAL__) == FSMC_WAIT_SIGNAL_ENABLE)) + +#define IS_FSMC_EXTENDED_MODE(__MODE__) (((__MODE__) == FSMC_EXTENDED_MODE_DISABLE) || \ + ((__MODE__) == FSMC_EXTENDED_MODE_ENABLE)) + +#define IS_FSMC_ASYNWAIT(__STATE__) (((__STATE__) == FSMC_ASYNCHRONOUS_WAIT_DISABLE) || \ + ((__STATE__) == FSMC_ASYNCHRONOUS_WAIT_ENABLE)) + +#define IS_FSMC_DATA_LATENCY(__LATENCY__) (((__LATENCY__) > 1) && ((__LATENCY__) <= 17)) + +#define IS_FSMC_WRITE_BURST(__BURST__) (((__BURST__) == FSMC_WRITE_BURST_DISABLE) || \ + ((__BURST__) == FSMC_WRITE_BURST_ENABLE)) + +#define IS_FSMC_ADDRESS_SETUP_TIME(__TIME__) ((__TIME__) <= 15) + +#define IS_FSMC_ADDRESS_HOLD_TIME(__TIME__) (((__TIME__) > 0) && ((__TIME__) <= 15)) + +#define IS_FSMC_DATASETUP_TIME(__TIME__) (((__TIME__) > 0) && ((__TIME__) <= 255)) + +#define IS_FSMC_TURNAROUND_TIME(__TIME__) ((__TIME__) <= 15) + +#define IS_FSMC_CONTINOUS_CLOCK(CCLOCK) (((CCLOCK) == FSMC_CONTINUOUS_CLOCK_SYNC_ONLY) || \ + ((CCLOCK) == FSMC_CONTINUOUS_CLOCK_SYNC_ASYNC)) + +#define IS_FSMC_CLK_DIV(DIV) (((DIV) > 1) && ((DIV) <= 16)) + +/** + * @} + */ +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup FSMC_LL_Private_Functions FSMC LL Private Functions + * @{ + */ + +/** @defgroup FSMC_LL_NORSRAM NOR SRAM + * @{ + */ + +/** @defgroup FSMC_LL_NORSRAM_Private_Functions_Group1 NOR SRAM Initialization/de-initialization functions + * @{ + */ +HAL_StatusTypeDef FSMC_NORSRAM_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_InitTypeDef *Init); +HAL_StatusTypeDef FSMC_NORSRAM_Timing_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank); +HAL_StatusTypeDef FSMC_NORSRAM_Extended_Timing_Init(FSMC_NORSRAM_EXTENDED_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, uint32_t ExtendedMode); +HAL_StatusTypeDef FSMC_NORSRAM_DeInit(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank); +/** + * @} + */ + +/** @defgroup FSMC_LL_NORSRAM_Private_Functions_Group2 NOR SRAM Control functions + * @{ + */ +HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Enable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Disable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank); +/** + * @} + */ +/** + * @} + */ + +/** @defgroup FSMC_LL_NAND NAND + * @{ + */ +/** @defgroup FSMC_LL_NAND_Private_Functions_Group1 NAND Initialization/de-initialization functions + * @{ + */ +HAL_StatusTypeDef FSMC_NAND_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_InitTypeDef *Init); +HAL_StatusTypeDef FSMC_NAND_CommonSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank); +HAL_StatusTypeDef FSMC_NAND_AttributeSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank); +HAL_StatusTypeDef FSMC_NAND_DeInit(FSMC_NAND_TypeDef *Device, uint32_t Bank); +/** + * @} + */ + +/** @defgroup FSMC_LL_NAND_Private_Functions_Group2 NAND Control functions + * @{ + */ +HAL_StatusTypeDef FSMC_NAND_ECC_Enable(FSMC_NAND_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FSMC_NAND_ECC_Disable(FSMC_NAND_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FSMC_NAND_GetECC(FSMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, uint32_t Timeout); +/** + * @} + */ +/** + * @} + */ + +/** @defgroup FSMC_LL_PCCARD PCCARD + * @{ + */ +/** @defgroup FSMC_LL_PCCARD_Private_Functions_Group1 PCCARD Initialization/de-initialization functions + * @{ + */ +HAL_StatusTypeDef FSMC_PCCARD_Init(FSMC_PCCARD_TypeDef *Device, FSMC_PCCARD_InitTypeDef *Init); +HAL_StatusTypeDef FSMC_PCCARD_CommonSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing); +HAL_StatusTypeDef FSMC_PCCARD_AttributeSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing); +HAL_StatusTypeDef FSMC_PCCARD_IOSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing); +HAL_StatusTypeDef FSMC_PCCARD_DeInit(FSMC_PCCARD_TypeDef *Device); +/** + * @} + */ +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_LL_FSMC_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_sdmmc.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_sdmmc.h new file mode 100644 index 0000000..801a9f8 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_sdmmc.h @@ -0,0 +1,908 @@ +/** + ****************************************************************************** + * @file stm32f4xx_ll_sdmmc.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of SDMMC HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_LL_SDMMC_H +#define __STM32F4xx_LL_SDMMC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_Driver + * @{ + */ + +/** @addtogroup SDMMC_LL + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup SDMMC_LL_Exported_Types SDMMC_LL Exported Types + * @{ + */ + +/** + * @brief SDMMC Configuration Structure definition + */ +typedef struct +{ + uint32_t ClockEdge; /*!< Specifies the clock transition on which the bit capture is made. + This parameter can be a value of @ref SDIO_Clock_Edge */ + + uint32_t ClockBypass; /*!< Specifies whether the SDIO Clock divider bypass is + enabled or disabled. + This parameter can be a value of @ref SDIO_Clock_Bypass */ + + uint32_t ClockPowerSave; /*!< Specifies whether SDIO Clock output is enabled or + disabled when the bus is idle. + This parameter can be a value of @ref SDIO_Clock_Power_Save */ + + uint32_t BusWide; /*!< Specifies the SDIO bus width. + This parameter can be a value of @ref SDIO_Bus_Wide */ + + uint32_t HardwareFlowControl; /*!< Specifies whether the SDIO hardware flow control is enabled or disabled. + This parameter can be a value of @ref SDIO_Hardware_Flow_Control */ + + uint32_t ClockDiv; /*!< Specifies the clock frequency of the SDIO controller. + This parameter can be a value between Min_Data = 0 and Max_Data = 255 */ + +}SDIO_InitTypeDef; + + +/** + * @brief SDIO Command Control structure + */ +typedef struct +{ + uint32_t Argument; /*!< Specifies the SDIO command argument which is sent + to a card as part of a command message. If a command + contains an argument, it must be loaded into this register + before writing the command to the command register. */ + + uint32_t CmdIndex; /*!< Specifies the SDIO command index. It must be Min_Data = 0 and + Max_Data = 64 */ + + uint32_t Response; /*!< Specifies the SDIO response type. + This parameter can be a value of @ref SDIO_Response_Type */ + + uint32_t WaitForInterrupt; /*!< Specifies whether SDIO wait for interrupt request is + enabled or disabled. + This parameter can be a value of @ref SDIO_Wait_Interrupt_State */ + + uint32_t CPSM; /*!< Specifies whether SDIO Command path state machine (CPSM) + is enabled or disabled. + This parameter can be a value of @ref SDIO_CPSM_State */ +}SDIO_CmdInitTypeDef; + + +/** + * @brief SDIO Data Control structure + */ +typedef struct +{ + uint32_t DataTimeOut; /*!< Specifies the data timeout period in card bus clock periods. */ + + uint32_t DataLength; /*!< Specifies the number of data bytes to be transferred. */ + + uint32_t DataBlockSize; /*!< Specifies the data block size for block transfer. + This parameter can be a value of @ref SDIO_Data_Block_Size */ + + uint32_t TransferDir; /*!< Specifies the data transfer direction, whether the transfer + is a read or write. + This parameter can be a value of @ref SDIO_Transfer_Direction */ + + uint32_t TransferMode; /*!< Specifies whether data transfer is in stream or block mode. + This parameter can be a value of @ref SDIO_Transfer_Type */ + + uint32_t DPSM; /*!< Specifies whether SDIO Data path state machine (DPSM) + is enabled or disabled. + This parameter can be a value of @ref SDIO_DPSM_State */ +}SDIO_DataInitTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup SDMMC_LL_Exported_Constants SDMMC_LL Exported Constants + * @{ + */ + +/** @defgroup SDIO_Clock_Edge Clock Edge + * @{ + */ +#define SDIO_CLOCK_EDGE_RISING ((uint32_t)0x00000000) +#define SDIO_CLOCK_EDGE_FALLING SDIO_CLKCR_NEGEDGE + +#define IS_SDIO_CLOCK_EDGE(EDGE) (((EDGE) == SDIO_CLOCK_EDGE_RISING) || \ + ((EDGE) == SDIO_CLOCK_EDGE_FALLING)) +/** + * @} + */ + +/** @defgroup SDIO_Clock_Bypass Clock Bypass + * @{ + */ +#define SDIO_CLOCK_BYPASS_DISABLE ((uint32_t)0x00000000) +#define SDIO_CLOCK_BYPASS_ENABLE SDIO_CLKCR_BYPASS + +#define IS_SDIO_CLOCK_BYPASS(BYPASS) (((BYPASS) == SDIO_CLOCK_BYPASS_DISABLE) || \ + ((BYPASS) == SDIO_CLOCK_BYPASS_ENABLE)) +/** + * @} + */ + +/** @defgroup SDIO_Clock_Power_Save Clock Power Saving + * @{ + */ +#define SDIO_CLOCK_POWER_SAVE_DISABLE ((uint32_t)0x00000000) +#define SDIO_CLOCK_POWER_SAVE_ENABLE SDIO_CLKCR_PWRSAV + +#define IS_SDIO_CLOCK_POWER_SAVE(SAVE) (((SAVE) == SDIO_CLOCK_POWER_SAVE_DISABLE) || \ + ((SAVE) == SDIO_CLOCK_POWER_SAVE_ENABLE)) +/** + * @} + */ + +/** @defgroup SDIO_Bus_Wide Bus Width + * @{ + */ +#define SDIO_BUS_WIDE_1B ((uint32_t)0x00000000) +#define SDIO_BUS_WIDE_4B SDIO_CLKCR_WIDBUS_0 +#define SDIO_BUS_WIDE_8B SDIO_CLKCR_WIDBUS_1 + +#define IS_SDIO_BUS_WIDE(WIDE) (((WIDE) == SDIO_BUS_WIDE_1B) || \ + ((WIDE) == SDIO_BUS_WIDE_4B) || \ + ((WIDE) == SDIO_BUS_WIDE_8B)) +/** + * @} + */ + +/** @defgroup SDIO_Hardware_Flow_Control Hardware Flow Control + * @{ + */ +#define SDIO_HARDWARE_FLOW_CONTROL_DISABLE ((uint32_t)0x00000000) +#define SDIO_HARDWARE_FLOW_CONTROL_ENABLE SDIO_CLKCR_HWFC_EN + +#define IS_SDIO_HARDWARE_FLOW_CONTROL(CONTROL) (((CONTROL) == SDIO_HARDWARE_FLOW_CONTROL_DISABLE) || \ + ((CONTROL) == SDIO_HARDWARE_FLOW_CONTROL_ENABLE)) +/** + * @} + */ + +/** @defgroup SDIO_Clock_Division Clock Division + * @{ + */ +#define IS_SDIO_CLKDIV(DIV) ((DIV) <= 0xFF) +/** + * @} + */ + +/** @defgroup SDIO_Command_Index Command Index + * @{ + */ +#define IS_SDIO_CMD_INDEX(INDEX) ((INDEX) < 0x40) +/** + * @} + */ + +/** @defgroup SDIO_Response_Type Response Type + * @{ + */ +#define SDIO_RESPONSE_NO ((uint32_t)0x00000000) +#define SDIO_RESPONSE_SHORT SDIO_CMD_WAITRESP_0 +#define SDIO_RESPONSE_LONG SDIO_CMD_WAITRESP + +#define IS_SDIO_RESPONSE(RESPONSE) (((RESPONSE) == SDIO_RESPONSE_NO) || \ + ((RESPONSE) == SDIO_RESPONSE_SHORT) || \ + ((RESPONSE) == SDIO_RESPONSE_LONG)) +/** + * @} + */ + +/** @defgroup SDIO_Wait_Interrupt_State Wait Interrupt + * @{ + */ +#define SDIO_WAIT_NO ((uint32_t)0x00000000) +#define SDIO_WAIT_IT SDIO_CMD_WAITINT +#define SDIO_WAIT_PEND SDIO_CMD_WAITPEND + +#define IS_SDIO_WAIT(WAIT) (((WAIT) == SDIO_WAIT_NO) || \ + ((WAIT) == SDIO_WAIT_IT) || \ + ((WAIT) == SDIO_WAIT_PEND)) +/** + * @} + */ + +/** @defgroup SDIO_CPSM_State CPSM State + * @{ + */ +#define SDIO_CPSM_DISABLE ((uint32_t)0x00000000) +#define SDIO_CPSM_ENABLE SDIO_CMD_CPSMEN + +#define IS_SDIO_CPSM(CPSM) (((CPSM) == SDIO_CPSM_DISABLE) || \ + ((CPSM) == SDIO_CPSM_ENABLE)) +/** + * @} + */ + +/** @defgroup SDIO_Response_Registers Response Register + * @{ + */ +#define SDIO_RESP1 ((uint32_t)0x00000000) +#define SDIO_RESP2 ((uint32_t)0x00000004) +#define SDIO_RESP3 ((uint32_t)0x00000008) +#define SDIO_RESP4 ((uint32_t)0x0000000C) + +#define IS_SDIO_RESP(RESP) (((RESP) == SDIO_RESP1) || \ + ((RESP) == SDIO_RESP2) || \ + ((RESP) == SDIO_RESP3) || \ + ((RESP) == SDIO_RESP4)) +/** + * @} + */ + +/** @defgroup SDIO_Data_Length Data Lenght + * @{ + */ +#define IS_SDIO_DATA_LENGTH(LENGTH) ((LENGTH) <= 0x01FFFFFF) +/** + * @} + */ + +/** @defgroup SDIO_Data_Block_Size Data Block Size + * @{ + */ +#define SDIO_DATABLOCK_SIZE_1B ((uint32_t)0x00000000) +#define SDIO_DATABLOCK_SIZE_2B SDIO_DCTRL_DBLOCKSIZE_0 +#define SDIO_DATABLOCK_SIZE_4B SDIO_DCTRL_DBLOCKSIZE_1 +#define SDIO_DATABLOCK_SIZE_8B ((uint32_t)0x00000030) +#define SDIO_DATABLOCK_SIZE_16B SDIO_DCTRL_DBLOCKSIZE_2 +#define SDIO_DATABLOCK_SIZE_32B ((uint32_t)0x00000050) +#define SDIO_DATABLOCK_SIZE_64B ((uint32_t)0x00000060) +#define SDIO_DATABLOCK_SIZE_128B ((uint32_t)0x00000070) +#define SDIO_DATABLOCK_SIZE_256B SDIO_DCTRL_DBLOCKSIZE_3 +#define SDIO_DATABLOCK_SIZE_512B ((uint32_t)0x00000090) +#define SDIO_DATABLOCK_SIZE_1024B ((uint32_t)0x000000A0) +#define SDIO_DATABLOCK_SIZE_2048B ((uint32_t)0x000000B0) +#define SDIO_DATABLOCK_SIZE_4096B ((uint32_t)0x000000C0) +#define SDIO_DATABLOCK_SIZE_8192B ((uint32_t)0x000000D0) +#define SDIO_DATABLOCK_SIZE_16384B ((uint32_t)0x000000E0) + +#define IS_SDIO_BLOCK_SIZE(SIZE) (((SIZE) == SDIO_DATABLOCK_SIZE_1B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_2B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_4B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_8B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_16B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_32B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_64B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_128B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_256B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_512B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_1024B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_2048B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_4096B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_8192B) || \ + ((SIZE) == SDIO_DATABLOCK_SIZE_16384B)) +/** + * @} + */ + +/** @defgroup SDIO_Transfer_Direction Transfer Direction + * @{ + */ +#define SDIO_TRANSFER_DIR_TO_CARD ((uint32_t)0x00000000) +#define SDIO_TRANSFER_DIR_TO_SDIO SDIO_DCTRL_DTDIR + +#define IS_SDIO_TRANSFER_DIR(DIR) (((DIR) == SDIO_TRANSFER_DIR_TO_CARD) || \ + ((DIR) == SDIO_TRANSFER_DIR_TO_SDIO)) +/** + * @} + */ + +/** @defgroup SDIO_Transfer_Type Transfer Type + * @{ + */ +#define SDIO_TRANSFER_MODE_BLOCK ((uint32_t)0x00000000) +#define SDIO_TRANSFER_MODE_STREAM SDIO_DCTRL_DTMODE + +#define IS_SDIO_TRANSFER_MODE(MODE) (((MODE) == SDIO_TRANSFER_MODE_BLOCK) || \ + ((MODE) == SDIO_TRANSFER_MODE_STREAM)) +/** + * @} + */ + +/** @defgroup SDIO_DPSM_State DPSM State + * @{ + */ +#define SDIO_DPSM_DISABLE ((uint32_t)0x00000000) +#define SDIO_DPSM_ENABLE SDIO_DCTRL_DTEN + +#define IS_SDIO_DPSM(DPSM) (((DPSM) == SDIO_DPSM_DISABLE) ||\ + ((DPSM) == SDIO_DPSM_ENABLE)) +/** + * @} + */ + +/** @defgroup SDIO_Read_Wait_Mode Read Wait Mode + * @{ + */ +#define SDIO_READ_WAIT_MODE_DATA2 ((uint32_t)0x00000000) +#define SDIO_READ_WAIT_MODE_CLK ((uint32_t)0x00000001) + +#define IS_SDIO_READWAIT_MODE(MODE) (((MODE) == SDIO_READ_WAIT_MODE_CLK) || \ + ((MODE) == SDIO_READ_WAIT_MODE_DATA2)) +/** + * @} + */ + +/** @defgroup SDIO_Interrupt_sources Interrupt Sources + * @{ + */ +#define SDIO_IT_CCRCFAIL SDIO_STA_CCRCFAIL +#define SDIO_IT_DCRCFAIL SDIO_STA_DCRCFAIL +#define SDIO_IT_CTIMEOUT SDIO_STA_CTIMEOUT +#define SDIO_IT_DTIMEOUT SDIO_STA_DTIMEOUT +#define SDIO_IT_TXUNDERR SDIO_STA_TXUNDERR +#define SDIO_IT_RXOVERR SDIO_STA_RXOVERR +#define SDIO_IT_CMDREND SDIO_STA_CMDREND +#define SDIO_IT_CMDSENT SDIO_STA_CMDSENT +#define SDIO_IT_DATAEND SDIO_STA_DATAEND +#define SDIO_IT_STBITERR SDIO_STA_STBITERR +#define SDIO_IT_DBCKEND SDIO_STA_DBCKEND +#define SDIO_IT_CMDACT SDIO_STA_CMDACT +#define SDIO_IT_TXACT SDIO_STA_TXACT +#define SDIO_IT_RXACT SDIO_STA_RXACT +#define SDIO_IT_TXFIFOHE SDIO_STA_TXFIFOHE +#define SDIO_IT_RXFIFOHF SDIO_STA_RXFIFOHF +#define SDIO_IT_TXFIFOF SDIO_STA_TXFIFOF +#define SDIO_IT_RXFIFOF SDIO_STA_RXFIFOF +#define SDIO_IT_TXFIFOE SDIO_STA_TXFIFOE +#define SDIO_IT_RXFIFOE SDIO_STA_RXFIFOE +#define SDIO_IT_TXDAVL SDIO_STA_TXDAVL +#define SDIO_IT_RXDAVL SDIO_STA_RXDAVL +#define SDIO_IT_SDIOIT SDIO_STA_SDIOIT +#define SDIO_IT_CEATAEND SDIO_STA_CEATAEND +/** + * @} + */ + +/** @defgroup SDIO_Flags Flags + * @{ + */ +#define SDIO_FLAG_CCRCFAIL SDIO_STA_CCRCFAIL +#define SDIO_FLAG_DCRCFAIL SDIO_STA_DCRCFAIL +#define SDIO_FLAG_CTIMEOUT SDIO_STA_CTIMEOUT +#define SDIO_FLAG_DTIMEOUT SDIO_STA_DTIMEOUT +#define SDIO_FLAG_TXUNDERR SDIO_STA_TXUNDERR +#define SDIO_FLAG_RXOVERR SDIO_STA_RXOVERR +#define SDIO_FLAG_CMDREND SDIO_STA_CMDREND +#define SDIO_FLAG_CMDSENT SDIO_STA_CMDSENT +#define SDIO_FLAG_DATAEND SDIO_STA_DATAEND +#define SDIO_FLAG_STBITERR SDIO_STA_STBITERR +#define SDIO_FLAG_DBCKEND SDIO_STA_DBCKEND +#define SDIO_FLAG_CMDACT SDIO_STA_CMDACT +#define SDIO_FLAG_TXACT SDIO_STA_TXACT +#define SDIO_FLAG_RXACT SDIO_STA_RXACT +#define SDIO_FLAG_TXFIFOHE SDIO_STA_TXFIFOHE +#define SDIO_FLAG_RXFIFOHF SDIO_STA_RXFIFOHF +#define SDIO_FLAG_TXFIFOF SDIO_STA_TXFIFOF +#define SDIO_FLAG_RXFIFOF SDIO_STA_RXFIFOF +#define SDIO_FLAG_TXFIFOE SDIO_STA_TXFIFOE +#define SDIO_FLAG_RXFIFOE SDIO_STA_RXFIFOE +#define SDIO_FLAG_TXDAVL SDIO_STA_TXDAVL +#define SDIO_FLAG_RXDAVL SDIO_STA_RXDAVL +#define SDIO_FLAG_SDIOIT SDIO_STA_SDIOIT +#define SDIO_FLAG_CEATAEND SDIO_STA_CEATAEND +/** + * @} + */ + +/** + * @} + */ +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup SDMMC_LL_Exported_macros SDMMC_LL Exported Macros + * @{ + */ + +/** @defgroup SDMMC_LL_Alias_Region Bit Address in the alias region + * @{ + */ +/* ------------ SDIO registers bit address in the alias region -------------- */ +#define SDIO_OFFSET (SDIO_BASE - PERIPH_BASE) + +/* --- CLKCR Register ---*/ +/* Alias word address of CLKEN bit */ +#define CLKCR_OFFSET (SDIO_OFFSET + 0x04) +#define CLKEN_BITNUMBER 0x08 +#define CLKCR_CLKEN_BB (PERIPH_BB_BASE + (CLKCR_OFFSET * 32) + (CLKEN_BITNUMBER * 4)) + +/* --- CMD Register ---*/ +/* Alias word address of SDIOSUSPEND bit */ +#define CMD_OFFSET (SDIO_OFFSET + 0x0C) +#define SDIOSUSPEND_BITNUMBER 0x0B +#define CMD_SDIOSUSPEND_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (SDIOSUSPEND_BITNUMBER * 4)) + +/* Alias word address of ENCMDCOMPL bit */ +#define ENCMDCOMPL_BITNUMBER 0x0C +#define CMD_ENCMDCOMPL_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (ENCMDCOMPL_BITNUMBER * 4)) + +/* Alias word address of NIEN bit */ +#define NIEN_BITNUMBER 0x0D +#define CMD_NIEN_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (NIEN_BITNUMBER * 4)) + +/* Alias word address of ATACMD bit */ +#define ATACMD_BITNUMBER 0x0E +#define CMD_ATACMD_BB (PERIPH_BB_BASE + (CMD_OFFSET * 32) + (ATACMD_BITNUMBER * 4)) + +/* --- DCTRL Register ---*/ +/* Alias word address of DMAEN bit */ +#define DCTRL_OFFSET (SDIO_OFFSET + 0x2C) +#define DMAEN_BITNUMBER 0x03 +#define DCTRL_DMAEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (DMAEN_BITNUMBER * 4)) + +/* Alias word address of RWSTART bit */ +#define RWSTART_BITNUMBER 0x08 +#define DCTRL_RWSTART_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWSTART_BITNUMBER * 4)) + +/* Alias word address of RWSTOP bit */ +#define RWSTOP_BITNUMBER 0x09 +#define DCTRL_RWSTOP_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWSTOP_BITNUMBER * 4)) + +/* Alias word address of RWMOD bit */ +#define RWMOD_BITNUMBER 0x0A +#define DCTRL_RWMOD_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (RWMOD_BITNUMBER * 4)) + +/* Alias word address of SDIOEN bit */ +#define SDIOEN_BITNUMBER 0x0B +#define DCTRL_SDIOEN_BB (PERIPH_BB_BASE + (DCTRL_OFFSET * 32) + (SDIOEN_BITNUMBER * 4)) +/** + * @} + */ + +/** @defgroup SDMMC_LL_Register Bits And Addresses Definitions + * @brief SDMMC_LL registers bit address in the alias region + * @{ + */ + +/* ---------------------- SDIO registers bit mask --------------------------- */ +/* --- CLKCR Register ---*/ +/* CLKCR register clear mask */ +#define CLKCR_CLEAR_MASK ((uint32_t)(SDIO_CLKCR_CLKDIV | SDIO_CLKCR_PWRSAV |\ + SDIO_CLKCR_BYPASS | SDIO_CLKCR_WIDBUS |\ + SDIO_CLKCR_NEGEDGE | SDIO_CLKCR_HWFC_EN)) + +/* --- PWRCTRL Register ---*/ +/* --- DCTRL Register ---*/ +/* SDIO DCTRL Clear Mask */ +#define DCTRL_CLEAR_MASK ((uint32_t)(SDIO_DCTRL_DTEN | SDIO_DCTRL_DTDIR |\ + SDIO_DCTRL_DTMODE | SDIO_DCTRL_DBLOCKSIZE)) + +/* --- CMD Register ---*/ +/* CMD Register clear mask */ +#define CMD_CLEAR_MASK ((uint32_t)(SDIO_CMD_CMDINDEX | SDIO_CMD_WAITRESP |\ + SDIO_CMD_WAITINT | SDIO_CMD_WAITPEND |\ + SDIO_CMD_CPSMEN | SDIO_CMD_SDIOSUSPEND)) + +/* SDIO RESP Registers Address */ +#define SDIO_RESP_ADDR ((uint32_t)(SDIO_BASE + 0x14)) + +/* SDIO Initialization Frequency (400KHz max) */ +#define SDIO_INIT_CLK_DIV ((uint8_t)0x76) + +/* SDIO Data Transfer Frequency (25MHz max) */ +#define SDIO_TRANSFER_CLK_DIV ((uint8_t)0x0) +/** + * @} + */ + +/** @defgroup SDMMC_LL_Interrupt_Clock Interrupt And Clock Configuration + * @brief macros to handle interrupts and specific clock configurations + * @{ + */ + +/** + * @brief Enable the SDIO device. + * @retval None + */ +#define __SDIO_ENABLE() (*(__IO uint32_t *)CLKCR_CLKEN_BB = ENABLE) + +/** + * @brief Disable the SDIO device. + * @retval None + */ +#define __SDIO_DISABLE() (*(__IO uint32_t *)CLKCR_CLKEN_BB = DISABLE) + +/** + * @brief Enable the SDIO DMA transfer. + * @retval None + */ +#define __SDIO_DMA_ENABLE() (*(__IO uint32_t *)DCTRL_DMAEN_BB = ENABLE) + +/** + * @brief Disable the SDIO DMA transfer. + * @retval None + */ +#define __SDIO_DMA_DISABLE() (*(__IO uint32_t *)DCTRL_DMAEN_BB = DISABLE) + +/** + * @brief Enable the SDIO device interrupt. + * @param __INSTANCE__ : Pointer to SDIO register base + * @param __INTERRUPT__ : specifies the SDIO interrupt sources to be enabled. + * This parameter can be one or a combination of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt + * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt + * @arg SDIO_IT_TXACT: Data transmit in progress interrupt + * @arg SDIO_IT_RXACT: Data receive in progress interrupt + * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt + * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt + * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt + * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt + * @retval None + */ +#define __SDIO_ENABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->MASK |= (__INTERRUPT__)) + +/** + * @brief Disable the SDIO device interrupt. + * @param __INSTANCE__ : Pointer to SDIO register base + * @param __INTERRUPT__ : specifies the SDIO interrupt sources to be disabled. + * This parameter can be one or a combination of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt + * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt + * @arg SDIO_IT_TXACT: Data transmit in progress interrupt + * @arg SDIO_IT_RXACT: Data receive in progress interrupt + * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt + * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt + * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt + * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt + * @retval None + */ +#define __SDIO_DISABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->MASK &= ~(__INTERRUPT__)) + +/** + * @brief Checks whether the specified SDIO flag is set or not. + * @param __INSTANCE__ : Pointer to SDIO register base + * @param __FLAG__: specifies the flag to check. + * This parameter can be one of the following values: + * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed) + * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) + * @arg SDIO_FLAG_CTIMEOUT: Command response timeout + * @arg SDIO_FLAG_DTIMEOUT: Data timeout + * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error + * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error + * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed) + * @arg SDIO_FLAG_CMDSENT: Command sent (no response required) + * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero) + * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide bus mode. + * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed) + * @arg SDIO_FLAG_CMDACT: Command transfer in progress + * @arg SDIO_FLAG_TXACT: Data transmit in progress + * @arg SDIO_FLAG_RXACT: Data receive in progress + * @arg SDIO_FLAG_TXFIFOHE: Transmit FIFO Half Empty + * @arg SDIO_FLAG_RXFIFOHF: Receive FIFO Half Full + * @arg SDIO_FLAG_TXFIFOF: Transmit FIFO full + * @arg SDIO_FLAG_RXFIFOF: Receive FIFO full + * @arg SDIO_FLAG_TXFIFOE: Transmit FIFO empty + * @arg SDIO_FLAG_RXFIFOE: Receive FIFO empty + * @arg SDIO_FLAG_TXDAVL: Data available in transmit FIFO + * @arg SDIO_FLAG_RXDAVL: Data available in receive FIFO + * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received + * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61 + * @retval The new state of SDIO_FLAG (SET or RESET). + */ +#define __SDIO_GET_FLAG(__INSTANCE__, __FLAG__) (((__INSTANCE__)->STA &(__FLAG__)) != RESET) + + +/** + * @brief Clears the SDIO pending flags. + * @param __INSTANCE__ : Pointer to SDIO register base + * @param __FLAG__: specifies the flag to clear. + * This parameter can be one or a combination of the following values: + * @arg SDIO_FLAG_CCRCFAIL: Command response received (CRC check failed) + * @arg SDIO_FLAG_DCRCFAIL: Data block sent/received (CRC check failed) + * @arg SDIO_FLAG_CTIMEOUT: Command response timeout + * @arg SDIO_FLAG_DTIMEOUT: Data timeout + * @arg SDIO_FLAG_TXUNDERR: Transmit FIFO underrun error + * @arg SDIO_FLAG_RXOVERR: Received FIFO overrun error + * @arg SDIO_FLAG_CMDREND: Command response received (CRC check passed) + * @arg SDIO_FLAG_CMDSENT: Command sent (no response required) + * @arg SDIO_FLAG_DATAEND: Data end (data counter, SDIDCOUNT, is zero) + * @arg SDIO_FLAG_STBITERR: Start bit not detected on all data signals in wide bus mode + * @arg SDIO_FLAG_DBCKEND: Data block sent/received (CRC check passed) + * @arg SDIO_FLAG_SDIOIT: SD I/O interrupt received + * @arg SDIO_FLAG_CEATAEND: CE-ATA command completion signal received for CMD61 + * @retval None + */ +#define __SDIO_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->ICR = (__FLAG__)) + +/** + * @brief Checks whether the specified SDIO interrupt has occurred or not. + * @param __INSTANCE__ : Pointer to SDIO register base + * @param __INTERRUPT__: specifies the SDIO interrupt source to check. + * This parameter can be one of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIDCOUNT, is zero) interrupt + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt + * @arg SDIO_IT_DBCKEND: Data block sent/received (CRC check passed) interrupt + * @arg SDIO_IT_CMDACT: Command transfer in progress interrupt + * @arg SDIO_IT_TXACT: Data transmit in progress interrupt + * @arg SDIO_IT_RXACT: Data receive in progress interrupt + * @arg SDIO_IT_TXFIFOHE: Transmit FIFO Half Empty interrupt + * @arg SDIO_IT_RXFIFOHF: Receive FIFO Half Full interrupt + * @arg SDIO_IT_TXFIFOF: Transmit FIFO full interrupt + * @arg SDIO_IT_RXFIFOF: Receive FIFO full interrupt + * @arg SDIO_IT_TXFIFOE: Transmit FIFO empty interrupt + * @arg SDIO_IT_RXFIFOE: Receive FIFO empty interrupt + * @arg SDIO_IT_TXDAVL: Data available in transmit FIFO interrupt + * @arg SDIO_IT_RXDAVL: Data available in receive FIFO interrupt + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 interrupt + * @retval The new state of SDIO_IT (SET or RESET). + */ +#define __SDIO_GET_IT (__INSTANCE__, __INTERRUPT__) (((__INSTANCE__)->STA &(__INTERRUPT__)) == (__INTERRUPT__)) + +/** + * @brief Clears the SDIO's interrupt pending bits. + * @param __INSTANCE__ : Pointer to SDIO register base + * @param __INTERRUPT__: specifies the interrupt pending bit to clear. + * This parameter can be one or a combination of the following values: + * @arg SDIO_IT_CCRCFAIL: Command response received (CRC check failed) interrupt + * @arg SDIO_IT_DCRCFAIL: Data block sent/received (CRC check failed) interrupt + * @arg SDIO_IT_CTIMEOUT: Command response timeout interrupt + * @arg SDIO_IT_DTIMEOUT: Data timeout interrupt + * @arg SDIO_IT_TXUNDERR: Transmit FIFO underrun error interrupt + * @arg SDIO_IT_RXOVERR: Received FIFO overrun error interrupt + * @arg SDIO_IT_CMDREND: Command response received (CRC check passed) interrupt + * @arg SDIO_IT_CMDSENT: Command sent (no response required) interrupt + * @arg SDIO_IT_DATAEND: Data end (data counter, SDIO_DCOUNT, is zero) interrupt + * @arg SDIO_IT_STBITERR: Start bit not detected on all data signals in wide + * bus mode interrupt + * @arg SDIO_IT_SDIOIT: SD I/O interrupt received interrupt + * @arg SDIO_IT_CEATAEND: CE-ATA command completion signal received for CMD61 + * @retval None + */ +#define __SDIO_CLEAR_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->ICR = (__INTERRUPT__)) + +/** + * @brief Enable Start the SD I/O Read Wait operation. + * @retval None + */ +#define __SDIO_START_READWAIT_ENABLE() (*(__IO uint32_t *) DCTRL_RWSTART_BB = ENABLE) + +/** + * @brief Disable Start the SD I/O Read Wait operations. + * @retval None + */ +#define __SDIO_START_READWAIT_DISABLE() (*(__IO uint32_t *) DCTRL_RWSTART_BB = DISABLE) + +/** + * @brief Enable Start the SD I/O Read Wait operation. + * @retval None + */ +#define __SDIO_STOP_READWAIT_ENABLE() (*(__IO uint32_t *) DCTRL_RWSTOP_BB = ENABLE) + +/** + * @brief Disable Stop the SD I/O Read Wait operations. + * @retval None + */ +#define __SDIO_STOP_READWAIT_DISABLE() (*(__IO uint32_t *) DCTRL_RWSTOP_BB = DISABLE) + +/** + * @brief Enable the SD I/O Mode Operation. + * @retval None + */ +#define __SDIO_OPERATION_ENABLE() (*(__IO uint32_t *) DCTRL_SDIOEN_BB = ENABLE) + +/** + * @brief Disable the SD I/O Mode Operation. + * @retval None + */ +#define __SDIO_OPERATION_DISABLE() (*(__IO uint32_t *) DCTRL_SDIOEN_BB = DISABLE) + +/** + * @brief Enable the SD I/O Suspend command sending. + * @retval None + */ +#define __SDIO_SUSPEND_CMD_ENABLE() (*(__IO uint32_t *) CMD_SDIOSUSPEND_BB = ENABLE) + +/** + * @brief Disable the SD I/O Suspend command sending. + * @retval None + */ +#define __SDIO_SUSPEND_CMD_DISABLE() (*(__IO uint32_t *) CMD_SDIOSUSPEND_BB = DISABLE) + +#if !defined(STM32F446xx) +/** + * @brief Enable the command completion signal. + * @retval None + */ +#define __SDIO_CEATA_CMD_COMPLETION_ENABLE() (*(__IO uint32_t *) CMD_ENCMDCOMPL_BB = ENABLE) + +/** + * @brief Disable the command completion signal. + * @retval None + */ +#define __SDIO_CEATA_CMD_COMPLETION_DISABLE() (*(__IO uint32_t *) CMD_ENCMDCOMPL_BB = DISABLE) + +/** + * @brief Enable the CE-ATA interrupt. + * @retval None + */ +#define __SDIO_CEATA_ENABLE_IT() (*(__IO uint32_t *) CMD_NIEN_BB = (uint32_t)0) + +/** + * @brief Disable the CE-ATA interrupt. + * @retval None + */ +#define __SDIO_CEATA_DISABLE_IT() (*(__IO uint32_t *) CMD_NIEN_BB = (uint32_t)1) + +/** + * @brief Enable send CE-ATA command (CMD61). + * @retval None + */ +#define __SDIO_CEATA_SENDCMD_ENABLE() (*(__IO uint32_t *) CMD_ATACMD_BB = ENABLE) + +/** + * @brief Disable send CE-ATA command (CMD61). + * @retval None + */ +#define __SDIO_CEATA_SENDCMD_DISABLE() (*(__IO uint32_t *) CMD_ATACMD_BB = DISABLE) +#endif /* !defined(STM32F446xx) */ +/** + * @} + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SDMMC_LL_Exported_Functions + * @{ + */ + +/* Initialization/de-initialization functions **********************************/ +/** @addtogroup HAL_SDMMC_LL_Group1 + * @{ + */ +HAL_StatusTypeDef SDIO_Init(SDIO_TypeDef *SDIOx, SDIO_InitTypeDef Init); +/** + * @} + */ + +/* I/O operation functions *****************************************************/ +/** @addtogroup HAL_SDMMC_LL_Group2 + * @{ + */ +/* Blocking mode: Polling */ +uint32_t SDIO_ReadFIFO(SDIO_TypeDef *SDIOx); +HAL_StatusTypeDef SDIO_WriteFIFO(SDIO_TypeDef *SDIOx, uint32_t *pWriteData); +/** + * @} + */ + +/* Peripheral Control functions ************************************************/ +/** @addtogroup HAL_SDMMC_LL_Group3 + * @{ + */ +HAL_StatusTypeDef SDIO_PowerState_ON(SDIO_TypeDef *SDIOx); +HAL_StatusTypeDef SDIO_PowerState_OFF(SDIO_TypeDef *SDIOx); +uint32_t SDIO_GetPowerState(SDIO_TypeDef *SDIOx); + +/* Command path state machine (CPSM) management functions */ +HAL_StatusTypeDef SDIO_SendCommand(SDIO_TypeDef *SDIOx, SDIO_CmdInitTypeDef *SDIO_CmdInitStruct); +uint8_t SDIO_GetCommandResponse(SDIO_TypeDef *SDIOx); +uint32_t SDIO_GetResponse(uint32_t SDIO_RESP); + +/* Data path state machine (DPSM) management functions */ +HAL_StatusTypeDef SDIO_DataConfig(SDIO_TypeDef *SDIOx, SDIO_DataInitTypeDef* SDIO_DataInitStruct); +uint32_t SDIO_GetDataCounter(SDIO_TypeDef *SDIOx); +uint32_t SDIO_GetFIFOCount(SDIO_TypeDef *SDIOx); + +/* SDIO IO Cards mode management functions */ +HAL_StatusTypeDef SDIO_SetSDIOReadWaitMode(uint32_t SDIO_ReadWaitMode); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_LL_SDMMC_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h new file mode 100644 index 0000000..89a2627 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_usb.h @@ -0,0 +1,470 @@ +/** + ****************************************************************************** + * @file stm32f4xx_ll_usb.h + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Header file of USB Core HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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_LL_USB_H +#define __STM32F4xx_LL_USB_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL + * @{ + */ + +/** @addtogroup USB_Core + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ + +/** + * @brief USB Mode definition + */ +typedef enum +{ + USB_OTG_DEVICE_MODE = 0, + USB_OTG_HOST_MODE = 1, + USB_OTG_DRD_MODE = 2 + +}USB_OTG_ModeTypeDef; + +/** + * @brief URB States definition + */ +typedef enum { + URB_IDLE = 0, + URB_DONE, + URB_NOTREADY, + URB_NYET, + URB_ERROR, + URB_STALL + +}USB_OTG_URBStateTypeDef; + +/** + * @brief Host channel States definition + */ +typedef enum { + HC_IDLE = 0, + HC_XFRC, + HC_HALTED, + HC_NAK, + HC_NYET, + HC_STALL, + HC_XACTERR, + HC_BBLERR, + HC_DATATGLERR + +}USB_OTG_HCStateTypeDef; + +/** + * @brief PCD Initialization Structure definition + */ +typedef struct +{ + uint32_t dev_endpoints; /*!< Device Endpoints number. + This parameter depends on the used USB core. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint32_t Host_channels; /*!< Host Channels number. + This parameter Depends on the used USB core. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint32_t speed; /*!< USB Core speed. + This parameter can be any value of @ref USB_Core_Speed_ */ + + uint32_t dma_enable; /*!< Enable or disable of the USB embedded DMA. */ + + uint32_t ep0_mps; /*!< Set the Endpoint 0 Max Packet size. + This parameter can be any value of @ref USB_EP0_MPS_ */ + + uint32_t phy_itface; /*!< Select the used PHY interface. + This parameter can be any value of @ref USB_Core_PHY_ */ + + uint32_t Sof_enable; /*!< Enable or disable the output of the SOF signal. */ + + uint32_t low_power_enable; /*!< Enable or disable the low power mode. */ + + uint32_t lpm_enable; /*!< Enable or disable Link Power Management. */ + + uint32_t vbus_sensing_enable; /*!< Enable or disable the VBUS Sensing feature. */ + + uint32_t use_dedicated_ep1; /*!< Enable or disable the use of the dedicated EP1 interrupt. */ + + uint32_t use_external_vbus; /*!< Enable or disable the use of the external VBUS. */ + +}USB_OTG_CfgTypeDef; + +typedef struct +{ + uint8_t num; /*!< Endpoint number + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t is_in; /*!< Endpoint direction + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t is_stall; /*!< Endpoint stall condition + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t type; /*!< Endpoint type + This parameter can be any value of @ref USB_EP_Type_ */ + + uint8_t data_pid_start; /*!< Initial data PID + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t even_odd_frame; /*!< IFrame parity + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint16_t tx_fifo_num; /*!< Transmission FIFO number + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint32_t maxpacket; /*!< Endpoint Max packet size + This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */ + + uint8_t *xfer_buff; /*!< Pointer to transfer buffer */ + + uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address */ + + uint32_t xfer_len; /*!< Current transfer length */ + + uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer */ + +}USB_OTG_EPTypeDef; + +typedef struct +{ + uint8_t *xfer_buff; /*!< Pointer to transfer buffer. */ + + uint32_t xfer_len; /*!< Current transfer length. */ + + uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer. */ + + uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address. */ + + uint32_t ErrCnt; /*!< Host channel error count.*/ + + USB_OTG_URBStateTypeDef urb_state; /*!< URB state. + This parameter can be any value of @ref USB_OTG_URBStateTypeDef */ + + USB_OTG_HCStateTypeDef state; /*!< Host Channel state. + This parameter can be any value of @ref USB_OTG_HCStateTypeDef */ + + uint16_t max_packet; /*!< Endpoint Max packet size. + This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */ + + uint8_t dev_addr ; /*!< USB device address. + This parameter must be a number between Min_Data = 1 and Max_Data = 255 */ + + uint8_t ch_num; /*!< Host channel number. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t ep_num; /*!< Endpoint number. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t ep_is_in; /*!< Endpoint direction + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t speed; /*!< USB Host speed. + This parameter can be any value of @ref USB_Core_Speed_ */ + + uint8_t do_ping; /*!< Enable or disable the use of the PING protocol for HS mode. */ + + uint8_t process_ping; /*!< Execute the PING protocol for HS mode. */ + + uint8_t ep_type; /*!< Endpoint Type. + This parameter can be any value of @ref USB_EP_Type_ */ + + uint8_t data_pid; /*!< Initial data PID. + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t toggle_in; /*!< IN transfer current toggle flag. + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t toggle_out; /*!< OUT transfer current toggle flag + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t packet_count; + + +}USB_OTG_HCTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup PCD_Exported_Constants PCD Exported Constants + * @{ + */ + +/** @defgroup USB_Core_Mode_ USB Core Mode + * @{ + */ +#define USB_OTG_MODE_DEVICE 0 +#define USB_OTG_MODE_HOST 1 +#define USB_OTG_MODE_DRD 2 +/** + * @} + */ + +/** @defgroup USB_Core_Speed_ USB Core Speed + * @{ + */ +#define USB_OTG_SPEED_HIGH 0 +#define USB_OTG_SPEED_HIGH_IN_FULL 1 +#define USB_OTG_SPEED_LOW 2 +#define USB_OTG_SPEED_FULL 3 +/** + * @} + */ + +/** @defgroup USB_Core_PHY_ USB Core PHY + * @{ + */ +#define USB_OTG_ULPI_PHY 1 +#define USB_OTG_EMBEDDED_PHY 2 +/** + * @} + */ + +/** @defgroup USB_Core_MPS_ USB Core MPS + * @{ + */ +#define USB_OTG_HS_MAX_PACKET_SIZE 512 +#define USB_OTG_FS_MAX_PACKET_SIZE 64 +#define USB_OTG_MAX_EP0_SIZE 64 +/** + * @} + */ + +/** @defgroup USB_Core_Phy_Frequency_ USB Core Phy Frequency + * @{ + */ +#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ (0 << 1) +#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ (1 << 1) +#define DSTS_ENUMSPD_LS_PHY_6MHZ (2 << 1) +#define DSTS_ENUMSPD_FS_PHY_48MHZ (3 << 1) +/** + * @} + */ + +/** @defgroup USB_CORE_Frame_Interval_ USB CORE Frame Interval + * @{ + */ +#define DCFG_FRAME_INTERVAL_80 0 +#define DCFG_FRAME_INTERVAL_85 1 +#define DCFG_FRAME_INTERVAL_90 2 +#define DCFG_FRAME_INTERVAL_95 3 +/** + * @} + */ + +/** @defgroup USB_EP0_MPS_ USB EP0 MPS + * @{ + */ +#define DEP0CTL_MPS_64 0 +#define DEP0CTL_MPS_32 1 +#define DEP0CTL_MPS_16 2 +#define DEP0CTL_MPS_8 3 +/** + * @} + */ + +/** @defgroup USB_EP_Speed_ USB EP Speed + * @{ + */ +#define EP_SPEED_LOW 0 +#define EP_SPEED_FULL 1 +#define EP_SPEED_HIGH 2 +/** + * @} + */ + +/** @defgroup USB_EP_Type_ USB EP Type + * @{ + */ +#define EP_TYPE_CTRL 0 +#define EP_TYPE_ISOC 1 +#define EP_TYPE_BULK 2 +#define EP_TYPE_INTR 3 +#define EP_TYPE_MSK 3 +/** + * @} + */ + +/** @defgroup USB_STS_Defines_ USB STS Defines + * @{ + */ +#define STS_GOUT_NAK 1 +#define STS_DATA_UPDT 2 +#define STS_XFER_COMP 3 +#define STS_SETUP_COMP 4 +#define STS_SETUP_UPDT 6 +/** + * @} + */ + +/** @defgroup HCFG_SPEED_Defines_ HCFG SPEED Defines + * @{ + */ +#define HCFG_30_60_MHZ 0 +#define HCFG_48_MHZ 1 +#define HCFG_6_MHZ 2 +/** + * @} + */ + +/** @defgroup HPRT0_PRTSPD_SPEED_Defines_ HPRT0 PRTSPD SPEED Defines + * @{ + */ +#define HPRT0_PRTSPD_HIGH_SPEED 0 +#define HPRT0_PRTSPD_FULL_SPEED 1 +#define HPRT0_PRTSPD_LOW_SPEED 2 +/** + * @} + */ + +#define HCCHAR_CTRL 0 +#define HCCHAR_ISOC 1 +#define HCCHAR_BULK 2 +#define HCCHAR_INTR 3 + +#define HC_PID_DATA0 0 +#define HC_PID_DATA2 1 +#define HC_PID_DATA1 2 +#define HC_PID_SETUP 3 + +#define GRXSTS_PKTSTS_IN 2 +#define GRXSTS_PKTSTS_IN_XFER_COMP 3 +#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5 +#define GRXSTS_PKTSTS_CH_HALTED 7 + +#define HxTXSTS_xTXQSAV_SHIFT 16 +#define HxTXSTS_xTXQSAV_MASK 0xFF + +#define USBx_PCGCCTL *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_PCGCCTL_BASE) +#define USBx_HPRT0 *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_HOST_PORT_BASE) + +#define USBx_DEVICE ((USB_OTG_DeviceTypeDef *)((uint32_t )USBx + USB_OTG_DEVICE_BASE)) +#define USBx_INEP(i) ((USB_OTG_INEndpointTypeDef *)((uint32_t)USBx + USB_OTG_IN_ENDPOINT_BASE + (i)*USB_OTG_EP_REG_SIZE)) +#define USBx_OUTEP(i) ((USB_OTG_OUTEndpointTypeDef *)((uint32_t)USBx + USB_OTG_OUT_ENDPOINT_BASE + (i)*USB_OTG_EP_REG_SIZE)) +#define USBx_DFIFO(i) *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_FIFO_BASE + (i) * USB_OTG_FIFO_SIZE) + +#define USBx_HOST ((USB_OTG_HostTypeDef *)((uint32_t )USBx + USB_OTG_HOST_BASE)) +#define USBx_HC(i) ((USB_OTG_HostChannelTypeDef *)((uint32_t)USBx + USB_OTG_HOST_CHANNEL_BASE + (i)*USB_OTG_HOST_CHANNEL_SIZE)) +/** + * @} + */ +/* Exported macro ------------------------------------------------------------*/ +#define USB_MASK_INTERRUPT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->GINTMSK &= ~(__INTERRUPT__)) +#define USB_UNMASK_INTERRUPT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->GINTMSK |= (__INTERRUPT__)) + +#define CLEAR_IN_EP_INTR(__EPNUM__, __INTERRUPT__) (USBx_INEP(__EPNUM__)->DIEPINT = (__INTERRUPT__)) +#define CLEAR_OUT_EP_INTR(__EPNUM__, __INTERRUPT__) (USBx_OUTEP(__EPNUM__)->DOEPINT = (__INTERRUPT__)) + +/* Exported functions --------------------------------------------------------*/ +HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef Init); +HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef Init); +HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx , USB_OTG_ModeTypeDef mode); +HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx , uint8_t speed); +HAL_StatusTypeDef USB_FlushRxFifo (USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_FlushTxFifo (USB_OTG_GlobalTypeDef *USBx, uint32_t num ); +HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep); +HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep); +HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep); +HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep); +HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma); +HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma); +HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma); +void * USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len); +HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep); +HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep); +HAL_StatusTypeDef USB_SetDevAddress (USB_OTG_GlobalTypeDef *USBx, uint8_t address); +HAL_StatusTypeDef USB_DevConnect (USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_DevDisconnect (USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_ActivateSetup (USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t dma, uint8_t *psetup); +uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx); +uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx); +uint32_t USB_ReadInterrupts (USB_OTG_GlobalTypeDef *USBx); +uint32_t USB_ReadDevAllOutEpInterrupt (USB_OTG_GlobalTypeDef *USBx); +uint32_t USB_ReadDevOutEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum); +uint32_t USB_ReadDevAllInEpInterrupt (USB_OTG_GlobalTypeDef *USBx); +uint32_t USB_ReadDevInEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum); +void USB_ClearInterrupts (USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt); + +HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg); +HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx , uint8_t freq); +HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_DriveVbus (USB_OTG_GlobalTypeDef *USBx, uint8_t state); +uint32_t USB_GetHostSpeed (USB_OTG_GlobalTypeDef *USBx); +uint32_t USB_GetCurrentFrame (USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, + uint8_t ch_num, + uint8_t epnum, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps); +HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma); +HAL_StatusTypeDef USB_HC_WriteEmptyTxFifo(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t periodic); +uint32_t USB_HC_ReadInterrupt (USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num); +HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx , uint8_t ch_num); +HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F4xx_LL_USB_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c new file mode 100644 index 0000000..c2b12fa --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c @@ -0,0 +1,533 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief HAL module driver. + * This is the common part of the HAL initialization + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The common HAL driver contains a set of generic and common APIs that can be + used by the PPP peripheral drivers and the user to start using the HAL. + [..] + The HAL contains two APIs' categories: + (+) Common HAL APIs + (+) Services HAL APIs + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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. + * + ****************************************************************************** + * + * Modifications by Robert Fisk + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup HAL HAL + * @brief HAL module driver. + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup HAL_Private_Constants + * @{ + */ +/** + * @brief STM32F4xx HAL Driver version number V1.3.2 + */ +#define __STM32F4xx_HAL_VERSION_MAIN (0x01) /*!< [31:24] main version */ +#define __STM32F4xx_HAL_VERSION_SUB1 (0x03) /*!< [23:16] sub1 version */ +#define __STM32F4xx_HAL_VERSION_SUB2 (0x02) /*!< [15:8] sub2 version */ +#define __STM32F4xx_HAL_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __STM32F4xx_HAL_VERSION ((__STM32F4xx_HAL_VERSION_MAIN << 24)\ + |(__STM32F4xx_HAL_VERSION_SUB1 << 16)\ + |(__STM32F4xx_HAL_VERSION_SUB2 << 8 )\ + |(__STM32F4xx_HAL_VERSION_RC)) + +#define IDCODE_DEVID_MASK ((uint32_t)0x00000FFF) + +/* ------------ RCC registers bit address in the alias region ----------- */ +#define SYSCFG_OFFSET (SYSCFG_BASE - PERIPH_BASE) +/* --- MEMRMP Register ---*/ +/* Alias word address of UFB_MODE bit */ +#define MEMRMP_OFFSET SYSCFG_OFFSET +#define UFB_MODE_BIT_NUMBER POSITION_VAL(SYSCFG_MEMRMP_UFB_MODE) +#define UFB_MODE_BB (uint32_t)(PERIPH_BB_BASE + (MEMRMP_OFFSET * 32) + (UFB_MODE_BIT_NUMBER * 4)) + +/* --- CMPCR Register ---*/ +/* Alias word address of CMP_PD bit */ +#define CMPCR_OFFSET (SYSCFG_OFFSET + 0x20) +#define CMP_PD_BIT_NUMBER POSITION_VAL(SYSCFG_CMPCR_CMP_PD) +#define CMPCR_CMP_PD_BB (uint32_t)(PERIPH_BB_BASE + (CMPCR_OFFSET * 32) + (CMP_PD_BIT_NUMBER * 4)) +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @addtogroup HAL_Private_Variables + * @{ + */ +static __IO uint32_t uwTick; +/** + * @} + */ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup HAL_Exported_Functions HAL Exported Functions + * @{ + */ + +/** @defgroup HAL_Exported_Functions_Group1 Initialization and de-initialization Functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initializes the Flash interface the NVIC allocation and initial clock + configuration. It initializes the systick also when timeout is needed + and the backup domain when enabled. + (+) de-Initializes common part of the HAL + (+) Configure The time base source to have 1ms time base with a dedicated + Tick interrupt priority. + (++) Systick timer is used by default as source of time base, but user + can eventually implement his proper time base source (a general purpose + timer for example or other time source), keeping in mind that Time base + duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and + handled in milliseconds basis. + (++) Time base configuration function (HAL_InitTick ()) is called automatically + at the beginning of the program after reset by HAL_Init() or at any time + when clock is configured, by HAL_RCC_ClockConfig(). + (++) Source of time base is configured to generate interrupts at regular + time intervals. Care must be taken if HAL_Delay() is called from a + peripheral ISR process, the Tick interrupt line must have higher priority + (numerically lower) than the peripheral interrupt. Otherwise the caller + ISR process will be blocked. + (++) functions affecting time base configurations are declared as __weak + to make override possible in case of other implementations in user file. +@endverbatim + * @{ + */ + +/** + * @brief This function is used to initialize the HAL Library; it must be the first + * instruction to be executed in the main program (before to call any other + * HAL function), it performs the following: + * Configure the Flash prefetch, instruction and Data caches. + * Configures the SysTick to generate an interrupt each 1 millisecond, + * which is clocked by the HSI (at this stage, the clock is not yet + * configured and thus the system is running from the internal HSI at 16 MHz). + * Set NVIC Group Priority to 4. + * Calls the HAL_MspInit() callback function defined in user file + * "stm32f4xx_hal_msp.c" to do the global low level hardware initialization + * + * @note SysTick is used as time base for the HAL_Delay() function, the application + * need to ensure that the SysTick time base is always set to 1 millisecond + * to have correct HAL operation. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_Init(void) +{ + /* Configure Flash prefetch, Instruction cache, Data cache */ +#if (INSTRUCTION_CACHE_ENABLE != 0) + __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); +#endif /* INSTRUCTION_CACHE_ENABLE */ + +#if (DATA_CACHE_ENABLE != 0) + __HAL_FLASH_DATA_CACHE_ENABLE(); +#endif /* DATA_CACHE_ENABLE */ + +#if (PREFETCH_ENABLE != 0) + __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); +#endif /* PREFETCH_ENABLE */ + + /* Set Interrupt Group Priority */ + HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); + + /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */ + HAL_InitTick(TICK_INT_PRIORITY); + + /* Init the low level hardware */ + HAL_MspInit(); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief This function de-Initializes common part of the HAL and stops the systick. + * This function is optional. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DeInit(void) +{ + /* Reset of all peripherals */ + __HAL_RCC_APB1_FORCE_RESET(); + __HAL_RCC_APB1_RELEASE_RESET(); + + __HAL_RCC_APB2_FORCE_RESET(); + __HAL_RCC_APB2_RELEASE_RESET(); + + __HAL_RCC_AHB1_FORCE_RESET(); + __HAL_RCC_AHB1_RELEASE_RESET(); + + __HAL_RCC_AHB2_FORCE_RESET(); + __HAL_RCC_AHB2_RELEASE_RESET(); + + __HAL_RCC_AHB3_FORCE_RESET(); + __HAL_RCC_AHB3_RELEASE_RESET(); + + /* De-Init the low level hardware */ + HAL_MspDeInit(); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the MSP. + * @retval None + */ +__weak void HAL_MspInit(void) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes the MSP. + * @retval None + */ +__weak void HAL_MspDeInit(void) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief This function configures the source of the time base. + * The time source is configured to have 1ms time base with a dedicated + * Tick interrupt priority. + * @note This function is called automatically at the beginning of program after + * reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig(). + * @note In the default implementation, SysTick timer is the source of time base. + * It is used to generate interrupts at regular time intervals. + * Care must be taken if HAL_Delay() is called from a peripheral ISR process, + * The the SysTick interrupt must have higher priority (numerically lower) + * than the peripheral interrupt. Otherwise the caller ISR process will be blocked. + * The function is declared as __weak to be overwritten in case of other + * implementation in user file. + * @param TickPriority: Tick interrupt priority. + * @retval HAL status + */ +__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + /*Configure the SysTick to have interrupt in 1ms time basis*/ + HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); + + /*Configure the SysTick IRQ priority */ + //HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority ,0); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup HAL_Exported_Functions_Group2 HAL Control functions + * @brief HAL Control functions + * +@verbatim + =============================================================================== + ##### HAL Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Provide a tick value in millisecond + (+) Provide a blocking delay in millisecond + (+) Suspend the time base source interrupt + (+) Resume the time base source interrupt + (+) Get the HAL API driver version + (+) Get the device identifier + (+) Get the device revision identifier + (+) Enable/Disable Debug module during SLEEP mode + (+) Enable/Disable Debug module during STOP mode + (+) Enable/Disable Debug module during STANDBY mode + +@endverbatim + * @{ + */ + +/** + * @brief This function is called to increment a global variable "uwTick" + * used as application time base. + * @note In the default implementation, this variable is incremented each 1ms + * in Systick ISR. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_IncTick(void) +{ + uwTick++; +} + +/** + * @brief Provides a tick value in millisecond. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval tick value + */ +__weak uint32_t HAL_GetTick(void) +{ + return uwTick; +} + +/** + * @brief This function provides accurate delay (in milliseconds) based + * on variable incremented. + * @note In the default implementation , SysTick timer is the source of time base. + * It is used to generate interrupts at regular time intervals where uwTick + * is incremented. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @param Delay: specifies the delay time length, in milliseconds. + * @retval None + */ +__weak void HAL_Delay(__IO uint32_t Delay) +{ + uint32_t tickstart = 0; + tickstart = HAL_GetTick(); + while((HAL_GetTick() - tickstart) < Delay) + { + } +} + +/** + * @brief Suspend Tick increment. + * @note In the default implementation , SysTick timer is the source of time base. It is + * used to generate interrupts at regular time intervals. Once HAL_SuspendTick() + * is called, the SysTick interrupt will be disabled and so Tick increment + * is suspended. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_SuspendTick(void) +{ + /* Disable SysTick Interrupt */ + SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; +} + +/** + * @brief Resume Tick increment. + * @note In the default implementation , SysTick timer is the source of time base. It is + * used to generate interrupts at regular time intervals. Once HAL_ResumeTick() + * is called, the SysTick interrupt will be enabled and so Tick increment + * is resumed. + * @note This function is declared as __weak to be overwritten in case of other + * implementations in user file. + * @retval None + */ +__weak void HAL_ResumeTick(void) +{ + /* Enable SysTick Interrupt */ + SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; +} + +/** + * @brief Returns the HAL revision + * @retval version : 0xXYZR (8bits for each decimal, R for RC) + */ +uint32_t HAL_GetHalVersion(void) +{ + return __STM32F4xx_HAL_VERSION; +} + +/** + * @brief Returns the device revision identifier. + * @retval Device revision identifier + */ +uint32_t HAL_GetREVID(void) +{ + return((DBGMCU->IDCODE) >> 16); +} + +/** + * @brief Returns the device identifier. + * @retval Device identifier + */ +uint32_t HAL_GetDEVID(void) +{ + return((DBGMCU->IDCODE) & IDCODE_DEVID_MASK); +} + +/** + * @brief Enable the Debug Module during SLEEP mode + * @retval None + */ +void HAL_DBGMCU_EnableDBGSleepMode(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP); +} + +/** + * @brief Disable the Debug Module during SLEEP mode + * @retval None + */ +void HAL_DBGMCU_DisableDBGSleepMode(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP); +} + +/** + * @brief Enable the Debug Module during STOP mode + * @retval None + */ +void HAL_DBGMCU_EnableDBGStopMode(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); +} + +/** + * @brief Disable the Debug Module during STOP mode + * @retval None + */ +void HAL_DBGMCU_DisableDBGStopMode(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); +} + +/** + * @brief Enable the Debug Module during STANDBY mode + * @retval None + */ +void HAL_DBGMCU_EnableDBGStandbyMode(void) +{ + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); +} + +/** + * @brief Disable the Debug Module during STANDBY mode + * @retval None + */ +void HAL_DBGMCU_DisableDBGStandbyMode(void) +{ + CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); +} + +/** + * @brief Enables the I/O Compensation Cell. + * @note The I/O compensation cell can be used only when the device supply + * voltage ranges from 2.4 to 3.6 V. + * @retval None + */ +void HAL_EnableCompensationCell(void) +{ + *(__IO uint32_t *)CMPCR_CMP_PD_BB = (uint32_t)ENABLE; +} + +/** + * @brief Power-down the I/O Compensation Cell. + * @note The I/O compensation cell can be used only when the device supply + * voltage ranges from 2.4 to 3.6 V. + * @retval None + */ +void HAL_DisableCompensationCell(void) +{ + *(__IO uint32_t *)CMPCR_CMP_PD_BB = (uint32_t)DISABLE; +} + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) +/** + * @brief Enables the Internal FLASH Bank Swapping. + * + * @note This function can be used only for STM32F42xxx/43xxx devices. + * + * @note Flash Bank2 mapped at 0x08000000 (and aliased @0x00000000) + * and Flash Bank1 mapped at 0x08100000 (and aliased at 0x00100000) + * + * @retval None + */ +void HAL_EnableMemorySwappingBank(void) +{ + *(__IO uint32_t *)UFB_MODE_BB = (uint32_t)ENABLE; +} + +/** + * @brief Disables the Internal FLASH Bank Swapping. + * + * @note This function can be used only for STM32F42xxx/43xxx devices. + * + * @note The default state : Flash Bank1 mapped at 0x08000000 (and aliased @0x0000 0000) + * and Flash Bank2 mapped at 0x08100000 (and aliased at 0x00100000) + * + * @retval None + */ +void HAL_DisableMemorySwappingBank(void) +{ + + *(__IO uint32_t *)UFB_MODE_BB = (uint32_t)DISABLE; +} +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c new file mode 100644 index 0000000..1b4dce2 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c @@ -0,0 +1,1412 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_adc.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief This file provides firmware functions to manage the following + * functionalities of the Analog to Digital Convertor (ADC) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + State and errors functions + * + @verbatim + ============================================================================== + ##### ADC Peripheral features ##### + ============================================================================== + [..] + (#) 12-bit, 10-bit, 8-bit or 6-bit configurable resolution. + (#) Interrupt generation at the end of conversion, end of injected conversion, + and in case of analog watchdog or overrun events + (#) Single and continuous conversion modes. + (#) Scan mode for automatic conversion of channel 0 to channel x. + (#) Data alignment with in-built data coherency. + (#) Channel-wise programmable sampling time. + (#) External trigger option with configurable polarity for both regular and + injected conversion. + (#) Dual/Triple mode (on devices with 2 ADCs or more). + (#) Configurable DMA data storage in Dual/Triple ADC mode. + (#) Configurable delay between conversions in Dual/Triple interleaved mode. + (#) ADC conversion type (refer to the datasheets). + (#) ADC supply requirements: 2.4 V to 3.6 V at full speed and down to 1.8 V at + slower speed. + (#) ADC input range: VREF(minus) = VIN = VREF(plus). + (#) DMA request generation during regular channel conversion. + + + ##### How to use this driver ##### + ============================================================================== + [..] + (#)Initialize the ADC low level resources by implementing the HAL_ADC_MspInit(): + (##) Enable the ADC interface clock using __HAL_RCC_ADC_CLK_ENABLE() + (##) ADC pins configuration + (+++) Enable the clock for the ADC GPIOs using the following function: + __HAL_RCC_GPIOx_CLK_ENABLE() + (+++) Configure these ADC pins in analog mode using HAL_GPIO_Init() + (##) In case of using interrupts (e.g. HAL_ADC_Start_IT()) + (+++) Configure the ADC interrupt priority using HAL_NVIC_SetPriority() + (+++) Enable the ADC IRQ handler using HAL_NVIC_EnableIRQ() + (+++) In ADC IRQ handler, call HAL_ADC_IRQHandler() + (##) In case of using DMA to control data transfer (e.g. HAL_ADC_Start_DMA()) + (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE() + (+++) Configure and enable two DMA streams stream for managing data + transfer from peripheral to memory (output stream) + (+++) Associate the initialized DMA handle to the CRYP DMA handle + using __HAL_LINKDMA() + (+++) Configure the priority and enable the NVIC for the transfer complete + interrupt on the two DMA Streams. The output stream should have higher + priority than the input stream. + + *** Configuration of ADC, groups regular/injected, channels parameters *** + ============================================================================== + [..] + (#) Configure the ADC parameters (resolution, data alignment, ...) + and regular group parameters (conversion trigger, sequencer, ...) + using function HAL_ADC_Init(). + + (#) Configure the channels for regular group parameters (channel number, + channel rank into sequencer, ..., into regular group) + using function HAL_ADC_ConfigChannel(). + + (#) Optionally, configure the injected group parameters (conversion trigger, + sequencer, ..., of injected group) + and the channels for injected group parameters (channel number, + channel rank into sequencer, ..., into injected group) + using function HAL_ADCEx_InjectedConfigChannel(). + + (#) Optionally, configure the analog watchdog parameters (channels + monitored, thresholds, ...) using function HAL_ADC_AnalogWDGConfig(). + + (#) Optionally, for devices with several ADC instances: configure the + multimode parameters using function HAL_ADCEx_MultiModeConfigChannel(). + + *** Execution of ADC conversions *** + ============================================================================== + [..] + (#) ADC driver can be used among three modes: polling, interruption, + transfer by DMA. + + *** Polling mode IO operation *** + ================================= + [..] + (+) Start the ADC peripheral using HAL_ADC_Start() + (+) Wait for end of conversion using HAL_ADC_PollForConversion(), at this stage + user can specify the value of timeout according to his end application + (+) To read the ADC converted values, use the HAL_ADC_GetValue() function. + (+) Stop the ADC peripheral using HAL_ADC_Stop() + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Start the ADC peripheral using HAL_ADC_Start_IT() + (+) Use HAL_ADC_IRQHandler() called under ADC_IRQHandler() Interrupt subroutine + (+) At ADC end of conversion HAL_ADC_ConvCpltCallback() function is executed and user can + add his own code by customization of function pointer HAL_ADC_ConvCpltCallback + (+) In case of ADC Error, HAL_ADC_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_ADC_ErrorCallback + (+) Stop the ADC peripheral using HAL_ADC_Stop_IT() + + *** DMA mode IO operation *** + ============================== + [..] + (+) Start the ADC peripheral using HAL_ADC_Start_DMA(), at this stage the user specify the length + of data to be transferred at each end of conversion + (+) At The end of data transfer by HAL_ADC_ConvCpltCallback() function is executed and user can + add his own code by customization of function pointer HAL_ADC_ConvCpltCallback + (+) In case of transfer Error, HAL_ADC_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_ADC_ErrorCallback + (+) Stop the ADC peripheral using HAL_ADC_Stop_DMA() + + *** ADC HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in ADC HAL driver. + + (+) __HAL_ADC_ENABLE : Enable the ADC peripheral + (+) __HAL_ADC_DISABLE : Disable the ADC peripheral + (+) __HAL_ADC_ENABLE_IT: Enable the ADC end of conversion interrupt + (+) __HAL_ADC_DISABLE_IT: Disable the ADC end of conversion interrupt + (+) __HAL_ADC_GET_IT_SOURCE: Check if the specified ADC interrupt source is enabled or disabled + (+) __HAL_ADC_CLEAR_FLAG: Clear the ADC's pending flags + (+) __HAL_ADC_GET_FLAG: Get the selected ADC's flag status + (+) ADC_GET_RESOLUTION: Return resolution bits in CR1 register + + [..] + (@) You can refer to the ADC HAL driver header file for more useful macros + + *** Deinitialization of ADC *** + ============================================================================== + [..] + (#) Disable the ADC interface + (++) ADC clock can be hard reset and disabled at RCC top level. + (++) Hard reset of ADC peripherals + using macro __HAL_RCC_ADC_FORCE_RESET(), __HAL_RCC_ADC_RELEASE_RESET(). + (++) ADC clock disable using the equivalent macro/functions as configuration step. + (+++) Example: + Into HAL_ADC_MspDeInit() (recommended code location) or with + other device clock parameters configuration: + (+++) HAL_RCC_GetOscConfig(&RCC_OscInitStructure); + (+++) RCC_OscInitStructure.OscillatorType = RCC_OSCILLATORTYPE_HSI; + (+++) RCC_OscInitStructure.HSIState = RCC_HSI_OFF; (if not used for system clock) + (+++) HAL_RCC_OscConfig(&RCC_OscInitStructure); + + (#) ADC pins configuration + (++) Disable the clock for the ADC GPIOs using macro __HAL_RCC_GPIOx_CLK_DISABLE() + + (#) Optionally, in case of usage of ADC with interruptions: + (++) Disable the NVIC for ADC using function HAL_NVIC_DisableIRQ(ADCx_IRQn) + + (#) Optionally, in case of usage of DMA: + (++) Deinitialize the DMA using function HAL_DMA_DeInit(). + (++) Disable the NVIC for DMA using function HAL_NVIC_DisableIRQ(DMAx_Channelx_IRQn) + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 ADC ADC + * @brief ADC driver modules + * @{ + */ + +#ifdef HAL_ADC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @addtogroup ADC_Private_Functions + * @{ + */ +/* Private function prototypes -----------------------------------------------*/ +static void ADC_Init(ADC_HandleTypeDef* hadc); +static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma); +static void ADC_DMAError(DMA_HandleTypeDef *hdma); +static void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma); +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup ADC_Exported_Functions ADC Exported Functions + * @{ + */ + +/** @defgroup ADC_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 and configure the ADC. + (+) De-initialize the ADC. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the ADCx peripheral according to the specified parameters + * in the ADC_InitStruct and initializes the ADC MSP. + * + * @note This function is used to configure the global features of the ADC ( + * ClockPrescaler, Resolution, Data Alignment and number of conversion), however, + * the rest of the configuration parameters are specific to the regular + * channels group (scan mode activation, continuous mode activation, + * External trigger source and edge, DMA continuous request after the + * last transfer and End of conversion selection). + * + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc) +{ + /* Check ADC handle */ + if(hadc == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_CLOCKPRESCALER(hadc->Init.ClockPrescaler)); + assert_param(IS_ADC_RESOLUTION(hadc->Init.Resolution)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ScanConvMode)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_EXT_TRIG(hadc->Init.ExternalTrigConv)); + assert_param(IS_ADC_DATA_ALIGN(hadc->Init.DataAlign)); + assert_param(IS_ADC_REGULAR_LENGTH(hadc->Init.NbrOfConversion)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests)); + assert_param(IS_ADC_EOCSelection(hadc->Init.EOCSelection)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DiscontinuousConvMode)); + + if(hadc->Init.ExternalTrigConv != ADC_SOFTWARE_START) + { + assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); + } + + if(hadc->State == HAL_ADC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hadc->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_ADC_MspInit(hadc); + } + + /* Initialize the ADC state */ + hadc->State = HAL_ADC_STATE_BUSY; + + /* Set ADC parameters */ + ADC_Init(hadc); + + /* Set ADC error code to none */ + hadc->ErrorCode = HAL_ADC_ERROR_NONE; + + /* Initialize the ADC state */ + hadc->State = HAL_ADC_STATE_READY; + + /* Release Lock */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Deinitializes the ADCx peripheral registers to their default reset values. + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef* hadc) +{ + /* Check ADC handle */ + if(hadc == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_BUSY; + + /* DeInit the low level hardware */ + HAL_ADC_MspDeInit(hadc); + + /* Set ADC error code to none */ + hadc->ErrorCode = HAL_ADC_ERROR_NONE; + + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_RESET; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the ADC MSP. + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +__weak void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ADC_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes the ADC MSP. + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +__weak void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ADC_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup ADC_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Start conversion of regular channel. + (+) Stop conversion of regular channel. + (+) Start conversion of regular channel and enable interrupt. + (+) Stop conversion of regular channel and disable interrupt. + (+) Start conversion of regular channel and enable DMA transfer. + (+) Stop conversion of regular channel and disable DMA transfer. + (+) Handle ADC interrupt request. + +@endverbatim + * @{ + */ + +/** + * @brief Enables ADC and starts conversion of the regular channels. + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc) +{ + __IO uint32_t counter = 0; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Check if an injected conversion is ongoing */ + if(hadc->State == HAL_ADC_STATE_BUSY_INJ) + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_BUSY_INJ_REG; + } + else + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_BUSY_REG; + } + + /* Check if ADC peripheral is disabled in order to enable it and wait during + Tstab time the ADC's stabilization */ + if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON) + { + /* Enable the Peripheral */ + __HAL_ADC_ENABLE(hadc); + + /* Delay for ADC stabilization time */ + /* Compute number of CPU cycles to wait for */ + counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000)); + while(counter != 0) + { + counter--; + } + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Check if Multimode enabled */ + if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI)) + { + /* if no external trigger present enable software conversion of regular channels */ + if((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET) + { + /* Enable the selected ADC software conversion for regular group */ + hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; + } + } + else + { + /* if instance of handle correspond to ADC1 and no external trigger present enable software conversion of regular channels */ + if((hadc->Instance == ADC1) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)) + { + /* Enable the selected ADC software conversion for regular group */ + hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Disables ADC and stop conversion of regular channels. + * + * @note Caution: This function will stop also injected channels. + * + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc) +{ + /* Disable the Peripheral */ + __HAL_ADC_DISABLE(hadc); + + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Poll for regular conversion complete + * @note ADC conversion flags EOS (end of sequence) and EOC (end of + * conversion) are cleared by this function. + * @note This function cannot be used in a particular setup: ADC configured + * in DMA mode and polling for end of each conversion (ADC init + * parameter "EOCSelection" set to ADC_EOC_SINGLE_CONV). + * In this case, DMA resets the flag EOC and polling cannot be + * performed on each conversion. Nevertheless, polling can still + * be performed on the complete sequence. + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param Timeout: Timeout value in millisecond. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Verification that ADC configuration is compliant with polling for */ + /* each conversion: */ + /* Particular case is ADC configured in DMA mode and ADC sequencer with */ + /* several ranks and polling for end of each conversion. */ + /* For code simplicity sake, this particular case is generalized to */ + /* ADC configured in DMA mode and polling for end of each conversion. */ + if (HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_EOCS) && + HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_DMA) ) + { + /* Update ADC state machine to error */ + hadc->State = HAL_ADC_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_ERROR; + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check End of conversion flag */ + while(!(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC))) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hadc->State= HAL_ADC_STATE_TIMEOUT; + /* Process unlocked */ + __HAL_UNLOCK(hadc); + return HAL_TIMEOUT; + } + } + } + + /* Check if an injected conversion is ready */ + if(hadc->State == HAL_ADC_STATE_EOC_INJ) + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_EOC_INJ_REG; + } + else + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_EOC_REG; + } + + /* Return ADC state */ + return HAL_OK; +} + +/** + * @brief Poll for conversion event + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param EventType: the ADC event type. + * This parameter can be one of the following values: + * @arg ADC_AWD_EVENT: ADC Analog watch Dog event. + * @arg ADC_OVR_EVENT: ADC Overrun event. + * @param Timeout: Timeout value in millisecond. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_ADC_EVENT_TYPE(EventType)); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check selected event flag */ + while(!(__HAL_ADC_GET_FLAG(hadc,EventType))) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hadc->State= HAL_ADC_STATE_TIMEOUT; + /* Process unlocked */ + __HAL_UNLOCK(hadc); + return HAL_TIMEOUT; + } + } + } + + /* Check analog watchdog flag */ + if(EventType == ADC_AWD_EVENT) + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_AWD; + + /* Clear the ADCx's analog watchdog flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD); + } + else + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_ERROR; + + /* Clear the ADCx's Overrun flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR); + } + + /* Return ADC state */ + return HAL_OK; +} + + +/** + * @brief Enables the interrupt and starts ADC conversion of regular channels. + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc) +{ + __IO uint32_t counter = 0; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Check if an injected conversion is ongoing */ + if(hadc->State == HAL_ADC_STATE_BUSY_INJ) + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_BUSY_INJ_REG; + } + else + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_BUSY_REG; + } + + /* Set ADC error code to none */ + hadc->ErrorCode = HAL_ADC_ERROR_NONE; + + /* Check if ADC peripheral is disabled in order to enable it and wait during + Tstab time the ADC's stabilization */ + if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON) + { + /* Enable the Peripheral */ + __HAL_ADC_ENABLE(hadc); + + /* Delay for ADC stabilization time */ + /* Compute number of CPU cycles to wait for */ + counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000)); + while(counter != 0) + { + counter--; + } + } + + /* Enable the ADC overrun interrupt */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); + + /* Enable the ADC end of conversion interrupt for regular group */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOC); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Check if Multimode enabled */ + if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI)) + { + /* if no external trigger present enable software conversion of regular channels */ + if((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET) + { + /* Enable the selected ADC software conversion for regular group */ + hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; + } + } + else + { + /* if instance of handle correspond to ADC1 and no external trigger present enable software conversion of regular channels */ + if((hadc->Instance == (ADC_TypeDef*)0x40012000) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)) + { + /* Enable the selected ADC software conversion for regular group */ + hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Disables the interrupt and stop ADC conversion of regular channels. + * + * @note Caution: This function will stop also injected channels. + * + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc) +{ + /* Disable the ADC end of conversion interrupt for regular group */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); + + /* Disable the ADC end of conversion interrupt for injected group */ + __HAL_ADC_DISABLE_IT(hadc, ADC_CR1_JEOCIE); + + /* Enable the Peripheral */ + __HAL_ADC_DISABLE(hadc); + + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Handles ADC interrupt request + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc) +{ + uint32_t tmp1 = 0, tmp2 = 0; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_REGULAR_LENGTH(hadc->Init.NbrOfConversion)); + assert_param(IS_ADC_EOCSelection(hadc->Init.EOCSelection)); + + tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC); + tmp2 = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_EOC); + /* Check End of conversion flag for regular channels */ + if(tmp1 && tmp2) + { + /* Check if an injected conversion is ready */ + if(hadc->State == HAL_ADC_STATE_EOC_INJ) + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_EOC_INJ_REG; + } + else + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_EOC_REG; + } + + if((hadc->Init.ContinuousConvMode == DISABLE) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)) + { + if(hadc->Init.EOCSelection == ADC_EOC_SEQ_CONV) + { + /* DISABLE the ADC end of conversion interrupt for regular group */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); + + /* DISABLE the ADC overrun interrupt */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR); + } + else + { + if (hadc->NbrOfCurrentConversionRank == 0) + { + hadc->NbrOfCurrentConversionRank = hadc->Init.NbrOfConversion; + } + + /* Decrement the number of conversion when an interrupt occurs */ + hadc->NbrOfCurrentConversionRank--; + + /* Check if all conversions are finished */ + if(hadc->NbrOfCurrentConversionRank == 0) + { + /* DISABLE the ADC end of conversion interrupt for regular group */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); + + /* DISABLE the ADC overrun interrupt */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR); + } + } + } + + /* Conversion complete callback */ + HAL_ADC_ConvCpltCallback(hadc); + + /* Clear the ADCx flag for regular end of conversion */ + __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_EOC); + } + + tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC); + tmp2 = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_JEOC); + /* Check End of conversion flag for injected channels */ + if(tmp1 && tmp2) + { + /* Check if a regular conversion is ready */ + if(hadc->State == HAL_ADC_STATE_EOC_REG) + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_EOC_INJ_REG; + } + else + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_EOC_INJ; + } + + tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); + tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); + if(((hadc->Init.ContinuousConvMode == DISABLE) || tmp1) && tmp2) + { + /* DISABLE the ADC end of conversion interrupt for injected group */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC); + } + + /* Conversion complete callback */ + HAL_ADCEx_InjectedConvCpltCallback(hadc); + + /* Clear the ADCx flag for injected end of conversion */ + __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_JEOC); + } + + tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_AWD); + tmp2 = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_AWD); + /* Check Analog watchdog flag */ + if(tmp1 && tmp2) + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_AWD; + + /* Clear the ADCx's Analog watchdog flag */ + __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_AWD); + + /* Level out of window callback */ + HAL_ADC_LevelOutOfWindowCallback(hadc); + } + + tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_OVR); + tmp2 = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_OVR); + /* Check Overrun flag */ + if(tmp1 && tmp2) + { + /* Change ADC state to overrun state */ + hadc->State = HAL_ADC_STATE_ERROR; + + /* Set ADC error code to overrun */ + hadc->ErrorCode |= HAL_ADC_ERROR_OVR; + + /* Clear the Overrun flag */ + __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_OVR); + + /* Error callback */ + HAL_ADC_ErrorCallback(hadc); + } +} + +/** + * @brief Enables ADC DMA request after last transfer (Single-ADC mode) and enables ADC peripheral + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param pData: The destination Buffer address. + * @param Length: The length of data to be transferred from ADC peripheral to memory. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length) +{ + __IO uint32_t counter = 0; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable ADC overrun interrupt */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); + + /* Enable ADC DMA mode */ + hadc->Instance->CR2 |= ADC_CR2_DMA; + + /* Set the DMA transfer complete callback */ + hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt; + + /* Set the DMA half transfer complete callback */ + hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt; + + /* Set the DMA error callback */ + hadc->DMA_Handle->XferErrorCallback = ADC_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length); + + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_BUSY_REG; + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Check if ADC peripheral is disabled in order to enable it and wait during + Tstab time the ADC's stabilization */ + if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON) + { + /* Enable the Peripheral */ + __HAL_ADC_ENABLE(hadc); + + /* Delay for ADC stabilization time */ + /* Compute number of CPU cycles to wait for */ + counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000)); + while(counter != 0) + { + counter--; + } + } + + /* if no external trigger present enable software conversion of regular channels */ + if((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET) + { + /* Enable the selected ADC software conversion for regular group */ + hadc->Instance->CR2 |= ADC_CR2_SWSTART; + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Disables ADC DMA (Single-ADC mode) and disables ADC peripheral + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc) +{ + /* Disable the Peripheral */ + __HAL_ADC_DISABLE(hadc); + + /* Disable ADC overrun interrupt */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR); + + /* Disable the selected ADC DMA mode */ + hadc->Instance->CR2 &= ~ADC_CR2_DMA; + + /* Disable the ADC DMA Stream */ + HAL_DMA_Abort(hadc->DMA_Handle); + + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Gets the converted value from data register of regular channel. + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval Converted value + */ +uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc) +{ + /* Return the selected ADC converted value */ + return hadc->Instance->DR; +} + +/** + * @brief Regular conversion complete callback in non blocking mode + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +__weak void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ADC_ConvCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Regular conversion half DMA transfer callback in non blocking mode + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +__weak void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ADC_ConvHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Analog watchdog callback in non blocking mode + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +__weak void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ADC_LevelOoutOfWindowCallback could be implemented in the user file + */ +} + +/** + * @brief Error ADC callback. + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +__weak void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ADC_ErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup ADC_Exported_Functions_Group3 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure regular channels. + (+) Configure injected channels. + (+) Configure multimode. + (+) Configure the analog watch dog. + +@endverbatim + * @{ + */ + + /** + * @brief Configures for the selected ADC regular channel its corresponding + * rank in the sequencer and its sample time. + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param sConfig: ADC configuration structure. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig) +{ + __IO uint32_t counter = 0; + + /* Check the parameters */ + assert_param(IS_ADC_CHANNEL(sConfig->Channel)); + assert_param(IS_ADC_REGULAR_RANK(sConfig->Rank)); + assert_param(IS_ADC_SAMPLE_TIME(sConfig->SamplingTime)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* if ADC_Channel_10 ... ADC_Channel_18 is selected */ + if (sConfig->Channel > ADC_CHANNEL_9) + { + /* Clear the old sample time */ + hadc->Instance->SMPR1 &= ~ADC_SMPR1(ADC_SMPR1_SMP10, sConfig->Channel); + + /* Set the new sample time */ + hadc->Instance->SMPR1 |= ADC_SMPR1(sConfig->SamplingTime, sConfig->Channel); + } + else /* ADC_Channel include in ADC_Channel_[0..9] */ + { + /* Clear the old sample time */ + hadc->Instance->SMPR2 &= ~ADC_SMPR2(ADC_SMPR2_SMP0, sConfig->Channel); + + /* Set the new sample time */ + hadc->Instance->SMPR2 |= ADC_SMPR2(sConfig->SamplingTime, sConfig->Channel); + } + + /* For Rank 1 to 6 */ + if (sConfig->Rank < 7) + { + /* Clear the old SQx bits for the selected rank */ + hadc->Instance->SQR3 &= ~ADC_SQR3_RK(ADC_SQR3_SQ1, sConfig->Rank); + + /* Set the SQx bits for the selected rank */ + hadc->Instance->SQR3 |= ADC_SQR3_RK(sConfig->Channel, sConfig->Rank); + } + /* For Rank 7 to 12 */ + else if (sConfig->Rank < 13) + { + /* Clear the old SQx bits for the selected rank */ + hadc->Instance->SQR2 &= ~ADC_SQR2_RK(ADC_SQR2_SQ7, sConfig->Rank); + + /* Set the SQx bits for the selected rank */ + hadc->Instance->SQR2 |= ADC_SQR2_RK(sConfig->Channel, sConfig->Rank); + } + /* For Rank 13 to 16 */ + else + { + /* Clear the old SQx bits for the selected rank */ + hadc->Instance->SQR1 &= ~ADC_SQR1_RK(ADC_SQR1_SQ13, sConfig->Rank); + + /* Set the SQx bits for the selected rank */ + hadc->Instance->SQR1 |= ADC_SQR1_RK(sConfig->Channel, sConfig->Rank); + } + + /* if ADC1 Channel_18 is selected enable VBAT Channel */ + if ((hadc->Instance == ADC1) && (sConfig->Channel == ADC_CHANNEL_VBAT)) + { + /* Enable the VBAT channel*/ + ADC->CCR |= ADC_CCR_VBATE; + } + + /* if ADC1 Channel_16 or Channel_17 is selected enable TSVREFE Channel(Temperature sensor and VREFINT) */ + if ((hadc->Instance == ADC1) && ((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) || (sConfig->Channel == ADC_CHANNEL_VREFINT))) + { + /* Enable the TSVREFE channel*/ + ADC->CCR |= ADC_CCR_TSVREFE; + + if((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR)) + { + /* Delay for temperature sensor stabilization time */ + /* Compute number of CPU cycles to wait for */ + counter = (ADC_TEMPSENSOR_DELAY_US * (SystemCoreClock / 1000000)); + while(counter != 0) + { + counter--; + } + } + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Configures the analog watchdog. + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param AnalogWDGConfig : pointer to an ADC_AnalogWDGConfTypeDef structure + * that contains the configuration information of ADC analog watchdog. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDGConfTypeDef* AnalogWDGConfig) +{ +#ifdef USE_FULL_ASSERT + uint32_t tmp = 0; +#endif /* USE_FULL_ASSERT */ + + /* Check the parameters */ + assert_param(IS_ADC_ANALOG_WATCHDOG(AnalogWDGConfig->WatchdogMode)); + assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel)); + assert_param(IS_FUNCTIONAL_STATE(AnalogWDGConfig->ITMode)); + +#ifdef USE_FULL_ASSERT + tmp = ADC_GET_RESOLUTION(hadc); + assert_param(IS_ADC_RANGE(tmp, AnalogWDGConfig->HighThreshold)); + assert_param(IS_ADC_RANGE(tmp, AnalogWDGConfig->LowThreshold)); +#endif /* USE_FULL_ASSERT */ + + /* Process locked */ + __HAL_LOCK(hadc); + + if(AnalogWDGConfig->ITMode == ENABLE) + { + /* Enable the ADC Analog watchdog interrupt */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_AWD); + } + else + { + /* Disable the ADC Analog watchdog interrupt */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_AWD); + } + + /* Clear AWDEN, JAWDEN and AWDSGL bits */ + hadc->Instance->CR1 &= ~(ADC_CR1_AWDSGL | ADC_CR1_JAWDEN | ADC_CR1_AWDEN); + + /* Set the analog watchdog enable mode */ + hadc->Instance->CR1 |= AnalogWDGConfig->WatchdogMode; + + /* Set the high threshold */ + hadc->Instance->HTR = AnalogWDGConfig->HighThreshold; + + /* Set the low threshold */ + hadc->Instance->LTR = AnalogWDGConfig->LowThreshold; + + /* Clear the Analog watchdog channel select bits */ + hadc->Instance->CR1 &= ~ADC_CR1_AWDCH; + + /* Set the Analog watchdog channel */ + hadc->Instance->CR1 |= (uint32_t)((uint16_t)(AnalogWDGConfig->Channel)); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup ADC_Exported_Functions_Group4 ADC Peripheral State functions + * @brief ADC Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State and errors functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to + (+) Check the ADC state + (+) Check the ADC Error + +@endverbatim + * @{ + */ + +/** + * @brief return the ADC state + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL state + */ +HAL_ADC_StateTypeDef HAL_ADC_GetState(ADC_HandleTypeDef* hadc) +{ + /* Return ADC state */ + return hadc->State; +} + +/** + * @brief Return the ADC error code + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval ADC Error Code + */ +uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc) +{ + return hadc->ErrorCode; +} + +/** + * @} + */ + +/** @addtogroup ADC_Private_Functions + * @{ + */ + +/** + * @brief Initializes the ADCx peripheral according to the specified parameters + * in the ADC_InitStruct without initializing the ADC MSP. + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +static void ADC_Init(ADC_HandleTypeDef* hadc) +{ + /* Set ADC parameters */ + /* Set the ADC clock prescaler */ + ADC->CCR &= ~(ADC_CCR_ADCPRE); + ADC->CCR |= hadc->Init.ClockPrescaler; + + /* Set ADC scan mode */ + hadc->Instance->CR1 &= ~(ADC_CR1_SCAN); + hadc->Instance->CR1 |= ADC_CR1_SCANCONV(hadc->Init.ScanConvMode); + + /* Set ADC resolution */ + hadc->Instance->CR1 &= ~(ADC_CR1_RES); + hadc->Instance->CR1 |= hadc->Init.Resolution; + + /* Set ADC data alignment */ + hadc->Instance->CR2 &= ~(ADC_CR2_ALIGN); + hadc->Instance->CR2 |= hadc->Init.DataAlign; + + /* Enable external trigger if trigger selection is different of software */ + /* start. */ + /* Note: This configuration keeps the hardware feature of parameter */ + /* ExternalTrigConvEdge "trigger edge none" equivalent to */ + /* software start. */ + if(hadc->Init.ExternalTrigConv != ADC_SOFTWARE_START) + { + /* Select external trigger to start conversion */ + hadc->Instance->CR2 &= ~(ADC_CR2_EXTSEL); + hadc->Instance->CR2 |= hadc->Init.ExternalTrigConv; + + /* Select external trigger polarity */ + hadc->Instance->CR2 &= ~(ADC_CR2_EXTEN); + hadc->Instance->CR2 |= hadc->Init.ExternalTrigConvEdge; + } + else + { + /* Reset the external trigger */ + hadc->Instance->CR2 &= ~(ADC_CR2_EXTSEL); + hadc->Instance->CR2 &= ~(ADC_CR2_EXTEN); + } + + /* Enable or disable ADC continuous conversion mode */ + hadc->Instance->CR2 &= ~(ADC_CR2_CONT); + hadc->Instance->CR2 |= ADC_CR2_CONTINUOUS(hadc->Init.ContinuousConvMode); + + if(hadc->Init.DiscontinuousConvMode != DISABLE) + { + assert_param(IS_ADC_REGULAR_DISC_NUMBER(hadc->Init.NbrOfDiscConversion)); + + /* Enable the selected ADC regular discontinuous mode */ + hadc->Instance->CR1 |= (uint32_t)ADC_CR1_DISCEN; + + /* Set the number of channels to be converted in discontinuous mode */ + hadc->Instance->CR1 &= ~(ADC_CR1_DISCNUM); + hadc->Instance->CR1 |= ADC_CR1_DISCONTINUOUS(hadc->Init.NbrOfDiscConversion); + } + else + { + /* Disable the selected ADC regular discontinuous mode */ + hadc->Instance->CR1 &= ~(ADC_CR1_DISCEN); + } + + /* Set ADC number of conversion */ + hadc->Instance->SQR1 &= ~(ADC_SQR1_L); + hadc->Instance->SQR1 |= ADC_SQR1(hadc->Init.NbrOfConversion); + + /* Enable or disable ADC DMA continuous request */ + hadc->Instance->CR2 &= ~(ADC_CR2_DDS); + hadc->Instance->CR2 |= ADC_CR2_DMAContReq(hadc->Init.DMAContinuousRequests); + + /* Enable or disable ADC end of conversion selection */ + hadc->Instance->CR2 &= ~(ADC_CR2_EOCS); + hadc->Instance->CR2 |= ADC_CR2_EOCSelection(hadc->Init.EOCSelection); +} + +/** + * @brief DMA transfer complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma) +{ + ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Check if an injected conversion is ready */ + if(hadc->State == HAL_ADC_STATE_EOC_INJ) + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_EOC_INJ_REG; + } + else + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_EOC_REG; + } + + HAL_ADC_ConvCpltCallback(hadc); +} + +/** + * @brief DMA half transfer complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma) +{ + ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + /* Conversion complete callback */ + HAL_ADC_ConvHalfCpltCallback(hadc); +} + +/** + * @brief DMA error callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void ADC_DMAError(DMA_HandleTypeDef *hdma) +{ + ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + hadc->State= HAL_ADC_STATE_ERROR; + /* Set ADC error code to DMA error */ + hadc->ErrorCode |= HAL_ADC_ERROR_DMA; + HAL_ADC_ErrorCallback(hadc); +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_ADC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c new file mode 100644 index 0000000..ee88993 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c @@ -0,0 +1,872 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_adc_ex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief This file provides firmware functions to manage the following + * functionalities of the ADC extension peripheral: + * + Extended features functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#)Initialize the ADC low level resources by implementing the HAL_ADC_MspInit(): + (##) Enable the ADC interface clock using __HAL_RCC_ADC_CLK_ENABLE() + (##) ADC pins configuration + (+++) Enable the clock for the ADC GPIOs using the following function: + __HAL_RCC_GPIOx_CLK_ENABLE() + (+++) Configure these ADC pins in analog mode using HAL_GPIO_Init() + (##) In case of using interrupts (e.g. HAL_ADC_Start_IT()) + (+++) Configure the ADC interrupt priority using HAL_NVIC_SetPriority() + (+++) Enable the ADC IRQ handler using HAL_NVIC_EnableIRQ() + (+++) In ADC IRQ handler, call HAL_ADC_IRQHandler() + (##) In case of using DMA to control data transfer (e.g. HAL_ADC_Start_DMA()) + (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE() + (+++) Configure and enable two DMA streams stream for managing data + transfer from peripheral to memory (output stream) + (+++) Associate the initialized DMA handle to the ADC DMA handle + using __HAL_LINKDMA() + (+++) Configure the priority and enable the NVIC for the transfer complete + interrupt on the two DMA Streams. The output stream should have higher + priority than the input stream. + (#) Configure the ADC Prescaler, conversion resolution and data alignment + using the HAL_ADC_Init() function. + + (#) Configure the ADC Injected channels group features, use HAL_ADC_Init() + and HAL_ADC_ConfigChannel() functions. + + (#) Three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Start the ADC peripheral using HAL_ADCEx_InjectedStart() + (+) Wait for end of conversion using HAL_ADC_PollForConversion(), at this stage + user can specify the value of timeout according to his end application + (+) To read the ADC converted values, use the HAL_ADCEx_InjectedGetValue() function. + (+) Stop the ADC peripheral using HAL_ADCEx_InjectedStop() + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Start the ADC peripheral using HAL_ADCEx_InjectedStart_IT() + (+) Use HAL_ADC_IRQHandler() called under ADC_IRQHandler() Interrupt subroutine + (+) At ADC end of conversion HAL_ADCEx_InjectedConvCpltCallback() function is executed and user can + add his own code by customization of function pointer HAL_ADCEx_InjectedConvCpltCallback + (+) In case of ADC Error, HAL_ADCEx_InjectedErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_ADCEx_InjectedErrorCallback + (+) Stop the ADC peripheral using HAL_ADCEx_InjectedStop_IT() + + + *** DMA mode IO operation *** + ============================== + [..] + (+) Start the ADC peripheral using HAL_ADCEx_InjectedStart_DMA(), at this stage the user specify the length + of data to be transferred at each end of conversion + (+) At The end of data transfer ba HAL_ADCEx_InjectedConvCpltCallback() function is executed and user can + add his own code by customization of function pointer HAL_ADCEx_InjectedConvCpltCallback + (+) In case of transfer Error, HAL_ADCEx_InjectedErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_ADCEx_InjectedErrorCallback + (+) Stop the ADC peripheral using HAL_ADCEx_InjectedStop_DMA() + + *** Multi mode ADCs Regular channels configuration *** + ====================================================== + [..] + (+) Select the Multi mode ADC regular channels features (dual or triple mode) + and configure the DMA mode using HAL_ADCEx_MultiModeConfigChannel() functions. + (+) Start the ADC peripheral using HAL_ADCEx_MultiModeStart_DMA(), at this stage the user specify the length + of data to be transferred at each end of conversion + (+) Read the ADCs converted values using the HAL_ADCEx_MultiModeGetValue() function. + + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 ADCEx ADCEx + * @brief ADC Extended driver modules + * @{ + */ + +#ifdef HAL_ADC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @addtogroup ADCEx_Private_Functions + * @{ + */ +/* Private function prototypes -----------------------------------------------*/ +static void ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef *hdma); +static void ADC_MultiModeDMAError(DMA_HandleTypeDef *hdma); +static void ADC_MultiModeDMAHalfConvCplt(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup ADCEx_Exported_Functions ADC Exported Functions + * @{ + */ + +/** @defgroup ADCEx_Exported_Functions_Group1 Extended features functions + * @brief Extended features functions + * +@verbatim + =============================================================================== + ##### Extended features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Start conversion of injected channel. + (+) Stop conversion of injected channel. + (+) Start multimode and enable DMA transfer. + (+) Stop multimode and disable DMA transfer. + (+) Get result of injected channel conversion. + (+) Get result of multimode conversion. + (+) Configure injected channels. + (+) Configure multimode. + +@endverbatim + * @{ + */ + +/** + * @brief Enables the selected ADC software start conversion of the injected channels. + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef* hadc) +{ + __IO uint32_t counter = 0; + uint32_t tmp1 = 0, tmp2 = 0; + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Check if a regular conversion is ongoing */ + if(hadc->State == HAL_ADC_STATE_BUSY_REG) + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_BUSY_INJ_REG; + } + else + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_BUSY_INJ; + } + + /* Check if ADC peripheral is disabled in order to enable it and wait during + Tstab time the ADC's stabilization */ + if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON) + { + /* Enable the Peripheral */ + __HAL_ADC_ENABLE(hadc); + + /* Delay for temperature sensor stabilization time */ + /* Compute number of CPU cycles to wait for */ + counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000)); + while(counter != 0) + { + counter--; + } + } + + /* Check if Multimode enabled */ + if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI)) + { + tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); + tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); + if(tmp1 && tmp2) + { + /* Enable the selected ADC software conversion for injected group */ + hadc->Instance->CR2 |= ADC_CR2_JSWSTART; + } + } + else + { + tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); + tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); + if((hadc->Instance == ADC1) && tmp1 && tmp2) + { + /* Enable the selected ADC software conversion for injected group */ + hadc->Instance->CR2 |= ADC_CR2_JSWSTART; + } + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Enables the interrupt and starts ADC conversion of injected channels. + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef* hadc) +{ + __IO uint32_t counter = 0; + uint32_t tmp1 = 0, tmp2 =0; + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Check if a regular conversion is ongoing */ + if(hadc->State == HAL_ADC_STATE_BUSY_REG) + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_BUSY_INJ_REG; + } + else + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_BUSY_INJ; + } + + /* Set ADC error code to none */ + hadc->ErrorCode = HAL_ADC_ERROR_NONE; + + /* Check if ADC peripheral is disabled in order to enable it and wait during + Tstab time the ADC's stabilization */ + if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON) + { + /* Enable the Peripheral */ + __HAL_ADC_ENABLE(hadc); + + /* Delay for temperature sensor stabilization time */ + /* Compute number of CPU cycles to wait for */ + counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000)); + while(counter != 0) + { + counter--; + } + } + + /* Enable the ADC end of conversion interrupt for injected group */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC); + + /* Enable the ADC overrun interrupt */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); + + /* Check if Multimode enabled */ + if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI)) + { + tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); + tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); + if(tmp1 && tmp2) + { + /* Enable the selected ADC software conversion for injected group */ + hadc->Instance->CR2 |= ADC_CR2_JSWSTART; + } + } + else + { + tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); + tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); + if((hadc->Instance == ADC1) && tmp1 && tmp2) + { + /* Enable the selected ADC software conversion for injected group */ + hadc->Instance->CR2 |= ADC_CR2_JSWSTART; + } + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Disables ADC and stop conversion of injected channels. + * + * @note Caution: This function will stop also regular channels. + * + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef* hadc) +{ + /* Disable the Peripheral */ + __HAL_ADC_DISABLE(hadc); + + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Poll for injected conversion complete + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param Timeout: Timeout value in millisecond. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check End of conversion flag */ + while(!(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC))) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hadc->State= HAL_ADC_STATE_TIMEOUT; + /* Process unlocked */ + __HAL_UNLOCK(hadc); + return HAL_TIMEOUT; + } + } + } + + /* Check if a regular conversion is ready */ + if(hadc->State == HAL_ADC_STATE_EOC_REG) + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_EOC_INJ_REG; + } + else + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_EOC_INJ; + } + + /* Return ADC state */ + return HAL_OK; +} + +/** + * @brief Disables the interrupt and stop ADC conversion of injected channels. + * + * @note Caution: This function will stop also regular channels. + * + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef* hadc) +{ + /* Disable the ADC end of conversion interrupt for regular group */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); + + /* Disable the ADC end of conversion interrupt for injected group */ + __HAL_ADC_DISABLE_IT(hadc, ADC_CR1_JEOCIE); + + /* Enable the Peripheral */ + __HAL_ADC_DISABLE(hadc); + + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Gets the converted value from data register of injected channel. + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param InjectedRank: the ADC injected rank. + * This parameter can be one of the following values: + * @arg ADC_INJECTED_RANK_1: Injected Channel1 selected + * @arg ADC_INJECTED_RANK_2: Injected Channel2 selected + * @arg ADC_INJECTED_RANK_3: Injected Channel3 selected + * @arg ADC_INJECTED_RANK_4: Injected Channel4 selected + * @retval None + */ +uint32_t HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef* hadc, uint32_t InjectedRank) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_ADC_INJECTED_RANK(InjectedRank)); + + /* Clear the ADCx's flag for injected end of conversion */ + __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_JEOC); + + /* Return the selected ADC converted value */ + switch(InjectedRank) + { + case ADC_INJECTED_RANK_4: + { + tmp = hadc->Instance->JDR4; + } + break; + case ADC_INJECTED_RANK_3: + { + tmp = hadc->Instance->JDR3; + } + break; + case ADC_INJECTED_RANK_2: + { + tmp = hadc->Instance->JDR2; + } + break; + case ADC_INJECTED_RANK_1: + { + tmp = hadc->Instance->JDR1; + } + break; + default: + break; + } + return tmp; +} + +/** + * @brief Enables ADC DMA request after last transfer (Multi-ADC mode) and enables ADC peripheral + * + * @note Caution: This function must be used only with the ADC master. + * + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param pData: Pointer to buffer in which transferred from ADC peripheral to memory will be stored. + * @param Length: The length of data to be transferred from ADC peripheral to memory. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length) +{ + __IO uint32_t counter = 0; + + /* Check the parameters */ + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable ADC overrun interrupt */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); + + if (hadc->Init.DMAContinuousRequests != DISABLE) + { + /* Enable the selected ADC DMA request after last transfer */ + ADC->CCR |= ADC_CCR_DDS; + } + else + { + /* Disable the selected ADC EOC rising on each regular channel conversion */ + ADC->CCR &= ~ADC_CCR_DDS; + } + + /* Set the DMA transfer complete callback */ + hadc->DMA_Handle->XferCpltCallback = ADC_MultiModeDMAConvCplt; + + /* Set the DMA half transfer complete callback */ + hadc->DMA_Handle->XferHalfCpltCallback = ADC_MultiModeDMAHalfConvCplt; + + /* Set the DMA error callback */ + hadc->DMA_Handle->XferErrorCallback = ADC_MultiModeDMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&ADC->CDR, (uint32_t)pData, Length); + + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_BUSY_REG; + + /* Check if ADC peripheral is disabled in order to enable it and wait during + Tstab time the ADC's stabilization */ + if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON) + { + /* Enable the Peripheral */ + __HAL_ADC_ENABLE(hadc); + + /* Delay for temperature sensor stabilization time */ + /* Compute number of CPU cycles to wait for */ + counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000)); + while(counter != 0) + { + counter--; + } + } + + /* if no external trigger present enable software conversion of regular channels */ + if((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET) + { + /* Enable the selected ADC software conversion for regular group */ + hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Disables ADC DMA (multi-ADC mode) and disables ADC peripheral + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef* hadc) +{ + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the Peripheral */ + __HAL_ADC_DISABLE(hadc); + + /* Disable ADC overrun interrupt */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR); + + /* Disable the selected ADC DMA request after last transfer */ + ADC->CCR &= ~ADC_CCR_DDS; + + /* Disable the ADC DMA Stream */ + HAL_DMA_Abort(hadc->DMA_Handle); + + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Returns the last ADC1, ADC2 and ADC3 regular conversions results + * data in the selected multi mode. + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval The converted data value. + */ +uint32_t HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef* hadc) +{ + /* Return the multi mode conversion value */ + return ADC->CDR; +} + +/** + * @brief Injected conversion complete callback in non blocking mode + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @retval None + */ +__weak void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ADC_InjectedConvCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Configures for the selected ADC injected channel its corresponding + * rank in the sequencer and its sample time. + * @param hadc: pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param sConfigInjected: ADC configuration structure for injected channel. + * @retval None + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc, ADC_InjectionConfTypeDef* sConfigInjected) +{ + +#ifdef USE_FULL_ASSERT + uint32_t tmp = 0; +#endif /* USE_FULL_ASSERT */ + + /* Check the parameters */ + assert_param(IS_ADC_CHANNEL(sConfigInjected->InjectedChannel)); + assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank)); + assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime)); + assert_param(IS_ADC_EXT_INJEC_TRIG(sConfigInjected->ExternalTrigInjecConv)); + assert_param(IS_ADC_INJECTED_LENGTH(sConfigInjected->InjectedNbrOfConversion)); + assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv)); + assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode)); + +#ifdef USE_FULL_ASSERT + tmp = ADC_GET_RESOLUTION(hadc); + assert_param(IS_ADC_RANGE(tmp, sConfigInjected->InjectedOffset)); +#endif /* USE_FULL_ASSERT */ + + if(sConfigInjected->ExternalTrigInjecConvEdge != ADC_INJECTED_SOFTWARE_START) + { + assert_param(IS_ADC_EXT_INJEC_TRIG_EDGE(sConfigInjected->ExternalTrigInjecConvEdge)); + } + + /* Process locked */ + __HAL_LOCK(hadc); + + /* if ADC_Channel_10 ... ADC_Channel_18 is selected */ + if (sConfigInjected->InjectedChannel > ADC_CHANNEL_9) + { + /* Clear the old sample time */ + hadc->Instance->SMPR1 &= ~ADC_SMPR1(ADC_SMPR1_SMP10, sConfigInjected->InjectedChannel); + + /* Set the new sample time */ + hadc->Instance->SMPR1 |= ADC_SMPR1(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel); + } + else /* ADC_Channel include in ADC_Channel_[0..9] */ + { + /* Clear the old sample time */ + hadc->Instance->SMPR2 &= ~ADC_SMPR2(ADC_SMPR2_SMP0, sConfigInjected->InjectedChannel); + + /* Set the new sample time */ + hadc->Instance->SMPR2 |= ADC_SMPR2(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel); + } + + /*---------------------------- ADCx JSQR Configuration -----------------*/ + hadc->Instance->JSQR &= ~(ADC_JSQR_JL); + hadc->Instance->JSQR |= ADC_SQR1(sConfigInjected->InjectedNbrOfConversion); + + /* Rank configuration */ + + /* Clear the old SQx bits for the selected rank */ + hadc->Instance->JSQR &= ~ADC_JSQR(ADC_JSQR_JSQ1, sConfigInjected->InjectedRank,sConfigInjected->InjectedNbrOfConversion); + + /* Set the SQx bits for the selected rank */ + hadc->Instance->JSQR |= ADC_JSQR(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank,sConfigInjected->InjectedNbrOfConversion); + + /* Enable external trigger if trigger selection is different of software */ + /* start. */ + /* Note: This configuration keeps the hardware feature of parameter */ + /* ExternalTrigConvEdge "trigger edge none" equivalent to */ + /* software start. */ + if(sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START) + { + /* Select external trigger to start conversion */ + hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL); + hadc->Instance->CR2 |= sConfigInjected->ExternalTrigInjecConv; + + /* Select external trigger polarity */ + hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN); + hadc->Instance->CR2 |= sConfigInjected->ExternalTrigInjecConvEdge; + } + else + { + /* Reset the external trigger */ + hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL); + hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN); + } + + if (sConfigInjected->AutoInjectedConv != DISABLE) + { + /* Enable the selected ADC automatic injected group conversion */ + hadc->Instance->CR1 |= ADC_CR1_JAUTO; + } + else + { + /* Disable the selected ADC automatic injected group conversion */ + hadc->Instance->CR1 &= ~(ADC_CR1_JAUTO); + } + + if (sConfigInjected->InjectedDiscontinuousConvMode != DISABLE) + { + /* Enable the selected ADC injected discontinuous mode */ + hadc->Instance->CR1 |= ADC_CR1_JDISCEN; + } + else + { + /* Disable the selected ADC injected discontinuous mode */ + hadc->Instance->CR1 &= ~(ADC_CR1_JDISCEN); + } + + switch(sConfigInjected->InjectedRank) + { + case 1: + /* Set injected channel 1 offset */ + hadc->Instance->JOFR1 &= ~(ADC_JOFR1_JOFFSET1); + hadc->Instance->JOFR1 |= sConfigInjected->InjectedOffset; + break; + case 2: + /* Set injected channel 2 offset */ + hadc->Instance->JOFR2 &= ~(ADC_JOFR2_JOFFSET2); + hadc->Instance->JOFR2 |= sConfigInjected->InjectedOffset; + break; + case 3: + /* Set injected channel 3 offset */ + hadc->Instance->JOFR3 &= ~(ADC_JOFR3_JOFFSET3); + hadc->Instance->JOFR3 |= sConfigInjected->InjectedOffset; + break; + default: + /* Set injected channel 4 offset */ + hadc->Instance->JOFR4 &= ~(ADC_JOFR4_JOFFSET4); + hadc->Instance->JOFR4 |= sConfigInjected->InjectedOffset; + break; + } + + /* if ADC1 Channel_18 is selected enable VBAT Channel */ + if ((hadc->Instance == ADC1) && (sConfigInjected->InjectedChannel == ADC_CHANNEL_VBAT)) + { + /* Enable the VBAT channel*/ + ADC->CCR |= ADC_CCR_VBATE; + } + + /* if ADC1 Channel_16 or Channel_17 is selected enable TSVREFE Channel(Temperature sensor and VREFINT) */ + if ((hadc->Instance == ADC1) && ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) || (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT))) + { + /* Enable the TSVREFE channel*/ + ADC->CCR |= ADC_CCR_TSVREFE; + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Configures the ADC multi-mode + * @param hadc : pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param multimode : pointer to an ADC_MultiModeTypeDef structure that contains + * the configuration information for multimode. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef* hadc, ADC_MultiModeTypeDef* multimode) +{ + /* Check the parameters */ + assert_param(IS_ADC_MODE(multimode->Mode)); + assert_param(IS_ADC_DMA_ACCESS_MODE(multimode->DMAAccessMode)); + assert_param(IS_ADC_SAMPLING_DELAY(multimode->TwoSamplingDelay)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Set ADC mode */ + ADC->CCR &= ~(ADC_CCR_MULTI); + ADC->CCR |= multimode->Mode; + + /* Set the ADC DMA access mode */ + ADC->CCR &= ~(ADC_CCR_DMA); + ADC->CCR |= multimode->DMAAccessMode; + + /* Set delay between two sampling phases */ + ADC->CCR &= ~(ADC_CCR_DELAY); + ADC->CCR |= multimode->TwoSamplingDelay; + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + + /** + * @brief DMA transfer complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef *hdma) +{ + ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Check if an injected conversion is ready */ + if(hadc->State == HAL_ADC_STATE_EOC_INJ) + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_EOC_INJ_REG; + } + else + { + /* Change ADC state */ + hadc->State = HAL_ADC_STATE_EOC_REG; + } + + HAL_ADC_ConvCpltCallback(hadc); +} + +/** + * @brief DMA half transfer complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void ADC_MultiModeDMAHalfConvCplt(DMA_HandleTypeDef *hdma) +{ + ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + /* Conversion complete callback */ + HAL_ADC_ConvHalfCpltCallback(hadc); +} + +/** + * @brief DMA error callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void ADC_MultiModeDMAError(DMA_HandleTypeDef *hdma) +{ + ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + hadc->State= HAL_ADC_STATE_ERROR; + /* Set ADC error code to DMA error */ + hadc->ErrorCode |= HAL_ADC_ERROR_DMA; + HAL_ADC_ErrorCallback(hadc); +} + +/** + * @} + */ + +#endif /* HAL_ADC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c new file mode 100644 index 0000000..e6ad694 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c @@ -0,0 +1,1438 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_can.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief This file provides firmware functions to manage the following + * functionalities of the Controller Area Network (CAN) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Error functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Enable the CAN controller interface clock using + __HAL_RCC_CAN1_CLK_ENABLE() for CAN1 and __HAL_RCC_CAN2_CLK_ENABLE() for CAN2 + -@- In case you are using CAN2 only, you have to enable the CAN1 clock. + + (#) CAN pins configuration + (++) Enable the clock for the CAN GPIOs using the following function: + __GPIOx_CLK_ENABLE() + (++) Connect and configure the involved CAN pins to AF9 using the + following function HAL_GPIO_Init() + + (#) Initialize and configure the CAN using CAN_Init() function. + + (#) Transmit the desired CAN frame using HAL_CAN_Transmit() function. + + (#) Receive a CAN frame using HAL_CAN_Receive() function. + + *** Polling mode IO operation *** + ================================= + [..] + (+) Start the CAN peripheral transmission and wait the end of this operation + using HAL_CAN_Transmit(), at this stage user can specify the value of timeout + according to his end application + (+) Start the CAN peripheral reception and wait the end of this operation + using HAL_CAN_Receive(), at this stage user can specify the value of timeout + according to his end application + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Start the CAN peripheral transmission using HAL_CAN_Transmit_IT() + (+) Start the CAN peripheral reception using HAL_CAN_Receive_IT() + (+) Use HAL_CAN_IRQHandler() called under the used CAN Interrupt subroutine + (+) At CAN end of transmission HAL_CAN_TxCpltCallback() function is executed and user can + add his own code by customization of function pointer HAL_CAN_TxCpltCallback + (+) In case of CAN Error, HAL_CAN_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_CAN_ErrorCallback + + *** CAN HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in CAN HAL driver. + + (+) __HAL_CAN_ENABLE_IT: Enable the specified CAN interrupts + (+) __HAL_CAN_DISABLE_IT: Disable the specified CAN interrupts + (+) __HAL_CAN_GET_IT_SOURCE: Check if the specified CAN interrupt source is enabled or disabled + (+) __HAL_CAN_CLEAR_FLAG: Clear the CAN's pending flags + (+) __HAL_CAN_GET_FLAG: Get the selected CAN's flag status + + [..] + (@) You can refer to the CAN HAL driver header file for more useful macros + + @endverbatim + + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 CAN CAN + * @brief CAN driver modules + * @{ + */ + +#ifdef HAL_CAN_MODULE_ENABLED + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F446xx) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup CAN_Private_Constants + * @{ + */ +#define CAN_TIMEOUT_VALUE 10 +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup CAN_Private_Functions + * @{ + */ +static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber); +static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup CAN_Exported_Functions CAN Exported Functions + * @{ + */ + +/** @defgroup CAN_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 and configure the CAN. + (+) De-initialize the CAN. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the CAN peripheral according to the specified + * parameters in the CAN_InitStruct. + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan) +{ + uint32_t InitStatus = 3; + uint32_t tickstart = 0; + + /* Check CAN handle */ + if(hcan == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance)); + assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM)); + assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM)); + assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM)); + assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART)); + assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM)); + assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP)); + assert_param(IS_CAN_MODE(hcan->Init.Mode)); + assert_param(IS_CAN_SJW(hcan->Init.SJW)); + assert_param(IS_CAN_BS1(hcan->Init.BS1)); + assert_param(IS_CAN_BS2(hcan->Init.BS2)); + assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler)); + + + if(hcan->State == HAL_CAN_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hcan->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_CAN_MspInit(hcan); + } + + /* Initialize the CAN state*/ + hcan->State = HAL_CAN_STATE_BUSY; + + /* Exit from sleep mode */ + hcan->Instance->MCR &= (~(uint32_t)CAN_MCR_SLEEP); + + /* Request initialisation */ + hcan->Instance->MCR |= CAN_MCR_INRQ ; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait the acknowledge */ + while((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) + { + if((HAL_GetTick() - tickstart ) > CAN_TIMEOUT_VALUE) + { + hcan->State= HAL_CAN_STATE_TIMEOUT; + /* Process unlocked */ + __HAL_UNLOCK(hcan); + return HAL_TIMEOUT; + } + } + + /* Check acknowledge */ + if ((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) + { + InitStatus = CAN_INITSTATUS_FAILED; + } + else + { + /* Set the time triggered communication mode */ + if (hcan->Init.TTCM == ENABLE) + { + hcan->Instance->MCR |= CAN_MCR_TTCM; + } + else + { + hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TTCM; + } + + /* Set the automatic bus-off management */ + if (hcan->Init.ABOM == ENABLE) + { + hcan->Instance->MCR |= CAN_MCR_ABOM; + } + else + { + hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_ABOM; + } + + /* Set the automatic wake-up mode */ + if (hcan->Init.AWUM == ENABLE) + { + hcan->Instance->MCR |= CAN_MCR_AWUM; + } + else + { + hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_AWUM; + } + + /* Set the no automatic retransmission */ + if (hcan->Init.NART == ENABLE) + { + hcan->Instance->MCR |= CAN_MCR_NART; + } + else + { + hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_NART; + } + + /* Set the receive FIFO locked mode */ + if (hcan->Init.RFLM == ENABLE) + { + hcan->Instance->MCR |= CAN_MCR_RFLM; + } + else + { + hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_RFLM; + } + + /* Set the transmit FIFO priority */ + if (hcan->Init.TXFP == ENABLE) + { + hcan->Instance->MCR |= CAN_MCR_TXFP; + } + else + { + hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TXFP; + } + + /* Set the bit timing register */ + hcan->Instance->BTR = (uint32_t)((uint32_t)hcan->Init.Mode) | \ + ((uint32_t)hcan->Init.SJW) | \ + ((uint32_t)hcan->Init.BS1) | \ + ((uint32_t)hcan->Init.BS2) | \ + ((uint32_t)hcan->Init.Prescaler - 1); + + /* Request leave initialisation */ + hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_INRQ; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait the acknowledge */ + while((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) + { + if((HAL_GetTick() - tickstart ) > CAN_TIMEOUT_VALUE) + { + hcan->State= HAL_CAN_STATE_TIMEOUT; + /* Process unlocked */ + __HAL_UNLOCK(hcan); + return HAL_TIMEOUT; + } + } + + /* Check acknowledged */ + if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) + { + InitStatus = CAN_INITSTATUS_FAILED; + } + else + { + InitStatus = CAN_INITSTATUS_SUCCESS; + } + } + + if(InitStatus == CAN_INITSTATUS_SUCCESS) + { + /* Set CAN error code to none */ + hcan->ErrorCode = HAL_CAN_ERROR_NONE; + + /* Initialize the CAN state */ + hcan->State = HAL_CAN_STATE_READY; + + /* Return function status */ + return HAL_OK; + } + else + { + /* Initialize the CAN state */ + hcan->State = HAL_CAN_STATE_ERROR; + + /* Return function status */ + return HAL_ERROR; + } +} + +/** + * @brief Configures the CAN reception filter according to the specified + * parameters in the CAN_FilterInitStruct. + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @param sFilterConfig: pointer to a CAN_FilterConfTypeDef structure that + * contains the filter configuration information. + * @retval None + */ +HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig) +{ + uint32_t filternbrbitpos = 0; + + /* Check the parameters */ + assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber)); + assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode)); + assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale)); + assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment)); + assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->FilterActivation)); + assert_param(IS_CAN_BANKNUMBER(sFilterConfig->BankNumber)); + + filternbrbitpos = ((uint32_t)1) << sFilterConfig->FilterNumber; + + /* Initialisation mode for the filter */ + CAN1->FMR |= (uint32_t)CAN_FMR_FINIT; + + /* Select the start slave bank */ + CAN1->FMR &= ~((uint32_t)CAN_FMR_CAN2SB); + CAN1->FMR |= (uint32_t)(sFilterConfig->BankNumber << 8); + + /* Filter Deactivation */ + CAN1->FA1R &= ~(uint32_t)filternbrbitpos; + + /* Filter Scale */ + if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT) + { + /* 16-bit scale for the filter */ + CAN1->FS1R &= ~(uint32_t)filternbrbitpos; + + /* First 16-bit identifier and First 16-bit mask */ + /* Or First 16-bit identifier and Second 16-bit identifier */ + CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR1 = + ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16) | + (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow); + + /* Second 16-bit identifier and Second 16-bit mask */ + /* Or Third 16-bit identifier and Fourth 16-bit identifier */ + CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR2 = + ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) | + (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh); + } + + if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT) + { + /* 32-bit scale for the filter */ + CAN1->FS1R |= filternbrbitpos; + /* 32-bit identifier or First 32-bit identifier */ + CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR1 = + ((0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh) << 16) | + (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow); + /* 32-bit mask or Second 32-bit identifier */ + CAN1->sFilterRegister[sFilterConfig->FilterNumber].FR2 = + ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16) | + (0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow); + } + + /* Filter Mode */ + if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK) + { + /*Id/Mask mode for the filter*/ + CAN1->FM1R &= ~(uint32_t)filternbrbitpos; + } + else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */ + { + /*Identifier list mode for the filter*/ + CAN1->FM1R |= (uint32_t)filternbrbitpos; + } + + /* Filter FIFO assignment */ + if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0) + { + /* FIFO 0 assignation for the filter */ + CAN1->FFA1R &= ~(uint32_t)filternbrbitpos; + } + + if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO1) + { + /* FIFO 1 assignation for the filter */ + CAN1->FFA1R |= (uint32_t)filternbrbitpos; + } + + /* Filter activation */ + if (sFilterConfig->FilterActivation == ENABLE) + { + CAN1->FA1R |= filternbrbitpos; + } + + /* Leave the initialisation mode for the filter */ + CAN1->FMR &= ~((uint32_t)CAN_FMR_FINIT); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Deinitializes the CANx peripheral registers to their default reset values. + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan) +{ + /* Check CAN handle */ + if(hcan == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance)); + + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_BUSY; + + /* DeInit the low level hardware */ + HAL_CAN_MspDeInit(hcan); + + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hcan); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CAN MSP. + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @retval None + */ +__weak void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_CAN_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes the CAN MSP. + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @retval None + */ +__weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_CAN_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup CAN_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Transmit a CAN frame message. + (+) Receive a CAN frame message. + (+) Enter CAN peripheral in sleep mode. + (+) Wake up the CAN peripheral from sleep mode. + +@endverbatim + * @{ + */ + +/** + * @brief Initiates and transmits a CAN frame message. + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout) +{ + uint32_t transmitmailbox = 5; + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE)); + assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR)); + assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC)); + + /* Process locked */ + __HAL_LOCK(hcan); + + if(hcan->State == HAL_CAN_STATE_BUSY_RX) + { + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_BUSY_TX_RX; + } + else + { + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_BUSY_TX; + } + + /* Select one empty transmit mailbox */ + if ((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) + { + transmitmailbox = 0; + } + else if ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) + { + transmitmailbox = 1; + } + else if ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2) + { + transmitmailbox = 2; + } + else + { + transmitmailbox = CAN_TXSTATUS_NOMAILBOX; + } + + if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX) + { + /* Set up the Id */ + hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ; + if (hcan->pTxMsg->IDE == CAN_ID_STD) + { + assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId)); + hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21) | \ + hcan->pTxMsg->RTR); + } + else + { + assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId)); + hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << 3) | \ + hcan->pTxMsg->IDE | \ + hcan->pTxMsg->RTR); + } + + /* Set up the DLC */ + hcan->pTxMsg->DLC &= (uint8_t)0x0000000F; + hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0; + hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC; + + /* Set up the data field */ + hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3] << 24) | + ((uint32_t)hcan->pTxMsg->Data[2] << 16) | + ((uint32_t)hcan->pTxMsg->Data[1] << 8) | + ((uint32_t)hcan->pTxMsg->Data[0])); + hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7] << 24) | + ((uint32_t)hcan->pTxMsg->Data[6] << 16) | + ((uint32_t)hcan->pTxMsg->Data[5] << 8) | + ((uint32_t)hcan->pTxMsg->Data[4])); + /* Request transmission */ + hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check End of transmission flag */ + while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox))) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hcan->State = HAL_CAN_STATE_TIMEOUT; + /* Process unlocked */ + __HAL_UNLOCK(hcan); + return HAL_TIMEOUT; + } + } + } + if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) + { + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_BUSY_RX; + + /* Process unlocked */ + __HAL_UNLOCK(hcan); + } + else + { + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hcan); + } + + /* Return function status */ + return HAL_OK; + } + else + { + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hcan); + + /* Return function status */ + return HAL_ERROR; + } +} + +/** + * @brief Initiates and transmits a CAN frame message. + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan) +{ + uint32_t transmitmailbox = 5; + uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE)); + assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR)); + assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC)); + + tmp = hcan->State; + if((tmp == HAL_CAN_STATE_READY) || (tmp == HAL_CAN_STATE_BUSY_RX)) + { + /* Process Locked */ + __HAL_LOCK(hcan); + + /* Select one empty transmit mailbox */ + if((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) + { + transmitmailbox = 0; + } + else if((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) + { + transmitmailbox = 1; + } + else if((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2) + { + transmitmailbox = 2; + } + else + { + transmitmailbox = CAN_TXSTATUS_NOMAILBOX; + } + + if(transmitmailbox != CAN_TXSTATUS_NOMAILBOX) + { + /* Set up the Id */ + hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ; + if(hcan->pTxMsg->IDE == CAN_ID_STD) + { + assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId)); + hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21) | \ + hcan->pTxMsg->RTR); + } + else + { + assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId)); + hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << 3) | \ + hcan->pTxMsg->IDE | \ + hcan->pTxMsg->RTR); + } + + /* Set up the DLC */ + hcan->pTxMsg->DLC &= (uint8_t)0x0000000F; + hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0; + hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC; + + /* Set up the data field */ + hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3] << 24) | + ((uint32_t)hcan->pTxMsg->Data[2] << 16) | + ((uint32_t)hcan->pTxMsg->Data[1] << 8) | + ((uint32_t)hcan->pTxMsg->Data[0])); + hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7] << 24) | + ((uint32_t)hcan->pTxMsg->Data[6] << 16) | + ((uint32_t)hcan->pTxMsg->Data[5] << 8) | + ((uint32_t)hcan->pTxMsg->Data[4])); + + if(hcan->State == HAL_CAN_STATE_BUSY_RX) + { + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_BUSY_TX_RX; + } + else + { + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_BUSY_TX; + } + + /* Set CAN error code to none */ + hcan->ErrorCode = HAL_CAN_ERROR_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hcan); + + /* Enable Error warning Interrupt */ + __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG); + + /* Enable Error passive Interrupt */ + __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EPV); + + /* Enable Bus-off Interrupt */ + __HAL_CAN_ENABLE_IT(hcan, CAN_IT_BOF); + + /* Enable Last error code Interrupt */ + __HAL_CAN_ENABLE_IT(hcan, CAN_IT_LEC); + + /* Enable Error Interrupt */ + __HAL_CAN_ENABLE_IT(hcan, CAN_IT_ERR); + + /* Enable Transmit mailbox empty Interrupt */ + __HAL_CAN_ENABLE_IT(hcan, CAN_IT_TME); + + /* Request transmission */ + hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ; + } + } + else + { + return HAL_BUSY; + } + + return HAL_OK; +} + +/** + * @brief Receives a correct CAN frame. + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @param FIFONumber: FIFO Number value + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_CAN_FIFO(FIFONumber)); + + /* Process locked */ + __HAL_LOCK(hcan); + + if(hcan->State == HAL_CAN_STATE_BUSY_TX) + { + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_BUSY_TX_RX; + } + else + { + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_BUSY_RX; + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check pending message */ + while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hcan->State = HAL_CAN_STATE_TIMEOUT; + /* Process unlocked */ + __HAL_UNLOCK(hcan); + return HAL_TIMEOUT; + } + } + } + + /* Get the Id */ + hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR; + if (hcan->pRxMsg->IDE == CAN_ID_STD) + { + hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21); + } + else + { + hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3); + } + + hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR; + /* Get the DLC */ + hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR; + /* Get the FMI */ + hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8); + /* Get the data field */ + hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR; + hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8); + hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16); + hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24); + hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR; + hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8); + hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16); + hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24); + + /* Release the FIFO */ + if(FIFONumber == CAN_FIFO0) + { + /* Release FIFO0 */ + __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0); + } + else /* FIFONumber == CAN_FIFO1 */ + { + /* Release FIFO1 */ + __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1); + } + + if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) + { + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_BUSY_TX; + + /* Process unlocked */ + __HAL_UNLOCK(hcan); + } + else + { + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hcan); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Receives a correct CAN frame. + * @param hcan: Pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @param FIFONumber: Specify the FIFO number + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber) +{ + uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_CAN_FIFO(FIFONumber)); + + tmp = hcan->State; + if((tmp == HAL_CAN_STATE_READY) || (tmp == HAL_CAN_STATE_BUSY_TX)) + { + /* Process locked */ + __HAL_LOCK(hcan); + + if(hcan->State == HAL_CAN_STATE_BUSY_TX) + { + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_BUSY_TX_RX; + } + else + { + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_BUSY_RX; + } + + /* Set CAN error code to none */ + hcan->ErrorCode = HAL_CAN_ERROR_NONE; + + /* Enable Error warning Interrupt */ + __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG); + + /* Enable Error passive Interrupt */ + __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EPV); + + /* Enable Bus-off Interrupt */ + __HAL_CAN_ENABLE_IT(hcan, CAN_IT_BOF); + + /* Enable Last error code Interrupt */ + __HAL_CAN_ENABLE_IT(hcan, CAN_IT_LEC); + + /* Enable Error Interrupt */ + __HAL_CAN_ENABLE_IT(hcan, CAN_IT_ERR); + + /* Process unlocked */ + __HAL_UNLOCK(hcan); + + if(FIFONumber == CAN_FIFO0) + { + /* Enable FIFO 0 message pending Interrupt */ + __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP0); + } + else + { + /* Enable FIFO 1 message pending Interrupt */ + __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP1); + } + + } + else + { + return HAL_BUSY; + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Enters the Sleep (low power) mode. + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan) +{ + uint32_t tickstart = 0; + + /* Process locked */ + __HAL_LOCK(hcan); + + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_BUSY; + + /* Request Sleep mode */ + hcan->Instance->MCR = (((hcan->Instance->MCR) & (uint32_t)(~(uint32_t)CAN_MCR_INRQ)) | CAN_MCR_SLEEP); + + /* Sleep mode status */ + if ((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK) + { + /* Process unlocked */ + __HAL_UNLOCK(hcan); + + /* Return function status */ + return HAL_ERROR; + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait the acknowledge */ + while((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK) + { + if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE) + { + hcan->State = HAL_CAN_STATE_TIMEOUT; + /* Process unlocked */ + __HAL_UNLOCK(hcan); + return HAL_TIMEOUT; + } + } + + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hcan); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Wakes up the CAN peripheral from sleep mode, after that the CAN peripheral + * is in the normal mode. + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan) +{ + uint32_t tickstart = 0; + + /* Process locked */ + __HAL_LOCK(hcan); + + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_BUSY; + + /* Wake up request */ + hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_SLEEP; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Sleep mode status */ + while((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK) + { + if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE) + { + hcan->State= HAL_CAN_STATE_TIMEOUT; + /* Process unlocked */ + __HAL_UNLOCK(hcan); + return HAL_TIMEOUT; + } + } + if((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK) + { + /* Process unlocked */ + __HAL_UNLOCK(hcan); + + /* Return function status */ + return HAL_ERROR; + } + + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hcan); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Handles CAN interrupt request + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @retval None + */ +void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan) +{ + uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0; + + /* Check End of transmission flag */ + if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME)) + { + tmp1 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0); + tmp2 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1); + tmp3 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2); + if(tmp1 || tmp2 || tmp3) + { + /* Call transmit function */ + CAN_Transmit_IT(hcan); + } + } + + tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0); + tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0); + /* Check End of reception flag for FIFO0 */ + if((tmp1 != 0) && tmp2) + { + /* Call receive function */ + CAN_Receive_IT(hcan, CAN_FIFO0); + } + + tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1); + tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1); + /* Check End of reception flag for FIFO1 */ + if((tmp1 != 0) && tmp2) + { + /* Call receive function */ + CAN_Receive_IT(hcan, CAN_FIFO1); + } + + tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG); + tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG); + tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR); + /* Check Error Warning Flag */ + if(tmp1 && tmp2 && tmp3) + { + /* Set CAN error code to EWG error */ + hcan->ErrorCode |= HAL_CAN_ERROR_EWG; + /* Clear Error Warning Flag */ + __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_EWG); + } + + tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV); + tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV); + tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR); + /* Check Error Passive Flag */ + if(tmp1 && tmp2 && tmp3) + { + /* Set CAN error code to EPV error */ + hcan->ErrorCode |= HAL_CAN_ERROR_EPV; + /* Clear Error Passive Flag */ + __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_EPV); + } + + tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF); + tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF); + tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR); + /* Check Bus-Off Flag */ + if(tmp1 && tmp2 && tmp3) + { + /* Set CAN error code to BOF error */ + hcan->ErrorCode |= HAL_CAN_ERROR_BOF; + /* Clear Bus-Off Flag */ + __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_BOF); + } + + tmp1 = HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC); + tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC); + tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR); + /* Check Last error code Flag */ + if((!tmp1) && tmp2 && tmp3) + { + tmp1 = (hcan->Instance->ESR) & CAN_ESR_LEC; + switch(tmp1) + { + case(CAN_ESR_LEC_0): + /* Set CAN error code to STF error */ + hcan->ErrorCode |= HAL_CAN_ERROR_STF; + break; + case(CAN_ESR_LEC_1): + /* Set CAN error code to FOR error */ + hcan->ErrorCode |= HAL_CAN_ERROR_FOR; + break; + case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0): + /* Set CAN error code to ACK error */ + hcan->ErrorCode |= HAL_CAN_ERROR_ACK; + break; + case(CAN_ESR_LEC_2): + /* Set CAN error code to BR error */ + hcan->ErrorCode |= HAL_CAN_ERROR_BR; + break; + case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0): + /* Set CAN error code to BD error */ + hcan->ErrorCode |= HAL_CAN_ERROR_BD; + break; + case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1): + /* Set CAN error code to CRC error */ + hcan->ErrorCode |= HAL_CAN_ERROR_CRC; + break; + default: + break; + } + + /* Clear Last error code Flag */ + hcan->Instance->ESR &= ~(CAN_ESR_LEC); + } + + /* Call the Error call Back in case of Errors */ + if(hcan->ErrorCode != HAL_CAN_ERROR_NONE) + { + /* Set the CAN state ready to be able to start again the process */ + hcan->State = HAL_CAN_STATE_READY; + /* Call Error callback function */ + HAL_CAN_ErrorCallback(hcan); + } +} + +/** + * @brief Transmission complete callback in non blocking mode + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @retval None + */ +__weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_CAN_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Transmission complete callback in non blocking mode + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @retval None + */ +__weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_CAN_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Error CAN callback. + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @retval None + */ +__weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_CAN_ErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions + * @brief CAN Peripheral State functions + * +@verbatim + ============================================================================== + ##### Peripheral State and Error functions ##### + ============================================================================== + [..] + This subsection provides functions allowing to : + (+) Check the CAN state. + (+) Check CAN Errors detected during interrupt process + +@endverbatim + * @{ + */ + +/** + * @brief return the CAN state + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @retval HAL state + */ +HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan) +{ + /* Return CAN state */ + return hcan->State; +} + +/** + * @brief Return the CAN error code + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @retval CAN Error Code + */ +uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan) +{ + return hcan->ErrorCode; +} + +/** + * @} + */ +/** + * @brief Initiates and transmits a CAN frame message. + * @param hcan: pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @retval HAL status + */ +static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan) +{ + /* Disable Transmit mailbox empty Interrupt */ + __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME); + + if(hcan->State == HAL_CAN_STATE_BUSY_TX) + { + /* Disable Error warning Interrupt */ + __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG); + + /* Disable Error passive Interrupt */ + __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EPV); + + /* Disable Bus-off Interrupt */ + __HAL_CAN_DISABLE_IT(hcan, CAN_IT_BOF); + + /* Disable Last error code Interrupt */ + __HAL_CAN_DISABLE_IT(hcan, CAN_IT_LEC); + + /* Disable Error Interrupt */ + __HAL_CAN_DISABLE_IT(hcan, CAN_IT_ERR); + } + + if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) + { + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_BUSY_RX; + } + else + { + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_READY; + } + + /* Transmission complete callback */ + HAL_CAN_TxCpltCallback(hcan); + + return HAL_OK; +} + +/** + * @brief Receives a correct CAN frame. + * @param hcan: Pointer to a CAN_HandleTypeDef structure that contains + * the configuration information for the specified CAN. + * @param FIFONumber: Specify the FIFO number + * @retval HAL status + * @retval None + */ +static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber) +{ + /* Get the Id */ + hcan->pRxMsg->IDE = (uint8_t)0x04 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR; + if (hcan->pRxMsg->IDE == CAN_ID_STD) + { + hcan->pRxMsg->StdId = (uint32_t)0x000007FF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21); + } + else + { + hcan->pRxMsg->ExtId = (uint32_t)0x1FFFFFFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3); + } + + hcan->pRxMsg->RTR = (uint8_t)0x02 & hcan->Instance->sFIFOMailBox[FIFONumber].RIR; + /* Get the DLC */ + hcan->pRxMsg->DLC = (uint8_t)0x0F & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR; + /* Get the FMI */ + hcan->pRxMsg->FMI = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8); + /* Get the data field */ + hcan->pRxMsg->Data[0] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR; + hcan->pRxMsg->Data[1] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8); + hcan->pRxMsg->Data[2] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16); + hcan->pRxMsg->Data[3] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24); + hcan->pRxMsg->Data[4] = (uint8_t)0xFF & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR; + hcan->pRxMsg->Data[5] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8); + hcan->pRxMsg->Data[6] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16); + hcan->pRxMsg->Data[7] = (uint8_t)0xFF & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24); + /* Release the FIFO */ + /* Release FIFO0 */ + if (FIFONumber == CAN_FIFO0) + { + __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0); + + /* Disable FIFO 0 message pending Interrupt */ + __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP0); + } + /* Release FIFO1 */ + else /* FIFONumber == CAN_FIFO1 */ + { + __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1); + + /* Disable FIFO 1 message pending Interrupt */ + __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP1); + } + + if(hcan->State == HAL_CAN_STATE_BUSY_RX) + { + /* Disable Error warning Interrupt */ + __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG); + + /* Disable Error passive Interrupt */ + __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EPV); + + /* Disable Bus-off Interrupt */ + __HAL_CAN_DISABLE_IT(hcan, CAN_IT_BOF); + + /* Disable Last error code Interrupt */ + __HAL_CAN_DISABLE_IT(hcan, CAN_IT_LEC); + + /* Disable Error Interrupt */ + __HAL_CAN_DISABLE_IT(hcan, CAN_IT_ERR); + } + + if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) + { + /* Disable CAN state */ + hcan->State = HAL_CAN_STATE_BUSY_TX; + } + else + { + /* Change CAN state */ + hcan->State = HAL_CAN_STATE_READY; + } + + /* Receive complete callback */ + HAL_CAN_RxCpltCallback(hcan); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ + +#endif /* HAL_CAN_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cec.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cec.c new file mode 100644 index 0000000..9516bf2 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cec.c @@ -0,0 +1,1112 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_cec.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief CEC HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the High Definition Multimedia Interface + * Consumer Electronics Control Peripheral (CEC). + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + * + @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + The CEC HAL driver can be used as follow: + + (#) Declare a CEC_HandleTypeDef handle structure. + (#) Initialize the CEC low level resources by implementing the HAL_CEC_MspInit ()API: + (##) Enable the CEC interface clock. + (##) CEC pins configuration: + (+) Enable the clock for the CEC GPIOs. + (+) Configure these CEC pins as alternate function pull-up. + (##) NVIC configuration if you need to use interrupt process (HAL_CEC_Transmit_IT() + and HAL_CEC_Receive_IT() APIs): + (+) Configure the CEC interrupt priority. + (+) Enable the NVIC CEC IRQ handle. + (@) The specific CEC interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) will be managed using the macros + __HAL_CEC_ENABLE_IT() and __HAL_CEC_DISABLE_IT() inside the transmit + and receive process. + + (#) Program the Signal Free Time (SFT) and SFT option, Tolerance, reception stop in + in case of Bit Rising Error, Error-Bit generation conditions, device logical + address and Listen mode in the hcec Init structure. + + (#) Initialize the CEC registers by calling the HAL_CEC_Init() API. + + (@) This API (HAL_CEC_Init()) configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) + by calling the customed HAL_CEC_MspInit() API. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 CEC CEC + * @brief HAL CEC module driver + * @{ + */ +#ifdef HAL_CEC_MODULE_ENABLED + +#if defined(STM32F446xx) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup CEC_Private_Constants CEC Private Constants + * @{ + */ +#define CEC_CFGR_FIELDS (CEC_CFGR_SFT | CEC_CFGR_RXTOL | CEC_CFGR_BRESTP \ + | CEC_CFGR_BREGEN | CEC_CFGR_LBPEGEN | CEC_CFGR_SFTOPT \ + | CEC_CFGR_BRDNOGEN | CEC_CFGR_OAR | CEC_CFGR_LSTN) +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup CEC_Private_Functions CEC Private Functions + * @{ + */ +static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec); +static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec); +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ +/** @defgroup CEC_Exported_Functions CEC Exported Functions + * @{ + */ + +/** @defgroup CEC_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim +=============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the CEC + (+) The following parameters need to be configured: + (++) SignalFreeTime + (++) Tolerance + (++) BRERxStop (RX stopped or not upon Bit Rising Error) + (++) BREErrorBitGen (Error-Bit generation in case of Bit Rising Error) + (++) LBPEErrorBitGen (Error-Bit generation in case of Long Bit Period Error) + (++) BroadcastMsgNoErrorBitGen (Error-bit generation in case of broadcast message error) + (++) SignalFreeTimeOption (SFT Timer start definition) + (++) OwnAddress (CEC device address) + (++) ListenMode + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the CEC mode according to the specified + * parameters in the CEC_InitTypeDef and creates the associated handle . + * @param hcec: CEC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CEC_Init(CEC_HandleTypeDef *hcec) +{ + uint32_t tmpreg = 0x0; + + /* Check the CEC handle allocation */ + if(hcec == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance)); + assert_param(IS_CEC_SIGNALFREETIME(hcec->Init.SignalFreeTime)); + assert_param(IS_CEC_TOLERANCE(hcec->Init.Tolerance)); + assert_param(IS_CEC_BRERXSTOP(hcec->Init.BRERxStop)); + assert_param(IS_CEC_BREERRORBITGEN(hcec->Init.BREErrorBitGen)); + assert_param(IS_CEC_LBPEERRORBITGEN(hcec->Init.LBPEErrorBitGen)); + assert_param(IS_CEC_BROADCASTERROR_NO_ERRORBIT_GENERATION(hcec->Init.BroadcastMsgNoErrorBitGen)); + assert_param(IS_CEC_SFTOP(hcec->Init.SignalFreeTimeOption)); + assert_param(IS_CEC_OAR_ADDRESS(hcec->Init.OwnAddress)); + assert_param(IS_CEC_LISTENING_MODE(hcec->Init.ListenMode)); + assert_param(IS_CEC_ADDRESS(hcec->Init.InitiatorAddress)); + + + if(hcec->State == HAL_CEC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hcec->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK */ + HAL_CEC_MspInit(hcec); + } + + hcec->State = HAL_CEC_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_CEC_DISABLE(hcec); + + tmpreg = hcec->Init.SignalFreeTime; + tmpreg |= hcec->Init.Tolerance; + tmpreg |= hcec->Init.BRERxStop; + tmpreg |= hcec->Init.BREErrorBitGen; + tmpreg |= hcec->Init.LBPEErrorBitGen; + tmpreg |= hcec->Init.BroadcastMsgNoErrorBitGen; + tmpreg |= hcec->Init.SignalFreeTimeOption; + tmpreg |= (hcec->Init.OwnAddress << CEC_CFGR_OAR_LSB_POS); + tmpreg |= hcec->Init.ListenMode; + + /* Write to CEC Control Register */ + MODIFY_REG(hcec->Instance->CFGR, CEC_CFGR_FIELDS, tmpreg); + + /* Enable the Peripheral */ + __HAL_CEC_ENABLE(hcec); + + hcec->State = HAL_CEC_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the CEC peripheral + * @param hcec: CEC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CEC_DeInit(CEC_HandleTypeDef *hcec) +{ + /* Check the CEC handle allocation */ + if(hcec == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_CEC_ALL_INSTANCE(hcec->Instance)); + + hcec->State = HAL_CEC_STATE_BUSY; + + /* DeInit the low level hardware */ + HAL_CEC_MspDeInit(hcec); + /* Disable the Peripheral */ + __HAL_CEC_DISABLE(hcec); + + hcec->ErrorCode = HAL_CEC_ERROR_NONE; + hcec->State = HAL_CEC_STATE_RESET; + + /* Process Unlock */ + __HAL_UNLOCK(hcec); + + return HAL_OK; +} + +/** + * @brief CEC MSP Init + * @param hcec: CEC handle + * @retval None + */ + __weak void HAL_CEC_MspInit(CEC_HandleTypeDef *hcec) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_CEC_MspInit can be implemented in the user file + */ +} + +/** + * @brief CEC MSP DeInit + * @param hcec: CEC handle + * @retval None + */ + __weak void HAL_CEC_MspDeInit(CEC_HandleTypeDef *hcec) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_CEC_MspDeInit can be implemented in the user file + */ +} +/** + * @} + */ + +/** @defgroup CEC_Exported_Functions_Group2 Input and Output operation functions + * @brief CEC Transmit/Receive functions + * +@verbatim + =============================================================================== + ##### I/O operation functions ##### + =============================================================================== + This subsection provides a set of functions allowing to manage the CEC data transfers. + + (#) The CEC handle must contain the initiator (TX side) and the destination (RX side) + logical addresses (4-bit long addresses, 0xF for broadcast messages destination) + + (#) There are two mode of transfer: + (+) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (+) No-Blocking mode: The communication is performed using Interrupts. + These API's return the HAL status. + The end of the data processing will be indicated through the + dedicated CEC IRQ when using Interrupt mode. + The HAL_CEC_TxCpltCallback(), HAL_CEC_RxCpltCallback() user callbacks + will be executed respectivelly at the end of the transmit or Receive process + The HAL_CEC_ErrorCallback()user callback will be executed when a communication + error is detected + + (#) Blocking mode API's are : + (+) HAL_CEC_Transmit() + (+) HAL_CEC_Receive() + + (#) Non-Blocking mode API's with Interrupt are : + (+) HAL_CEC_Transmit_IT() + (+) HAL_CEC_Receive_IT() + (+) HAL_CEC_IRQHandler() + + (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode: + (+) HAL_CEC_TxCpltCallback() + (+) HAL_CEC_RxCpltCallback() + (+) HAL_CEC_ErrorCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Send data in blocking mode + * @param hcec: CEC handle + * @param DestinationAddress: destination logical address + * @param pData: pointer to input byte data buffer + * @param Size: amount of data to be sent in bytes (without counting the header). + * 0 means only the header is sent (ping operation). + * Maximum TX size is 15 bytes (1 opcode and up to 14 operands). + * @param Timeout: Timeout duration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CEC_Transmit(CEC_HandleTypeDef *hcec, uint8_t DestinationAddress, uint8_t *pData, uint32_t Size, uint32_t Timeout) +{ + uint8_t temp = 0; + uint32_t tempisr = 0; + uint32_t tickstart = 0; + + if((hcec->State == HAL_CEC_STATE_READY) && (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) == RESET)) + { + hcec->ErrorCode = HAL_CEC_ERROR_NONE; + if((pData == NULL ) && (Size > 0)) + { + hcec->State = HAL_CEC_STATE_ERROR; + return HAL_ERROR; + } + + assert_param(IS_CEC_ADDRESS(DestinationAddress)); + assert_param(IS_CEC_MSGSIZE(Size)); + + /* Process Locked */ + __HAL_LOCK(hcec); + + hcec->State = HAL_CEC_STATE_BUSY_TX; + + hcec->TxXferCount = Size; + + /* case no data to be sent, sender is only pinging the system */ + if (Size == 0) + { + /* Set TX End of Message (TXEOM) bit, must be set before writing data to TXDR */ + __HAL_CEC_LAST_BYTE_TX_SET(hcec); + } + + /* send header block */ + temp = ((uint32_t)hcec->Init.InitiatorAddress << CEC_INITIATOR_LSB_POS) | DestinationAddress; + hcec->Instance->TXDR = temp; + /* Set TX Start of Message (TXSOM) bit */ + __HAL_CEC_FIRST_BYTE_TX_SET(hcec); + + while (hcec->TxXferCount > 0) + { + hcec->TxXferCount--; + + tickstart = HAL_GetTick(); + while(HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_FLAG_TXBR)) + { + if(Timeout != HAL_MAX_DELAY) + { + if((HAL_GetTick() - tickstart) > Timeout) + { + hcec->State = HAL_CEC_STATE_TIMEOUT; + /* Process Unlocked */ + __HAL_UNLOCK(hcec); + return HAL_TIMEOUT; + } + } + + /* check whether error occured while waiting for TXBR to be set: + * has Tx underrun occurred ? + * has Tx error occurred ? + * has Tx Missing Acknowledge error occurred ? + * has Arbitration Loss error occurred ? */ + tempisr = hcec->Instance->ISR; + if ((tempisr & (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE|CEC_FLAG_ARBLST)) != 0) + { + /* copy ISR for error handling purposes */ + hcec->ErrorCode = tempisr; + /* clear all error flags by default */ + __HAL_CEC_CLEAR_FLAG(hcec, (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE|CEC_FLAG_ARBLST)); + hcec->State = HAL_CEC_STATE_ERROR; + __HAL_UNLOCK(hcec); + return HAL_ERROR; + } + } + /* TXBR to clear BEFORE writing TXDR register */ + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXBR); + if (hcec->TxXferCount == 0) + { + /* if last byte transmission, set TX End of Message (TXEOM) bit */ + __HAL_CEC_LAST_BYTE_TX_SET(hcec); + } + hcec->Instance->TXDR = *pData++; + + /* error check after TX byte write up */ + tempisr = hcec->Instance->ISR; + if ((tempisr & (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE|CEC_FLAG_ARBLST)) != 0) + { + /* copy ISR for error handling purposes */ + hcec->ErrorCode = tempisr; + /* clear all error flags by default */ + __HAL_CEC_CLEAR_FLAG(hcec, (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE|CEC_FLAG_ARBLST)); + hcec->State = HAL_CEC_STATE_ERROR; + __HAL_UNLOCK(hcec); + return HAL_ERROR; + } + } /* end while (while (hcec->TxXferCount > 0)) */ + + + /* if no error up to this point, check that transmission is + * complete, that is wait until TXEOM is reset */ + tickstart = HAL_GetTick(); + + while (HAL_IS_BIT_SET(hcec->Instance->CR, CEC_CR_TXEOM)) + { + if(Timeout != HAL_MAX_DELAY) + { + if((HAL_GetTick() - tickstart) > Timeout) + { + hcec->State = HAL_CEC_STATE_ERROR; + __HAL_UNLOCK(hcec); + return HAL_TIMEOUT; + } + } + } + + /* Final error check once all bytes have been transmitted */ + tempisr = hcec->Instance->ISR; + if ((tempisr & (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE)) != 0) + { + /* copy ISR for error handling purposes */ + hcec->ErrorCode = tempisr; + /* clear all error flags by default */ + __HAL_CEC_CLEAR_FLAG(hcec, (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE)); + hcec->State = HAL_CEC_STATE_ERROR; + __HAL_UNLOCK(hcec); + return HAL_ERROR; + } + + hcec->State = HAL_CEC_STATE_READY; + __HAL_UNLOCK(hcec); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive data in blocking mode. Must be invoked when RXBR has been set. + * @param hcec: CEC handle + * @param pData: pointer to received data buffer. + * @param Timeout: Timeout duration. + * Note that the received data size is not known beforehand, the latter is known + * when the reception is complete and is stored in hcec->RxXferSize. + * hcec->RxXferSize is the sum of opcodes + operands (0 to 14 operands max). + * If only a header is received, hcec->RxXferSize = 0 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CEC_Receive(CEC_HandleTypeDef *hcec, uint8_t *pData, uint32_t Timeout) +{ + uint32_t temp; + uint32_t tickstart = 0; + + if (hcec->State == HAL_CEC_STATE_READY) + { + hcec->ErrorCode = HAL_CEC_ERROR_NONE; + if (pData == NULL ) + { + hcec->State = HAL_CEC_STATE_ERROR; + return HAL_ERROR; + } + + hcec->RxXferSize = 0; + /* Process Locked */ + __HAL_LOCK(hcec); + + + /* Rx loop until CEC_ISR_RXEND is set */ + while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_FLAG_RXEND)) + { + tickstart = HAL_GetTick(); + /* Wait for next byte to be received */ + while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_FLAG_RXBR)) + { + if(Timeout != HAL_MAX_DELAY) + { + if((HAL_GetTick() - tickstart) > Timeout) + { + hcec->State = HAL_CEC_STATE_TIMEOUT; + __HAL_UNLOCK(hcec); + return HAL_TIMEOUT; + } + } + /* any error so far ? + * has Rx Missing Acknowledge occurred ? + * has Rx Long Bit Period error occurred ? + * has Rx Short Bit Period error occurred ? + * has Rx Bit Rising error occurred ? + * has Rx Overrun error occurred ? */ + temp = (uint32_t) (hcec->Instance->ISR); + if ((temp & (CEC_FLAG_RXACKE|CEC_FLAG_LBPE|CEC_FLAG_SBPE|CEC_FLAG_BRE|CEC_FLAG_RXOVR)) != 0) + { + /* copy ISR for error handling purposes */ + hcec->ErrorCode = temp; + /* clear all error flags by default */ + __HAL_CEC_CLEAR_FLAG(hcec,(CEC_FLAG_RXACKE|CEC_FLAG_LBPE|CEC_FLAG_SBPE|CEC_FLAG_BRE|CEC_FLAG_RXOVR)); + hcec->State = HAL_CEC_STATE_ERROR; + __HAL_UNLOCK(hcec); + return HAL_ERROR; + } + } /* while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_ISR_RXBR)) */ + + + /* read received data */ + *pData++ = hcec->Instance->RXDR; + temp = (uint32_t) (hcec->Instance->ISR); + /* end of message ? */ + if ((temp & CEC_ISR_RXEND) != 0) + { + assert_param(IS_CEC_MSGSIZE(hcec->RxXferSize)); + __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_RXEND); + hcec->State = HAL_CEC_STATE_READY; + __HAL_UNLOCK(hcec); + return HAL_OK; + } + + /* clear Rx-Byte Received flag */ + __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_RXBR); + /* increment payload byte counter */ + hcec->RxXferSize++; + } /* while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_ISR_RXEND)) */ + + /* if the instructions below are executed, it means RXEND was set when RXBR was + * set for the first time: + * the code within the "while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_ISR_RXEND))" + * loop has not been executed and this means a single byte has been sent */ + *pData++ = hcec->Instance->RXDR; + /* only one header is received: RxXferSize is set to 0 (no operand, no opcode) */ + hcec->RxXferSize = 0; + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXEND); + + hcec->State = HAL_CEC_STATE_READY; + __HAL_UNLOCK(hcec); + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Send data in interrupt mode + * @param hcec: CEC handle + * @param DestinationAddress: destination logical address + * @param pData: pointer to input byte data buffer + * @param Size: amount of data to be sent in bytes (without counting the header). + * 0 means only the header is sent (ping operation). + * Maximum TX size is 15 bytes (1 opcode and up to 14 operands). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CEC_Transmit_IT(CEC_HandleTypeDef *hcec, uint8_t DestinationAddress, uint8_t *pData, uint32_t Size) +{ + uint8_t temp = 0; + /* if the IP isn't already busy and if there is no previous transmission + already pending due to arbitration lost */ + if (((hcec->State == HAL_CEC_STATE_READY) || (hcec->State == HAL_CEC_STATE_STANDBY_RX)) + && (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) == RESET)) + { + if((pData == NULL) && (Size > 0)) + { + hcec->State = HAL_CEC_STATE_ERROR; + return HAL_ERROR; + } + + assert_param(IS_CEC_ADDRESS(DestinationAddress)); + assert_param(IS_CEC_MSGSIZE(Size)); + + /* Process Locked */ + __HAL_LOCK(hcec); + hcec->pTxBuffPtr = pData; + hcec->State = HAL_CEC_STATE_BUSY_TX; + hcec->ErrorCode = HAL_CEC_ERROR_NONE; + + /* Disable Peripheral to write CEC_IER register */ + __HAL_CEC_DISABLE(hcec); + + /* Enable the following two CEC Transmission interrupts as + * well as the following CEC Transmission Errors interrupts: + * Tx Byte Request IT + * End of Transmission IT + * Tx Missing Acknowledge IT + * Tx-Error IT + * Tx-Buffer Underrun IT + * Tx arbitration lost */ + __HAL_CEC_ENABLE_IT(hcec, CEC_IT_TXBR|CEC_IT_TXEND|CEC_IER_TX_ALL_ERR); + + /* Enable the Peripheral */ + __HAL_CEC_ENABLE(hcec); + + /* initialize the number of bytes to send, + * 0 means only one header is sent (ping operation) */ + hcec->TxXferCount = Size; + + /* Process Unlocked */ + __HAL_UNLOCK(hcec); + + /* in case of no payload (Size = 0), sender is only pinging the system; + * Set TX End of Message (TXEOM) bit, must be set before writing data to TXDR */ + if (Size == 0) + { + __HAL_CEC_LAST_BYTE_TX_SET(hcec); + } + + /* send header block */ + temp = (uint8_t)((uint32_t)(hcec->Init.InitiatorAddress) << CEC_INITIATOR_LSB_POS) | DestinationAddress; + hcec->Instance->TXDR = temp; + /* Set TX Start of Message (TXSOM) bit */ + __HAL_CEC_FIRST_BYTE_TX_SET(hcec); + + return HAL_OK; + } + /* if the IP is already busy or if there is a previous transmission + already pending due to arbitration loss */ + else if ((hcec->State == HAL_CEC_STATE_BUSY_TX) + || (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) != RESET)) + { + __HAL_LOCK(hcec); + /* set state to BUSY TX, in case it wasn't set already (case + * of transmission new attempt after arbitration loss) */ + if (hcec->State != HAL_CEC_STATE_BUSY_TX) + { + hcec->State = HAL_CEC_STATE_BUSY_TX; + } + + /* if all data have been sent */ + if(hcec->TxXferCount == 0) + { + /* Disable Peripheral to write CEC_IER register */ + __HAL_CEC_DISABLE(hcec); + + /* Disable the CEC Transmission Interrupts */ + __HAL_CEC_DISABLE_IT(hcec, CEC_IT_TXBR|CEC_IT_TXEND); + /* Disable the CEC Transmission Error Interrupts */ + __HAL_CEC_DISABLE_IT(hcec, CEC_IER_TX_ALL_ERR); + + /* Enable the Peripheral */ + __HAL_CEC_ENABLE(hcec); + + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXBR|CEC_FLAG_TXEND); + + hcec->State = HAL_CEC_STATE_READY; + /* Call the Process Unlocked before calling the Tx call back API to give the possibility to + start again the Transmission under the Tx call back API */ + __HAL_UNLOCK(hcec); + + HAL_CEC_TxCpltCallback(hcec); + + return HAL_OK; + } + else + { + if (hcec->TxXferCount == 1) + { + /* if this is the last byte transmission, set TX End of Message (TXEOM) bit */ + __HAL_CEC_LAST_BYTE_TX_SET(hcec); + } + /* clear Tx-Byte request flag */ + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXBR); + hcec->Instance->TXDR = *hcec->pTxBuffPtr++; + hcec->TxXferCount--; + + /* Process Unlocked */ + __HAL_UNLOCK(hcec); + + return HAL_OK; + } + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive data in interrupt mode. + * @param hcec: CEC handle + * @param pData: pointer to received data buffer. + * Note that the received data size is not known beforehand, the latter is known + * when the reception is complete and is stored in hcec->RxXferSize. + * hcec->RxXferSize is the sum of opcodes + operands (0 to 14 operands max). + * If only a header is received, hcec->RxXferSize = 0 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CEC_Receive_IT(CEC_HandleTypeDef *hcec, uint8_t *pData) +{ + if(hcec->State == HAL_CEC_STATE_READY) + { + if(pData == NULL) + { + hcec->State = HAL_CEC_STATE_ERROR; + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hcec); + hcec->RxXferSize = 0; + hcec->pRxBuffPtr = pData; + hcec->ErrorCode = HAL_CEC_ERROR_NONE; + /* the IP is moving to a ready to receive state */ + hcec->State = HAL_CEC_STATE_STANDBY_RX; + + /* Disable Peripheral to write CEC_IER register */ + __HAL_CEC_DISABLE(hcec); + + /* Enable the following CEC Reception Error Interrupts: + * Rx overrun + * Rx bit rising error + * Rx short bit period error + * Rx long bit period error + * Rx missing acknowledge */ + __HAL_CEC_ENABLE_IT(hcec, CEC_IER_RX_ALL_ERR); + + /* Process Unlocked */ + __HAL_UNLOCK(hcec); + + /* Enable the following two CEC Reception interrupts: + * Rx Byte Received IT + * End of Reception IT */ + __HAL_CEC_ENABLE_IT(hcec, CEC_IT_RXBR|CEC_IT_RXEND); + + __HAL_CEC_ENABLE(hcec); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Get size of the received frame. + * @param hcec: CEC handle + * @retval Frame size + */ +uint32_t HAL_CEC_GetReceivedFrameSize(CEC_HandleTypeDef *hcec) +{ + return hcec->RxXferSize; +} + +/** + * @brief This function handles CEC interrupt requests. + * @param hcec: CEC handle + * @retval None + */ +void HAL_CEC_IRQHandler(CEC_HandleTypeDef *hcec) +{ + /* save interrupts register for further error or interrupts handling purposes */ + hcec->ErrorCode = hcec->Instance->ISR; + /* CEC TX missing acknowledge error interrupt occurred -------------------------------------*/ + if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TXACKE) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_TXACKE) != RESET)) + { + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXACKE); + hcec->State = HAL_CEC_STATE_ERROR; + } + + /* CEC transmit error interrupt occured --------------------------------------*/ + if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TXERR) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_TXERR) != RESET)) + { + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXERR); + hcec->State = HAL_CEC_STATE_ERROR; + } + + /* CEC TX underrun error interrupt occured --------------------------------------*/ + if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TXUDR) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_TXUDR) != RESET)) + { + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXUDR); + hcec->State = HAL_CEC_STATE_ERROR; + } + + /* CEC TX arbitration error interrupt occured --------------------------------------*/ + if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_ARBLST) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_ARBLST) != RESET)) + { + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_ARBLST); + hcec->State = HAL_CEC_STATE_ERROR; + } + + /* CEC RX overrun error interrupt occured --------------------------------------*/ + if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RXOVR) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_RXOVR) != RESET)) + { + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXOVR); + hcec->State = HAL_CEC_STATE_ERROR; + } + + /* CEC RX bit rising error interrupt occured --------------------------------------*/ + if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_BRE) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_BRE) != RESET)) + { + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_BRE); + hcec->State = HAL_CEC_STATE_ERROR; + } + + /* CEC RX short bit period error interrupt occured --------------------------------------*/ + if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_SBPE) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_SBPE) != RESET)) + { + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_SBPE); + hcec->State = HAL_CEC_STATE_ERROR; + } + + /* CEC RX long bit period error interrupt occured --------------------------------------*/ + if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_LBPE) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_LBPE) != RESET)) + { + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_LBPE); + hcec->State = HAL_CEC_STATE_ERROR; + } + + /* CEC RX missing acknowledge error interrupt occured --------------------------------------*/ + if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RXACKE) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_RXACKE) != RESET)) + { + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXACKE); + hcec->State = HAL_CEC_STATE_ERROR; + } + + if ((hcec->ErrorCode & CEC_ISR_ALL_ERROR) != 0) + { + HAL_CEC_ErrorCallback(hcec); + } + + /* CEC RX byte received interrupt ---------------------------------------------------*/ + if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RXBR) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_RXBR) != RESET)) + { + /* RXBR IT is cleared during HAL_CEC_Transmit_IT processing */ + CEC_Receive_IT(hcec); + } + + /* CEC RX end received interrupt ---------------------------------------------------*/ + if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RXEND) != RESET) && (__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_RXEND) != RESET)) + { + /* RXBR IT is cleared during HAL_CEC_Transmit_IT processing */ + CEC_Receive_IT(hcec); + } + + + /* CEC TX byte request interrupt ------------------------------------------------*/ + if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TXBR) != RESET) &&(__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_TXBR) != RESET)) + { + /* TXBR IT is cleared during HAL_CEC_Transmit_IT processing */ + CEC_Transmit_IT(hcec); + } + + /* CEC TX end interrupt ------------------------------------------------*/ + if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TXEND) != RESET) &&(__HAL_CEC_GET_IT_SOURCE(hcec, CEC_IT_TXEND) != RESET)) + { + /* TXEND IT is cleared during HAL_CEC_Transmit_IT processing */ + CEC_Transmit_IT(hcec); + } +} + +/** + * @brief Tx Transfer completed callback + * @param hcec: CEC handle + * @retval None + */ + __weak void HAL_CEC_TxCpltCallback(CEC_HandleTypeDef *hcec) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_CEC_TxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callback + * @param hcec: CEC handle + * @retval None + */ +__weak void HAL_CEC_RxCpltCallback(CEC_HandleTypeDef *hcec) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_CEC_TxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief CEC error callbacks + * @param hcec: CEC handle + * @retval None + */ + __weak void HAL_CEC_ErrorCallback(CEC_HandleTypeDef *hcec) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_CEC_ErrorCallback can be implemented in the user file + */ +} +/** + * @} + */ + +/** @defgroup CEC_Exported_Functions_Group3 Peripheral Control function + * @brief CEC control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control function ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the CEC. + (+) HAL_CEC_GetState() API can be helpful to check in run-time the state of the CEC peripheral. +@endverbatim + * @{ + */ +/** + * @brief return the CEC state + * @param hcec: CEC handle + * @retval HAL state + */ +HAL_CEC_StateTypeDef HAL_CEC_GetState(CEC_HandleTypeDef *hcec) +{ + return hcec->State; +} + +/** +* @brief Return the CEC error code +* @param hcec : pointer to a CEC_HandleTypeDef structure that contains + * the configuration information for the specified CEC. +* @retval CEC Error Code +*/ +uint32_t HAL_CEC_GetError(CEC_HandleTypeDef *hcec) +{ + return hcec->ErrorCode; +} + +/** + * @} + */ + +/** + * @brief Send data in interrupt mode + * @param hcec: CEC handle. + * Function called under interruption only, once + * interruptions have been enabled by HAL_CEC_Transmit_IT() + * @retval HAL status + */ +static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec) +{ + /* if the IP is already busy or if there is a previous transmission + already pending due to arbitration loss */ + if ((hcec->State == HAL_CEC_STATE_BUSY_TX) + || (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) != RESET)) + { + __HAL_LOCK(hcec); + /* set state to BUSY TX, in case it wasn't set already (case + * of transmission new attempt after arbitration loss) */ + if (hcec->State != HAL_CEC_STATE_BUSY_TX) + { + hcec->State = HAL_CEC_STATE_BUSY_TX; + } + + /* if all data have been sent */ + if(hcec->TxXferCount == 0) + { + /* Disable Peripheral to write CEC_IER register */ + __HAL_CEC_DISABLE(hcec); + + /* Disable the CEC Transmission Interrupts */ + __HAL_CEC_DISABLE_IT(hcec, CEC_IT_TXBR|CEC_IT_TXEND); + /* Disable the CEC Transmission Error Interrupts */ + __HAL_CEC_DISABLE_IT(hcec, CEC_IER_TX_ALL_ERR); + + /* Enable the Peripheral */ + __HAL_CEC_ENABLE(hcec); + + __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_TXBR|CEC_FLAG_TXEND); + + hcec->State = HAL_CEC_STATE_READY; + /* Call the Process Unlocked before calling the Tx call back API to give the possibility to + start again the Transmission under the Tx call back API */ + __HAL_UNLOCK(hcec); + + HAL_CEC_TxCpltCallback(hcec); + + return HAL_OK; + } + else + { + if (hcec->TxXferCount == 1) + { + /* if this is the last byte transmission, set TX End of Message (TXEOM) bit */ + __HAL_CEC_LAST_BYTE_TX_SET(hcec); + } + /* clear Tx-Byte request flag */ + __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_TXBR); + hcec->Instance->TXDR = *hcec->pTxBuffPtr++; + hcec->TxXferCount--; + + /* Process Unlocked */ + __HAL_UNLOCK(hcec); + + return HAL_OK; + } + } + else + { + return HAL_BUSY; + } +} + + +/** + * @brief Receive data in interrupt mode. + * @param hcec: CEC handle. + * Function called under interruption only, once + * interruptions have been enabled by HAL_CEC_Receive_IT() + * @retval HAL status + */ +static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec) +{ + uint32_t tempisr; + + /* Three different conditions are tested to carry out the RX IT processing: + * - the IP is in reception stand-by (the IP state is HAL_CEC_STATE_STANDBY_RX) and + * the reception of the first byte is starting + * - a message reception is already on-going (the IP state is HAL_CEC_STATE_BUSY_RX) + * and a new byte is being received + * - a transmission has just been started (the IP state is HAL_CEC_STATE_BUSY_TX) + * but has been interrupted by a new message reception or discarded due to + * arbitration loss: the reception of the first or higher priority message + * (the arbitration winner) is starting */ + if ((hcec->State == HAL_CEC_STATE_STANDBY_RX) + || (hcec->State == HAL_CEC_STATE_BUSY_RX) + || (hcec->State == HAL_CEC_STATE_BUSY_TX)) + { + /* reception is starting */ + hcec->State = HAL_CEC_STATE_BUSY_RX; + tempisr = (uint32_t) (hcec->Instance->ISR); + if ((tempisr & CEC_FLAG_RXBR) != 0) + { + /* Process Locked */ + __HAL_LOCK(hcec); + /* read received byte */ + *hcec->pRxBuffPtr++ = hcec->Instance->RXDR; + /* if last byte has been received */ + if ((tempisr & CEC_FLAG_RXEND) != 0) + { + /* clear IT */ + __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_RXBR|CEC_FLAG_RXEND); + /* RX interrupts are not disabled at this point. + * Indeed, to disable the IT, the IP must be disabled first + * which resets the TXSOM flag. In case of arbitration loss, + * this leads to a transmission abort. + * Therefore, RX interruptions disabling if so required, + * is done in HAL_CEC_RxCpltCallback */ + + /* IP state is moved to READY. + * If the IP must remain in standby mode to listen + * any new message, it is up to HAL_CEC_RxCpltCallback + * to move it again to HAL_CEC_STATE_STANDBY_RX */ + hcec->State = HAL_CEC_STATE_READY; + + /* Call the Process Unlocked before calling the Rx call back API */ + __HAL_UNLOCK(hcec); + HAL_CEC_RxCpltCallback(hcec); + + return HAL_OK; + } + __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXBR); + + hcec->RxXferSize++; + /* Process Unlocked */ + __HAL_UNLOCK(hcec); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } + } + else + { + return HAL_BUSY; + } +} +/** + * @} + */ + +#endif /* STM32F446xx */ + +#endif /* HAL_CEC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c new file mode 100644 index 0000000..59209d0 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c @@ -0,0 +1,436 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_cortex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief CORTEX HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the CORTEX: + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + + [..] + *** How to configure Interrupts using CORTEX HAL driver *** + =========================================================== + [..] + This section provides functions allowing to configure the NVIC interrupts (IRQ). + The Cortex-M4 exceptions are managed by CMSIS functions. + + (#) Configure the NVIC Priority Grouping using HAL_NVIC_SetPriorityGrouping() + function according to the following table. + (#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority(). + (#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ(). + (#) please refer to programing manual for details in how to configure priority. + + -@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ preemption is no more possible. + The pending IRQ priority will be managed only by the sub priority. + + -@- IRQ priority order (sorted by highest to lowest priority): + (+@) Lowest preemption priority + (+@) Lowest sub priority + (+@) Lowest hardware priority (IRQ number) + + [..] + *** How to configure Systick using CORTEX HAL driver *** + ======================================================== + [..] + Setup SysTick Timer for time base. + + (+) The HAL_SYSTICK_Config() function calls the SysTick_Config() function which + is a CMSIS function that: + (++) Configures the SysTick Reload register with value passed as function parameter. + (++) Configures the SysTick IRQ priority to the lowest value (0x0F). + (++) Resets the SysTick Counter register. + (++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK). + (++) Enables the SysTick Interrupt. + (++) Starts the SysTick Counter. + + (+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro + __HAL_CORTEX_SYSTICKCLK_CONFIG(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the + HAL_SYSTICK_Config() function call. The __HAL_CORTEX_SYSTICKCLK_CONFIG() macro is defined + inside the stm32f4xx_hal_cortex.h file. + + (+) You can change the SysTick IRQ priority by calling the + HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function + call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function. + + (+) To adjust the SysTick time base, use the following formula: + + Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s) + (++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function + (++) Reload Value should not exceed 0xFFFFFF + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 CORTEX CORTEX + * @brief CORTEX HAL module driver + * @{ + */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup CORTEX_Exported_Functions CORTEX Exported Functions + * @{ + */ + + +/** @defgroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and de-initialization functions ##### + ============================================================================== + [..] + This section provides the CORTEX HAL driver functions allowing to configure Interrupts + Systick functionalities + +@endverbatim + * @{ + */ + + +/** + * @brief Sets the priority grouping field (preemption priority and subpriority) + * using the required unlock sequence. + * @param PriorityGroup: The priority grouping bits length. + * This parameter can be one of the following values: + * @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority + * 4 bits for subpriority + * @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority + * 3 bits for subpriority + * @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority + * 2 bits for subpriority + * @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority + * 1 bits for subpriority + * @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority + * 0 bits for subpriority + * @note When the NVIC_PriorityGroup_0 is selected, IRQ preemption is no more possible. + * The pending IRQ priority will be managed only by the subpriority. + * @retval None + */ +void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + /* Check the parameters */ + assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup)); + + /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */ + NVIC_SetPriorityGrouping(PriorityGroup); +} + +/** + * @brief Sets the priority of an interrupt. + * @param IRQn: External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h)) + * @param PreemptPriority: The preemption priority for the IRQn channel. + * This parameter can be a value between 0 and 15 + * A lower priority value indicates a higher priority + * @param SubPriority: the subpriority level for the IRQ channel. + * This parameter can be a value between 0 and 15 + * A lower priority value indicates a higher priority. + * @retval None + */ +void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t prioritygroup = 0x00; + + /* Check the parameters */ + assert_param(IS_NVIC_SUB_PRIORITY(SubPriority)); + assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority)); + + prioritygroup = NVIC_GetPriorityGrouping(); + + NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority)); +} + +/** + * @brief Enables a device specific interrupt in the NVIC interrupt controller. + * @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig() + * function should be called before. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h)) + * @retval None + */ +void HAL_NVIC_EnableIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Enable interrupt */ + NVIC_EnableIRQ(IRQn); +} + +/** + * @brief Disables a device specific interrupt in the NVIC interrupt controller. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h)) + * @retval None + */ +void HAL_NVIC_DisableIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Disable interrupt */ + NVIC_DisableIRQ(IRQn); +} + +/** + * @brief Initiates a system reset request to reset the MCU. + * @retval None + */ +void HAL_NVIC_SystemReset(void) +{ + /* System Reset */ + NVIC_SystemReset(); +} + +/** + * @brief Initializes the System Timer and its interrupt, and starts the System Tick Timer. + * Counter is in free running mode to generate periodic interrupts. + * @param TicksNumb: Specifies the ticks Number of ticks between two interrupts. + * @retval status: - 0 Function succeeded. + * - 1 Function failed. + */ +uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb) +{ + return SysTick_Config(TicksNumb); +} +/** + * @} + */ + +/** @defgroup CORTEX_Exported_Functions_Group2 Peripheral Control functions + * @brief Cortex control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control the CORTEX + (NVIC, SYSTICK) functionalities. + + +@endverbatim + * @{ + */ + +/** + * @brief Gets the priority grouping field from the NVIC Interrupt Controller. + * @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field) + */ +uint32_t HAL_NVIC_GetPriorityGrouping(void) +{ + /* Get the PRIGROUP[10:8] field value */ + return NVIC_GetPriorityGrouping(); +} + +/** + * @brief Gets the priority of an interrupt. + * @param IRQn: External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h)) + * @param PriorityGroup: the priority grouping bits length. + * This parameter can be one of the following values: + * @arg NVIC_PRIORITYGROUP_0: 0 bits for preemption priority + * 4 bits for subpriority + * @arg NVIC_PRIORITYGROUP_1: 1 bits for preemption priority + * 3 bits for subpriority + * @arg NVIC_PRIORITYGROUP_2: 2 bits for preemption priority + * 2 bits for subpriority + * @arg NVIC_PRIORITYGROUP_3: 3 bits for preemption priority + * 1 bits for subpriority + * @arg NVIC_PRIORITYGROUP_4: 4 bits for preemption priority + * 0 bits for subpriority + * @param pPreemptPriority: Pointer on the Preemptive priority value (starting from 0). + * @param pSubPriority: Pointer on the Subpriority value (starting from 0). + * @retval None + */ +void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t *pPreemptPriority, uint32_t *pSubPriority) +{ + /* Check the parameters */ + assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup)); + /* Get priority for Cortex-M system or device specific interrupts */ + NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority); +} + +/** + * @brief Sets Pending bit of an external interrupt. + * @param IRQn External interrupt number + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h)) + * @retval None + */ +void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Set interrupt pending */ + NVIC_SetPendingIRQ(IRQn); +} + +/** + * @brief Gets Pending Interrupt (reads the pending register in the NVIC + * and returns the pending bit for the specified interrupt). + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h)) + * @retval status: - 0 Interrupt status is not pending. + * - 1 Interrupt status is pending. + */ +uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Return 1 if pending else 0 */ + return NVIC_GetPendingIRQ(IRQn); +} + +/** + * @brief Clears the pending bit of an external interrupt. + * @param IRQn External interrupt number. + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h)) + * @retval None + */ +void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Clear pending interrupt */ + NVIC_ClearPendingIRQ(IRQn); +} + +/** + * @brief Gets active interrupt ( reads the active register in NVIC and returns the active bit). + * @param IRQn External interrupt number + * This parameter can be an enumerator of IRQn_Type enumeration + * (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f4xxxx.h)) + * @retval status: - 0 Interrupt status is not pending. + * - 1 Interrupt status is pending. + */ +uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn) +{ + /* Check the parameters */ + assert_param(IS_NVIC_DEVICE_IRQ(IRQn)); + + /* Return 1 if active else 0 */ + return NVIC_GetActive(IRQn); +} + +/** + * @brief Configures the SysTick clock source. + * @param CLKSource: specifies the SysTick clock source. + * This parameter can be one of the following values: + * @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source. + * @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source. + * @retval None + */ +void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource) +{ + /* Check the parameters */ + assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource)); + if (CLKSource == SYSTICK_CLKSOURCE_HCLK) + { + SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK; + } + else + { + SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK; + } +} + +/** + * @brief This function handles SYSTICK interrupt request. + * @retval None + */ +void HAL_SYSTICK_IRQHandler(void) +{ + HAL_SYSTICK_Callback(); +} + +/** + * @brief SYSTICK callback. + * @retval None + */ +__weak void HAL_SYSTICK_Callback(void) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SYSTICK_Callback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_CORTEX_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_crc.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_crc.c new file mode 100644 index 0000000..6db9a27 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_crc.c @@ -0,0 +1,342 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_crc.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief CRC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Cyclic Redundancy Check (CRC) peripheral: + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The CRC HAL driver can be used as follows: + + (#) Enable CRC AHB clock using __HAL_RCC_CRC_CLK_ENABLE(); + + (#) Use HAL_CRC_Accumulate() function to compute the CRC value of + a 32-bit data buffer using combination of the previous CRC value + and the new one. + + (#) Use HAL_CRC_Calculate() function to compute the CRC Value of + a new 32-bit data buffer. This function resets the CRC computation + unit before starting the computation to avoid getting wrong CRC values. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 + * @{ + */ + +/** @addtogroup CRC + * @{ + */ + +#ifdef HAL_CRC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup CRC_Exported_Functions + * @{ + */ + +/** @addtogroup CRC_Exported_Functions_Group1 + * @brief Initialization and de-initialization functions + * +@verbatim + ============================================================================== + ##### Initialization and de-initialization functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Initialize the CRC according to the specified parameters + in the CRC_InitTypeDef and create the associated handle + (+) DeInitialize the CRC peripheral + (+) Initialize the CRC MSP + (+) DeInitialize CRC MSP + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the CRC according to the specified + * parameters in the CRC_InitTypeDef and creates the associated handle. + * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains + * the configuration information for CRC + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc) +{ + /* Check the CRC handle allocation */ + if(hcrc == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance)); + + if(hcrc->State == HAL_CRC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hcrc->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_CRC_MspInit(hcrc); + } + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_BUSY; + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief DeInitializes the CRC peripheral. + * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains + * the configuration information for CRC + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc) +{ + /* Check the CRC handle allocation */ + if(hcrc == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance)); + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_BUSY; + + /* DeInit the low level hardware */ + HAL_CRC_MspDeInit(hcrc); + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hcrc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRC MSP. + * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains + * the configuration information for CRC + * @retval None + */ +__weak void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_CRC_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes the CRC MSP. + * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains + * the configuration information for CRC + * @retval None + */ +__weak void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_CRC_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @addtogroup CRC_Exported_Functions_Group2 + * @brief Peripheral Control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Compute the 32-bit CRC value of 32-bit data buffer, + using combination of the previous CRC value and the new one. + (+) Compute the 32-bit CRC value of 32-bit data buffer, + independently of the previous CRC value. + +@endverbatim + * @{ + */ + +/** + * @brief Computes the 32-bit CRC of 32-bit data buffer using combination + * of the previous CRC value and the new one. + * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains + * the configuration information for CRC + * @param pBuffer: pointer to the buffer containing the data to be computed + * @param BufferLength: length of the buffer to be computed + * @retval 32-bit CRC + */ +uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength) +{ + uint32_t index = 0; + + /* Process Locked */ + __HAL_LOCK(hcrc); + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_BUSY; + + /* Enter Data to the CRC calculator */ + for(index = 0; index < BufferLength; index++) + { + hcrc->Instance->DR = pBuffer[index]; + } + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcrc); + + /* Return the CRC computed value */ + return hcrc->Instance->DR; +} + +/** + * @brief Computes the 32-bit CRC of 32-bit data buffer independently + * of the previous CRC value. + * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains + * the configuration information for CRC + * @param pBuffer: Pointer to the buffer containing the data to be computed + * @param BufferLength: Length of the buffer to be computed + * @retval 32-bit CRC + */ +uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength) +{ + uint32_t index = 0; + + /* Process Locked */ + __HAL_LOCK(hcrc); + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_BUSY; + + /* Reset CRC Calculation Unit */ + __HAL_CRC_DR_RESET(hcrc); + + /* Enter Data to the CRC calculator */ + for(index = 0; index < BufferLength; index++) + { + hcrc->Instance->DR = pBuffer[index]; + } + + /* Change CRC peripheral state */ + hcrc->State = HAL_CRC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcrc); + + /* Return the CRC computed value */ + return hcrc->Instance->DR; +} + +/** + * @} + */ + + +/** @addtogroup CRC_Exported_Functions_Group3 + * @brief Peripheral State functions + * +@verbatim + ============================================================================== + ##### Peripheral State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the CRC state. + * @param hcrc: pointer to a CRC_HandleTypeDef structure that contains + * the configuration information for CRC + * @retval HAL state + */ +HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc) +{ + return hcrc->State; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_CRC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp.c new file mode 100644 index 0000000..74b3a9b --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp.c @@ -0,0 +1,3813 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_cryp.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief CRYP HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Cryptography (CRYP) peripheral: + * + Initialization and de-initialization functions + * + AES processing functions + * + DES processing functions + * + TDES processing functions + * + DMA callback functions + * + CRYP IRQ handler management + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The CRYP HAL driver can be used as follows: + + (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit(): + (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE() + (##) In case of using interrupts (e.g. HAL_CRYP_AESECB_Encrypt_IT()) + (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority() + (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ() + (+++) In CRYP IRQ handler, call HAL_CRYP_IRQHandler() + (##) In case of using DMA to control data transfer (e.g. HAL_CRYP_AESECB_Encrypt_DMA()) + (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE() + (+++) Configure and enable two DMA streams one for managing data transfer from + memory to peripheral (input stream) and another stream for managing data + transfer from peripheral to memory (output stream) + (+++) Associate the initialized DMA handle to the CRYP DMA handle + using __HAL_LINKDMA() + (+++) Configure the priority and enable the NVIC for the transfer complete + interrupt on the two DMA Streams. The output stream should have higher + priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ() + + (#)Initialize the CRYP HAL using HAL_CRYP_Init(). This function configures mainly: + (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit + (##) The key size: 128, 192 and 256. This parameter is relevant only for AES + (##) The encryption/decryption key. It's size depends on the algorithm + used for encryption/decryption + (##) The initialization vector (counter). It is not used ECB mode. + + (#)Three processing (encryption/decryption) functions are available: + (##) Polling mode: encryption and decryption APIs are blocking functions + i.e. they process the data and wait till the processing is finished, + e.g. HAL_CRYP_AESCBC_Encrypt() + (##) Interrupt mode: encryption and decryption APIs are not blocking functions + i.e. they process the data under interrupt, + e.g. HAL_CRYP_AESCBC_Encrypt_IT() + (##) DMA mode: encryption and decryption APIs are not blocking functions + i.e. the data transfer is ensured by DMA, + e.g. HAL_CRYP_AESCBC_Encrypt_DMA() + + (#)When the processing function is called at first time after HAL_CRYP_Init() + the CRYP peripheral is initialized and processes the buffer in input. + At second call, the processing function performs an append of the already + processed buffer. + When a new data block is to be processed, call HAL_CRYP_Init() then the + processing function. + + (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 CRYP CRYP + * @brief CRYP HAL module driver. + * @{ + */ + +#ifdef HAL_CRYP_MODULE_ENABLED + +#if defined(STM32F415xx) || defined(STM32F417xx) || defined(STM32F437xx) || defined(STM32F439xx) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup CRYP_Private_define + * @{ + */ +#define CRYP_TIMEOUT_VALUE 1 +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup CRYP_Private_Functions_prototypes + * @{ + */ +static void CRYP_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector, uint32_t IVSize); +static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize); +static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout); +static HAL_StatusTypeDef CRYP_ProcessData2Words(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout); +static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma); +static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma); +static void CRYP_DMAError(DMA_HandleTypeDef *hdma); +static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr); +static void CRYP_SetTDESECBMode(CRYP_HandleTypeDef *hcryp, uint32_t Direction); +static void CRYP_SetTDESCBCMode(CRYP_HandleTypeDef *hcryp, uint32_t Direction); +static void CRYP_SetDESECBMode(CRYP_HandleTypeDef *hcryp, uint32_t Direction); +static void CRYP_SetDESCBCMode(CRYP_HandleTypeDef *hcryp, uint32_t Direction); +/** + * @} + */ + + +/* Private functions ---------------------------------------------------------*/ + +/** @addtogroup CRYP_Private_Functions + * @{ + */ + + +/** + * @brief DMA CRYP Input Data process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void CRYP_DMAInCplt(DMA_HandleTypeDef *hdma) +{ + CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Disable the DMA transfer for input FIFO request by resetting the DIEN bit + in the DMACR register */ + hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN); + + /* Call input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); +} + +/** + * @brief DMA CRYP Output Data process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void CRYP_DMAOutCplt(DMA_HandleTypeDef *hdma) +{ + CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Disable the DMA transfer for output FIFO request by resetting the DOEN bit + in the DMACR register */ + hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN); + + /* Disable CRYP */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change the CRYP state to ready */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Call output data transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); +} + +/** + * @brief DMA CRYP communication error callback. + * @param hdma: DMA handle + * @retval None + */ +static void CRYP_DMAError(DMA_HandleTypeDef *hdma) +{ + CRYP_HandleTypeDef* hcryp = (CRYP_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + hcryp->State= HAL_CRYP_STATE_READY; + HAL_CRYP_ErrorCallback(hcryp); +} + +/** + * @brief Writes the Key in Key registers. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param Key: Pointer to Key buffer + * @param KeySize: Size of Key + * @retval None + */ +static void CRYP_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize) +{ + uint32_t keyaddr = (uint32_t)Key; + + switch(KeySize) + { + case CRYP_KEYSIZE_256B: + /* Key Initialisation */ + hcryp->Instance->K0LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K0RR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K1LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K1RR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr)); + break; + case CRYP_KEYSIZE_192B: + hcryp->Instance->K1LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K1RR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr)); + break; + case CRYP_KEYSIZE_128B: + hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr)); + break; + default: + break; + } +} + +/** + * @brief Writes the InitVector/InitCounter in IV registers. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param InitVector: Pointer to InitVector/InitCounter buffer + * @param IVSize: Size of the InitVector/InitCounter + * @retval None + */ +static void CRYP_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector, uint32_t IVSize) +{ + uint32_t ivaddr = (uint32_t)InitVector; + + switch(IVSize) + { + case CRYP_KEYSIZE_128B: + hcryp->Instance->IV0LR = __REV(*(uint32_t*)(ivaddr)); + ivaddr+=4; + hcryp->Instance->IV0RR = __REV(*(uint32_t*)(ivaddr)); + ivaddr+=4; + hcryp->Instance->IV1LR = __REV(*(uint32_t*)(ivaddr)); + ivaddr+=4; + hcryp->Instance->IV1RR = __REV(*(uint32_t*)(ivaddr)); + break; + /* Whatever key size 192 or 256, Init vector is written in IV0LR and IV0RR */ + case CRYP_KEYSIZE_192B: + hcryp->Instance->IV0LR = __REV(*(uint32_t*)(ivaddr)); + ivaddr+=4; + hcryp->Instance->IV0RR = __REV(*(uint32_t*)(ivaddr)); + break; + case CRYP_KEYSIZE_256B: + hcryp->Instance->IV0LR = __REV(*(uint32_t*)(ivaddr)); + ivaddr+=4; + hcryp->Instance->IV0RR = __REV(*(uint32_t*)(ivaddr)); + break; + default: + break; + } +} + +/** + * @brief Process Data: Writes Input data in polling mode and read the output data + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param Input: Pointer to the Input buffer + * @param Ilength: Length of the Input buffer, must be a multiple of 16. + * @param Output: Pointer to the returned buffer + * @param Timeout: Timeout value + * * @retval None + */ +static HAL_StatusTypeDef CRYP_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + uint32_t i = 0; + uint32_t inputaddr = (uint32_t)Input; + uint32_t outputaddr = (uint32_t)Output; + + for(i=0; (i < Ilength); i+=16) + { + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE)) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + } + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Process Data: Write Input data in polling mode. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param Input: Pointer to the Input buffer + * @param Ilength: Length of the Input buffer, must be a multiple of 8 + * @param Output: Pointer to the returned buffer + * @param Timeout: Specify Timeout value + * @retval None + */ +static HAL_StatusTypeDef CRYP_ProcessData2Words(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint8_t* Output, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + uint32_t i = 0; + uint32_t inputaddr = (uint32_t)Input; + uint32_t outputaddr = (uint32_t)Output; + + for(i=0; (i < Ilength); i+=8) + { + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE)) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + } + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Set the DMA configuration and start the DMA transfer + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param inputaddr: address of the Input buffer + * @param Size: Size of the Input buffer, must be a multiple of 16. + * @param outputaddr: address of the Output buffer + * @retval None + */ +static void CRYP_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr) +{ + /* Set the CRYP DMA transfer complete callback */ + hcryp->hdmain->XferCpltCallback = CRYP_DMAInCplt; + /* Set the DMA error callback */ + hcryp->hdmain->XferErrorCallback = CRYP_DMAError; + + /* Set the CRYP DMA transfer complete callback */ + hcryp->hdmaout->XferCpltCallback = CRYP_DMAOutCplt; + /* Set the DMA error callback */ + hcryp->hdmaout->XferErrorCallback = CRYP_DMAError; + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Enable the DMA In DMA Stream */ + HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DR, Size/4); + + /* Enable In DMA request */ + hcryp->Instance->DMACR = (CRYP_DMACR_DIEN); + + /* Enable the DMA Out DMA Stream */ + HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUT, outputaddr, Size/4); + + /* Enable Out DMA request */ + hcryp->Instance->DMACR |= CRYP_DMACR_DOEN; + +} + +/** + * @brief Sets the CRYP peripheral in DES ECB mode. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param Direction: Encryption or decryption + * @retval None + */ +static void CRYP_SetDESECBMode(CRYP_HandleTypeDef *hcryp, uint32_t Direction) +{ + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the CRYP peripheral in AES ECB mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_DES_ECB | Direction); + + /* Set the key */ + hcryp->Instance->K1LR = __REV(*(uint32_t*)(hcryp->Init.pKey)); + hcryp->Instance->K1RR = __REV(*(uint32_t*)(hcryp->Init.pKey+4)); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } +} + +/** + * @brief Sets the CRYP peripheral in DES CBC mode. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param Direction: Encryption or decryption + * @retval None + */ +static void CRYP_SetDESCBCMode(CRYP_HandleTypeDef *hcryp, uint32_t Direction) +{ + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the CRYP peripheral in AES ECB mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_DES_CBC | Direction); + + /* Set the key */ + hcryp->Instance->K1LR = __REV(*(uint32_t*)(hcryp->Init.pKey)); + hcryp->Instance->K1RR = __REV(*(uint32_t*)(hcryp->Init.pKey+4)); + + /* Set the Initialization Vector */ + CRYP_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_256B); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } +} + +/** + * @brief Sets the CRYP peripheral in TDES ECB mode. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param Direction: Encryption or decryption + * @retval None + */ +static void CRYP_SetTDESECBMode(CRYP_HandleTypeDef *hcryp, uint32_t Direction) +{ + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the CRYP peripheral in AES ECB mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_TDES_ECB | Direction); + + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, CRYP_KEYSIZE_192B); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } +} + +/** + * @brief Sets the CRYP peripheral in TDES CBC mode + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param Direction: Encryption or decryption + * @retval None + */ +static void CRYP_SetTDESCBCMode(CRYP_HandleTypeDef *hcryp, uint32_t Direction) +{ + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the CRYP peripheral in AES CBC mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_TDES_CBC | Direction); + + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, CRYP_KEYSIZE_192B); + + /* Set the Initialization Vector */ + CRYP_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_256B); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } +} + +/** + * @} + */ + + /* Exported functions --------------------------------------------------------*/ +/** @addtogroup CRYP_Exported_Functions + * @{ + */ + +/** @defgroup CRYP_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 CRYP according to the specified parameters + in the CRYP_InitTypeDef and creates the associated handle + (+) DeInitialize the CRYP peripheral + (+) Initialize the CRYP MSP + (+) DeInitialize CRYP MSP + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the CRYP according to the specified + * parameters in the CRYP_InitTypeDef and creates the associated handle. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_Init(CRYP_HandleTypeDef *hcryp) +{ + /* Check the CRYP handle allocation */ + if(hcryp == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_CRYP_KEYSIZE(hcryp->Init.KeySize)); + assert_param(IS_CRYP_DATATYPE(hcryp->Init.DataType)); + + if(hcryp->State == HAL_CRYP_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hcryp->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_CRYP_MspInit(hcryp); + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set the key size and data type*/ + CRYP->CR = (uint32_t) (hcryp->Init.KeySize | hcryp->Init.DataType); + + /* Reset CrypInCount and CrypOutCount */ + hcryp->CrypInCount = 0; + hcryp->CrypOutCount = 0; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Set the default CRYP phase */ + hcryp->Phase = HAL_CRYP_PHASE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief DeInitializes the CRYP peripheral. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_DeInit(CRYP_HandleTypeDef *hcryp) +{ + /* Check the CRYP handle allocation */ + if(hcryp == NULL) + { + return HAL_ERROR; + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set the default CRYP phase */ + hcryp->Phase = HAL_CRYP_PHASE_READY; + + /* Reset CrypInCount and CrypOutCount */ + hcryp->CrypInCount = 0; + hcryp->CrypOutCount = 0; + + /* Disable the CRYP Peripheral Clock */ + __HAL_CRYP_DISABLE(hcryp); + + /* DeInit the low level hardware: CLOCK, NVIC.*/ + HAL_CRYP_MspDeInit(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP MSP. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval None + */ +__weak void HAL_CRYP_MspInit(CRYP_HandleTypeDef *hcryp) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_CRYP_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes CRYP MSP. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval None + */ +__weak void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef *hcryp) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_CRYP_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup CRYP_Exported_Functions_Group2 AES processing functions + * @brief processing functions. + * +@verbatim + ============================================================================== + ##### AES processing functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Encrypt plaintext using AES-128/192/256 using chaining modes + (+) Decrypt cyphertext using AES-128/192/256 using chaining modes + [..] Three processing functions are available: + (+) Polling mode + (+) Interrupt mode + (+) DMA mode + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the CRYP peripheral in AES ECB encryption mode + * then encrypt pPlainData. The cypher data are available in pCypherData + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16. + * @param pCypherData: Pointer to the cyphertext buffer + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESECB_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout) +{ + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES ECB mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_ECB); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Write Plain Data and Get Cypher Data */ + if(CRYP_ProcessData(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES CBC encryption mode + * then encrypt pPlainData. The cypher data are available in pCypherData + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16. + * @param pCypherData: Pointer to the cyphertext buffer + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESCBC_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout) +{ + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES ECB mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CBC); + + /* Set the Initialization Vector */ + CRYP_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Write Plain Data and Get Cypher Data */ + if(CRYP_ProcessData(hcryp,pPlainData, Size, pCypherData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES CTR encryption mode + * then encrypt pPlainData. The cypher data are available in pCypherData + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16. + * @param pCypherData: Pointer to the cyphertext buffer + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESCTR_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout) +{ + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES ECB mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CTR); + + /* Set the Initialization Vector */ + CRYP_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Write Plain Data and Get Cypher Data */ + if(CRYP_ProcessData(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + + + +/** + * @brief Initializes the CRYP peripheral in AES ECB decryption mode + * then decrypted pCypherData. The cypher data are available in pPlainData + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16. + * @param pPlainData: Pointer to the plaintext buffer + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESECB_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES Key mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_KEY | CRYP_CR_ALGODIR); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY)) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + + /* Disable CRYP */ + __HAL_CRYP_DISABLE(hcryp); + + /* Reset the ALGOMODE bits*/ + CRYP->CR &= (uint32_t)(~CRYP_CR_ALGOMODE); + + /* Set the CRYP peripheral in AES ECB decryption mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_ECB | CRYP_CR_ALGODIR); + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Write Plain Data and Get Cypher Data */ + if(CRYP_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES ECB decryption mode + * then decrypted pCypherData. The cypher data are available in pPlainData + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16. + * @param pPlainData: Pointer to the plaintext buffer + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESCBC_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES Key mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_KEY | CRYP_CR_ALGODIR); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY)) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + + /* Reset the ALGOMODE bits*/ + CRYP->CR &= (uint32_t)(~CRYP_CR_ALGOMODE); + + /* Set the CRYP peripheral in AES CBC decryption mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CBC | CRYP_CR_ALGODIR); + + /* Set the Initialization Vector */ + CRYP_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Write Plain Data and Get Cypher Data */ + if(CRYP_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES CTR decryption mode + * then decrypted pCypherData. The cypher data are available in pPlainData + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16. + * @param pPlainData: Pointer to the plaintext buffer + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESCTR_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout) +{ + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES CTR mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CTR | CRYP_CR_ALGODIR); + + /* Set the Initialization Vector */ + CRYP_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Write Plain Data and Get Cypher Data */ + if(CRYP_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES ECB encryption mode using Interrupt. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 bytes + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESECB_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pPlainData; + hcryp->pCrypOutBuffPtr = pCypherData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES ECB mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_ECB); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Return function status */ + return HAL_OK; + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + hcryp->pCrypInBuffPtr += 16; + hcryp->CrypInCount -= 16; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + hcryp->pCrypOutBuffPtr += 16; + hcryp->CrypOutCount -= 16; + if(hcryp->CrypOutCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Process Locked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES CBC encryption mode using Interrupt. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 bytes + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESCBC_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pPlainData; + hcryp->pCrypOutBuffPtr = pCypherData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES CBC mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CBC); + + /* Set the Initialization Vector */ + CRYP_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Return function status */ + return HAL_OK; + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + hcryp->pCrypInBuffPtr += 16; + hcryp->CrypInCount -= 16; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + hcryp->pCrypOutBuffPtr += 16; + hcryp->CrypOutCount -= 16; + if(hcryp->CrypOutCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Process Locked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES CTR encryption mode using Interrupt. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 bytes + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESCTR_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pPlainData; + hcryp->pCrypOutBuffPtr = pCypherData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES CTR mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CTR); + + /* Set the Initialization Vector */ + CRYP_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Return function status */ + return HAL_OK; + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + hcryp->pCrypInBuffPtr += 16; + hcryp->CrypInCount -= 16; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + hcryp->pCrypOutBuffPtr += 16; + hcryp->CrypOutCount -= 16; + if(hcryp->CrypOutCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + + +/** + * @brief Initializes the CRYP peripheral in AES ECB decryption mode using Interrupt. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16. + * @param pPlainData: Pointer to the plaintext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESECB_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t tickstart = 0; + + uint32_t inputaddr; + uint32_t outputaddr; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pCypherData; + hcryp->pCrypOutBuffPtr = pPlainData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES Key mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_KEY | CRYP_CR_ALGODIR); + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY)) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYP_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + + /* Reset the ALGOMODE bits*/ + CRYP->CR &= (uint32_t)(~CRYP_CR_ALGOMODE); + + /* Set the CRYP peripheral in AES ECB decryption mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_ECB | CRYP_CR_ALGODIR); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Return function status */ + return HAL_OK; + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + hcryp->pCrypInBuffPtr += 16; + hcryp->CrypInCount -= 16; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + hcryp->pCrypOutBuffPtr += 16; + hcryp->CrypOutCount -= 16; + if(hcryp->CrypOutCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES CBC decryption mode using IT. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 + * @param pPlainData: Pointer to the plaintext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESCBC_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + + uint32_t tickstart = 0; + uint32_t inputaddr; + uint32_t outputaddr; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Get the buffer addresses and sizes */ + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pCypherData; + hcryp->pCrypOutBuffPtr = pPlainData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES Key mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_KEY | CRYP_CR_ALGODIR); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY)) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYP_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + + /* Reset the ALGOMODE bits*/ + CRYP->CR &= (uint32_t)(~CRYP_CR_ALGOMODE); + + /* Set the CRYP peripheral in AES CBC decryption mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CBC | CRYP_CR_ALGODIR); + + /* Set the Initialization Vector */ + CRYP_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Return function status */ + return HAL_OK; + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + hcryp->pCrypInBuffPtr += 16; + hcryp->CrypInCount -= 16; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + hcryp->pCrypOutBuffPtr += 16; + hcryp->CrypOutCount -= 16; + if(hcryp->CrypOutCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES CTR decryption mode using Interrupt. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 + * @param pPlainData: Pointer to the plaintext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESCTR_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Get the buffer addresses and sizes */ + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pCypherData; + hcryp->pCrypOutBuffPtr = pPlainData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES CTR mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CTR | CRYP_CR_ALGODIR); + + /* Set the Initialization Vector */ + CRYP_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Return function status */ + return HAL_OK; + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + hcryp->pCrypInBuffPtr += 16; + hcryp->CrypInCount -= 16; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + hcryp->pCrypOutBuffPtr += 16; + hcryp->CrypOutCount -= 16; + if(hcryp->CrypOutCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES ECB encryption mode using DMA. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 bytes + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESECB_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pPlainData; + outputaddr = (uint32_t)pCypherData; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES ECB mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_ECB); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + /* Set the input and output addresses and start DMA transfer */ + CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Initializes the CRYP peripheral in AES CBC encryption mode using DMA. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16. + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESCBC_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pPlainData; + outputaddr = (uint32_t)pCypherData; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES ECB mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CBC); + + /* Set the Initialization Vector */ + CRYP_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + /* Set the input and output addresses and start DMA transfer */ + CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Initializes the CRYP peripheral in AES CTR encryption mode using DMA. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16. + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESCTR_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pPlainData; + outputaddr = (uint32_t)pCypherData; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES ECB mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CTR); + + /* Set the Initialization Vector */ + CRYP_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Set the input and output addresses and start DMA transfer */ + CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Initializes the CRYP peripheral in AES ECB decryption mode using DMA. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 bytes + * @param pPlainData: Pointer to the plaintext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESECB_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t tickstart = 0; + uint32_t inputaddr; + uint32_t outputaddr; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pCypherData; + outputaddr = (uint32_t)pPlainData; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES Key mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_KEY | CRYP_CR_ALGODIR); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY)) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYP_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + + /* Reset the ALGOMODE bits*/ + CRYP->CR &= (uint32_t)(~CRYP_CR_ALGOMODE); + + /* Set the CRYP peripheral in AES ECB decryption mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_ECB | CRYP_CR_ALGODIR); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Set the input and output addresses and start DMA transfer */ + CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Initializes the CRYP peripheral in AES CBC encryption mode using DMA. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 bytes + * @param pPlainData: Pointer to the plaintext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESCBC_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t tickstart = 0; + uint32_t inputaddr; + uint32_t outputaddr; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pCypherData; + outputaddr = (uint32_t)pPlainData; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES Key mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_KEY | CRYP_CR_ALGODIR); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_SET(hcryp->Instance->SR, CRYP_FLAG_BUSY)) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYP_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + + /* Reset the ALGOMODE bits*/ + CRYP->CR &= (uint32_t)(~CRYP_CR_ALGOMODE); + + /* Set the CRYP peripheral in AES CBC decryption mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CBC | CRYP_CR_ALGODIR); + + /* Set the Initialization Vector */ + CRYP_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Set the input and output addresses and start DMA transfer */ + CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Initializes the CRYP peripheral in AES CTR decryption mode using DMA. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 + * @param pPlainData: Pointer to the plaintext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_AESCTR_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pCypherData; + outputaddr = (uint32_t)pPlainData; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYP_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES CTR mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CTR | CRYP_CR_ALGODIR); + + /* Set the Initialization Vector */ + CRYP_SetInitVector(hcryp, hcryp->Init.pInitVect, CRYP_KEYSIZE_128B); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Set the input and output addresses and start DMA transfer */ + CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + + +/** + * @} + */ + +/** @defgroup CRYP_Exported_Functions_Group3 DES processing functions + * @brief processing functions. + * +@verbatim + ============================================================================== + ##### DES processing functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Encrypt plaintext using DES using ECB or CBC chaining modes + (+) Decrypt cyphertext using ECB or CBC chaining modes + [..] Three processing functions are available: + (+) Polling mode + (+) Interrupt mode + (+) DMA mode + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the CRYP peripheral in DES ECB encryption mode. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_DESECB_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout) +{ + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in DES ECB encryption mode */ + CRYP_SetDESECBMode(hcryp, 0); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Write Plain Data and Get Cypher Data */ + if(CRYP_ProcessData2Words(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in DES ECB decryption mode. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_DESECB_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout) +{ + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in DES ECB decryption mode */ + CRYP_SetDESECBMode(hcryp, CRYP_CR_ALGODIR); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Write Plain Data and Get Cypher Data */ + if(CRYP_ProcessData2Words(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in DES CBC encryption mode. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_DESCBC_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout) +{ + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in DES CBC encryption mode */ + CRYP_SetDESCBCMode(hcryp, 0); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Write Plain Data and Get Cypher Data */ + if(CRYP_ProcessData2Words(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in DES ECB decryption mode. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_DESCBC_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout) +{ + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in DES CBC decryption mode */ + CRYP_SetDESCBCMode(hcryp, CRYP_CR_ALGODIR); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Write Plain Data and Get Cypher Data */ + if(CRYP_ProcessData2Words(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in DES ECB encryption mode using IT. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_DESECB_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pPlainData; + hcryp->pCrypOutBuffPtr = pCypherData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in DES ECB encryption mode */ + CRYP_SetDESECBMode(hcryp, 0); + + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Return function status */ + return HAL_OK; + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + + hcryp->pCrypInBuffPtr += 8; + hcryp->CrypInCount -= 8; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + + hcryp->pCrypOutBuffPtr += 8; + hcryp->CrypOutCount -= 8; + if(hcryp->CrypOutCount == 0) + { + /* Disable IT */ + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Disable CRYP */ + __HAL_CRYP_DISABLE(hcryp); + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in DES CBC encryption mode using interrupt. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_DESCBC_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pPlainData; + hcryp->pCrypOutBuffPtr = pCypherData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in DES CBC encryption mode */ + CRYP_SetDESCBCMode(hcryp, 0); + + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Return function status */ + return HAL_OK; + } + + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + + hcryp->pCrypInBuffPtr += 8; + hcryp->CrypInCount -= 8; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + + hcryp->pCrypOutBuffPtr += 8; + hcryp->CrypOutCount -= 8; + if(hcryp->CrypOutCount == 0) + { + /* Disable IT */ + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Disable CRYP */ + __HAL_CRYP_DISABLE(hcryp); + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in DES ECB decryption mode using IT. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_DESECB_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pCypherData; + hcryp->pCrypOutBuffPtr = pPlainData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in DES ECB decryption mode */ + CRYP_SetDESECBMode(hcryp, CRYP_CR_ALGODIR); + + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Return function status */ + return HAL_OK; + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + + hcryp->pCrypInBuffPtr += 8; + hcryp->CrypInCount -= 8; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + + hcryp->pCrypOutBuffPtr += 8; + hcryp->CrypOutCount -= 8; + if(hcryp->CrypOutCount == 0) + { + /* Disable IT */ + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Disable CRYP */ + __HAL_CRYP_DISABLE(hcryp); + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in DES ECB decryption mode using interrupt. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_DESCBC_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pCypherData; + hcryp->pCrypOutBuffPtr = pPlainData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in DES CBC decryption mode */ + CRYP_SetDESCBCMode(hcryp, CRYP_CR_ALGODIR); + + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Return function status */ + return HAL_OK; + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + + hcryp->pCrypInBuffPtr += 8; + hcryp->CrypInCount -= 8; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + + hcryp->pCrypOutBuffPtr += 8; + hcryp->CrypOutCount -= 8; + if(hcryp->CrypOutCount == 0) + { + /* Disable IT */ + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Disable CRYP */ + __HAL_CRYP_DISABLE(hcryp); + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in DES ECB encryption mode using DMA. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_DESECB_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pPlainData; + outputaddr = (uint32_t)pCypherData; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in DES ECB encryption mode */ + CRYP_SetDESECBMode(hcryp, 0); + + /* Set the input and output addresses and start DMA transfer */ + CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Initializes the CRYP peripheral in DES CBC encryption mode using DMA. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_DESCBC_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pPlainData; + outputaddr = (uint32_t)pCypherData; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in DES CBC encryption mode */ + CRYP_SetDESCBCMode(hcryp, 0); + + /* Set the input and output addresses and start DMA transfer */ + CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Initializes the CRYP peripheral in DES ECB decryption mode using DMA. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_DESECB_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pCypherData; + outputaddr = (uint32_t)pPlainData; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in DES ECB decryption mode */ + CRYP_SetDESECBMode(hcryp, CRYP_CR_ALGODIR); + + /* Set the input and output addresses and start DMA transfer */ + CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Initializes the CRYP peripheral in DES ECB decryption mode using DMA. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_DESCBC_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pCypherData; + outputaddr = (uint32_t)pPlainData; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in DES CBC decryption mode */ + CRYP_SetDESCBCMode(hcryp, CRYP_CR_ALGODIR); + + /* Set the input and output addresses and start DMA transfer */ + CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @} + */ + +/** @defgroup CRYP_Exported_Functions_Group4 TDES processing functions + * @brief processing functions. + * +@verbatim + ============================================================================== + ##### TDES processing functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Encrypt plaintext using TDES based on ECB or CBC chaining modes + (+) Decrypt cyphertext using TDES based on ECB or CBC chaining modes + [..] Three processing functions are available: + (+) Polling mode + (+) Interrupt mode + (+) DMA mode + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the CRYP peripheral in TDES ECB encryption mode + * then encrypt pPlainData. The cypher data are available in pCypherData + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_TDESECB_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout) +{ + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in TDES ECB encryption mode */ + CRYP_SetTDESECBMode(hcryp, 0); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Write Plain Data and Get Cypher Data */ + if(CRYP_ProcessData2Words(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in TDES ECB decryption mode + * then decrypted pCypherData. The cypher data are available in pPlainData + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_TDESECB_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout) +{ + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in TDES ECB decryption mode */ + CRYP_SetTDESECBMode(hcryp, CRYP_CR_ALGODIR); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Write Cypher Data and Get Plain Data */ + if(CRYP_ProcessData2Words(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in TDES CBC encryption mode + * then encrypt pPlainData. The cypher data are available in pCypherData + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_TDESCBC_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout) +{ + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in TDES CBC encryption mode */ + CRYP_SetTDESCBCMode(hcryp, 0); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Write Plain Data and Get Cypher Data */ + if(CRYP_ProcessData2Words(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in TDES CBC decryption mode + * then decrypted pCypherData. The cypher data are available in pPlainData + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pPlainData: Pointer to the plaintext buffer + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_TDESCBC_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout) +{ + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in TDES CBC decryption mode */ + CRYP_SetTDESCBCMode(hcryp, CRYP_CR_ALGODIR); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Write Cypher Data and Get Plain Data */ + if(CRYP_ProcessData2Words(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in TDES ECB encryption mode using interrupt. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_TDESECB_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pPlainData; + hcryp->pCrypOutBuffPtr = pCypherData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in TDES ECB encryption mode */ + CRYP_SetTDESECBMode(hcryp, 0); + + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Return function status */ + return HAL_OK; + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + + hcryp->pCrypInBuffPtr += 8; + hcryp->CrypInCount -= 8; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + + hcryp->pCrypOutBuffPtr += 8; + hcryp->CrypOutCount -= 8; + if(hcryp->CrypOutCount == 0) + { + /* Disable IT */ + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Disable CRYP */ + __HAL_CRYP_DISABLE(hcryp); + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call the Output data transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in TDES CBC encryption mode. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_TDESCBC_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pPlainData; + hcryp->pCrypOutBuffPtr = pCypherData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in TDES CBC encryption mode */ + CRYP_SetTDESCBCMode(hcryp, 0); + + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Return function status */ + return HAL_OK; + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + + hcryp->pCrypInBuffPtr += 8; + hcryp->CrypInCount -= 8; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + + hcryp->pCrypOutBuffPtr += 8; + hcryp->CrypOutCount -= 8; + if(hcryp->CrypOutCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Disable CRYP */ + __HAL_CRYP_DISABLE(hcryp); + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in TDES ECB decryption mode. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_TDESECB_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pCypherData; + hcryp->pCrypOutBuffPtr = pPlainData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in TDES ECB decryption mode */ + CRYP_SetTDESECBMode(hcryp, CRYP_CR_ALGODIR); + + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Return function status */ + return HAL_OK; + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + + hcryp->pCrypInBuffPtr += 8; + hcryp->CrypInCount -= 8; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + + hcryp->pCrypOutBuffPtr += 8; + hcryp->CrypOutCount -= 8; + if(hcryp->CrypOutCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Disable CRYP */ + __HAL_CRYP_DISABLE(hcryp); + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in TDES CBC decryption mode. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pPlainData: Pointer to the plaintext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_TDESCBC_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pCypherData; + hcryp->pCrypOutBuffPtr = pPlainData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in TDES CBC decryption mode */ + CRYP_SetTDESCBCMode(hcryp, CRYP_CR_ALGODIR); + + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + + /* Enable CRYP */ + __HAL_CRYP_ENABLE(hcryp); + + /* Return function status */ + return HAL_OK; + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + + hcryp->pCrypInBuffPtr += 8; + hcryp->CrypInCount -= 8; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if(__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + + hcryp->pCrypOutBuffPtr += 8; + hcryp->CrypOutCount -= 8; + if(hcryp->CrypOutCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Disable CRYP */ + __HAL_CRYP_DISABLE(hcryp); + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in TDES ECB encryption mode using DMA. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_TDESECB_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pPlainData; + outputaddr = (uint32_t)pCypherData; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in TDES ECB encryption mode */ + CRYP_SetTDESECBMode(hcryp, 0); + + /* Set the input and output addresses and start DMA transfer */ + CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Initializes the CRYP peripheral in TDES CBC encryption mode using DMA. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_TDESCBC_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pPlainData; + outputaddr = (uint32_t)pCypherData; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in TDES CBC encryption mode */ + CRYP_SetTDESCBCMode(hcryp, 0); + + /* Set the input and output addresses and start DMA transfer */ + CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Initializes the CRYP peripheral in TDES ECB decryption mode using DMA. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_TDESECB_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pCypherData; + outputaddr = (uint32_t)pPlainData; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in TDES ECB decryption mode */ + CRYP_SetTDESECBMode(hcryp, CRYP_CR_ALGODIR); + + /* Set the input and output addresses and start DMA transfer */ + CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Initializes the CRYP peripheral in TDES CBC decryption mode using DMA. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 8 + * @param pPlainData: Pointer to the plaintext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYP_TDESCBC_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pCypherData; + outputaddr = (uint32_t)pPlainData; + + /* Change the CRYP state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Set CRYP peripheral in TDES CBC decryption mode */ + CRYP_SetTDESCBCMode(hcryp, CRYP_CR_ALGODIR); + + /* Set the input and output addresses and start DMA transfer */ + CRYP_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @} + */ + +/** @defgroup CRYP_Exported_Functions_Group5 DMA callback functions + * @brief DMA callback functions. + * +@verbatim + ============================================================================== + ##### DMA callback functions ##### + ============================================================================== + [..] This section provides DMA callback functions: + (+) DMA Input data transfer complete + (+) DMA Output data transfer complete + (+) DMA error + +@endverbatim + * @{ + */ + +/** + * @brief Input FIFO transfer completed callbacks. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval None + */ +__weak void HAL_CRYP_InCpltCallback(CRYP_HandleTypeDef *hcryp) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_CRYP_InCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Output FIFO transfer completed callbacks. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval None + */ +__weak void HAL_CRYP_OutCpltCallback(CRYP_HandleTypeDef *hcryp) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_CRYP_OutCpltCallback could be implemented in the user file + */ +} + +/** + * @brief CRYP error callbacks. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval None + */ + __weak void HAL_CRYP_ErrorCallback(CRYP_HandleTypeDef *hcryp) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_CRYP_ErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup CRYP_Exported_Functions_Group6 CRYP IRQ handler management + * @brief CRYP IRQ handler. + * +@verbatim + ============================================================================== + ##### CRYP IRQ handler management ##### + ============================================================================== +[..] This section provides CRYP IRQ handler function. + +@endverbatim + * @{ + */ + +/** + * @brief This function handles CRYP interrupt request. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval None + */ +void HAL_CRYP_IRQHandler(CRYP_HandleTypeDef *hcryp) +{ + switch(CRYP->CR & CRYP_CR_ALGOMODE_DIRECTION) + { + case CRYP_CR_ALGOMODE_TDES_ECB_ENCRYPT: + HAL_CRYP_TDESECB_Encrypt_IT(hcryp, NULL, 0, NULL); + break; + + case CRYP_CR_ALGOMODE_TDES_ECB_DECRYPT: + HAL_CRYP_TDESECB_Decrypt_IT(hcryp, NULL, 0, NULL); + break; + + case CRYP_CR_ALGOMODE_TDES_CBC_ENCRYPT: + HAL_CRYP_TDESCBC_Encrypt_IT(hcryp, NULL, 0, NULL); + break; + + case CRYP_CR_ALGOMODE_TDES_CBC_DECRYPT: + HAL_CRYP_TDESCBC_Decrypt_IT(hcryp, NULL, 0, NULL); + break; + + case CRYP_CR_ALGOMODE_DES_ECB_ENCRYPT: + HAL_CRYP_DESECB_Encrypt_IT(hcryp, NULL, 0, NULL); + break; + + case CRYP_CR_ALGOMODE_DES_ECB_DECRYPT: + HAL_CRYP_DESECB_Decrypt_IT(hcryp, NULL, 0, NULL); + break; + + case CRYP_CR_ALGOMODE_DES_CBC_ENCRYPT: + HAL_CRYP_DESCBC_Encrypt_IT(hcryp, NULL, 0, NULL); + break; + + case CRYP_CR_ALGOMODE_DES_CBC_DECRYPT: + HAL_CRYP_DESCBC_Decrypt_IT(hcryp, NULL, 0, NULL); + break; + + case CRYP_CR_ALGOMODE_AES_ECB_ENCRYPT: + HAL_CRYP_AESECB_Encrypt_IT(hcryp, NULL, 0, NULL); + break; + + case CRYP_CR_ALGOMODE_AES_ECB_DECRYPT: + HAL_CRYP_AESECB_Decrypt_IT(hcryp, NULL, 0, NULL); + break; + + case CRYP_CR_ALGOMODE_AES_CBC_ENCRYPT: + HAL_CRYP_AESCBC_Encrypt_IT(hcryp, NULL, 0, NULL); + break; + + case CRYP_CR_ALGOMODE_AES_CBC_DECRYPT: + HAL_CRYP_AESCBC_Decrypt_IT(hcryp, NULL, 0, NULL); + break; + + case CRYP_CR_ALGOMODE_AES_CTR_ENCRYPT: + HAL_CRYP_AESCTR_Encrypt_IT(hcryp, NULL, 0, NULL); + break; + + case CRYP_CR_ALGOMODE_AES_CTR_DECRYPT: + HAL_CRYP_AESCTR_Decrypt_IT(hcryp, NULL, 0, NULL); + break; + + default: + break; + } +} + +/** + * @} + */ + +/** @defgroup CRYP_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 Returns the CRYP state. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval HAL state + */ +HAL_CRYP_STATETypeDef HAL_CRYP_GetState(CRYP_HandleTypeDef *hcryp) +{ + return hcryp->State; +} + +/** + * @} + */ + + +/** + * @} + */ + +#endif /* STM32F415xx || STM32F417xx || STM32F437xx || STM32F439xx */ + +#endif /* HAL_CRYP_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp_ex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp_ex.c new file mode 100644 index 0000000..a160788 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp_ex.c @@ -0,0 +1,3043 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_cryp_ex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Extended CRYP HAL module driver + * This file provides firmware functions to manage the following + * functionalities of CRYP extension peripheral: + * + Extended AES processing functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The CRYP Extension HAL driver can be used as follows: + (#)Initialize the CRYP low level resources by implementing the HAL_CRYP_MspInit(): + (##) Enable the CRYP interface clock using __HAL_RCC_CRYP_CLK_ENABLE() + (##) In case of using interrupts (e.g. HAL_CRYPEx_AESGCM_Encrypt_IT()) + (+++) Configure the CRYP interrupt priority using HAL_NVIC_SetPriority() + (+++) Enable the CRYP IRQ handler using HAL_NVIC_EnableIRQ() + (+) In CRYP IRQ handler, call HAL_CRYP_IRQHandler() + (##) In case of using DMA to control data transfer (e.g. HAL_AES_ECB_Encrypt_DMA()) + (+++) Enable the DMAx interface clock using __DMAx_CLK_ENABLE() + (+++) Configure and enable two DMA streams one for managing data transfer from + memory to peripheral (input stream) and another stream for managing data + transfer from peripheral to memory (output stream) + (+++) Associate the initialized DMA handle to the CRYP DMA handle + using __HAL_LINKDMA() + (+++) Configure the priority and enable the NVIC for the transfer complete + interrupt on the two DMA Streams. The output stream should have higher + priority than the input stream HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ() + (#)Initialize the CRYP HAL using HAL_CRYP_Init(). This function configures mainly: + (##) The data type: 1-bit, 8-bit, 16-bit and 32-bit + (##) The key size: 128, 192 and 256. This parameter is relevant only for AES + (##) The encryption/decryption key. Its size depends on the algorithm + used for encryption/decryption + (##) The initialization vector (counter). It is not used ECB mode. + (#)Three processing (encryption/decryption) functions are available: + (##) Polling mode: encryption and decryption APIs are blocking functions + i.e. they process the data and wait till the processing is finished + e.g. HAL_CRYPEx_AESGCM_Encrypt() + (##) Interrupt mode: encryption and decryption APIs are not blocking functions + i.e. they process the data under interrupt + e.g. HAL_CRYPEx_AESGCM_Encrypt_IT() + (##) DMA mode: encryption and decryption APIs are not blocking functions + i.e. the data transfer is ensured by DMA + e.g. HAL_CRYPEx_AESGCM_Encrypt_DMA() + (#)When the processing function is called at first time after HAL_CRYP_Init() + the CRYP peripheral is initialized and processes the buffer in input. + At second call, the processing function performs an append of the already + processed buffer. + When a new data block is to be processed, call HAL_CRYP_Init() then the + processing function. + (#)In AES-GCM and AES-CCM modes are an authenticated encryption algorithms + which provide authentication messages. + HAL_AES_GCM_Finish() and HAL_AES_CCM_Finish() are used to provide those + authentication messages. + Call those functions after the processing ones (polling, interrupt or DMA). + e.g. in AES-CCM mode call HAL_CRYPEx_AESCCM_Encrypt() to encrypt the plain data + then call HAL_CRYPEx_AESCCM_Finish() to get the authentication message + @note: For CCM Encrypt/Decrypt API's, only DataType = 8-bit is supported by this version. + @note: The HAL_CRYPEx_AESGCM_xxxx() implementation is limited to 32bits inputs data length + (Plain/Cyphertext, Header) compared with GCM standards specifications (800-38D). + (#)Call HAL_CRYP_DeInit() to deinitialize the CRYP peripheral. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 CRYPEx CRYPEx + * @brief CRYP Extension HAL module driver. + * @{ + */ + +#ifdef HAL_CRYP_MODULE_ENABLED + +#if defined(STM32F437xx) || defined(STM32F439xx) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup CRYPEx_Private_define + * @{ + */ +#define CRYPEx_TIMEOUT_VALUE 1 +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup CRYPEx_Private_Functions_prototypes CRYP Private Functions Prototypes + * @{ + */ +static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector); +static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize); +static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout); +static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout); +static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma); +static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma); +static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma); +static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr); +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup CRYPEx_Private_Functions + * @{ + */ + +/** + * @brief DMA CRYP Input Data process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void CRYPEx_GCMCCM_DMAInCplt(DMA_HandleTypeDef *hdma) +{ + CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Disable the DMA transfer for input Fifo request by resetting the DIEN bit + in the DMACR register */ + hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DIEN); + + /* Call input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); +} + +/** + * @brief DMA CRYP Output Data process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void CRYPEx_GCMCCM_DMAOutCplt(DMA_HandleTypeDef *hdma) +{ + CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Disable the DMA transfer for output Fifo request by resetting the DOEN bit + in the DMACR register */ + hcryp->Instance->DMACR &= (uint32_t)(~CRYP_DMACR_DOEN); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_DISABLE(hcryp); + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Call output data transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); +} + +/** + * @brief DMA CRYP communication error callback. + * @param hdma: DMA handle + * @retval None + */ +static void CRYPEx_GCMCCM_DMAError(DMA_HandleTypeDef *hdma) +{ + CRYP_HandleTypeDef* hcryp = ( CRYP_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + hcryp->State= HAL_CRYP_STATE_READY; + HAL_CRYP_ErrorCallback(hcryp); +} + +/** + * @brief Writes the Key in Key registers. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param Key: Pointer to Key buffer + * @param KeySize: Size of Key + * @retval None + */ +static void CRYPEx_GCMCCM_SetKey(CRYP_HandleTypeDef *hcryp, uint8_t *Key, uint32_t KeySize) +{ + uint32_t keyaddr = (uint32_t)Key; + + switch(KeySize) + { + case CRYP_KEYSIZE_256B: + /* Key Initialisation */ + hcryp->Instance->K0LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K0RR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K1LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K1RR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr)); + break; + case CRYP_KEYSIZE_192B: + hcryp->Instance->K1LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K1RR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr)); + break; + case CRYP_KEYSIZE_128B: + hcryp->Instance->K2LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K2RR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K3LR = __REV(*(uint32_t*)(keyaddr)); + keyaddr+=4; + hcryp->Instance->K3RR = __REV(*(uint32_t*)(keyaddr)); + break; + default: + break; + } +} + +/** + * @brief Writes the InitVector/InitCounter in IV registers. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param InitVector: Pointer to InitVector/InitCounter buffer + * @retval None + */ +static void CRYPEx_GCMCCM_SetInitVector(CRYP_HandleTypeDef *hcryp, uint8_t *InitVector) +{ + uint32_t ivaddr = (uint32_t)InitVector; + + hcryp->Instance->IV0LR = __REV(*(uint32_t*)(ivaddr)); + ivaddr+=4; + hcryp->Instance->IV0RR = __REV(*(uint32_t*)(ivaddr)); + ivaddr+=4; + hcryp->Instance->IV1LR = __REV(*(uint32_t*)(ivaddr)); + ivaddr+=4; + hcryp->Instance->IV1RR = __REV(*(uint32_t*)(ivaddr)); +} + +/** + * @brief Process Data: Writes Input data in polling mode and read the Output data. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param Input: Pointer to the Input buffer. + * @param Ilength: Length of the Input buffer, must be a multiple of 16 + * @param Output: Pointer to the returned buffer + * @param Timeout: Timeout value + * @retval None + */ +static HAL_StatusTypeDef CRYPEx_GCMCCM_ProcessData(CRYP_HandleTypeDef *hcryp, uint8_t *Input, uint16_t Ilength, uint8_t *Output, uint32_t Timeout) +{ + uint32_t tickstart = 0; + uint32_t i = 0; + uint32_t inputaddr = (uint32_t)Input; + uint32_t outputaddr = (uint32_t)Output; + + for(i=0; (i < Ilength); i+=16) + { + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE)) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + /* Read the Output block from the OUT FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + } + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Sets the header phase + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param Input: Pointer to the Input buffer. + * @param Ilength: Length of the Input buffer, must be a multiple of 16 + * @param Timeout: Timeout value + * @retval None + */ +static HAL_StatusTypeDef CRYPEx_GCMCCM_SetHeaderPhase(CRYP_HandleTypeDef *hcryp, uint8_t* Input, uint16_t Ilength, uint32_t Timeout) +{ + uint32_t tickstart = 0; + uint32_t loopcounter = 0; + uint32_t headeraddr = (uint32_t)Input; + + /***************************** Header phase *********************************/ + if(hcryp->Init.HeaderSize != 0) + { + /* Select header phase */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + for(loopcounter = 0; (loopcounter < hcryp->Init.HeaderSize); loopcounter+=16) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + } + + /* Wait until the complete message has been processed */ + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + } + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Sets the DMA configuration and start the DMA transfer. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param inputaddr: Address of the Input buffer + * @param Size: Size of the Input buffer, must be a multiple of 16 + * @param outputaddr: Address of the Output buffer + * @retval None + */ +static void CRYPEx_GCMCCM_SetDMAConfig(CRYP_HandleTypeDef *hcryp, uint32_t inputaddr, uint16_t Size, uint32_t outputaddr) +{ + /* Set the CRYP DMA transfer complete callback */ + hcryp->hdmain->XferCpltCallback = CRYPEx_GCMCCM_DMAInCplt; + /* Set the DMA error callback */ + hcryp->hdmain->XferErrorCallback = CRYPEx_GCMCCM_DMAError; + + /* Set the CRYP DMA transfer complete callback */ + hcryp->hdmaout->XferCpltCallback = CRYPEx_GCMCCM_DMAOutCplt; + /* Set the DMA error callback */ + hcryp->hdmaout->XferErrorCallback = CRYPEx_GCMCCM_DMAError; + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Enable the DMA In DMA Stream */ + HAL_DMA_Start_IT(hcryp->hdmain, inputaddr, (uint32_t)&hcryp->Instance->DR, Size/4); + + /* Enable In DMA request */ + hcryp->Instance->DMACR = CRYP_DMACR_DIEN; + + /* Enable the DMA Out DMA Stream */ + HAL_DMA_Start_IT(hcryp->hdmaout, (uint32_t)&hcryp->Instance->DOUT, outputaddr, Size/4); + + /* Enable Out DMA request */ + hcryp->Instance->DMACR |= CRYP_DMACR_DOEN; +} + +/** + * @} + */ + +/* Exported functions---------------------------------------------------------*/ +/** @addtogroup CRYPEx_Exported_Functions + * @{ + */ + +/** @defgroup CRYPEx_Exported_Functions_Group1 Extended AES processing functions + * @brief Extended processing functions. + * +@verbatim + ============================================================================== + ##### Extended AES processing functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Encrypt plaintext using AES-128/192/256 using GCM and CCM chaining modes + (+) Decrypt cyphertext using AES-128/192/256 using GCM and CCM chaining modes + (+) Finish the processing. This function is available only for GCM and CCM + [..] Three processing methods are available: + (+) Polling mode + (+) Interrupt mode + (+) DMA mode + +@endverbatim + * @{ + */ + + +/** + * @brief Initializes the CRYP peripheral in AES CCM encryption mode then + * encrypt pPlainData. The cypher data are available in pCypherData. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 + * @param pCypherData: Pointer to the cyphertext buffer + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout) +{ + uint32_t tickstart = 0; + uint32_t headersize = hcryp->Init.HeaderSize; + uint32_t headeraddr = (uint32_t)hcryp->Init.Header; + uint32_t loopcounter = 0; + uint32_t bufferidx = 0; + uint8_t blockb0[16] = {0};/* Block B0 */ + uint8_t ctr[16] = {0}; /* Counter */ + uint32_t b0addr = (uint32_t)blockb0; + + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /************************ Formatting the header block *********************/ + if(headersize != 0) + { + /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */ + if(headersize < 65280) + { + hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF); + hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF); + headersize += 2; + } + else + { + /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */ + hcryp->Init.pScratch[bufferidx++] = 0xFF; + hcryp->Init.pScratch[bufferidx++] = 0xFE; + hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff; + headersize += 6; + } + /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */ + for(loopcounter = 0; loopcounter < headersize; loopcounter++) + { + hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter]; + } + /* Check if the header size is modulo 16 */ + if ((headersize % 16) != 0) + { + /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */ + for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++) + { + hcryp->Init.pScratch[loopcounter] = 0; + } + /* Set the header size to modulo 16 */ + headersize = ((headersize/16) + 1) * 16; + } + /* Set the pointer headeraddr to hcryp->Init.pScratch */ + headeraddr = (uint32_t)hcryp->Init.pScratch; + } + /*********************** Formatting the block B0 **************************/ + if(headersize != 0) + { + blockb0[0] = 0x40; + } + /* Flags byte */ + /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */ + blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3); + blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07); + + for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++) + { + blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter]; + } + for ( ; loopcounter < 13; loopcounter++) + { + blockb0[loopcounter+1] = 0; + } + + blockb0[14] = (Size >> 8); + blockb0[15] = (Size & 0xFF); + + /************************* Formatting the initial counter *****************/ + /* Byte 0: + Bits 7 and 6 are reserved and shall be set to 0 + Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter blocks + are distinct from B0 + Bits 0, 1, and 2 contain the same encoding of q as in B0 + */ + ctr[0] = blockb0[0] & 0x07; + /* byte 1 to NonceSize is the IV (Nonce) */ + for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++) + { + ctr[loopcounter] = blockb0[loopcounter]; + } + /* Set the LSB to 1 */ + ctr[15] |= 0x01; + + /* Set the key */ + CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES CCM mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT); + + /* Set the Initialization Vector */ + CRYPEx_GCMCCM_SetInitVector(hcryp, ctr); + + /* Select init phase */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); + + b0addr = (uint32_t)blockb0; + /* Write the blockb0 block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + /***************************** Header phase *******************************/ + if(headersize != 0) + { + /* Select header phase */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)) + { + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + } + /* Write the header block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + } + /* Save formatted counter into the scratch buffer pScratch */ + for(loopcounter = 0; (loopcounter < 16); loopcounter++) + { + hcryp->Init.pScratch[loopcounter] = ctr[loopcounter]; + } + /* Reset bit 0 */ + hcryp->Init.pScratch[15] &= 0xfe; + + /* Select payload phase once the header phase is performed */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Write Plain Data and Get Cypher Data */ + if(CRYPEx_GCMCCM_ProcessData(hcryp,pPlainData, Size, pCypherData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES GCM encryption mode then + * encrypt pPlainData. The cypher data are available in pCypherData. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 + * @param pCypherData: Pointer to the cyphertext buffer + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES GCM mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT); + + /* Set the Initialization Vector */ + CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + + /* Set the header phase */ + if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Disable the CRYP peripheral */ + __HAL_CRYP_DISABLE(hcryp); + + /* Select payload phase once the header phase is performed */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Write Plain Data and Get Cypher Data */ + if(CRYPEx_GCMCCM_ProcessData(hcryp, pPlainData, Size, pCypherData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES GCM decryption mode then + * decrypted pCypherData. The cypher data are available in pPlainData. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer + * @param Size: Length of the cyphertext buffer, must be a multiple of 16 + * @param pPlainData: Pointer to the plaintext buffer + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES GCM decryption mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT); + + /* Set the Initialization Vector */ + CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + + /* Set the header phase */ + if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + /* Disable the CRYP peripheral */ + __HAL_CRYP_DISABLE(hcryp); + + /* Select payload phase once the header phase is performed */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Write Plain Data and Get Cypher Data */ + if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Computes the authentication TAG. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param Size: Total length of the plain/cyphertext buffer + * @param AuthTag: Pointer to the authentication buffer + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Finish(CRYP_HandleTypeDef *hcryp, uint32_t Size, uint8_t *AuthTag, uint32_t Timeout) +{ + uint32_t tickstart = 0; + uint64_t headerlength = hcryp->Init.HeaderSize * 8; /* Header length in bits */ + uint64_t inputlength = Size * 8; /* input length in bits */ + uint32_t tagaddr = (uint32_t)AuthTag; + + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS) + { + /* Change the CRYP phase */ + hcryp->Phase = HAL_CRYP_PHASE_FINAL; + + /* Disable CRYP to start the final phase */ + __HAL_CRYP_DISABLE(hcryp); + + /* Select final phase */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_FINAL); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Write the number of bits in header (64 bits) followed by the number of bits + in the payload */ + if(hcryp->Init.DataType == CRYP_DATATYPE_1B) + { + hcryp->Instance->DR = __RBIT(headerlength >> 32); + hcryp->Instance->DR = __RBIT(headerlength); + hcryp->Instance->DR = __RBIT(inputlength >> 32); + hcryp->Instance->DR = __RBIT(inputlength); + } + else if(hcryp->Init.DataType == CRYP_DATATYPE_8B) + { + hcryp->Instance->DR = __REV(headerlength >> 32); + hcryp->Instance->DR = __REV(headerlength); + hcryp->Instance->DR = __REV(inputlength >> 32); + hcryp->Instance->DR = __REV(inputlength); + } + else if(hcryp->Init.DataType == CRYP_DATATYPE_16B) + { + hcryp->Instance->DR = __ROR((uint32_t)(headerlength >> 32), 16); + hcryp->Instance->DR = __ROR((uint32_t)headerlength, 16); + hcryp->Instance->DR = __ROR((uint32_t)(inputlength >> 32), 16); + hcryp->Instance->DR = __ROR((uint32_t)inputlength, 16); + } + else if(hcryp->Init.DataType == CRYP_DATATYPE_32B) + { + hcryp->Instance->DR = (uint32_t)(headerlength >> 32); + hcryp->Instance->DR = (uint32_t)(headerlength); + hcryp->Instance->DR = (uint32_t)(inputlength >> 32); + hcryp->Instance->DR = (uint32_t)(inputlength); + } + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE)) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + + /* Read the Auth TAG in the IN FIFO */ + *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT; + tagaddr+=4; + *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT; + tagaddr+=4; + *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT; + tagaddr+=4; + *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT; + } + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Computes the authentication TAG for AES CCM mode. + * @note This API is called after HAL_AES_CCM_Encrypt()/HAL_AES_CCM_Decrypt() + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param AuthTag: Pointer to the authentication buffer + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Finish(CRYP_HandleTypeDef *hcryp, uint8_t *AuthTag, uint32_t Timeout) +{ + uint32_t tickstart = 0; + uint32_t tagaddr = (uint32_t)AuthTag; + uint32_t ctraddr = (uint32_t)hcryp->Init.pScratch; + uint32_t temptag[4] = {0}; /* Temporary TAG (MAC) */ + uint32_t loopcounter; + + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_PROCESS) + { + /* Change the CRYP phase */ + hcryp->Phase = HAL_CRYP_PHASE_FINAL; + + /* Disable CRYP to start the final phase */ + __HAL_CRYP_DISABLE(hcryp); + + /* Select final phase */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_FINAL); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Write the counter block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)ctraddr; + ctraddr+=4; + hcryp->Instance->DR = *(uint32_t*)ctraddr; + ctraddr+=4; + hcryp->Instance->DR = *(uint32_t*)ctraddr; + ctraddr+=4; + hcryp->Instance->DR = *(uint32_t*)ctraddr; + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE)) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + + /* Read the Auth TAG in the IN FIFO */ + temptag[0] = hcryp->Instance->DOUT; + temptag[1] = hcryp->Instance->DOUT; + temptag[2] = hcryp->Instance->DOUT; + temptag[3] = hcryp->Instance->DOUT; + } + + /* Copy temporary authentication TAG in user TAG buffer */ + for(loopcounter = 0; loopcounter < hcryp->Init.TagSize ; loopcounter++) + { + /* Set the authentication TAG buffer */ + *((uint8_t*)tagaddr+loopcounter) = *((uint8_t*)temptag+loopcounter); + } + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES CCM decryption mode then + * decrypted pCypherData. The cypher data are available in pPlainData. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 + * @param pCypherData: Pointer to the cyphertext buffer + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData, uint32_t Timeout) +{ + uint32_t tickstart = 0; + uint32_t headersize = hcryp->Init.HeaderSize; + uint32_t headeraddr = (uint32_t)hcryp->Init.Header; + uint32_t loopcounter = 0; + uint32_t bufferidx = 0; + uint8_t blockb0[16] = {0};/* Block B0 */ + uint8_t ctr[16] = {0}; /* Counter */ + uint32_t b0addr = (uint32_t)blockb0; + + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /************************ Formatting the header block *********************/ + if(headersize != 0) + { + /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */ + if(headersize < 65280) + { + hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF); + hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF); + headersize += 2; + } + else + { + /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */ + hcryp->Init.pScratch[bufferidx++] = 0xFF; + hcryp->Init.pScratch[bufferidx++] = 0xFE; + hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff; + headersize += 6; + } + /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */ + for(loopcounter = 0; loopcounter < headersize; loopcounter++) + { + hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter]; + } + /* Check if the header size is modulo 16 */ + if ((headersize % 16) != 0) + { + /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */ + for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++) + { + hcryp->Init.pScratch[loopcounter] = 0; + } + /* Set the header size to modulo 16 */ + headersize = ((headersize/16) + 1) * 16; + } + /* Set the pointer headeraddr to hcryp->Init.pScratch */ + headeraddr = (uint32_t)hcryp->Init.pScratch; + } + /*********************** Formatting the block B0 **************************/ + if(headersize != 0) + { + blockb0[0] = 0x40; + } + /* Flags byte */ + /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */ + blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3); + blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07); + + for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++) + { + blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter]; + } + for ( ; loopcounter < 13; loopcounter++) + { + blockb0[loopcounter+1] = 0; + } + + blockb0[14] = (Size >> 8); + blockb0[15] = (Size & 0xFF); + + /************************* Formatting the initial counter *****************/ + /* Byte 0: + Bits 7 and 6 are reserved and shall be set to 0 + Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter + blocks are distinct from B0 + Bits 0, 1, and 2 contain the same encoding of q as in B0 + */ + ctr[0] = blockb0[0] & 0x07; + /* byte 1 to NonceSize is the IV (Nonce) */ + for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++) + { + ctr[loopcounter] = blockb0[loopcounter]; + } + /* Set the LSB to 1 */ + ctr[15] |= 0x01; + + /* Set the key */ + CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES CCM mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT); + + /* Set the Initialization Vector */ + CRYPEx_GCMCCM_SetInitVector(hcryp, ctr); + + /* Select init phase */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); + + b0addr = (uint32_t)blockb0; + /* Write the blockb0 block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + /***************************** Header phase *******************************/ + if(headersize != 0) + { + /* Select header phase */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); + + /* Enable Crypto processor */ + __HAL_CRYP_ENABLE(hcryp); + + for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + /* Write the header block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + } + /* Save formatted counter into the scratch buffer pScratch */ + for(loopcounter = 0; (loopcounter < 16); loopcounter++) + { + hcryp->Init.pScratch[loopcounter] = ctr[loopcounter]; + } + /* Reset bit 0 */ + hcryp->Init.pScratch[15] &= 0xfe; + /* Select payload phase once the header phase is performed */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Write Plain Data and Get Cypher Data */ + if(CRYPEx_GCMCCM_ProcessData(hcryp, pCypherData, Size, pPlainData, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES GCM encryption mode using IT. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t tickstart = 0; + uint32_t inputaddr; + uint32_t outputaddr; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Get the buffer addresses and sizes */ + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pPlainData; + hcryp->pCrypOutBuffPtr = pCypherData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES GCM mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT); + + /* Set the Initialization Vector */ + CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Enable CRYP to start the init phase */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) + { + /* Check for the Timeout */ + + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + + } + } + + /* Set the header phase */ + if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK) + { + return HAL_TIMEOUT; + } + /* Disable the CRYP peripheral */ + __HAL_CRYP_DISABLE(hcryp); + + /* Select payload phase once the header phase is performed */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + if(Size != 0) + { + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + } + else + { + /* Process Locked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP state and phase */ + hcryp->State = HAL_CRYP_STATE_READY; + } + /* Return function status */ + return HAL_OK; + } + else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + hcryp->pCrypInBuffPtr += 16; + hcryp->CrypInCount -= 16; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + hcryp->pCrypOutBuffPtr += 16; + hcryp->CrypOutCount -= 16; + if(hcryp->CrypOutCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES CCM encryption mode using interrupt. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t tickstart = 0; + uint32_t inputaddr; + uint32_t outputaddr; + + uint32_t headersize = hcryp->Init.HeaderSize; + uint32_t headeraddr = (uint32_t)hcryp->Init.Header; + uint32_t loopcounter = 0; + uint32_t bufferidx = 0; + uint8_t blockb0[16] = {0};/* Block B0 */ + uint8_t ctr[16] = {0}; /* Counter */ + uint32_t b0addr = (uint32_t)blockb0; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pPlainData; + hcryp->pCrypOutBuffPtr = pCypherData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /************************ Formatting the header block *******************/ + if(headersize != 0) + { + /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */ + if(headersize < 65280) + { + hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF); + hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF); + headersize += 2; + } + else + { + /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */ + hcryp->Init.pScratch[bufferidx++] = 0xFF; + hcryp->Init.pScratch[bufferidx++] = 0xFE; + hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff; + headersize += 6; + } + /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */ + for(loopcounter = 0; loopcounter < headersize; loopcounter++) + { + hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter]; + } + /* Check if the header size is modulo 16 */ + if ((headersize % 16) != 0) + { + /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */ + for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++) + { + hcryp->Init.pScratch[loopcounter] = 0; + } + /* Set the header size to modulo 16 */ + headersize = ((headersize/16) + 1) * 16; + } + /* Set the pointer headeraddr to hcryp->Init.pScratch */ + headeraddr = (uint32_t)hcryp->Init.pScratch; + } + /*********************** Formatting the block B0 ************************/ + if(headersize != 0) + { + blockb0[0] = 0x40; + } + /* Flags byte */ + /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */ + blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3); + blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07); + + for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++) + { + blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter]; + } + for ( ; loopcounter < 13; loopcounter++) + { + blockb0[loopcounter+1] = 0; + } + + blockb0[14] = (Size >> 8); + blockb0[15] = (Size & 0xFF); + + /************************* Formatting the initial counter ***************/ + /* Byte 0: + Bits 7 and 6 are reserved and shall be set to 0 + Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter + blocks are distinct from B0 + Bits 0, 1, and 2 contain the same encoding of q as in B0 + */ + ctr[0] = blockb0[0] & 0x07; + /* byte 1 to NonceSize is the IV (Nonce) */ + for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++) + { + ctr[loopcounter] = blockb0[loopcounter]; + } + /* Set the LSB to 1 */ + ctr[15] |= 0x01; + + /* Set the key */ + CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES CCM mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT); + + /* Set the Initialization Vector */ + CRYPEx_GCMCCM_SetInitVector(hcryp, ctr); + + /* Select init phase */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); + + b0addr = (uint32_t)blockb0; + /* Write the blockb0 block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + /***************************** Header phase *****************************/ + if(headersize != 0) + { + /* Select header phase */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); + + /* Enable Crypto processor */ + __HAL_CRYP_ENABLE(hcryp); + + for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + /* Write the header block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + /* Save formatted counter into the scratch buffer pScratch */ + for(loopcounter = 0; (loopcounter < 16); loopcounter++) + { + hcryp->Init.pScratch[loopcounter] = ctr[loopcounter]; + } + /* Reset bit 0 */ + hcryp->Init.pScratch[15] &= 0xfe; + + /* Select payload phase once the header phase is performed */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + if(Size != 0) + { + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + } + else + { + /* Change the CRYP state and phase */ + hcryp->State = HAL_CRYP_STATE_READY; + } + + /* Return function status */ + return HAL_OK; + } + else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + hcryp->pCrypInBuffPtr += 16; + hcryp->CrypInCount -= 16; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call Input transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + hcryp->pCrypOutBuffPtr += 16; + hcryp->CrypOutCount -= 16; + if(hcryp->CrypOutCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES GCM decryption mode using IT. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer + * @param Size: Length of the cyphertext buffer, must be a multiple of 16 + * @param pPlainData: Pointer to the plaintext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t tickstart = 0; + uint32_t inputaddr; + uint32_t outputaddr; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + /* Get the buffer addresses and sizes */ + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pCypherData; + hcryp->pCrypOutBuffPtr = pPlainData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES GCM decryption mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT); + + /* Set the Initialization Vector */ + CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Enable CRYP to start the init phase */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + + /* Set the header phase */ + if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK) + { + return HAL_TIMEOUT; + } + /* Disable the CRYP peripheral */ + __HAL_CRYP_DISABLE(hcryp); + + /* Select payload phase once the header phase is performed */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + if(Size != 0) + { + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + } + else + { + /* Process Locked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP state and phase */ + hcryp->State = HAL_CRYP_STATE_READY; + } + + /* Return function status */ + return HAL_OK; + } + else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + hcryp->pCrypInBuffPtr += 16; + hcryp->CrypInCount -= 16; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + hcryp->pCrypOutBuffPtr += 16; + hcryp->CrypOutCount -= 16; + if(hcryp->CrypOutCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES CCM decryption mode using interrupt + * then decrypted pCypherData. The cypher data are available in pPlainData. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 + * @param pPlainData: Pointer to the plaintext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_IT(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t inputaddr; + uint32_t outputaddr; + uint32_t tickstart = 0; + uint32_t headersize = hcryp->Init.HeaderSize; + uint32_t headeraddr = (uint32_t)hcryp->Init.Header; + uint32_t loopcounter = 0; + uint32_t bufferidx = 0; + uint8_t blockb0[16] = {0};/* Block B0 */ + uint8_t ctr[16] = {0}; /* Counter */ + uint32_t b0addr = (uint32_t)blockb0; + + if(hcryp->State == HAL_CRYP_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pCypherData; + hcryp->pCrypOutBuffPtr = pPlainData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /************************ Formatting the header block *******************/ + if(headersize != 0) + { + /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */ + if(headersize < 65280) + { + hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF); + hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF); + headersize += 2; + } + else + { + /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */ + hcryp->Init.pScratch[bufferidx++] = 0xFF; + hcryp->Init.pScratch[bufferidx++] = 0xFE; + hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff; + headersize += 6; + } + /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */ + for(loopcounter = 0; loopcounter < headersize; loopcounter++) + { + hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter]; + } + /* Check if the header size is modulo 16 */ + if ((headersize % 16) != 0) + { + /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */ + for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++) + { + hcryp->Init.pScratch[loopcounter] = 0; + } + /* Set the header size to modulo 16 */ + headersize = ((headersize/16) + 1) * 16; + } + /* Set the pointer headeraddr to hcryp->Init.pScratch */ + headeraddr = (uint32_t)hcryp->Init.pScratch; + } + /*********************** Formatting the block B0 ************************/ + if(headersize != 0) + { + blockb0[0] = 0x40; + } + /* Flags byte */ + /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */ + blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3); + blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07); + + for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++) + { + blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter]; + } + for ( ; loopcounter < 13; loopcounter++) + { + blockb0[loopcounter+1] = 0; + } + + blockb0[14] = (Size >> 8); + blockb0[15] = (Size & 0xFF); + + /************************* Formatting the initial counter ***************/ + /* Byte 0: + Bits 7 and 6 are reserved and shall be set to 0 + Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter + blocks are distinct from B0 + Bits 0, 1, and 2 contain the same encoding of q as in B0 + */ + ctr[0] = blockb0[0] & 0x07; + /* byte 1 to NonceSize is the IV (Nonce) */ + for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++) + { + ctr[loopcounter] = blockb0[loopcounter]; + } + /* Set the LSB to 1 */ + ctr[15] |= 0x01; + + /* Set the key */ + CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES CCM mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT); + + /* Set the Initialization Vector */ + CRYPEx_GCMCCM_SetInitVector(hcryp, ctr); + + /* Select init phase */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); + + b0addr = (uint32_t)blockb0; + /* Write the blockb0 block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + /***************************** Header phase *****************************/ + if(headersize != 0) + { + /* Select header phase */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); + + /* Enable Crypto processor */ + __HAL_CRYP_ENABLE(hcryp); + + for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + /* Write the header block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + /* Save formatted counter into the scratch buffer pScratch */ + for(loopcounter = 0; (loopcounter < 16); loopcounter++) + { + hcryp->Init.pScratch[loopcounter] = ctr[loopcounter]; + } + /* Reset bit 0 */ + hcryp->Init.pScratch[15] &= 0xfe; + /* Select payload phase once the header phase is performed */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Enable Interrupts */ + __HAL_CRYP_ENABLE_IT(hcryp, CRYP_IT_INI | CRYP_IT_OUTI); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Return function status */ + return HAL_OK; + } + else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_INI)) + { + inputaddr = (uint32_t)hcryp->pCrypInBuffPtr; + /* Write the Input block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + inputaddr+=4; + hcryp->Instance->DR = *(uint32_t*)(inputaddr); + hcryp->pCrypInBuffPtr += 16; + hcryp->CrypInCount -= 16; + if(hcryp->CrypInCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_INI); + /* Call the Input data transfer complete callback */ + HAL_CRYP_InCpltCallback(hcryp); + } + } + else if (__HAL_CRYP_GET_IT(hcryp, CRYP_IT_OUTI)) + { + outputaddr = (uint32_t)hcryp->pCrypOutBuffPtr; + /* Read the Output block from the Output FIFO */ + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + outputaddr+=4; + *(uint32_t*)(outputaddr) = hcryp->Instance->DOUT; + hcryp->pCrypOutBuffPtr += 16; + hcryp->CrypOutCount -= 16; + if(hcryp->CrypOutCount == 0) + { + __HAL_CRYP_DISABLE_IT(hcryp, CRYP_IT_OUTI); + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_READY; + /* Call Input transfer complete callback */ + HAL_CRYP_OutCpltCallback(hcryp); + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the CRYP peripheral in AES GCM encryption mode using DMA. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t tickstart = 0; + uint32_t inputaddr; + uint32_t outputaddr; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pPlainData; + outputaddr = (uint32_t)pCypherData; + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES GCM mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT); + + /* Set the Initialization Vector */ + CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Enable CRYP to start the init phase */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the header phase */ + if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK) + { + return HAL_TIMEOUT; + } + /* Disable the CRYP peripheral */ + __HAL_CRYP_DISABLE(hcryp); + + /* Select payload phase once the header phase is performed */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Set the input and output addresses and start DMA transfer */ + CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Unlock process */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Initializes the CRYP peripheral in AES CCM encryption mode using interrupt. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pPlainData: Pointer to the plaintext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 + * @param pCypherData: Pointer to the cyphertext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Encrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size, uint8_t *pCypherData) +{ + uint32_t tickstart = 0; + uint32_t inputaddr; + uint32_t outputaddr; + uint32_t headersize; + uint32_t headeraddr; + uint32_t loopcounter = 0; + uint32_t bufferidx = 0; + uint8_t blockb0[16] = {0};/* Block B0 */ + uint8_t ctr[16] = {0}; /* Counter */ + uint32_t b0addr = (uint32_t)blockb0; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pPlainData; + outputaddr = (uint32_t)pCypherData; + + headersize = hcryp->Init.HeaderSize; + headeraddr = (uint32_t)hcryp->Init.Header; + + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pPlainData; + hcryp->pCrypOutBuffPtr = pCypherData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /************************ Formatting the header block *******************/ + if(headersize != 0) + { + /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */ + if(headersize < 65280) + { + hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF); + hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF); + headersize += 2; + } + else + { + /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */ + hcryp->Init.pScratch[bufferidx++] = 0xFF; + hcryp->Init.pScratch[bufferidx++] = 0xFE; + hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff; + headersize += 6; + } + /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */ + for(loopcounter = 0; loopcounter < headersize; loopcounter++) + { + hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter]; + } + /* Check if the header size is modulo 16 */ + if ((headersize % 16) != 0) + { + /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */ + for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++) + { + hcryp->Init.pScratch[loopcounter] = 0; + } + /* Set the header size to modulo 16 */ + headersize = ((headersize/16) + 1) * 16; + } + /* Set the pointer headeraddr to hcryp->Init.pScratch */ + headeraddr = (uint32_t)hcryp->Init.pScratch; + } + /*********************** Formatting the block B0 ************************/ + if(headersize != 0) + { + blockb0[0] = 0x40; + } + /* Flags byte */ + /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */ + blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3); + blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07); + + for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++) + { + blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter]; + } + for ( ; loopcounter < 13; loopcounter++) + { + blockb0[loopcounter+1] = 0; + } + + blockb0[14] = (Size >> 8); + blockb0[15] = (Size & 0xFF); + + /************************* Formatting the initial counter ***************/ + /* Byte 0: + Bits 7 and 6 are reserved and shall be set to 0 + Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter + blocks are distinct from B0 + Bits 0, 1, and 2 contain the same encoding of q as in B0 + */ + ctr[0] = blockb0[0] & 0x07; + /* byte 1 to NonceSize is the IV (Nonce) */ + for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++) + { + ctr[loopcounter] = blockb0[loopcounter]; + } + /* Set the LSB to 1 */ + ctr[15] |= 0x01; + + /* Set the key */ + CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES CCM mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT); + + /* Set the Initialization Vector */ + CRYPEx_GCMCCM_SetInitVector(hcryp, ctr); + + /* Select init phase */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); + + b0addr = (uint32_t)blockb0; + /* Write the blockb0 block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + /***************************** Header phase *****************************/ + if(headersize != 0) + { + /* Select header phase */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); + + /* Enable Crypto processor */ + __HAL_CRYP_ENABLE(hcryp); + + for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + /* Write the header block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + /* Save formatted counter into the scratch buffer pScratch */ + for(loopcounter = 0; (loopcounter < 16); loopcounter++) + { + hcryp->Init.pScratch[loopcounter] = ctr[loopcounter]; + } + /* Reset bit 0 */ + hcryp->Init.pScratch[15] &= 0xfe; + + /* Select payload phase once the header phase is performed */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Set the input and output addresses and start DMA transfer */ + CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Unlock process */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Initializes the CRYP peripheral in AES GCM decryption mode using DMA. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer. + * @param Size: Length of the cyphertext buffer, must be a multiple of 16 + * @param pPlainData: Pointer to the plaintext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_AESGCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t tickstart = 0; + uint32_t inputaddr; + uint32_t outputaddr; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pCypherData; + outputaddr = (uint32_t)pPlainData; + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /* Set the key */ + CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES GCM decryption mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_GCM_DECRYPT); + + /* Set the Initialization Vector */ + CRYPEx_GCMCCM_SetInitVector(hcryp, hcryp->Init.pInitVect); + + /* Enable CRYP to start the init phase */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + + /* Set the header phase */ + if(CRYPEx_GCMCCM_SetHeaderPhase(hcryp, hcryp->Init.Header, hcryp->Init.HeaderSize, 1) != HAL_OK) + { + return HAL_TIMEOUT; + } + /* Disable the CRYP peripheral */ + __HAL_CRYP_DISABLE(hcryp); + + /* Select payload phase once the header phase is performed */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + + /* Set the input and output addresses and start DMA transfer */ + CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Unlock process */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Initializes the CRYP peripheral in AES CCM decryption mode using DMA + * then decrypted pCypherData. The cypher data are available in pPlainData. + * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @param pCypherData: Pointer to the cyphertext buffer + * @param Size: Length of the plaintext buffer, must be a multiple of 16 + * @param pPlainData: Pointer to the plaintext buffer + * @retval HAL status + */ +HAL_StatusTypeDef HAL_CRYPEx_AESCCM_Decrypt_DMA(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uint16_t Size, uint8_t *pPlainData) +{ + uint32_t tickstart = 0; + uint32_t inputaddr; + uint32_t outputaddr; + uint32_t headersize; + uint32_t headeraddr; + uint32_t loopcounter = 0; + uint32_t bufferidx = 0; + uint8_t blockb0[16] = {0};/* Block B0 */ + uint8_t ctr[16] = {0}; /* Counter */ + uint32_t b0addr = (uint32_t)blockb0; + + if((hcryp->State == HAL_CRYP_STATE_READY) || (hcryp->Phase == HAL_CRYP_PHASE_PROCESS)) + { + /* Process Locked */ + __HAL_LOCK(hcryp); + + inputaddr = (uint32_t)pCypherData; + outputaddr = (uint32_t)pPlainData; + + headersize = hcryp->Init.HeaderSize; + headeraddr = (uint32_t)hcryp->Init.Header; + + hcryp->CrypInCount = Size; + hcryp->pCrypInBuffPtr = pCypherData; + hcryp->pCrypOutBuffPtr = pPlainData; + hcryp->CrypOutCount = Size; + + /* Change the CRYP peripheral state */ + hcryp->State = HAL_CRYP_STATE_BUSY; + + /* Check if initialization phase has already been performed */ + if(hcryp->Phase == HAL_CRYP_PHASE_READY) + { + /************************ Formatting the header block *******************/ + if(headersize != 0) + { + /* Check that the associated data (or header) length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */ + if(headersize < 65280) + { + hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize >> 8) & 0xFF); + hcryp->Init.pScratch[bufferidx++] = (uint8_t) ((headersize) & 0xFF); + headersize += 2; + } + else + { + /* Header is encoded as 0xff || 0xfe || [headersize]32, i.e., six octets */ + hcryp->Init.pScratch[bufferidx++] = 0xFF; + hcryp->Init.pScratch[bufferidx++] = 0xFE; + hcryp->Init.pScratch[bufferidx++] = headersize & 0xff000000; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x00ff0000; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x0000ff00; + hcryp->Init.pScratch[bufferidx++] = headersize & 0x000000ff; + headersize += 6; + } + /* Copy the header buffer in internal buffer "hcryp->Init.pScratch" */ + for(loopcounter = 0; loopcounter < headersize; loopcounter++) + { + hcryp->Init.pScratch[bufferidx++] = hcryp->Init.Header[loopcounter]; + } + /* Check if the header size is modulo 16 */ + if ((headersize % 16) != 0) + { + /* Padd the header buffer with 0s till the hcryp->Init.pScratch length is modulo 16 */ + for(loopcounter = headersize; loopcounter <= ((headersize/16) + 1) * 16; loopcounter++) + { + hcryp->Init.pScratch[loopcounter] = 0; + } + /* Set the header size to modulo 16 */ + headersize = ((headersize/16) + 1) * 16; + } + /* Set the pointer headeraddr to hcryp->Init.pScratch */ + headeraddr = (uint32_t)hcryp->Init.pScratch; + } + /*********************** Formatting the block B0 ************************/ + if(headersize != 0) + { + blockb0[0] = 0x40; + } + /* Flags byte */ + /* blockb0[0] |= 0u | (((( (uint8_t) hcryp->Init.TagSize - 2) / 2) & 0x07 ) << 3 ) | ( ( (uint8_t) (15 - hcryp->Init.IVSize) - 1) & 0x07) */ + blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)(((uint8_t)(hcryp->Init.TagSize - (uint8_t)(2))) >> 1) & (uint8_t)0x07 ) << 3); + blockb0[0] |= (uint8_t)((uint8_t)((uint8_t)((uint8_t)(15) - hcryp->Init.IVSize) - (uint8_t)1) & (uint8_t)0x07); + + for (loopcounter = 0; loopcounter < hcryp->Init.IVSize; loopcounter++) + { + blockb0[loopcounter+1] = hcryp->Init.pInitVect[loopcounter]; + } + for ( ; loopcounter < 13; loopcounter++) + { + blockb0[loopcounter+1] = 0; + } + + blockb0[14] = (Size >> 8); + blockb0[15] = (Size & 0xFF); + + /************************* Formatting the initial counter ***************/ + /* Byte 0: + Bits 7 and 6 are reserved and shall be set to 0 + Bits 3, 4, and 5 shall also be set to 0, to ensure that all the counter + blocks are distinct from B0 + Bits 0, 1, and 2 contain the same encoding of q as in B0 + */ + ctr[0] = blockb0[0] & 0x07; + /* byte 1 to NonceSize is the IV (Nonce) */ + for(loopcounter = 1; loopcounter < hcryp->Init.IVSize + 1; loopcounter++) + { + ctr[loopcounter] = blockb0[loopcounter]; + } + /* Set the LSB to 1 */ + ctr[15] |= 0x01; + + /* Set the key */ + CRYPEx_GCMCCM_SetKey(hcryp, hcryp->Init.pKey, hcryp->Init.KeySize); + + /* Set the CRYP peripheral in AES CCM mode */ + __HAL_CRYP_SET_MODE(hcryp, CRYP_CR_ALGOMODE_AES_CCM_DECRYPT); + + /* Set the Initialization Vector */ + CRYPEx_GCMCCM_SetInitVector(hcryp, ctr); + + /* Select init phase */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_INIT); + + b0addr = (uint32_t)blockb0; + /* Write the blockb0 block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + b0addr+=4; + hcryp->Instance->DR = *(uint32_t*)(b0addr); + + /* Enable the CRYP peripheral */ + __HAL_CRYP_ENABLE(hcryp); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((CRYP->CR & CRYP_CR_CRYPEN) == CRYP_CR_CRYPEN) + { + /* Check for the Timeout */ + + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + + } + } + /***************************** Header phase *****************************/ + if(headersize != 0) + { + /* Select header phase */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_HEADER); + + /* Enable Crypto processor */ + __HAL_CRYP_ENABLE(hcryp); + + for(loopcounter = 0; (loopcounter < headersize); loopcounter+=16) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_IFEM)) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + /* Write the header block in the IN FIFO */ + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + hcryp->Instance->DR = *(uint32_t*)(headeraddr); + headeraddr+=4; + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((hcryp->Instance->SR & CRYP_FLAG_BUSY) == CRYP_FLAG_BUSY) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > CRYPEx_TIMEOUT_VALUE) + { + /* Change state */ + hcryp->State = HAL_CRYP_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hcryp); + + return HAL_TIMEOUT; + } + } + } + /* Save formatted counter into the scratch buffer pScratch */ + for(loopcounter = 0; (loopcounter < 16); loopcounter++) + { + hcryp->Init.pScratch[loopcounter] = ctr[loopcounter]; + } + /* Reset bit 0 */ + hcryp->Init.pScratch[15] &= 0xfe; + /* Select payload phase once the header phase is performed */ + __HAL_CRYP_SET_PHASE(hcryp, CRYP_PHASE_PAYLOAD); + + /* Flush FIFO */ + __HAL_CRYP_FIFO_FLUSH(hcryp); + + /* Set the phase */ + hcryp->Phase = HAL_CRYP_PHASE_PROCESS; + } + /* Set the input and output addresses and start DMA transfer */ + CRYPEx_GCMCCM_SetDMAConfig(hcryp, inputaddr, Size, outputaddr); + + /* Unlock process */ + __HAL_UNLOCK(hcryp); + + /* Return function status */ + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @} + */ + +/** @defgroup CRYPEx_Exported_Functions_Group2 CRYPEx IRQ handler management + * @brief CRYPEx IRQ handler. + * +@verbatim + ============================================================================== + ##### CRYPEx IRQ handler management ##### + ============================================================================== +[..] This section provides CRYPEx IRQ handler function. + +@endverbatim + * @{ + */ + +/** + * @brief This function handles CRYPEx interrupt request. + * @param hcryp: pointer to a CRYPEx_HandleTypeDef structure that contains + * the configuration information for CRYP module + * @retval None + */ + +void HAL_CRYPEx_GCMCCM_IRQHandler(CRYP_HandleTypeDef *hcryp) +{ + switch(CRYP->CR & CRYP_CR_ALGOMODE_DIRECTION) + { + case CRYP_CR_ALGOMODE_AES_GCM_ENCRYPT: + HAL_CRYPEx_AESGCM_Encrypt_IT(hcryp, NULL, 0, NULL); + break; + + case CRYP_CR_ALGOMODE_AES_GCM_DECRYPT: + HAL_CRYPEx_AESGCM_Decrypt_IT(hcryp, NULL, 0, NULL); + break; + + case CRYP_CR_ALGOMODE_AES_CCM_ENCRYPT: + HAL_CRYPEx_AESCCM_Encrypt_IT(hcryp, NULL, 0, NULL); + break; + + case CRYP_CR_ALGOMODE_AES_CCM_DECRYPT: + HAL_CRYPEx_AESCCM_Decrypt_IT(hcryp, NULL, 0, NULL); + break; + + default: + break; + } +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F437xx || STM32F439xx */ + +#endif /* HAL_CRYP_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac.c new file mode 100644 index 0000000..9a7ccef --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac.c @@ -0,0 +1,953 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_dac.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief DAC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Digital to Analog Converter (DAC) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Errors functions + * + * + @verbatim + ============================================================================== + ##### DAC Peripheral features ##### + ============================================================================== + [..] + *** DAC Channels *** + ==================== + [..] + The device integrates two 12-bit Digital Analog Converters that can + be used independently or simultaneously (dual mode): + (#) DAC channel1 with DAC_OUT1 (PA4) as output + (#) DAC channel2 with DAC_OUT2 (PA5) as output + + *** DAC Triggers *** + ==================== + [..] + Digital to Analog conversion can be non-triggered using DAC_TRIGGER_NONE + and DAC_OUT1/DAC_OUT2 is available once writing to DHRx register. + [..] + Digital to Analog conversion can be triggered by: + (#) External event: EXTI Line 9 (any GPIOx_Pin9) using DAC_TRIGGER_EXT_IT9. + The used pin (GPIOx_Pin9) must be configured in input mode. + + (#) Timers TRGO: TIM2, TIM4, TIM5, TIM6, TIM7 and TIM8 + (DAC_TRIGGER_T2_TRGO, DAC_TRIGGER_T4_TRGO...) + + (#) Software using DAC_TRIGGER_SOFTWARE + + *** DAC Buffer mode feature *** + =============================== + [..] + Each DAC channel integrates an output buffer that can be used to + reduce the output impedance, and to drive external loads directly + without having to add an external operational amplifier. + To enable, the output buffer use + sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; + [..] + (@) Refer to the device datasheet for more details about output + impedance value with and without output buffer. + + *** DAC wave generation feature *** + =================================== + [..] + Both DAC channels can be used to generate + (#) Noise wave + (#) Triangle wave + + *** DAC data format *** + ======================= + [..] + The DAC data format can be: + (#) 8-bit right alignment using DAC_ALIGN_8B_R + (#) 12-bit left alignment using DAC_ALIGN_12B_L + (#) 12-bit right alignment using DAC_ALIGN_12B_R + + *** DAC data value to voltage correspondence *** + ================================================ + [..] + The analog output voltage on each DAC channel pin is determined + by the following equation: + DAC_OUTx = VREF+ * DOR / 4095 + with DOR is the Data Output Register + VEF+ is the input voltage reference (refer to the device datasheet) + e.g. To set DAC_OUT1 to 0.7V, use + Assuming that VREF+ = 3.3V, DAC_OUT1 = (3.3 * 868) / 4095 = 0.7V + + *** DMA requests *** + ===================== + [..] + A DMA1 request can be generated when an external trigger (but not + a software trigger) occurs if DMA1 requests are enabled using + HAL_DAC_Start_DMA() + [..] + DMA1 requests are mapped as following: + (#) DAC channel1 : mapped on DMA1 Stream5 channel7 which must be + already configured + (#) DAC channel2 : mapped on DMA1 Stream6 channel7 which must be + already configured + + -@- For Dual mode and specific signal (Triangle and noise) generation please + refer to Extension Features Driver description + + + ##### How to use this driver ##### + ============================================================================== + [..] + (+) DAC APB clock must be enabled to get write access to DAC + registers using HAL_DAC_Init() + (+) Configure DAC_OUTx (DAC_OUT1: PA4, DAC_OUT2: PA5) in analog mode. + (+) Configure the DAC channel using HAL_DAC_ConfigChannel() function. + (+) Enable the DAC channel using HAL_DAC_Start() or HAL_DAC_Start_DMA functions + + *** Polling mode IO operation *** + ================================= + [..] + (+) Start the DAC peripheral using HAL_DAC_Start() + (+) To read the DAC last data output value, use the HAL_DAC_GetValue() function. + (+) Stop the DAC peripheral using HAL_DAC_Stop() + + *** DMA mode IO operation *** + ============================== + [..] + (+) Start the DAC peripheral using HAL_DAC_Start_DMA(), at this stage the user specify the length + of data to be transferred at each end of conversion + (+) At The end of data transfer HAL_DAC_ConvCpltCallbackCh1()or HAL_DAC_ConvCpltCallbackCh2() + function is executed and user can add his own code by customization of function pointer + HAL_DAC_ConvCpltCallbackCh1 or HAL_DAC_ConvCpltCallbackCh2 + (+) In case of transfer Error, HAL_DAC_ErrorCallbackCh1() function is executed and user can + add his own code by customization of function pointer HAL_DAC_ErrorCallbackCh1 + (+) Stop the DAC peripheral using HAL_DAC_Stop_DMA() + + *** DAC HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in DAC HAL driver. + + (+) __HAL_DAC_ENABLE : Enable the DAC peripheral + (+) __HAL_DAC_DISABLE : Disable the DAC peripheral + (+) __HAL_DAC_CLEAR_FLAG: Clear the DAC's pending flags + (+) __HAL_DAC_GET_FLAG: Get the selected DAC's flag status + + [..] + (@) You can refer to the DAC HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 DAC DAC + * @brief DAC driver modules + * @{ + */ + +#ifdef HAL_DAC_MODULE_ENABLED + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F446xx) +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @addtogroup DAC_Private_Functions + * @{ + */ +/* Private function prototypes -----------------------------------------------*/ +static void DAC_DMAConvCpltCh1(DMA_HandleTypeDef *hdma); +static void DAC_DMAErrorCh1(DMA_HandleTypeDef *hdma); +static void DAC_DMAHalfConvCpltCh1(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup DAC_Exported_Functions DAC Exported Functions + * @{ + */ + +/** @defgroup DAC_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 and configure the DAC. + (+) De-initialize the DAC. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the DAC peripheral according to the specified parameters + * in the DAC_InitStruct. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DAC_Init(DAC_HandleTypeDef* hdac) +{ + /* Check DAC handle */ + if(hdac == NULL) + { + return HAL_ERROR; + } + /* Check the parameters */ + assert_param(IS_DAC_ALL_INSTANCE(hdac->Instance)); + + if(hdac->State == HAL_DAC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hdac->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_DAC_MspInit(hdac); + } + + /* Initialize the DAC state*/ + hdac->State = HAL_DAC_STATE_BUSY; + + /* Set DAC error code to none */ + hdac->ErrorCode = HAL_DAC_ERROR_NONE; + + /* Initialize the DAC state*/ + hdac->State = HAL_DAC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Deinitializes the DAC peripheral registers to their default reset values. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DAC_DeInit(DAC_HandleTypeDef* hdac) +{ + /* Check DAC handle */ + if(hdac == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DAC_ALL_INSTANCE(hdac->Instance)); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_BUSY; + + /* DeInit the low level hardware */ + HAL_DAC_MspDeInit(hdac); + + /* Set DAC error code to none */ + hdac->ErrorCode = HAL_DAC_ERROR_NONE; + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hdac); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the DAC MSP. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DAC_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes the DAC MSP. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DAC_MspDeInit(DAC_HandleTypeDef* hdac) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DAC_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup DAC_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Start conversion. + (+) Stop conversion. + (+) Start conversion and enable DMA transfer. + (+) Stop conversion and disable DMA transfer. + (+) Get result of conversion. + +@endverbatim + * @{ + */ + +/** + * @brief Enables DAC and starts conversion of channel. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef* hdac, uint32_t Channel) +{ + uint32_t tmp1 = 0, tmp2 = 0; + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + + /* Process locked */ + __HAL_LOCK(hdac); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_BUSY; + + /* Enable the Peripheral */ + __HAL_DAC_ENABLE(hdac, Channel); + + if(Channel == DAC_CHANNEL_1) + { + tmp1 = hdac->Instance->CR & DAC_CR_TEN1; + tmp2 = hdac->Instance->CR & DAC_CR_TSEL1; + /* Check if software trigger enabled */ + if((tmp1 == DAC_CR_TEN1) && (tmp2 == DAC_CR_TSEL1)) + { + /* Enable the selected DAC software conversion */ + hdac->Instance->SWTRIGR |= (uint32_t)DAC_SWTRIGR_SWTRIG1; + } + } + else + { + tmp1 = hdac->Instance->CR & DAC_CR_TEN2; + tmp2 = hdac->Instance->CR & DAC_CR_TSEL2; + /* Check if software trigger enabled */ + if((tmp1 == DAC_CR_TEN2) && (tmp2 == DAC_CR_TSEL2)) + { + /* Enable the selected DAC software conversion*/ + hdac->Instance->SWTRIGR |= (uint32_t)DAC_SWTRIGR_SWTRIG2; + } + } + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hdac); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Disables DAC and stop conversion of channel. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DAC_Stop(DAC_HandleTypeDef* hdac, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + + /* Disable the Peripheral */ + __HAL_DAC_DISABLE(hdac, Channel); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Enables DAC and starts conversion of channel. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @param pData: The destination peripheral Buffer address. + * @param Length: The length of data to be transferred from memory to DAC peripheral + * @param Alignment: Specifies the data alignment for DAC channel. + * This parameter can be one of the following values: + * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected + * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected + * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + assert_param(IS_DAC_ALIGN(Alignment)); + + /* Process locked */ + __HAL_LOCK(hdac); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_BUSY; + + if(Channel == DAC_CHANNEL_1) + { + /* Set the DMA transfer complete callback for channel1 */ + hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1; + + /* Set the DMA half transfer complete callback for channel1 */ + hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1; + + /* Set the DMA error callback for channel1 */ + hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1; + + /* Enable the selected DAC channel1 DMA request */ + hdac->Instance->CR |= DAC_CR_DMAEN1; + + /* Case of use of channel 1 */ + switch(Alignment) + { + case DAC_ALIGN_12B_R: + /* Get DHR12R1 address */ + tmpreg = (uint32_t)&hdac->Instance->DHR12R1; + break; + case DAC_ALIGN_12B_L: + /* Get DHR12L1 address */ + tmpreg = (uint32_t)&hdac->Instance->DHR12L1; + break; + case DAC_ALIGN_8B_R: + /* Get DHR8R1 address */ + tmpreg = (uint32_t)&hdac->Instance->DHR8R1; + break; + default: + break; + } + } + else + { + /* Set the DMA transfer complete callback for channel2 */ + hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2; + + /* Set the DMA half transfer complete callback for channel2 */ + hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2; + + /* Set the DMA error callback for channel2 */ + hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2; + + /* Enable the selected DAC channel2 DMA request */ + hdac->Instance->CR |= DAC_CR_DMAEN2; + + /* Case of use of channel 2 */ + switch(Alignment) + { + case DAC_ALIGN_12B_R: + /* Get DHR12R2 address */ + tmpreg = (uint32_t)&hdac->Instance->DHR12R2; + break; + case DAC_ALIGN_12B_L: + /* Get DHR12L2 address */ + tmpreg = (uint32_t)&hdac->Instance->DHR12L2; + break; + case DAC_ALIGN_8B_R: + /* Get DHR8R2 address */ + tmpreg = (uint32_t)&hdac->Instance->DHR8R2; + break; + default: + break; + } + } + + /* Enable the DMA Stream */ + if(Channel == DAC_CHANNEL_1) + { + /* Enable the DAC DMA underrun interrupt */ + __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1); + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, Length); + } + else + { + /* Enable the DAC DMA underrun interrupt */ + __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2); + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, Length); + } + + /* Enable the Peripheral */ + __HAL_DAC_ENABLE(hdac, Channel); + + /* Process Unlocked */ + __HAL_UNLOCK(hdac); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Disables DAC and stop conversion of channel. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + + /* Disable the selected DAC channel DMA request */ + hdac->Instance->CR &= ~(DAC_CR_DMAEN1 << Channel); + + /* Disable the Peripheral */ + __HAL_DAC_DISABLE(hdac, Channel); + + /* Disable the DMA Channel */ + /* Channel1 is used */ + if(Channel == DAC_CHANNEL_1) + { + status = HAL_DMA_Abort(hdac->DMA_Handle1); + } + else /* Channel2 is used for */ + { + status = HAL_DMA_Abort(hdac->DMA_Handle2); + } + + /* Check if DMA Channel effectively disabled */ + if(status != HAL_OK) + { + /* Update DAC state machine to error */ + hdac->State = HAL_DAC_STATE_ERROR; + } + else + { + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_READY; + } + + /* Return function status */ + return status; +} + +/** + * @brief Returns the last data output value of the selected DAC channel. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @retval The selected DAC channel data output value. + */ +uint32_t HAL_DAC_GetValue(DAC_HandleTypeDef* hdac, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + + /* Returns the DAC channel data output register value */ + if(Channel == DAC_CHANNEL_1) + { + return hdac->Instance->DOR1; + } + else + { + return hdac->Instance->DOR2; + } +} + +/** + * @brief Handles DAC interrupt request + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +void HAL_DAC_IRQHandler(DAC_HandleTypeDef* hdac) +{ + /* Check underrun channel 1 flag */ + if(__HAL_DAC_GET_FLAG(hdac, DAC_FLAG_DMAUDR1)) + { + /* Change DAC state to error state */ + hdac->State = HAL_DAC_STATE_ERROR; + + /* Set DAC error code to channel1 DMA underrun error */ + hdac->ErrorCode |= HAL_DAC_ERROR_DMAUNDERRUNCH1; + + /* Clear the underrun flag */ + __HAL_DAC_CLEAR_FLAG(hdac,DAC_FLAG_DMAUDR1); + + /* Disable the selected DAC channel1 DMA request */ + hdac->Instance->CR &= ~DAC_CR_DMAEN1; + + /* Error callback */ + HAL_DAC_DMAUnderrunCallbackCh1(hdac); + } + /* Check underrun channel 2 flag */ + if(__HAL_DAC_GET_FLAG(hdac, DAC_FLAG_DMAUDR2)) + { + /* Change DAC state to error state */ + hdac->State = HAL_DAC_STATE_ERROR; + + /* Set DAC error code to channel2 DMA underrun error */ + hdac->ErrorCode |= HAL_DAC_ERROR_DMAUNDERRUNCH2; + + /* Clear the underrun flag */ + __HAL_DAC_CLEAR_FLAG(hdac,DAC_FLAG_DMAUDR2); + + /* Disable the selected DAC channel1 DMA request */ + hdac->Instance->CR &= ~DAC_CR_DMAEN2; + + /* Error callback */ + HAL_DACEx_DMAUnderrunCallbackCh2(hdac); + } +} + +/** + * @brief Conversion complete callback in non blocking mode for Channel1 + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef* hdac) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DAC_ConvCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Conversion half DMA transfer callback in non blocking mode for Channel1 + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef* hdac) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DAC_ConvHalfCpltCallbackCh1 could be implemented in the user file + */ +} + +/** + * @brief Error DAC callback for Channel1. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DAC_ErrorCallbackCh1(DAC_HandleTypeDef *hdac) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DAC_ErrorCallbackCh1 could be implemented in the user file + */ +} + +/** + * @brief DMA underrun DAC callback for channel1. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DAC_DMAUnderrunCallbackCh1(DAC_HandleTypeDef *hdac) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DAC_DMAUnderrunCallbackCh1 could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup DAC_Exported_Functions_Group3 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Configure channels. + (+) Set the specified data holding register value for DAC channel. + +@endverbatim + * @{ + */ + +/** + * @brief Configures the selected DAC channel. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param sConfig: DAC configuration structure. + * @param Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef* hdac, DAC_ChannelConfTypeDef* sConfig, uint32_t Channel) +{ + uint32_t tmpreg1 = 0, tmpreg2 = 0; + + /* Check the DAC parameters */ + assert_param(IS_DAC_TRIGGER(sConfig->DAC_Trigger)); + assert_param(IS_DAC_OUTPUT_BUFFER_STATE(sConfig->DAC_OutputBuffer)); + assert_param(IS_DAC_CHANNEL(Channel)); + + /* Process locked */ + __HAL_LOCK(hdac); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_BUSY; + + /* Get the DAC CR value */ + tmpreg1 = hdac->Instance->CR; + /* Clear BOFFx, TENx, TSELx, WAVEx and MAMPx bits */ + tmpreg1 &= ~(((uint32_t)(DAC_CR_MAMP1 | DAC_CR_WAVE1 | DAC_CR_TSEL1 | DAC_CR_TEN1 | DAC_CR_BOFF1)) << Channel); + /* Configure for the selected DAC channel: buffer output, trigger */ + /* Set TSELx and TENx bits according to DAC_Trigger value */ + /* Set BOFFx bit according to DAC_OutputBuffer value */ + tmpreg2 = (sConfig->DAC_Trigger | sConfig->DAC_OutputBuffer); + /* Calculate CR register value depending on DAC_Channel */ + tmpreg1 |= tmpreg2 << Channel; + /* Write to DAC CR */ + hdac->Instance->CR = tmpreg1; + /* Disable wave generation */ + hdac->Instance->CR &= ~(DAC_CR_WAVE1 << Channel); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hdac); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Set the specified data holding register value for DAC channel. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel: The selected DAC channel. + * This parameter can be one of the following values: + * @arg DAC_CHANNEL_1: DAC Channel1 selected + * @arg DAC_CHANNEL_2: DAC Channel2 selected + * @param Alignment: Specifies the data alignment. + * This parameter can be one of the following values: + * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected + * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected + * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected + * @param Data: Data to be loaded in the selected data holding register. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + assert_param(IS_DAC_ALIGN(Alignment)); + assert_param(IS_DAC_DATA(Data)); + + tmp = (uint32_t)hdac->Instance; + if(Channel == DAC_CHANNEL_1) + { + tmp += DAC_DHR12R1_ALIGNMENT(Alignment); + } + else + { + tmp += DAC_DHR12R2_ALIGNMENT(Alignment); + } + + /* Set the DAC channel1 selected data holding register */ + *(__IO uint32_t *) tmp = Data; + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup DAC_Exported_Functions_Group4 Peripheral State and Errors functions + * @brief Peripheral State and Errors functions + * +@verbatim + ============================================================================== + ##### Peripheral State and Errors functions ##### + ============================================================================== + [..] + This subsection provides functions allowing to + (+) Check the DAC state. + (+) Check the DAC Errors. + +@endverbatim + * @{ + */ + +/** + * @brief return the DAC state + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval HAL state + */ +HAL_DAC_StateTypeDef HAL_DAC_GetState(DAC_HandleTypeDef* hdac) +{ + /* Return DAC state */ + return hdac->State; +} + + +/** + * @brief Return the DAC error code + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval DAC Error Code + */ +uint32_t HAL_DAC_GetError(DAC_HandleTypeDef *hdac) +{ + return hdac->ErrorCode; +} + +/** + * @} + */ + +/** + * @brief DMA conversion complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void DAC_DMAConvCpltCh1(DMA_HandleTypeDef *hdma) +{ + DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + HAL_DAC_ConvCpltCallbackCh1(hdac); + + hdac->State= HAL_DAC_STATE_READY; +} + +/** + * @brief DMA half transfer complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void DAC_DMAHalfConvCpltCh1(DMA_HandleTypeDef *hdma) +{ + DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + /* Conversion complete callback */ + HAL_DAC_ConvHalfCpltCallbackCh1(hdac); +} + +/** + * @brief DMA error callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void DAC_DMAErrorCh1(DMA_HandleTypeDef *hdma) +{ + DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Set DAC error code to DMA error */ + hdac->ErrorCode |= HAL_DAC_ERROR_DMA; + + HAL_DAC_ErrorCallbackCh1(hdac); + + hdac->State= HAL_DAC_STATE_READY; +} + +/** + * @} + */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx ||\ + STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||\ + STM32F446xx + */ +#endif /* HAL_DAC_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac_ex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac_ex.c new file mode 100644 index 0000000..a8d3e7d --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac_ex.c @@ -0,0 +1,382 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_dac_ex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief DAC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of DAC extension peripheral: + * + Extended features functions + * + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (+) When Dual mode is enabled (i.e DAC Channel1 and Channel2 are used simultaneously) : + Use HAL_DACEx_DualGetValue() to get digital data to be converted and use + HAL_DACEx_DualSetValue() to set digital value to converted simultaneously in Channel 1 and Channel 2. + (+) Use HAL_DACEx_TriangleWaveGenerate() to generate Triangle signal. + (+) Use HAL_DACEx_NoiseWaveGenerate() to generate Noise signal. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 DACEx DACEx + * @brief DAC driver modules + * @{ + */ + +#ifdef HAL_DAC_MODULE_ENABLED + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F446xx) +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup DACEx_Exported_Functions DAC Exported Functions + * @{ + */ + +/** @defgroup DACEx_Exported_Functions_Group1 Extended features functions + * @brief Extended features functions + * +@verbatim + ============================================================================== + ##### Extended features functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Start conversion. + (+) Stop conversion. + (+) Start conversion and enable DMA transfer. + (+) Stop conversion and disable DMA transfer. + (+) Get result of conversion. + (+) Get result of dual mode conversion. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the last data output value of the selected DAC channel. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval The selected DAC channel data output value. + */ +uint32_t HAL_DACEx_DualGetValue(DAC_HandleTypeDef* hdac) +{ + uint32_t tmp = 0; + + tmp |= hdac->Instance->DOR1; + + tmp |= hdac->Instance->DOR2 << 16; + + /* Returns the DAC channel data output register value */ + return tmp; +} + +/** + * @brief Enables or disables the selected DAC channel wave generation. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel: The selected DAC channel. + * This parameter can be one of the following values: + * DAC_CHANNEL_1 / DAC_CHANNEL_2 + * @param Amplitude: Select max triangle amplitude. + * This parameter can be one of the following values: + * @arg DAC_TRIANGLEAMPLITUDE_1: Select max triangle amplitude of 1 + * @arg DAC_TRIANGLEAMPLITUDE_3: Select max triangle amplitude of 3 + * @arg DAC_TRIANGLEAMPLITUDE_7: Select max triangle amplitude of 7 + * @arg DAC_TRIANGLEAMPLITUDE_15: Select max triangle amplitude of 15 + * @arg DAC_TRIANGLEAMPLITUDE_31: Select max triangle amplitude of 31 + * @arg DAC_TRIANGLEAMPLITUDE_63: Select max triangle amplitude of 63 + * @arg DAC_TRIANGLEAMPLITUDE_127: Select max triangle amplitude of 127 + * @arg DAC_TRIANGLEAMPLITUDE_255: Select max triangle amplitude of 255 + * @arg DAC_TRIANGLEAMPLITUDE_511: Select max triangle amplitude of 511 + * @arg DAC_TRIANGLEAMPLITUDE_1023: Select max triangle amplitude of 1023 + * @arg DAC_TRIANGLEAMPLITUDE_2047: Select max triangle amplitude of 2047 + * @arg DAC_TRIANGLEAMPLITUDE_4095: Select max triangle amplitude of 4095 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude)); + + /* Process locked */ + __HAL_LOCK(hdac); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_BUSY; + + /* Enable the selected wave generation for the selected DAC channel */ + MODIFY_REG(hdac->Instance->CR, (DAC_CR_WAVE1 | DAC_CR_MAMP1) << Channel, (DAC_CR_WAVE1_1 | Amplitude) << Channel); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hdac); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Enables or disables the selected DAC channel wave generation. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Channel: The selected DAC channel. + * This parameter can be one of the following values: + * DAC_CHANNEL_1 / DAC_CHANNEL_2 + * @param Amplitude: Unmask DAC channel LFSR for noise wave generation. + * This parameter can be one of the following values: + * @arg DAC_LFSRUNMASK_BIT0: Unmask DAC channel LFSR bit0 for noise wave generation + * @arg DAC_LFSRUNMASK_BITS1_0: Unmask DAC channel LFSR bit[1:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS2_0: Unmask DAC channel LFSR bit[2:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS3_0: Unmask DAC channel LFSR bit[3:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS4_0: Unmask DAC channel LFSR bit[4:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS5_0: Unmask DAC channel LFSR bit[5:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS6_0: Unmask DAC channel LFSR bit[6:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS7_0: Unmask DAC channel LFSR bit[7:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS8_0: Unmask DAC channel LFSR bit[8:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS9_0: Unmask DAC channel LFSR bit[9:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS10_0: Unmask DAC channel LFSR bit[10:0] for noise wave generation + * @arg DAC_LFSRUNMASK_BITS11_0: Unmask DAC channel LFSR bit[11:0] for noise wave generation + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude) +{ + /* Check the parameters */ + assert_param(IS_DAC_CHANNEL(Channel)); + assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude)); + + /* Process locked */ + __HAL_LOCK(hdac); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_BUSY; + + /* Enable the selected wave generation for the selected DAC channel */ + MODIFY_REG(hdac->Instance->CR, (DAC_CR_WAVE1 | DAC_CR_MAMP1) << Channel, (DAC_CR_WAVE1_0 | Amplitude) << Channel); + + /* Change DAC state */ + hdac->State = HAL_DAC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hdac); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Set the specified data holding register value for dual DAC channel. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @param Alignment: Specifies the data alignment for dual channel DAC. + * This parameter can be one of the following values: + * DAC_ALIGN_8B_R: 8bit right data alignment selected + * DAC_ALIGN_12B_L: 12bit left data alignment selected + * DAC_ALIGN_12B_R: 12bit right data alignment selected + * @param Data1: Data for DAC Channel2 to be loaded in the selected data holding register. + * @param Data2: Data for DAC Channel1 to be loaded in the selected data holding register. + * @note In dual mode, a unique register access is required to write in both + * DAC channels at the same time. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef* hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2) +{ + uint32_t data = 0, tmp = 0; + + /* Check the parameters */ + assert_param(IS_DAC_ALIGN(Alignment)); + assert_param(IS_DAC_DATA(Data1)); + assert_param(IS_DAC_DATA(Data2)); + + /* Calculate and set dual DAC data holding register value */ + if (Alignment == DAC_ALIGN_8B_R) + { + data = ((uint32_t)Data2 << 8) | Data1; + } + else + { + data = ((uint32_t)Data2 << 16) | Data1; + } + + tmp = (uint32_t)hdac->Instance; + tmp += DAC_DHR12RD_ALIGNMENT(Alignment); + + /* Set the dual DAC selected data holding register */ + *(__IO uint32_t *)tmp = data; + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** + * @brief Conversion complete callback in non blocking mode for Channel2 + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef* hdac) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DAC_ConvCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Conversion half DMA transfer callback in non blocking mode for Channel2 + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef* hdac) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DAC_ConvHalfCpltCallbackCh2 could be implemented in the user file + */ +} + +/** + * @brief Error DAC callback for Channel2. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef *hdac) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DAC_ErrorCallback could be implemented in the user file + */ +} + +/** + * @brief DMA underrun DAC callback for channel2. + * @param hdac: pointer to a DAC_HandleTypeDef structure that contains + * the configuration information for the specified DAC. + * @retval None + */ +__weak void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef *hdac) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DAC_DMAUnderrunCallbackCh2 could be implemented in the user file + */ +} + +/** + * @brief DMA conversion complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma) +{ + DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + HAL_DACEx_ConvCpltCallbackCh2(hdac); + + hdac->State= HAL_DAC_STATE_READY; +} + +/** + * @brief DMA half transfer complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma) +{ + DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + /* Conversion complete callback */ + HAL_DACEx_ConvHalfCpltCallbackCh2(hdac); +} + +/** + * @brief DMA error callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma) +{ + DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Set DAC error code to DMA error */ + hdac->ErrorCode |= HAL_DAC_ERROR_DMA; + + HAL_DACEx_ErrorCallbackCh2(hdac); + + hdac->State= HAL_DAC_STATE_READY; +} + +/** + * @} + */ + +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx ||\ + STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||\ + STM32F446xx + */ + +#endif /* HAL_DAC_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dcmi.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dcmi.c new file mode 100644 index 0000000..5713a86 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dcmi.c @@ -0,0 +1,830 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_dcmi.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief DCMI HAL module driver + * This file provides firmware functions to manage the following + * functionalities of the Digital Camera Interface (DCMI) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Error functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The sequence below describes how to use this driver to capture image + from a camera module connected to the DCMI Interface. + This sequence does not take into account the configuration of the + camera module, which should be made before to configure and enable + the DCMI to capture images. + + (#) Program the required configuration through following parameters: + horizontal and vertical polarity, pixel clock polarity, Capture Rate, + Synchronization Mode, code of the frame delimiter and data width + using HAL_DCMI_Init() function. + + (#) Configure the DMA2_Stream1 channel1 to transfer Data from DCMI DR + register to the destination memory buffer. + + (#) Program the required configuration through following parameters: + DCMI mode, destination memory Buffer address and the data length + and enable capture using HAL_DCMI_Start_DMA() function. + + (#) Optionally, configure and Enable the CROP feature to select a rectangular + window from the received image using HAL_DCMI_ConfigCrop() + and HAL_DCMI_EnableCROP() functions + + (#) The capture can be stopped using HAL_DCMI_Stop() function. + + (#) To control DCMI state you can use the function HAL_DCMI_GetState(). + + *** DCMI HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in DCMI HAL driver. + + (+) __HAL_DCMI_ENABLE: Enable the DCMI peripheral. + (+) __HAL_DCMI_DISABLE: Disable the DCMI peripheral. + (+) __HAL_DCMI_GET_FLAG: Get the DCMI pending flags. + (+) __HAL_DCMI_CLEAR_FLAG: Clear the DCMI pending flags. + (+) __HAL_DCMI_ENABLE_IT: Enable the specified DCMI interrupts. + (+) __HAL_DCMI_DISABLE_IT: Disable the specified DCMI interrupts. + (+) __HAL_DCMI_GET_IT_SOURCE: Check whether the specified DCMI interrupt has occurred or not. + + [..] + (@) You can refer to the DCMI HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 DCMI DCMI + * @brief DCMI HAL module driver + * @{ + */ + +#ifdef HAL_DCMI_MODULE_ENABLED + +#if defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) ||\ + defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define HAL_TIMEOUT_DCMI_STOP ((uint32_t)1000) /* 1s */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static void DCMI_DMAConvCplt(DMA_HandleTypeDef *hdma); +static void DCMI_DMAError(DMA_HandleTypeDef *hdma); + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup DCMI_Exported_Functions DCMI Exported Functions + * @{ + */ + +/** @defgroup DCMI_Exported_Functions_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initialize and configure the DCMI + (+) De-initialize the DCMI + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the DCMI according to the specified + * parameters in the DCMI_InitTypeDef and create the associated handle. + * @param hdcmi: pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval HAL status + */ +__weak HAL_StatusTypeDef HAL_DCMI_Init(DCMI_HandleTypeDef *hdcmi) +{ + /* Check the DCMI peripheral state */ + if(hdcmi == NULL) + { + return HAL_ERROR; + } + + /* Check function parameters */ + assert_param(IS_DCMI_ALL_INSTANCE(hdcmi->Instance)); + assert_param(IS_DCMI_PCKPOLARITY(hdcmi->Init.PCKPolarity)); + assert_param(IS_DCMI_VSPOLARITY(hdcmi->Init.VSPolarity)); + assert_param(IS_DCMI_HSPOLARITY(hdcmi->Init.HSPolarity)); + assert_param(IS_DCMI_SYNCHRO(hdcmi->Init.SynchroMode)); + assert_param(IS_DCMI_CAPTURE_RATE(hdcmi->Init.CaptureRate)); + assert_param(IS_DCMI_EXTENDED_DATA(hdcmi->Init.ExtendedDataMode)); + assert_param(IS_DCMI_MODE_JPEG(hdcmi->Init.JPEGMode)); + + if(hdcmi->State == HAL_DCMI_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hdcmi->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_DCMI_MspInit(hdcmi); + } + + /* Change the DCMI state */ + hdcmi->State = HAL_DCMI_STATE_BUSY; + /* Configures the HS, VS, DE and PC polarity */ + hdcmi->Instance->CR &= ~(DCMI_CR_PCKPOL | DCMI_CR_HSPOL | DCMI_CR_VSPOL | DCMI_CR_EDM_0 | + DCMI_CR_EDM_1 | DCMI_CR_FCRC_0 | DCMI_CR_FCRC_1 | DCMI_CR_JPEG | + DCMI_CR_ESS); + hdcmi->Instance->CR |= (uint32_t)(hdcmi->Init.SynchroMode | hdcmi->Init.CaptureRate | \ + hdcmi->Init.VSPolarity | hdcmi->Init.HSPolarity | \ + hdcmi->Init.PCKPolarity | hdcmi->Init.ExtendedDataMode | \ + hdcmi->Init.JPEGMode); + + if(hdcmi->Init.SynchroMode == DCMI_SYNCHRO_EMBEDDED) + { + DCMI->ESCR = (((uint32_t)hdcmi->Init.SyncroCode.FrameStartCode) | + ((uint32_t)hdcmi->Init.SyncroCode.LineStartCode << 8)| + ((uint32_t)hdcmi->Init.SyncroCode.LineEndCode << 16) | + ((uint32_t)hdcmi->Init.SyncroCode.FrameEndCode << 24)); + + } + + /* Enable the Line interrupt */ + __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_LINE); + + /* Enable the VSYNC interrupt */ + __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_VSYNC); + + /* Enable the Frame capture complete interrupt */ + __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_FRAME); + + /* Enable the Synchronization error interrupt */ + __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_ERR); + + /* Enable the Overflow interrupt */ + __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_OVF); + + /* Enable DCMI by setting DCMIEN bit */ + __HAL_DCMI_ENABLE(hdcmi); + + /* Update error code */ + hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE; + + /* Initialize the DCMI state*/ + hdcmi->State = HAL_DCMI_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Deinitializes the DCMI peripheral registers to their default reset + * values. + * @param hdcmi: pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_DCMI_DeInit(DCMI_HandleTypeDef *hdcmi) +{ + /* DeInit the low level hardware */ + HAL_DCMI_MspDeInit(hdcmi); + + /* Update error code */ + hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE; + + /* Initialize the DCMI state*/ + hdcmi->State = HAL_DCMI_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hdcmi); + + return HAL_OK; +} + +/** + * @brief Initializes the DCMI MSP. + * @param hdcmi: pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval None + */ +__weak void HAL_DCMI_MspInit(DCMI_HandleTypeDef* hdcmi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DCMI_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes the DCMI MSP. + * @param hdcmi: pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval None + */ +__weak void HAL_DCMI_MspDeInit(DCMI_HandleTypeDef* hdcmi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DCMI_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ +/** @defgroup DCMI_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure destination address and data length and + Enables DCMI DMA request and enables DCMI capture + (+) Stop the DCMI capture. + (+) Handles DCMI interrupt request. + +@endverbatim + * @{ + */ + +/** + * @brief Enables DCMI DMA request and enables DCMI capture + * @param hdcmi: pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @param DCMI_Mode: DCMI capture mode snapshot or continuous grab. + * @param pData: The destination memory Buffer address (LCD Frame buffer). + * @param Length: The length of capture to be transferred. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_Start_DMA(DCMI_HandleTypeDef* hdcmi, uint32_t DCMI_Mode, uint32_t pData, uint32_t Length) +{ + /* Initialize the second memory address */ + uint32_t SecondMemAddress = 0; + + /* Check function parameters */ + assert_param(IS_DCMI_CAPTURE_MODE(DCMI_Mode)); + + /* Process Locked */ + __HAL_LOCK(hdcmi); + + /* Lock the DCMI peripheral state */ + hdcmi->State = HAL_DCMI_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_DCMI_CAPTURE_MODE(DCMI_Mode)); + + /* Configure the DCMI Mode */ + hdcmi->Instance->CR &= ~(DCMI_CR_CM); + hdcmi->Instance->CR |= (uint32_t)(DCMI_Mode); + + /* Set the DMA memory0 conversion complete callback */ + hdcmi->DMA_Handle->XferCpltCallback = DCMI_DMAConvCplt; + + /* Set the DMA error callback */ + hdcmi->DMA_Handle->XferErrorCallback = DCMI_DMAError; + + if(Length <= 0xFFFF) + { + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)pData, Length); + } + else /* DCMI_DOUBLE_BUFFER Mode */ + { + /* Set the DMA memory1 conversion complete callback */ + hdcmi->DMA_Handle->XferM1CpltCallback = DCMI_DMAConvCplt; + + /* Initialize transfer parameters */ + hdcmi->XferCount = 1; + hdcmi->XferSize = Length; + hdcmi->pBuffPtr = pData; + + /* Get the number of buffer */ + while(hdcmi->XferSize > 0xFFFF) + { + hdcmi->XferSize = (hdcmi->XferSize/2); + hdcmi->XferCount = hdcmi->XferCount*2; + } + + /* Update DCMI counter and transfer number*/ + hdcmi->XferCount = (hdcmi->XferCount - 2); + hdcmi->XferTransferNumber = hdcmi->XferCount; + + /* Update second memory address */ + SecondMemAddress = (uint32_t)(pData + (4*hdcmi->XferSize)); + + /* Start DMA multi buffer transfer */ + HAL_DMAEx_MultiBufferStart_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)pData, SecondMemAddress, hdcmi->XferSize); + } + + /* Enable Capture */ + DCMI->CR |= DCMI_CR_CAPTURE; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Disable DCMI DMA request and Disable DCMI capture + * @param hdcmi: pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_Stop(DCMI_HandleTypeDef* hdcmi) +{ + uint32_t tickstart = 0; + + /* Lock the DCMI peripheral state */ + hdcmi->State = HAL_DCMI_STATE_BUSY; + + __HAL_DCMI_DISABLE(hdcmi); + + /* Disable Capture */ + DCMI->CR &= ~(DCMI_CR_CAPTURE); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check if the DCMI capture effectively disabled */ + while((hdcmi->Instance->CR & DCMI_CR_CAPTURE) != 0) + { + if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DCMI_STOP) + { + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + /* Update error code */ + hdcmi->ErrorCode |= HAL_DCMI_ERROR_TIMEOUT; + + /* Change DCMI state */ + hdcmi->State = HAL_DCMI_STATE_TIMEOUT; + + return HAL_TIMEOUT; + } + } + + /* Disable the DMA */ + HAL_DMA_Abort(hdcmi->DMA_Handle); + + /* Update error code */ + hdcmi->ErrorCode |= HAL_DCMI_ERROR_NONE; + + /* Change DCMI state */ + hdcmi->State = HAL_DCMI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Handles DCMI interrupt request. + * @param hdcmi: pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for the DCMI. + * @retval None + */ +void HAL_DCMI_IRQHandler(DCMI_HandleTypeDef *hdcmi) +{ + /* Synchronization error interrupt management *******************************/ + if(__HAL_DCMI_GET_FLAG(hdcmi, DCMI_FLAG_ERRRI) != RESET) + { + if(__HAL_DCMI_GET_IT_SOURCE(hdcmi, DCMI_IT_ERR) != RESET) + { + /* Disable the Synchronization error interrupt */ + __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_ERR); + + /* Clear the Synchronization error flag */ + __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_ERRRI); + + /* Update error code */ + hdcmi->ErrorCode |= HAL_DCMI_ERROR_SYNC; + + /* Change DCMI state */ + hdcmi->State = HAL_DCMI_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + /* Abort the DMA Transfer */ + HAL_DMA_Abort(hdcmi->DMA_Handle); + + /* Synchronization error Callback */ + HAL_DCMI_ErrorCallback(hdcmi); + } + } + /* Overflow interrupt management ********************************************/ + if(__HAL_DCMI_GET_FLAG(hdcmi, DCMI_FLAG_OVFRI) != RESET) + { + if(__HAL_DCMI_GET_IT_SOURCE(hdcmi, DCMI_IT_OVF) != RESET) + { + /* Disable the Overflow interrupt */ + __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_OVF); + + /* Clear the Overflow flag */ + __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_OVFRI); + + /* Update error code */ + hdcmi->ErrorCode |= HAL_DCMI_ERROR_OVF; + + /* Change DCMI state */ + hdcmi->State = HAL_DCMI_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + /* Abort the DMA Transfer */ + HAL_DMA_Abort(hdcmi->DMA_Handle); + + /* Overflow Callback */ + HAL_DCMI_ErrorCallback(hdcmi); + } + } + /* Line Interrupt management ************************************************/ + if(__HAL_DCMI_GET_FLAG(hdcmi, DCMI_FLAG_LINERI) != RESET) + { + if(__HAL_DCMI_GET_IT_SOURCE(hdcmi, DCMI_IT_LINE) != RESET) + { + /* Clear the Line interrupt flag */ + __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_LINERI); + + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + /* Line interrupt Callback */ + HAL_DCMI_LineEventCallback(hdcmi); + } + } + /* VSYNC interrupt management ***********************************************/ + if(__HAL_DCMI_GET_FLAG(hdcmi, DCMI_FLAG_VSYNCRI) != RESET) + { + if(__HAL_DCMI_GET_IT_SOURCE(hdcmi, DCMI_IT_VSYNC) != RESET) + { + /* Disable the VSYNC interrupt */ + __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_VSYNC); + + /* Clear the VSYNC flag */ + __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_VSYNCRI); + + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + /* VSYNC Callback */ + HAL_DCMI_VsyncEventCallback(hdcmi); + } + } + /* End of Frame interrupt management ****************************************/ + if(__HAL_DCMI_GET_FLAG(hdcmi, DCMI_FLAG_FRAMERI) != RESET) + { + if(__HAL_DCMI_GET_IT_SOURCE(hdcmi, DCMI_IT_FRAME) != RESET) + { + /* Disable the End of Frame interrupt */ + __HAL_DCMI_DISABLE_IT(hdcmi, DCMI_IT_FRAME); + + /* Clear the End of Frame flag */ + __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_FRAMERI); + + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + /* End of Frame Callback */ + HAL_DCMI_FrameEventCallback(hdcmi); + } + } +} + +/** + * @brief Error DCMI callback. + * @param hdcmi: pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval None + */ +__weak void HAL_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DCMI_ErrorCallback could be implemented in the user file + */ +} + +/** + * @brief Line Event callback. + * @param hdcmi: pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval None + */ +__weak void HAL_DCMI_LineEventCallback(DCMI_HandleTypeDef *hdcmi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DCMI_LineEventCallback could be implemented in the user file + */ +} + +/** + * @brief VSYNC Event callback. + * @param hdcmi: pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval None + */ +__weak void HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef *hdcmi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DCMI_VsyncEventCallback could be implemented in the user file + */ +} + +/** + * @brief Frame Event callback. + * @param hdcmi: pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval None + */ +__weak void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DCMI_FrameEventCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup DCMI_Exported_Functions_Group3 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== +[..] This section provides functions allowing to: + (+) Configure the CROP feature. + (+) Enable/Disable the CROP feature. + +@endverbatim + * @{ + */ + +/** + * @brief Configure the DCMI CROP coordinate. + * @param hdcmi: pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @param YSize: DCMI Line number + * @param XSize: DCMI Pixel per line + * @param X0: DCMI window X offset + * @param Y0: DCMI window Y offset + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_ConfigCROP(DCMI_HandleTypeDef *hdcmi, uint32_t X0, uint32_t Y0, uint32_t XSize, uint32_t YSize) +{ + /* Process Locked */ + __HAL_LOCK(hdcmi); + + /* Lock the DCMI peripheral state */ + hdcmi->State = HAL_DCMI_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_DCMI_WINDOW_COORDINATE(X0)); + assert_param(IS_DCMI_WINDOW_COORDINATE(YSize)); + assert_param(IS_DCMI_WINDOW_COORDINATE(XSize)); + assert_param(IS_DCMI_WINDOW_HEIGHT(Y0)); + + /* Configure CROP */ + DCMI->CWSIZER = (XSize | (YSize << 16)); + DCMI->CWSTRTR = (X0 | (Y0 << 16)); + + /* Initialize the DCMI state*/ + hdcmi->State = HAL_DCMI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + return HAL_OK; +} + +/** + * @brief Disable the Crop feature. + * @param hdcmi: pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_DisableCROP(DCMI_HandleTypeDef *hdcmi) +{ + /* Process Locked */ + __HAL_LOCK(hdcmi); + + /* Lock the DCMI peripheral state */ + hdcmi->State = HAL_DCMI_STATE_BUSY; + + /* Disable DCMI Crop feature */ + DCMI->CR &= ~(uint32_t)DCMI_CR_CROP; + + /* Change the DCMI state*/ + hdcmi->State = HAL_DCMI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + return HAL_OK; +} + +/** + * @brief Enable the Crop feature. + * @param hdcmi: pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_EnableCROP(DCMI_HandleTypeDef *hdcmi) +{ + /* Process Locked */ + __HAL_LOCK(hdcmi); + + /* Lock the DCMI peripheral state */ + hdcmi->State = HAL_DCMI_STATE_BUSY; + + /* Enable DCMI Crop feature */ + DCMI->CR |= (uint32_t)DCMI_CR_CROP; + + /* Change the DCMI state*/ + hdcmi->State = HAL_DCMI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup DCMI_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to + (+) Check the DCMI state. + (+) Get the specific DCMI error flag. + +@endverbatim + * @{ + */ + +/** + * @brief Return the DCMI state + * @param hdcmi: pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval HAL state + */ +HAL_DCMI_StateTypeDef HAL_DCMI_GetState(DCMI_HandleTypeDef *hdcmi) +{ + return hdcmi->State; +} + +/** +* @brief Return the DCMI error code +* @param hdcmi : pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. +* @retval DCMI Error Code +*/ +uint32_t HAL_DCMI_GetError(DCMI_HandleTypeDef *hdcmi) +{ + return hdcmi->ErrorCode; +} + +/** + * @} + */ +/* Private functions ---------------------------------------------------------*/ +/** @defgroup DCMI_Private_Functions DCMI Private Functions + * @{ + */ + + /** + * @brief DMA conversion complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void DCMI_DMAConvCplt(DMA_HandleTypeDef *hdma) +{ + uint32_t tmp = 0; + + DCMI_HandleTypeDef* hdcmi = ( DCMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + hdcmi->State= HAL_DCMI_STATE_READY; + + if(hdcmi->XferCount != 0) + { + /* Update memory 0 address location */ + tmp = ((hdcmi->DMA_Handle->Instance->CR) & DMA_SxCR_CT); + if(((hdcmi->XferCount % 2) == 0) && (tmp != 0)) + { + tmp = hdcmi->DMA_Handle->Instance->M0AR; + HAL_DMAEx_ChangeMemory(hdcmi->DMA_Handle, (tmp + (8*hdcmi->XferSize)), MEMORY0); + hdcmi->XferCount--; + } + /* Update memory 1 address location */ + else if((hdcmi->DMA_Handle->Instance->CR & DMA_SxCR_CT) == 0) + { + tmp = hdcmi->DMA_Handle->Instance->M1AR; + HAL_DMAEx_ChangeMemory(hdcmi->DMA_Handle, (tmp + (8*hdcmi->XferSize)), MEMORY1); + hdcmi->XferCount--; + } + } + /* Update memory 0 address location */ + else if((hdcmi->DMA_Handle->Instance->CR & DMA_SxCR_CT) != 0) + { + hdcmi->DMA_Handle->Instance->M0AR = hdcmi->pBuffPtr; + } + /* Update memory 1 address location */ + else if((hdcmi->DMA_Handle->Instance->CR & DMA_SxCR_CT) == 0) + { + tmp = hdcmi->pBuffPtr; + hdcmi->DMA_Handle->Instance->M1AR = (tmp + (4*hdcmi->XferSize)); + hdcmi->XferCount = hdcmi->XferTransferNumber; + } + + if(__HAL_DCMI_GET_FLAG(hdcmi, DCMI_FLAG_FRAMERI) != RESET) + { + /* Process Unlocked */ + __HAL_UNLOCK(hdcmi); + + /* FRAME Callback */ + HAL_DCMI_FrameEventCallback(hdcmi); + } +} + +/** + * @brief DMA error callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void DCMI_DMAError(DMA_HandleTypeDef *hdma) +{ + DCMI_HandleTypeDef* hdcmi = ( DCMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + hdcmi->State= HAL_DCMI_STATE_READY; + HAL_DCMI_ErrorCallback(hdcmi); +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\ + STM32F429xx || STM32F439xx || STM32F446xx */ +#endif /* HAL_DCMI_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dcmi_ex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dcmi_ex.c new file mode 100644 index 0000000..4cc2d45 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dcmi_ex.c @@ -0,0 +1,212 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_dcmi_ex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief DCMI Extension HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of DCMI extension peripheral: + * + Extension features functions + * + @verbatim + ============================================================================== + ##### DCMI peripheral extension features ##### + ============================================================================== + + [..] Comparing to other previous devices, the DCMI interface for STM32F446xx + devices contains the following additional features : + + (+) Support of Black and White cameras + + ##### How to use this driver ##### + ============================================================================== + [..] This driver provides functions to manage the Black and White feature + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 DCMI DCMI + * @brief DCMI HAL module driver + * @{ + */ + +#ifdef HAL_DCMI_MODULE_ENABLED + +#if defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup DCMIEx_Exported_Functions DCMI Extended Exported Functions + * @{ + */ + +/** @defgroup DCMIEx_Exported_Functions_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initialize and configure the DCMI + (+) De-initialize the DCMI + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the DCMI according to the specified + * parameters in the DCMI_InitTypeDef and create the associated handle. + * @param hdcmi: pointer to a DCMI_HandleTypeDef structure that contains + * the configuration information for DCMI. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DCMI_Init(DCMI_HandleTypeDef *hdcmi) +{ + /* Check the DCMI peripheral state */ + if(hdcmi == NULL) + { + return HAL_ERROR; + } + + /* Check function parameters */ + assert_param(IS_DCMI_ALL_INSTANCE(hdcmi->Instance)); + assert_param(IS_DCMI_PCKPOLARITY(hdcmi->Init.PCKPolarity)); + assert_param(IS_DCMI_VSPOLARITY(hdcmi->Init.VSPolarity)); + assert_param(IS_DCMI_HSPOLARITY(hdcmi->Init.HSPolarity)); + assert_param(IS_DCMI_SYNCHRO(hdcmi->Init.SynchroMode)); + assert_param(IS_DCMI_CAPTURE_RATE(hdcmi->Init.CaptureRate)); + assert_param(IS_DCMI_EXTENDED_DATA(hdcmi->Init.ExtendedDataMode)); + assert_param(IS_DCMI_MODE_JPEG(hdcmi->Init.JPEGMode)); +#if defined(STM32F446xx) + assert_param(IS_DCMI_BYTE_SELECT_MODE(hdcmi->Init.ByteSelectMode)); + assert_param(IS_DCMI_BYTE_SELECT_START(hdcmi->Init.ByteSelectStart)); + assert_param(IS_DCMI_LINE_SELECT_MODE(hdcmi->Init.LineSelectMode)); + assert_param(IS_DCMI_LINE_SELECT_START(hdcmi->Init.LineSelectStart)); +#endif + if(hdcmi->State == HAL_DCMI_STATE_RESET) + { + /* Init the low level hardware */ + HAL_DCMI_MspInit(hdcmi); + } + + /* Change the DCMI state */ + hdcmi->State = HAL_DCMI_STATE_BUSY; + /* Configures the HS, VS, DE and PC polarity */ + hdcmi->Instance->CR &= ~(DCMI_CR_PCKPOL | DCMI_CR_HSPOL | DCMI_CR_VSPOL | DCMI_CR_EDM_0 |\ + DCMI_CR_EDM_1 | DCMI_CR_FCRC_0 | DCMI_CR_FCRC_1 | DCMI_CR_JPEG |\ + DCMI_CR_ESS +#if defined(STM32F446xx) + | DCMI_CR_BSM_0 | DCMI_CR_BSM_1 | DCMI_CR_OEBS |\ + DCMI_CR_LSM | DCMI_CR_OELS +#endif + ); + hdcmi->Instance->CR |= (uint32_t)(hdcmi->Init.SynchroMode | hdcmi->Init.CaptureRate |\ + hdcmi->Init.VSPolarity | hdcmi->Init.HSPolarity |\ + hdcmi->Init.PCKPolarity | hdcmi->Init.ExtendedDataMode |\ + hdcmi->Init.JPEGMode +#if defined(STM32F446xx) + | hdcmi->Init.ByteSelectMode |\ + hdcmi->Init.ByteSelectStart | hdcmi->Init.LineSelectMode |\ + hdcmi->Init.LineSelectStart +#endif + ); + if(hdcmi->Init.SynchroMode == DCMI_SYNCHRO_EMBEDDED) + { + DCMI->ESCR = (((uint32_t)hdcmi->Init.SyncroCode.FrameStartCode) | + ((uint32_t)hdcmi->Init.SyncroCode.LineStartCode << 8)| + ((uint32_t)hdcmi->Init.SyncroCode.LineEndCode << 16) | + ((uint32_t)hdcmi->Init.SyncroCode.FrameEndCode << 24)); + + } + + /* Enable the Line interrupt */ + __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_LINE); + + /* Enable the VSYNC interrupt */ + __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_VSYNC); + + /* Enable the Frame capture complete interrupt */ + __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_FRAME); + + /* Enable the Synchronization error interrupt */ + __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_ERR); + + /* Enable the Overflow interrupt */ + __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_OVF); + + /* Enable DCMI by setting DCMIEN bit */ + __HAL_DCMI_ENABLE(hdcmi); + + /* Update error code */ + hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE; + + /* Initialize the DCMI state*/ + hdcmi->State = HAL_DCMI_STATE_READY; + + return HAL_OK; +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ +#endif /* HAL_DCMI_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c new file mode 100644 index 0000000..c53f314 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c @@ -0,0 +1,928 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_dma.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief DMA HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the Direct Memory Access (DMA) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State and errors functions + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Enable and configure the peripheral to be connected to the DMA Stream + (except for internal SRAM/FLASH memories: no initialization is + necessary) please refer to Reference manual for connection between peripherals + and DMA requests . + + (#) For a given Stream, program the required configuration through the following parameters: + Transfer Direction, Source and Destination data formats, + Circular, Normal or peripheral flow control mode, Stream Priority level, + Source and Destination Increment mode, FIFO mode and its Threshold (if needed), + Burst mode for Source and/or Destination (if needed) using HAL_DMA_Init() function. + + *** Polling mode IO operation *** + ================================= + [..] + (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source + address and destination address and the Length of data to be transferred + (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this + case a fixed Timeout can be configured by User depending from his application. + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority() + (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ() + (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of + Source address and destination address and the Length of data to be transferred. In this + case the DMA interrupt is configured + (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine + (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can + add his own function by customization of function pointer XferCpltCallback and + XferErrorCallback (i.e a member of DMA handle structure). + [..] + (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error + detection. + + (#) Use HAL_DMA_Abort() function to abort the current transfer + + -@- In Memory-to-Memory transfer mode, Circular mode is not allowed. + + -@- The FIFO is used mainly to reduce bus usage and to allow data packing/unpacking: it is + possible to set different Data Sizes for the Peripheral and the Memory (ie. you can set + Half-Word data size for the peripheral to access its data register and set Word data size + for the Memory to gain in access time. Each two half words will be packed and written in + a single access to a Word in the Memory). + + -@- When FIFO is disabled, it is not allowed to configure different Data Sizes for Source + and Destination. In this case the Peripheral Data Size will be applied to both Source + and Destination. + + *** DMA HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in DMA HAL driver. + + (+) __HAL_DMA_ENABLE: Enable the specified DMA Stream. + (+) __HAL_DMA_DISABLE: Disable the specified DMA Stream. + (+) __HAL_DMA_GET_FS: Return the current DMA Stream FIFO filled level. + (+) __HAL_DMA_GET_FLAG: Get the DMA Stream pending flags. + (+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Stream pending flags. + (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Stream interrupts. + (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Stream interrupts. + (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Stream interrupt has occurred or not. + + [..] + (@) You can refer to the DMA HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 DMA DMA + * @brief DMA HAL module driver + * @{ + */ + +#ifdef HAL_DMA_MODULE_ENABLED + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @addtogroup DMA_Private_Constants + * @{ + */ + #define HAL_TIMEOUT_DMA_ABORT ((uint32_t)1000) /* 1s */ +/** + * @} + */ +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup DMA_Private_Functions + * @{ + */ +static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength); +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ +/** @addtogroup DMA_Exported_Functions + * @{ + */ + +/** @addtogroup DMA_Exported_Functions_Group1 + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] + This section provides functions allowing to initialize the DMA Stream source + and destination addresses, incrementation and data sizes, transfer direction, + circular/normal mode selection, memory-to-memory mode selection and Stream priority value. + [..] + The HAL_DMA_Init() function follows the DMA configuration procedures as described in + reference manual. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the DMA according to the specified + * parameters in the DMA_InitTypeDef and create the associated handle. + * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma) +{ + uint32_t tmp = 0; + + /* Check the DMA peripheral state */ + if(hdma == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA_STREAM_ALL_INSTANCE(hdma->Instance)); + assert_param(IS_DMA_CHANNEL(hdma->Init.Channel)); + assert_param(IS_DMA_DIRECTION(hdma->Init.Direction)); + assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc)); + assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc)); + assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment)); + assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment)); + assert_param(IS_DMA_MODE(hdma->Init.Mode)); + assert_param(IS_DMA_PRIORITY(hdma->Init.Priority)); + assert_param(IS_DMA_FIFO_MODE_STATE(hdma->Init.FIFOMode)); + /* Check the memory burst, peripheral burst and FIFO threshold parameters only + when FIFO mode is enabled */ + if(hdma->Init.FIFOMode != DMA_FIFOMODE_DISABLE) + { + assert_param(IS_DMA_FIFO_THRESHOLD(hdma->Init.FIFOThreshold)); + assert_param(IS_DMA_MEMORY_BURST(hdma->Init.MemBurst)); + assert_param(IS_DMA_PERIPHERAL_BURST(hdma->Init.PeriphBurst)); + } + + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_BUSY; + + /* Get the CR register value */ + tmp = hdma->Instance->CR; + + /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, CT and DBM bits */ + tmp &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \ + DMA_SxCR_PL | DMA_SxCR_MSIZE | DMA_SxCR_PSIZE | \ + DMA_SxCR_MINC | DMA_SxCR_PINC | DMA_SxCR_CIRC | \ + DMA_SxCR_DIR | DMA_SxCR_CT | DMA_SxCR_DBM)); + + /* Prepare the DMA Stream configuration */ + tmp |= hdma->Init.Channel | hdma->Init.Direction | + hdma->Init.PeriphInc | hdma->Init.MemInc | + hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment | + hdma->Init.Mode | hdma->Init.Priority; + + /* the Memory burst and peripheral burst are not used when the FIFO is disabled */ + if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE) + { + /* Get memory burst and peripheral burst */ + tmp |= hdma->Init.MemBurst | hdma->Init.PeriphBurst; + } + + /* Write to DMA Stream CR register */ + hdma->Instance->CR = tmp; + + /* Get the FCR register value */ + tmp = hdma->Instance->FCR; + + /* Clear Direct mode and FIFO threshold bits */ + tmp &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH); + + /* Prepare the DMA Stream FIFO configuration */ + tmp |= hdma->Init.FIFOMode; + + /* the FIFO threshold is not used when the FIFO mode is disabled */ + if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE) + { + /* Get the FIFO threshold */ + tmp |= hdma->Init.FIFOThreshold; + } + + /* Write to DMA Stream FCR */ + hdma->Instance->FCR = tmp; + + /* Initialize the error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Initialize the DMA state */ + hdma->State = HAL_DMA_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the DMA peripheral + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma) +{ + /* Check the DMA peripheral state */ + if(hdma == NULL) + { + return HAL_ERROR; + } + + /* Check the DMA peripheral state */ + if(hdma->State == HAL_DMA_STATE_BUSY) + { + return HAL_ERROR; + } + + /* Disable the selected DMA Streamx */ + __HAL_DMA_DISABLE(hdma); + + /* Reset DMA Streamx control register */ + hdma->Instance->CR = 0; + + /* Reset DMA Streamx number of data to transfer register */ + hdma->Instance->NDTR = 0; + + /* Reset DMA Streamx peripheral address register */ + hdma->Instance->PAR = 0; + + /* Reset DMA Streamx memory 0 address register */ + hdma->Instance->M0AR = 0; + + /* Reset DMA Streamx memory 1 address register */ + hdma->Instance->M1AR = 0; + + /* Reset DMA Streamx FIFO control register */ + hdma->Instance->FCR = (uint32_t)0x00000021; + + /* Clear all flags */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)); + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)); + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); + + /* Initialize the error code */ + hdma->ErrorCode = HAL_DMA_ERROR_NONE; + + /* Initialize the DMA state */ + hdma->State = HAL_DMA_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hdma); + + return HAL_OK; +} + +/** + * @} + */ + +/** @addtogroup DMA_Exported_Functions_Group2 + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure the source, destination address and data length and Start DMA transfer + (+) Configure the source, destination address and data length and + Start DMA transfer with interrupt + (+) Abort DMA transfer + (+) Poll for transfer complete + (+) Handle DMA interrupt request + +@endverbatim + * @{ + */ + +/** + * @brief Starts the DMA Transfer. + * @param hdma : pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @param SrcAddress: The source memory Buffer address + * @param DstAddress: The destination memory Buffer address + * @param DataLength: The length of data to be transferred from source to destination + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) +{ + /* Process locked */ + __HAL_LOCK(hdma); + + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_DMA_BUFFER_SIZE(DataLength)); + + /* Disable the peripheral */ + __HAL_DMA_DISABLE(hdma); + + /* Configure the source, destination address and the data length */ + DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); + + /* Enable the Peripheral */ + __HAL_DMA_ENABLE(hdma); + + return HAL_OK; +} + +/** + * @brief Start the DMA Transfer with interrupt enabled. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @param SrcAddress: The source memory Buffer address + * @param DstAddress: The destination memory Buffer address + * @param DataLength: The length of data to be transferred from source to destination + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) +{ + /* Process locked */ + __HAL_LOCK(hdma); + + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_DMA_BUFFER_SIZE(DataLength)); + + /* Disable the peripheral */ + __HAL_DMA_DISABLE(hdma); + + /* Configure the source, destination address and the data length */ + DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); + + /* Enable the transfer complete interrupt */ + __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC); + + /* Enable the Half transfer complete interrupt */ +// __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT); + + /* Enable the transfer Error interrupt */ + __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE); + + /* Enable the FIFO Error interrupt */ + __HAL_DMA_ENABLE_IT(hdma, DMA_IT_FE); + + /* Enable the direct mode Error interrupt */ + __HAL_DMA_ENABLE_IT(hdma, DMA_IT_DME); + + /* Enable the Peripheral */ + __HAL_DMA_ENABLE(hdma); + + return HAL_OK; +} + +/** + * @brief Aborts the DMA Transfer. + * @param hdma : pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * + * @note After disabling a DMA Stream, a check for wait until the DMA Stream is + * effectively disabled is added. If a Stream is disabled + * while a data transfer is ongoing, the current data will be transferred + * and the Stream will be effectively disabled only after the transfer of + * this single data is finished. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma) +{ + uint32_t tickstart = 0; + + /* Disable the stream */ + __HAL_DMA_DISABLE(hdma); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check if the DMA Stream is effectively disabled */ + while((hdma->Instance->CR & DMA_SxCR_EN) != 0) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT) + { + /* Update error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_TIMEOUT; + + return HAL_TIMEOUT; + } + } + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + /* Change the DMA state*/ + hdma->State = HAL_DMA_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Polling for transfer complete. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @param CompleteLevel: Specifies the DMA level complete. + * @param Timeout: Timeout duration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout) +{ + uint32_t temp, tmp, tmp1, tmp2; + uint32_t tickstart = 0; + + /* Get the level transfer complete flag */ + if(CompleteLevel == HAL_DMA_FULL_TRANSFER) + { + /* Transfer Complete flag */ + temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma); + } + else + { + /* Half Transfer Complete flag */ + temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma); + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET) + { + tmp = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); + tmp1 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)); + tmp2 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)); + if((tmp != RESET) || (tmp1 != RESET) || (tmp2 != RESET)) + { + if(tmp != RESET) + { + /* Update error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_TE; + + /* Clear the transfer error flag */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); + } + if(tmp1 != RESET) + { + /* Update error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_FE; + + /* Clear the FIFO error flag */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)); + } + if(tmp2 != RESET) + { + /* Update error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_DME; + + /* Clear the Direct Mode error flag */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)); + } + /* Change the DMA state */ + hdma->State= HAL_DMA_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_ERROR; + } + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Update error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT; + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + return HAL_TIMEOUT; + } + } + } + + if(CompleteLevel == HAL_DMA_FULL_TRANSFER) + { + /* Multi_Buffering mode enabled */ + if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0) + { + /* Clear the half transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); + /* Clear the transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); + + /* Current memory buffer used is Memory 0 */ + if((hdma->Instance->CR & DMA_SxCR_CT) == 0) + { + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_READY_MEM0; + } + /* Current memory buffer used is Memory 1 */ + else if((hdma->Instance->CR & DMA_SxCR_CT) != 0) + { + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_READY_MEM1; + } + } + else + { + /* Clear the half transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); + /* Clear the transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); + + /* The selected Streamx EN bit is cleared (DMA is disabled and all transfers + are complete) */ + hdma->State = HAL_DMA_STATE_READY_MEM0; + } + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + } + else + { + /* Multi_Buffering mode enabled */ + if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0) + { + /* Clear the half transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); + + /* Current memory buffer used is Memory 0 */ + if((hdma->Instance->CR & DMA_SxCR_CT) == 0) + { + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_READY_HALF_MEM0; + } + /* Current memory buffer used is Memory 1 */ + else if((hdma->Instance->CR & DMA_SxCR_CT) != 0) + { + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_READY_HALF_MEM1; + } + } + else + { + /* Clear the half transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); + + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_READY_HALF_MEM0; + } + } + return HAL_OK; +} + +/** + * @brief Handles DMA interrupt request. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @retval None + */ +void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma) +{ + /* Transfer Error Interrupt management ***************************************/ + if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET) + { + /* Disable the transfer error interrupt */ + __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE); + + /* Clear the transfer error flag */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); + + /* Update error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_TE; + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + if(hdma->XferErrorCallback != NULL) + { + /* Transfer error callback */ + hdma->XferErrorCallback(hdma); + } + } + } + /* FIFO Error Interrupt management ******************************************/ + if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET) + { + /* Disable the FIFO Error interrupt */ + __HAL_DMA_DISABLE_IT(hdma, DMA_IT_FE); + + /* Clear the FIFO error flag */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)); + + /* Update error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_FE; + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + if(hdma->XferErrorCallback != NULL) + { + /* Transfer error callback */ + hdma->XferErrorCallback(hdma); + } + } + } + /* Direct Mode Error Interrupt management ***********************************/ + if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET) + { + /* Disable the direct mode Error interrupt */ + __HAL_DMA_DISABLE_IT(hdma, DMA_IT_DME); + + /* Clear the direct mode error flag */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)); + + /* Update error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_DME; + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + if(hdma->XferErrorCallback != NULL) + { + /* Transfer error callback */ + hdma->XferErrorCallback(hdma); + } + } + } + /* Half Transfer Complete Interrupt management ******************************/ + if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET) + { + /* Multi_Buffering mode enabled */ + if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0) + { + /* Clear the half transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); + + /* Current memory buffer used is Memory 0 */ + if((hdma->Instance->CR & DMA_SxCR_CT) == 0) + { + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_READY_HALF_MEM0; + } + /* Current memory buffer used is Memory 1 */ + else if((hdma->Instance->CR & DMA_SxCR_CT) != 0) + { + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_READY_HALF_MEM1; + } + } + else + { + /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */ + if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) + { + /* Disable the half transfer interrupt */ + __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT); + } + /* Clear the half transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); + + /* Change DMA peripheral state */ + hdma->State = HAL_DMA_STATE_READY_HALF_MEM0; + } + + if(hdma->XferHalfCpltCallback != NULL) + { + /* Half transfer callback */ + hdma->XferHalfCpltCallback(hdma); + } + } + } + /* Transfer Complete Interrupt management ***********************************/ + if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET) + { + if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET) + { + if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0) + { + /* Clear the transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); + + /* Current memory buffer used is Memory 1 */ + if((hdma->Instance->CR & DMA_SxCR_CT) == 0) + { + if(hdma->XferM1CpltCallback != NULL) + { + /* Transfer complete Callback for memory1 */ + hdma->XferM1CpltCallback(hdma); + } + } + /* Current memory buffer used is Memory 0 */ + else if((hdma->Instance->CR & DMA_SxCR_CT) != 0) + { + if(hdma->XferCpltCallback != NULL) + { + /* Transfer complete Callback for memory0 */ + hdma->XferCpltCallback(hdma); + } + } + } + /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */ + else + { + if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) + { + /* Disable the transfer complete interrupt */ + __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC); + } + /* Clear the transfer complete flag */ + __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); + + /* Update error code */ + hdma->ErrorCode |= HAL_DMA_ERROR_NONE; + + /* Change the DMA state */ + hdma->State = HAL_DMA_STATE_READY_MEM0; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma); + + if(hdma->XferCpltCallback != NULL) + { + /* Transfer complete callback */ + hdma->XferCpltCallback(hdma); + } + } + } + } +} + +/** + * @} + */ + +/** @addtogroup DMA_Exported_Functions_Group3 + * +@verbatim + =============================================================================== + ##### State and Errors functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to + (+) Check the DMA state + (+) Get error code + +@endverbatim + * @{ + */ + +/** + * @brief Returns the DMA state. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @retval HAL state + */ +HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma) +{ + return hdma->State; +} + +/** + * @brief Return the DMA error code + * @param hdma : pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @retval DMA Error Code + */ +uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma) +{ + return hdma->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup DMA_Private_Functions + * @{ + */ + +/** + * @brief Sets the DMA Transfer parameter. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @param SrcAddress: The source memory Buffer address + * @param DstAddress: The destination memory Buffer address + * @param DataLength: The length of data to be transferred from source to destination + * @retval HAL status + */ +static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) +{ + /* Clear DBM bit */ + hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM); + + /* Configure DMA Stream data length */ + hdma->Instance->NDTR = DataLength; + + /* Peripheral to Memory */ + if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) + { + /* Configure DMA Stream destination address */ + hdma->Instance->PAR = DstAddress; + + /* Configure DMA Stream source address */ + hdma->Instance->M0AR = SrcAddress; + } + /* Memory to Peripheral */ + else + { + /* Configure DMA Stream source address */ + hdma->Instance->PAR = SrcAddress; + + /* Configure DMA Stream destination address */ + hdma->Instance->M0AR = DstAddress; + } +} +/** + * @} + */ + +#endif /* HAL_DMA_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c new file mode 100644 index 0000000..a41cb31 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c @@ -0,0 +1,1266 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_dma2d.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief DMA2D HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the DMA2D peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Errors functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Program the required configuration through following parameters: + the Transfer Mode, the output color mode and the output offset using + HAL_DMA2D_Init() function. + + (#) Program the required configuration through following parameters: + the input color mode, the input color, input alpha value, alpha mode + and the input offset using HAL_DMA2D_ConfigLayer() function for foreground + or/and background layer. + + *** Polling mode IO operation *** + ================================= + [..] + (+) Configure the pdata, Destination and data length and Enable + the transfer using HAL_DMA2D_Start() + (+) Wait for end of transfer using HAL_DMA2D_PollForTransfer(), at this stage + user can specify the value of timeout according to his end application. + + *** Interrupt mode IO operation *** + =================================== + [..] + (#) Configure the pdata, Destination and data length and Enable + the transfer using HAL_DMA2D_Start_IT() + (#) Use HAL_DMA2D_IRQHandler() called under DMA2D_IRQHandler() Interrupt subroutine + (#) At the end of data transfer HAL_DMA2D_IRQHandler() function is executed and user can + add his own function by customization of function pointer XferCpltCallback and + XferErrorCallback (i.e a member of DMA2D handle structure). + + -@- In Register-to-Memory transfer mode, the pdata parameter is the register + color, in Memory-to-memory or memory-to-memory with pixel format + conversion the pdata is the source address. + + -@- Configure the foreground source address, the background source address, + the Destination and data length and Enable the transfer using + HAL_DMA2D_BlendingStart() in polling mode and HAL_DMA2D_BlendingStart_IT() + in interrupt mode. + + -@- HAL_DMA2D_BlendingStart() and HAL_DMA2D_BlendingStart_IT() functions + are used if the memory to memory with blending transfer mode is selected. + + (#) Optionally, configure and enable the CLUT using HAL_DMA2D_ConfigCLUT() + HAL_DMA2D_EnableCLUT() functions. + + (#) Optionally, configure and enable LineInterrupt using the following function: + HAL_DMA2D_ProgramLineEvent(). + + (#) The transfer can be suspended, continued and aborted using the following + functions: HAL_DMA2D_Suspend(), HAL_DMA2D_Resume(), HAL_DMA2D_Abort(). + + (#) To control DMA2D state you can use the following function: HAL_DMA2D_GetState() + + *** DMA2D HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in DMA2D HAL driver : + + (+) __HAL_DMA2D_ENABLE: Enable the DMA2D peripheral. + (+) __HAL_DMA2D_DISABLE: Disable the DMA2D peripheral. + (+) __HAL_DMA2D_GET_FLAG: Get the DMA2D pending flags. + (+) __HAL_DMA2D_CLEAR_FLAG: Clear the DMA2D pending flags. + (+) __HAL_DMA2D_ENABLE_IT: Enable the specified DMA2D interrupts. + (+) __HAL_DMA2D_DISABLE_IT: Disable the specified DMA2D interrupts. + (+) __HAL_DMA2D_GET_IT_SOURCE: Check whether the specified DMA2D interrupt has occurred or not. + + [..] + (@) You can refer to the DMA2D HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 + * @{ + */ +/** @addtogroup DMA2D + * @brief DMA2D HAL module driver + * @{ + */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + +/* Private types -------------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup DMA2D_Private_Defines + * @{ + */ +#define HAL_TIMEOUT_DMA2D_ABORT ((uint32_t)1000) /* 1s */ +#define HAL_TIMEOUT_DMA2D_SUSPEND ((uint32_t)1000) /* 1s */ +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup DMA2D_Private_Functions_Prototypes + * @{ + */ +static void DMA2D_SetConfig(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width, uint32_t Height); +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup DMA2D_Exported_Functions + * @{ + */ + +/** @defgroup DMA2D_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initialize and configure the DMA2D + (+) De-initialize the DMA2D + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the DMA2D according to the specified + * parameters in the DMA2D_InitTypeDef and create the associated handle. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_Init(DMA2D_HandleTypeDef *hdma2d) +{ + uint32_t tmp = 0; + + /* Check the DMA2D peripheral state */ + if(hdma2d == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_DMA2D_ALL_INSTANCE(hdma2d->Instance)); + assert_param(IS_DMA2D_MODE(hdma2d->Init.Mode)); + assert_param(IS_DMA2D_CMODE(hdma2d->Init.ColorMode)); + assert_param(IS_DMA2D_OFFSET(hdma2d->Init.OutputOffset)); + + if(hdma2d->State == HAL_DMA2D_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hdma2d->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_DMA2D_MspInit(hdma2d); + } + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + +/* DMA2D CR register configuration -------------------------------------------*/ + /* Get the CR register value */ + tmp = hdma2d->Instance->CR; + + /* Clear Mode bits */ + tmp &= (uint32_t)~DMA2D_CR_MODE; + + /* Prepare the value to be wrote to the CR register */ + tmp |= hdma2d->Init.Mode; + + /* Write to DMA2D CR register */ + hdma2d->Instance->CR = tmp; + +/* DMA2D OPFCCR register configuration ---------------------------------------*/ + /* Get the OPFCCR register value */ + tmp = hdma2d->Instance->OPFCCR; + + /* Clear Color Mode bits */ + tmp &= (uint32_t)~DMA2D_OPFCCR_CM; + + /* Prepare the value to be wrote to the OPFCCR register */ + tmp |= hdma2d->Init.ColorMode; + + /* Write to DMA2D OPFCCR register */ + hdma2d->Instance->OPFCCR = tmp; + +/* DMA2D OOR register configuration ------------------------------------------*/ + /* Get the OOR register value */ + tmp = hdma2d->Instance->OOR; + + /* Clear Offset bits */ + tmp &= (uint32_t)~DMA2D_OOR_LO; + + /* Prepare the value to be wrote to the OOR register */ + tmp |= hdma2d->Init.OutputOffset; + + /* Write to DMA2D OOR register */ + hdma2d->Instance->OOR = tmp; + + /* Update error code */ + hdma2d->ErrorCode = HAL_DMA2D_ERROR_NONE; + + /* Initialize the DMA2D state*/ + hdma2d->State = HAL_DMA2D_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Deinitializes the DMA2D peripheral registers to their default reset + * values. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval None + */ + +HAL_StatusTypeDef HAL_DMA2D_DeInit(DMA2D_HandleTypeDef *hdma2d) +{ + /* Check the DMA2D peripheral state */ + if(hdma2d == NULL) + { + return HAL_ERROR; + } + + /* DeInit the low level hardware */ + HAL_DMA2D_MspDeInit(hdma2d); + + /* Update error code */ + hdma2d->ErrorCode = HAL_DMA2D_ERROR_NONE; + + /* Initialize the DMA2D state*/ + hdma2d->State = HAL_DMA2D_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hdma2d); + + return HAL_OK; +} + +/** + * @brief Initializes the DMA2D MSP. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval None + */ +__weak void HAL_DMA2D_MspInit(DMA2D_HandleTypeDef* hdma2d) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DMA2D_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes the DMA2D MSP. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval None + */ +__weak void HAL_DMA2D_MspDeInit(DMA2D_HandleTypeDef* hdma2d) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_DMA2D_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup DMA2D_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure the pdata, destination address and data size and + Start DMA2D transfer. + (+) Configure the source for foreground and background, destination address + and data size and Start MultiBuffer DMA2D transfer. + (+) Configure the pdata, destination address and data size and + Start DMA2D transfer with interrupt. + (+) Configure the source for foreground and background, destination address + and data size and Start MultiBuffer DMA2D transfer with interrupt. + (+) Abort DMA2D transfer. + (+) Suspend DMA2D transfer. + (+) Continue DMA2D transfer. + (+) Poll for transfer complete. + (+) handle DMA2D interrupt request. + +@endverbatim + * @{ + */ + +/** + * @brief Start the DMA2D Transfer. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param pdata: Configure the source memory Buffer address if + * the memory to memory or memory to memory with pixel format + * conversion DMA2D mode is selected, and configure + * the color value if register to memory DMA2D mode is selected. + * @param DstAddress: The destination memory Buffer address. + * @param Width: The width of data to be transferred from source to destination. + * @param Height: The height of data to be transferred from source to destination. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_Start(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width, uint32_t Height) +{ + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_DMA2D_LINE(Height)); + assert_param(IS_DMA2D_PIXEL(Width)); + + /* Disable the Peripheral */ + __HAL_DMA2D_DISABLE(hdma2d); + + /* Configure the source, destination address and the data size */ + DMA2D_SetConfig(hdma2d, pdata, DstAddress, Width, Height); + + /* Enable the Peripheral */ + __HAL_DMA2D_ENABLE(hdma2d); + + return HAL_OK; +} + +/** + * @brief Start the DMA2D Transfer with interrupt enabled. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param pdata: Configure the source memory Buffer address if + * the memory to memory or memory to memory with pixel format + * conversion DMA2D mode is selected, and configure + * the color value if register to memory DMA2D mode is selected. + * @param DstAddress: The destination memory Buffer address. + * @param Width: The width of data to be transferred from source to destination. + * @param Height: The height of data to be transferred from source to destination. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_Start_IT(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width, uint32_t Height) +{ + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_DMA2D_LINE(Height)); + assert_param(IS_DMA2D_PIXEL(Width)); + + /* Disable the Peripheral */ + __HAL_DMA2D_DISABLE(hdma2d); + + /* Configure the source, destination address and the data size */ + DMA2D_SetConfig(hdma2d, pdata, DstAddress, Width, Height); + + /* Enable the transfer complete interrupt */ + __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_TC); + + /* Enable the transfer Error interrupt */ + __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_TE); + + /* Enable the Peripheral */ + __HAL_DMA2D_ENABLE(hdma2d); + + /* Enable the configuration error interrupt */ + __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_CE); + + return HAL_OK; +} + +/** + * @brief Start the multi-source DMA2D Transfer. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param SrcAddress1: The source memory Buffer address of the foreground layer. + * @param SrcAddress2: The source memory Buffer address of the background layer. + * @param DstAddress: The destination memory Buffer address + * @param Width: The width of data to be transferred from source to destination. + * @param Height: The height of data to be transferred from source to destination. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_BlendingStart(DMA2D_HandleTypeDef *hdma2d, uint32_t SrcAddress1, uint32_t SrcAddress2, uint32_t DstAddress, uint32_t Width, uint32_t Height) +{ + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_DMA2D_LINE(Height)); + assert_param(IS_DMA2D_PIXEL(Width)); + + /* Disable the Peripheral */ + __HAL_DMA2D_DISABLE(hdma2d); + + /* Configure DMA2D Stream source2 address */ + hdma2d->Instance->BGMAR = SrcAddress2; + + /* Configure the source, destination address and the data size */ + DMA2D_SetConfig(hdma2d, SrcAddress1, DstAddress, Width, Height); + + /* Enable the Peripheral */ + __HAL_DMA2D_ENABLE(hdma2d); + + return HAL_OK; +} + +/** + * @brief Start the multi-source DMA2D Transfer with interrupt enabled. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param SrcAddress1: The source memory Buffer address of the foreground layer. + * @param SrcAddress2: The source memory Buffer address of the background layer. + * @param DstAddress: The destination memory Buffer address. + * @param Width: The width of data to be transferred from source to destination. + * @param Height: The height of data to be transferred from source to destination. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_BlendingStart_IT(DMA2D_HandleTypeDef *hdma2d, uint32_t SrcAddress1, uint32_t SrcAddress2, uint32_t DstAddress, uint32_t Width, uint32_t Height) +{ + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_DMA2D_LINE(Height)); + assert_param(IS_DMA2D_PIXEL(Width)); + + /* Disable the Peripheral */ + __HAL_DMA2D_DISABLE(hdma2d); + + /* Configure DMA2D Stream source2 address */ + hdma2d->Instance->BGMAR = SrcAddress2; + + /* Configure the source, destination address and the data size */ + DMA2D_SetConfig(hdma2d, SrcAddress1, DstAddress, Width, Height); + + /* Enable the configuration error interrupt */ + __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_CE); + + /* Enable the transfer complete interrupt */ + __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_TC); + + /* Enable the transfer Error interrupt */ + __HAL_DMA2D_ENABLE_IT(hdma2d, DMA2D_IT_TE); + + /* Enable the Peripheral */ + __HAL_DMA2D_ENABLE(hdma2d); + + return HAL_OK; +} + +/** + * @brief Abort the DMA2D Transfer. + * @param hdma2d : pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_Abort(DMA2D_HandleTypeDef *hdma2d) +{ + uint32_t tickstart = 0; + + /* Disable the DMA2D */ + __HAL_DMA2D_DISABLE(hdma2d); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check if the DMA2D is effectively disabled */ + while((hdma2d->Instance->CR & DMA2D_CR_START) != 0) + { + if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA2D_ABORT) + { + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT; + + /* Change the DMA2D state */ + hdma2d->State= HAL_DMA2D_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_TIMEOUT; + } + } + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + /* Change the DMA2D state*/ + hdma2d->State = HAL_DMA2D_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Suspend the DMA2D Transfer. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_Suspend(DMA2D_HandleTypeDef *hdma2d) +{ + uint32_t tickstart = 0; + + /* Suspend the DMA2D transfer */ + hdma2d->Instance->CR |= DMA2D_CR_SUSP; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check if the DMA2D is effectively suspended */ + while((hdma2d->Instance->CR & DMA2D_CR_SUSP) != DMA2D_CR_SUSP) + { + if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA2D_SUSPEND) + { + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT; + + /* Change the DMA2D state */ + hdma2d->State= HAL_DMA2D_STATE_TIMEOUT; + + return HAL_TIMEOUT; + } + } + /* Change the DMA2D state*/ + hdma2d->State = HAL_DMA2D_STATE_SUSPEND; + + return HAL_OK; +} + +/** + * @brief Resume the DMA2D Transfer. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_Resume(DMA2D_HandleTypeDef *hdma2d) +{ + /* Resume the DMA2D transfer */ + hdma2d->Instance->CR &= ~DMA2D_CR_SUSP; + + /* Change the DMA2D state*/ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + return HAL_OK; +} + +/** + * @brief Polling for transfer complete or CLUT loading. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_PollForTransfer(DMA2D_HandleTypeDef *hdma2d, uint32_t Timeout) +{ + uint32_t tmp, tmp1; + uint32_t tickstart = 0; + + /* Polling for DMA2D transfer */ + if((hdma2d->Instance->CR & DMA2D_CR_START) != 0) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + while(__HAL_DMA2D_GET_FLAG(hdma2d, DMA2D_FLAG_TC) == RESET) + { + tmp = __HAL_DMA2D_GET_FLAG(hdma2d, DMA2D_FLAG_CE); + tmp1 = __HAL_DMA2D_GET_FLAG(hdma2d, DMA2D_FLAG_TE); + + if((tmp != RESET) || (tmp1 != RESET)) + { + /* Clear the transfer and configuration error flags */ + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CE); + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TE); + + /* Change DMA2D state */ + hdma2d->State= HAL_DMA2D_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_ERROR; + } + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Process unlocked */ + __HAL_UNLOCK(hdma2d); + + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT; + + /* Change the DMA2D state */ + hdma2d->State= HAL_DMA2D_STATE_TIMEOUT; + + return HAL_TIMEOUT; + } + } + } + } + /* Polling for CLUT loading */ + if((hdma2d->Instance->FGPFCCR & DMA2D_FGPFCCR_START) != 0) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + while(__HAL_DMA2D_GET_FLAG(hdma2d, DMA2D_FLAG_CTC) == RESET) + { + if((__HAL_DMA2D_GET_FLAG(hdma2d, DMA2D_FLAG_CAE) != RESET)) + { + /* Clear the transfer and configuration error flags */ + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CAE); + + /* Change DMA2D state */ + hdma2d->State= HAL_DMA2D_STATE_ERROR; + + return HAL_ERROR; + } + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TIMEOUT; + + /* Change the DMA2D state */ + hdma2d->State= HAL_DMA2D_STATE_TIMEOUT; + + return HAL_TIMEOUT; + } + } + } + } + /* Clear the transfer complete flag */ + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TC); + + /* Clear the CLUT loading flag */ + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CTC); + + /* Change DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_OK; +} +/** + * @brief Handles DMA2D interrupt request. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval HAL status + */ +void HAL_DMA2D_IRQHandler(DMA2D_HandleTypeDef *hdma2d) +{ + /* Transfer Error Interrupt management ***************************************/ + if(__HAL_DMA2D_GET_FLAG(hdma2d, DMA2D_FLAG_TE) != RESET) + { + if(__HAL_DMA2D_GET_IT_SOURCE(hdma2d, DMA2D_IT_TE) != RESET) + { + /* Disable the transfer Error interrupt */ + __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_TE); + + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_TE; + + /* Clear the transfer error flag */ + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TE); + + /* Change DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + if(hdma2d->XferErrorCallback != NULL) + { + /* Transfer error Callback */ + hdma2d->XferErrorCallback(hdma2d); + } + } + } + /* Configuration Error Interrupt management **********************************/ + if(__HAL_DMA2D_GET_FLAG(hdma2d, DMA2D_FLAG_CE) != RESET) + { + if(__HAL_DMA2D_GET_IT_SOURCE(hdma2d, DMA2D_IT_CE) != RESET) + { + /* Disable the Configuration Error interrupt */ + __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_CE); + + /* Clear the Configuration error flag */ + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_CE); + + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_CE; + + /* Change DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + if(hdma2d->XferErrorCallback != NULL) + { + /* Transfer error Callback */ + hdma2d->XferErrorCallback(hdma2d); + } + } + } + /* Transfer Complete Interrupt management ************************************/ + if(__HAL_DMA2D_GET_FLAG(hdma2d, DMA2D_FLAG_TC) != RESET) + { + if(__HAL_DMA2D_GET_IT_SOURCE(hdma2d, DMA2D_IT_TC) != RESET) + { + /* Disable the transfer complete interrupt */ + __HAL_DMA2D_DISABLE_IT(hdma2d, DMA2D_IT_TC); + + /* Clear the transfer complete flag */ + __HAL_DMA2D_CLEAR_FLAG(hdma2d, DMA2D_FLAG_TC); + + /* Update error code */ + hdma2d->ErrorCode |= HAL_DMA2D_ERROR_NONE; + + /* Change DMA2D state */ + hdma2d->State = HAL_DMA2D_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hdma2d); + + if(hdma2d->XferCpltCallback != NULL) + { + /* Transfer complete Callback */ + hdma2d->XferCpltCallback(hdma2d); + } + } + } +} + +/** + * @} + */ + +/** @defgroup DMA2D_Group3 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure the DMA2D foreground or/and background parameters. + (+) Configure the DMA2D CLUT transfer. + (+) Enable DMA2D CLUT. + (+) Disable DMA2D CLUT. + (+) Configure the line watermark + +@endverbatim + * @{ + */ +/** + * @brief Configure the DMA2D Layer according to the specified + * parameters in the DMA2D_InitTypeDef and create the associated handle. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param LayerIdx: DMA2D Layer index. + * This parameter can be one of the following values: + * 0(background) / 1(foreground) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_ConfigLayer(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx) +{ + DMA2D_LayerCfgTypeDef *pLayerCfg = &hdma2d->LayerCfg[LayerIdx]; + + uint32_t tmp = 0; + + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_DMA2D_LAYER(LayerIdx)); + assert_param(IS_DMA2D_OFFSET(pLayerCfg->InputOffset)); + if(hdma2d->Init.Mode != DMA2D_R2M) + { + assert_param(IS_DMA2D_INPUT_COLOR_MODE(pLayerCfg->InputColorMode)); + if(hdma2d->Init.Mode != DMA2D_M2M) + { + assert_param(IS_DMA2D_ALPHA_MODE(pLayerCfg->AlphaMode)); + } + } + + /* Configure the background DMA2D layer */ + if(LayerIdx == 0) + { + /* DMA2D BGPFCR register configuration -----------------------------------*/ + /* Get the BGPFCCR register value */ + tmp = hdma2d->Instance->BGPFCCR; + + /* Clear Input color mode, alpha value and alpha mode bits */ + tmp &= (uint32_t)~(DMA2D_BGPFCCR_CM | DMA2D_BGPFCCR_AM | DMA2D_BGPFCCR_ALPHA); + + if ((pLayerCfg->InputColorMode == CM_A4) || (pLayerCfg->InputColorMode == CM_A8)) + { + /* Prepare the value to be wrote to the BGPFCCR register */ + tmp |= (pLayerCfg->InputColorMode | (pLayerCfg->AlphaMode << 16) | ((pLayerCfg->InputAlpha) & 0xFF000000)); + } + else + { + /* Prepare the value to be wrote to the BGPFCCR register */ + tmp |= (pLayerCfg->InputColorMode | (pLayerCfg->AlphaMode << 16) | (pLayerCfg->InputAlpha << 24)); + } + + /* Write to DMA2D BGPFCCR register */ + hdma2d->Instance->BGPFCCR = tmp; + + /* DMA2D BGOR register configuration -------------------------------------*/ + /* Get the BGOR register value */ + tmp = hdma2d->Instance->BGOR; + + /* Clear colors bits */ + tmp &= (uint32_t)~DMA2D_BGOR_LO; + + /* Prepare the value to be wrote to the BGOR register */ + tmp |= pLayerCfg->InputOffset; + + /* Write to DMA2D BGOR register */ + hdma2d->Instance->BGOR = tmp; + + if ((pLayerCfg->InputColorMode == CM_A4) || (pLayerCfg->InputColorMode == CM_A8)) + { + /* Prepare the value to be wrote to the BGCOLR register */ + tmp = ((pLayerCfg->InputAlpha) & 0x00FFFFFF); + + /* Write to DMA2D BGCOLR register */ + hdma2d->Instance->BGCOLR = tmp; + } + } + /* Configure the foreground DMA2D layer */ + else + { + /* DMA2D FGPFCR register configuration -----------------------------------*/ + /* Get the FGPFCCR register value */ + tmp = hdma2d->Instance->FGPFCCR; + + /* Clear Input color mode, alpha value and alpha mode bits */ + tmp &= (uint32_t)~(DMA2D_FGPFCCR_CM | DMA2D_FGPFCCR_AM | DMA2D_FGPFCCR_ALPHA); + + if ((pLayerCfg->InputColorMode == CM_A4) || (pLayerCfg->InputColorMode == CM_A8)) + { + /* Prepare the value to be wrote to the FGPFCCR register */ + tmp |= (pLayerCfg->InputColorMode | (pLayerCfg->AlphaMode << 16) | ((pLayerCfg->InputAlpha) & 0xFF000000)); + } + else + { + /* Prepare the value to be wrote to the FGPFCCR register */ + tmp |= (pLayerCfg->InputColorMode | (pLayerCfg->AlphaMode << 16) | (pLayerCfg->InputAlpha << 24)); + } + + /* Write to DMA2D FGPFCCR register */ + hdma2d->Instance->FGPFCCR = tmp; + + /* DMA2D FGOR register configuration -------------------------------------*/ + /* Get the FGOR register value */ + tmp = hdma2d->Instance->FGOR; + + /* Clear colors bits */ + tmp &= (uint32_t)~DMA2D_FGOR_LO; + + /* Prepare the value to be wrote to the FGOR register */ + tmp |= pLayerCfg->InputOffset; + + /* Write to DMA2D FGOR register */ + hdma2d->Instance->FGOR = tmp; + + if ((pLayerCfg->InputColorMode == CM_A4) || (pLayerCfg->InputColorMode == CM_A8)) + { + /* Prepare the value to be wrote to the FGCOLR register */ + tmp = ((pLayerCfg->InputAlpha) & 0x00FFFFFF); + + /* Write to DMA2D FGCOLR register */ + hdma2d->Instance->FGCOLR = tmp; + } + } + /* Initialize the DMA2D state*/ + hdma2d->State = HAL_DMA2D_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_OK; +} + +/** + * @brief Configure the DMA2D CLUT Transfer. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param CLUTCfg: pointer to a DMA2D_CLUTCfgTypeDef structure that contains + * the configuration information for the color look up table. + * @param LayerIdx: DMA2D Layer index. + * This parameter can be one of the following values: + * 0(background) / 1(foreground) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_ConfigCLUT(DMA2D_HandleTypeDef *hdma2d, DMA2D_CLUTCfgTypeDef CLUTCfg, uint32_t LayerIdx) +{ + uint32_t tmp = 0, tmp1 = 0; + + /* Check the parameters */ + assert_param(IS_DMA2D_LAYER(LayerIdx)); + assert_param(IS_DMA2D_CLUT_CM(CLUTCfg.CLUTColorMode)); + assert_param(IS_DMA2D_CLUT_SIZE(CLUTCfg.Size)); + + /* Configure the CLUT of the background DMA2D layer */ + if(LayerIdx == 0) + { + /* Get the BGCMAR register value */ + tmp = hdma2d->Instance->BGCMAR; + + /* Clear CLUT address bits */ + tmp &= (uint32_t)~DMA2D_BGCMAR_MA; + + /* Prepare the value to be wrote to the BGCMAR register */ + tmp |= (uint32_t)CLUTCfg.pCLUT; + + /* Write to DMA2D BGCMAR register */ + hdma2d->Instance->BGCMAR = tmp; + + /* Get the BGPFCCR register value */ + tmp = hdma2d->Instance->BGPFCCR; + + /* Clear CLUT size and CLUT address bits */ + tmp &= (uint32_t)~(DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM); + + /* Get the CLUT size */ + tmp1 = CLUTCfg.Size << 16; + + /* Prepare the value to be wrote to the BGPFCCR register */ + tmp |= (CLUTCfg.CLUTColorMode | tmp1); + + /* Write to DMA2D BGPFCCR register */ + hdma2d->Instance->BGPFCCR = tmp; + } + /* Configure the CLUT of the foreground DMA2D layer */ + else + { + /* Get the FGCMAR register value */ + tmp = hdma2d->Instance->FGCMAR; + + /* Clear CLUT address bits */ + tmp &= (uint32_t)~DMA2D_FGCMAR_MA; + + /* Prepare the value to be wrote to the FGCMAR register */ + tmp |= (uint32_t)CLUTCfg.pCLUT; + + /* Write to DMA2D FGCMAR register */ + hdma2d->Instance->FGCMAR = tmp; + + /* Get the FGPFCCR register value */ + tmp = hdma2d->Instance->FGPFCCR; + + /* Clear CLUT size and CLUT address bits */ + tmp &= (uint32_t)~(DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM); + + /* Get the CLUT size */ + tmp1 = CLUTCfg.Size << 8; + + /* Prepare the value to be wrote to the FGPFCCR register */ + tmp |= (CLUTCfg.CLUTColorMode | tmp1); + + /* Write to DMA2D FGPFCCR register */ + hdma2d->Instance->FGPFCCR = tmp; + } + + return HAL_OK; +} + +/** + * @brief Enable the DMA2D CLUT Transfer. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param LayerIdx: DMA2D Layer index. + * This parameter can be one of the following values: + * 0(background) / 1(foreground) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_EnableCLUT(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_DMA2D_LAYER(LayerIdx)); + + if(LayerIdx == 0) + { + /* Enable the CLUT loading for the background */ + hdma2d->Instance->BGPFCCR |= DMA2D_BGPFCCR_START; + } + else + { + /* Enable the CLUT loading for the foreground */ + hdma2d->Instance->FGPFCCR |= DMA2D_FGPFCCR_START; + } + + return HAL_OK; +} + +/** + * @brief Disable the DMA2D CLUT Transfer. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param LayerIdx: DMA2D Layer index. + * This parameter can be one of the following values: + * 0(background) / 1(foreground) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMA2D_DisableCLUT(DMA2D_HandleTypeDef *hdma2d, uint32_t LayerIdx) +{ + /* Check the parameters */ + assert_param(IS_DMA2D_LAYER(LayerIdx)); + + if(LayerIdx == 0) + { + /* Disable the CLUT loading for the background */ + hdma2d->Instance->BGPFCCR &= ~DMA2D_BGPFCCR_START; + } + else + { + /* Disable the CLUT loading for the foreground */ + hdma2d->Instance->FGPFCCR &= ~DMA2D_FGPFCCR_START; + } + + return HAL_OK; +} + +/** + * @brief Define the configuration of the line watermark . + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @param Line: Line Watermark configuration. + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_DMA2D_ProgramLineEvent(DMA2D_HandleTypeDef *hdma2d, uint32_t Line) +{ + /* Process locked */ + __HAL_LOCK(hdma2d); + + /* Change DMA2D peripheral state */ + hdma2d->State = HAL_DMA2D_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_DMA2D_LineWatermark(Line)); + + /* Sets the Line watermark configuration */ + DMA2D->LWR = (uint32_t)Line; + + /* Initialize the DMA2D state*/ + hdma2d->State = HAL_DMA2D_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hdma2d); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup DMA2D_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to : + (+) Check the DMA2D state + (+) Get error code + +@endverbatim + * @{ + */ + +/** + * @brief Return the DMA2D state + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the DMA2D. + * @retval HAL state + */ +HAL_DMA2D_StateTypeDef HAL_DMA2D_GetState(DMA2D_HandleTypeDef *hdma2d) +{ + return hdma2d->State; +} + +/** + * @brief Return the DMA2D error code + * @param hdma2d : pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for DMA2D. + * @retval DMA2D Error Code + */ +uint32_t HAL_DMA2D_GetError(DMA2D_HandleTypeDef *hdma2d) +{ + return hdma2d->ErrorCode; +} + +/** + * @} + */ + + +/** + * @brief Set the DMA2D Transfer parameter. + * @param hdma2d: pointer to a DMA2D_HandleTypeDef structure that contains + * the configuration information for the specified DMA2D. + * @param pdata: The source memory Buffer address + * @param DstAddress: The destination memory Buffer address + * @param Width: The width of data to be transferred from source to destination. + * @param Height: The height of data to be transferred from source to destination. + * @retval HAL status + */ +static void DMA2D_SetConfig(DMA2D_HandleTypeDef *hdma2d, uint32_t pdata, uint32_t DstAddress, uint32_t Width, uint32_t Height) +{ + uint32_t tmp = 0; + uint32_t tmp1 = 0; + uint32_t tmp2 = 0; + uint32_t tmp3 = 0; + uint32_t tmp4 = 0; + + tmp = Width << 16; + + /* Configure DMA2D data size */ + hdma2d->Instance->NLR = (Height | tmp); + + /* Configure DMA2D destination address */ + hdma2d->Instance->OMAR = DstAddress; + + /* Register to memory DMA2D mode selected */ + if (hdma2d->Init.Mode == DMA2D_R2M) + { + tmp1 = pdata & DMA2D_OCOLR_ALPHA_1; + tmp2 = pdata & DMA2D_OCOLR_RED_1; + tmp3 = pdata & DMA2D_OCOLR_GREEN_1; + tmp4 = pdata & DMA2D_OCOLR_BLUE_1; + + /* Prepare the value to be wrote to the OCOLR register according to the color mode */ + if (hdma2d->Init.ColorMode == DMA2D_ARGB8888) + { + tmp = (tmp3 | tmp2 | tmp1| tmp4); + } + else if (hdma2d->Init.ColorMode == DMA2D_RGB888) + { + tmp = (tmp3 | tmp2 | tmp4); + } + else if (hdma2d->Init.ColorMode == DMA2D_RGB565) + { + tmp2 = (tmp2 >> 19); + tmp3 = (tmp3 >> 10); + tmp4 = (tmp4 >> 3 ); + tmp = ((tmp3 << 5) | (tmp2 << 11) | tmp4); + } + else if (hdma2d->Init.ColorMode == DMA2D_ARGB1555) + { + tmp1 = (tmp1 >> 31); + tmp2 = (tmp2 >> 19); + tmp3 = (tmp3 >> 11); + tmp4 = (tmp4 >> 3 ); + tmp = ((tmp3 << 5) | (tmp2 << 10) | (tmp1 << 15) | tmp4); + } + else /* DMA2D_CMode = DMA2D_ARGB4444 */ + { + tmp1 = (tmp1 >> 28); + tmp2 = (tmp2 >> 20); + tmp3 = (tmp3 >> 12); + tmp4 = (tmp4 >> 4 ); + tmp = ((tmp3 << 4) | (tmp2 << 8) | (tmp1 << 12) | tmp4); + } + /* Write to DMA2D OCOLR register */ + hdma2d->Instance->OCOLR = tmp; + } + else /* M2M, M2M_PFC or M2M_Blending DMA2D Mode */ + { + /* Configure DMA2D source address */ + hdma2d->Instance->FGMAR = pdata; + } +} + +/** + * @} + */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +#endif /* HAL_DMA2D_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c new file mode 100644 index 0000000..bf293fb --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c @@ -0,0 +1,307 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_dma_ex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief DMA Extension HAL module driver + * This file provides firmware functions to manage the following + * functionalities of the DMA Extension peripheral: + * + Extended features functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The DMA Extension HAL driver can be used as follows: + (#) Start a multi buffer transfer using the HAL_DMA_MultiBufferStart() function + for polling mode or HAL_DMA_MultiBufferStart_IT() for interrupt mode. + + -@- In Memory-to-Memory transfer mode, Multi (Double) Buffer mode is not allowed. + -@- When Multi (Double) Buffer mode is enabled the, transfer is circular by default. + -@- In Multi (Double) buffer mode, it is possible to update the base address for + the AHB memory port on the fly (DMA_SxM0AR or DMA_SxM1AR) when the stream is enabled. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 DMAEx DMAEx + * @brief DMA Extended HAL module driver + * @{ + */ + +#ifdef HAL_DMA_MODULE_ENABLED + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private Constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup DMAEx_Private_Functions + * @{ + */ +static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength); +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ + +/** @addtogroup DMAEx_Exported_Functions + * @{ + */ + + +/** @addtogroup DMAEx_Exported_Functions_Group1 + * +@verbatim + =============================================================================== + ##### Extended features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure the source, destination address and data length and + Start MultiBuffer DMA transfer + (+) Configure the source, destination address and data length and + Start MultiBuffer DMA transfer with interrupt + (+) Change on the fly the memory0 or memory1 address. + +@endverbatim + * @{ + */ + + +/** + * @brief Starts the multi_buffer DMA Transfer. + * @param hdma : pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @param SrcAddress: The source memory Buffer address + * @param DstAddress: The destination memory Buffer address + * @param SecondMemAddress: The second memory Buffer address in case of multi buffer Transfer + * @param DataLength: The length of data to be transferred from source to destination + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength) +{ + /* Process Locked */ + __HAL_LOCK(hdma); + + /* Current memory buffer used is Memory 0 */ + if((hdma->Instance->CR & DMA_SxCR_CT) == 0) + { + hdma->State = HAL_DMA_STATE_BUSY_MEM0; + } + /* Current memory buffer used is Memory 1 */ + else if((hdma->Instance->CR & DMA_SxCR_CT) != 0) + { + hdma->State = HAL_DMA_STATE_BUSY_MEM1; + } + + /* Check the parameters */ + assert_param(IS_DMA_BUFFER_SIZE(DataLength)); + + /* Disable the peripheral */ + __HAL_DMA_DISABLE(hdma); + + /* Enable the double buffer mode */ + hdma->Instance->CR |= (uint32_t)DMA_SxCR_DBM; + + /* Configure DMA Stream destination address */ + hdma->Instance->M1AR = SecondMemAddress; + + /* Configure the source, destination address and the data length */ + DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength); + + /* Enable the peripheral */ + __HAL_DMA_ENABLE(hdma); + + return HAL_OK; +} + +/** + * @brief Starts the multi_buffer DMA Transfer with interrupt enabled. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @param SrcAddress: The source memory Buffer address + * @param DstAddress: The destination memory Buffer address + * @param SecondMemAddress: The second memory Buffer address in case of multi buffer Transfer + * @param DataLength: The length of data to be transferred from source to destination + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength) +{ + /* Process Locked */ + __HAL_LOCK(hdma); + + /* Current memory buffer used is Memory 0 */ + if((hdma->Instance->CR & DMA_SxCR_CT) == 0) + { + hdma->State = HAL_DMA_STATE_BUSY_MEM0; + } + /* Current memory buffer used is Memory 1 */ + else if((hdma->Instance->CR & DMA_SxCR_CT) != 0) + { + hdma->State = HAL_DMA_STATE_BUSY_MEM1; + } + + /* Check the parameters */ + assert_param(IS_DMA_BUFFER_SIZE(DataLength)); + + /* Disable the peripheral */ + __HAL_DMA_DISABLE(hdma); + + /* Enable the Double buffer mode */ + hdma->Instance->CR |= (uint32_t)DMA_SxCR_DBM; + + /* Configure DMA Stream destination address */ + hdma->Instance->M1AR = SecondMemAddress; + + /* Configure the source, destination address and the data length */ + DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength); + + /* Enable the transfer complete interrupt */ + __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC); + + /* Enable the Half transfer interrupt */ + __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT); + + /* Enable the transfer Error interrupt */ + __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE); + + /* Enable the fifo Error interrupt */ + __HAL_DMA_ENABLE_IT(hdma, DMA_IT_FE); + + /* Enable the direct mode Error interrupt */ + __HAL_DMA_ENABLE_IT(hdma, DMA_IT_DME); + + /* Enable the peripheral */ + __HAL_DMA_ENABLE(hdma); + + return HAL_OK; +} + +/** + * @brief Change the memory0 or memory1 address on the fly. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @param Address: The new address + * @param memory: the memory to be changed, This parameter can be one of + * the following values: + * MEMORY0 / + * MEMORY1 + * @note The MEMORY0 address can be changed only when the current transfer use + * MEMORY1 and the MEMORY1 address can be changed only when the current + * transfer use MEMORY0. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_DMAEx_ChangeMemory(DMA_HandleTypeDef *hdma, uint32_t Address, HAL_DMA_MemoryTypeDef memory) +{ + if(memory == MEMORY0) + { + /* change the memory0 address */ + hdma->Instance->M0AR = Address; + } + else + { + /* change the memory1 address */ + hdma->Instance->M1AR = Address; + } + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup DMAEx_Private_Functions + * @{ + */ + +/** + * @brief Set the DMA Transfer parameter. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA Stream. + * @param SrcAddress: The source memory Buffer address + * @param DstAddress: The destination memory Buffer address + * @param DataLength: The length of data to be transferred from source to destination + * @retval HAL status + */ +static void DMA_MultiBufferSetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) +{ + /* Configure DMA Stream data length */ + hdma->Instance->NDTR = DataLength; + + /* Peripheral to Memory */ + if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) + { + /* Configure DMA Stream destination address */ + hdma->Instance->PAR = DstAddress; + + /* Configure DMA Stream source address */ + hdma->Instance->M0AR = SrcAddress; + } + /* Memory to Peripheral */ + else + { + /* Configure DMA Stream source address */ + hdma->Instance->PAR = SrcAddress; + + /* Configure DMA Stream destination address */ + hdma->Instance->M0AR = DstAddress; + } +} + +/** + * @} + */ + +#endif /* HAL_DMA_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c new file mode 100644 index 0000000..e458ede --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c @@ -0,0 +1,2017 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_eth.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief ETH HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Ethernet (ETH) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Errors functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#)Declare a ETH_HandleTypeDef handle structure, for example: + ETH_HandleTypeDef heth; + + (#)Fill parameters of Init structure in heth handle + + (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...) + + (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API: + (##) Enable the Ethernet interface clock using + (+++) __HAL_RCC_ETHMAC_CLK_ENABLE(); + (+++) __HAL_RCC_ETHMACTX_CLK_ENABLE(); + (+++) __HAL_RCC_ETHMACRX_CLK_ENABLE(); + + (##) Initialize the related GPIO clocks + (##) Configure Ethernet pin-out + (##) Configure Ethernet NVIC interrupt (IT mode) + + (#)Initialize Ethernet DMA Descriptors in chain mode and point to allocated buffers: + (##) HAL_ETH_DMATxDescListInit(); for Transmission process + (##) HAL_ETH_DMARxDescListInit(); for Reception process + + (#)Enable MAC and DMA transmission and reception: + (##) HAL_ETH_Start(); + + (#)Prepare ETH DMA TX Descriptors and give the hand to ETH DMA to transfer + the frame to MAC TX FIFO: + (##) HAL_ETH_TransmitFrame(); + + (#)Poll for a received frame in ETH RX DMA Descriptors and get received + frame parameters + (##) HAL_ETH_GetReceivedFrame(); (should be called into an infinite loop) + + (#) Get a received frame when an ETH RX interrupt occurs: + (##) HAL_ETH_GetReceivedFrame_IT(); (called in IT mode only) + + (#) Communicate with external PHY device: + (##) Read a specific register from the PHY + HAL_ETH_ReadPHYRegister(); + (##) Write data to a specific RHY register: + HAL_ETH_WritePHYRegister(); + + (#) Configure the Ethernet MAC after ETH peripheral initialization + HAL_ETH_ConfigMAC(); all MAC parameters should be filled. + + (#) Configure the Ethernet DMA after ETH peripheral initialization + HAL_ETH_ConfigDMA(); all DMA parameters should be filled. + + -@- The PTP protocol and the DMA descriptors ring mode are not supported + in this driver + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 ETH ETH + * @brief ETH HAL module driver + * @{ + */ + +#ifdef HAL_ETH_MODULE_ENABLED + +#if defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup ETH_Private_Constants ETH Private Constants + * @{ + */ +#define LINKED_STATE_TIMEOUT_VALUE ((uint32_t)2000) /* 2000 ms */ +#define AUTONEGO_COMPLETED_TIMEOUT_VALUE ((uint32_t)1000) /* 1000 ms */ + +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup ETH_Private_Functions ETH Private Functions + * @{ + */ +static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err); +static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr); +static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth); +static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth); +static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth); +static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth); +static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth); +static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth); +static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth); +static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth); +static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth); + +/** + * @} + */ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup ETH_Exported_Functions ETH Exported Functions + * @{ + */ + +/** @defgroup ETH_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 and configure the Ethernet peripheral + (+) De-initialize the Ethernet peripheral + + @endverbatim + * @{ + */ + +/** + * @brief Initializes the Ethernet MAC and DMA according to default + * parameters. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth) +{ + uint32_t tmpreg1 = 0, phyreg = 0; + uint32_t hclk = 60000000; + uint32_t tickstart = 0; + uint32_t err = ETH_SUCCESS; + + /* Check the ETH peripheral state */ + if(heth == NULL) + { + return HAL_ERROR; + } + + /* Check parameters */ + assert_param(IS_ETH_AUTONEGOTIATION(heth->Init.AutoNegotiation)); + assert_param(IS_ETH_RX_MODE(heth->Init.RxMode)); + assert_param(IS_ETH_CHECKSUM_MODE(heth->Init.ChecksumMode)); + assert_param(IS_ETH_MEDIA_INTERFACE(heth->Init.MediaInterface)); + + if(heth->State == HAL_ETH_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + heth->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, NVIC. */ + HAL_ETH_MspInit(heth); + } + + /* Enable SYSCFG Clock */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + + /* Select MII or RMII Mode*/ + SYSCFG->PMC &= ~(SYSCFG_PMC_MII_RMII_SEL); + SYSCFG->PMC |= (uint32_t)heth->Init.MediaInterface; + + /* Ethernet Software reset */ + /* Set the SWR bit: resets all MAC subsystem internal registers and logic */ + /* After reset all the registers holds their respective reset values */ + (heth->Instance)->DMABMR |= ETH_DMABMR_SR; + + /* Wait for software reset */ + while (((heth->Instance)->DMABMR & ETH_DMABMR_SR) != (uint32_t)RESET) + { + } + + /*-------------------------------- MAC Initialization ----------------------*/ + /* Get the ETHERNET MACMIIAR value */ + tmpreg1 = (heth->Instance)->MACMIIAR; + /* Clear CSR Clock Range CR[2:0] bits */ + tmpreg1 &= ETH_MACMIIAR_CR_MASK; + + /* Get hclk frequency value */ + hclk = HAL_RCC_GetHCLKFreq(); + + /* Set CR bits depending on hclk value */ + if((hclk >= 20000000)&&(hclk < 35000000)) + { + /* CSR Clock Range between 20-35 MHz */ + tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_Div16; + } + else if((hclk >= 35000000)&&(hclk < 60000000)) + { + /* CSR Clock Range between 35-60 MHz */ + tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_Div26; + } + else if((hclk >= 60000000)&&(hclk < 100000000)) + { + /* CSR Clock Range between 60-100 MHz */ + tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_Div42; + } + else if((hclk >= 100000000)&&(hclk < 150000000)) + { + /* CSR Clock Range between 100-150 MHz */ + tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_Div62; + } + else /* ((hclk >= 150000000)&&(hclk <= 168000000)) */ + { + /* CSR Clock Range between 150-168 MHz */ + tmpreg1 |= (uint32_t)ETH_MACMIIAR_CR_Div102; + } + + /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */ + (heth->Instance)->MACMIIAR = (uint32_t)tmpreg1; + + /*-------------------- PHY initialization and configuration ----------------*/ + /* Put the PHY in reset mode */ + if((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_RESET)) != HAL_OK) + { + /* In case of write timeout */ + err = ETH_ERROR; + + /* Config MAC and DMA */ + ETH_MACDMAConfig(heth, err); + + /* Set the ETH peripheral state to READY */ + heth->State = HAL_ETH_STATE_READY; + + /* Return HAL_ERROR */ + return HAL_ERROR; + } + + /* Delay to assure PHY reset */ + HAL_Delay(PHY_RESET_DELAY); + + if((heth->Init).AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + /* We wait for linked status */ + do + { + HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg); + + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > LINKED_STATE_TIMEOUT_VALUE) + { + /* In case of write timeout */ + err = ETH_ERROR; + + /* Config MAC and DMA */ + ETH_MACDMAConfig(heth, err); + + heth->State= HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + return HAL_TIMEOUT; + } + } while (((phyreg & PHY_LINKED_STATUS) != PHY_LINKED_STATUS)); + + + /* Enable Auto-Negotiation */ + if((HAL_ETH_WritePHYRegister(heth, PHY_BCR, PHY_AUTONEGOTIATION)) != HAL_OK) + { + /* In case of write timeout */ + err = ETH_ERROR; + + /* Config MAC and DMA */ + ETH_MACDMAConfig(heth, err); + + /* Set the ETH peripheral state to READY */ + heth->State = HAL_ETH_STATE_READY; + + /* Return HAL_ERROR */ + return HAL_ERROR; + } + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until the auto-negotiation will be completed */ + do + { + HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg); + + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > AUTONEGO_COMPLETED_TIMEOUT_VALUE) + { + /* In case of write timeout */ + err = ETH_ERROR; + + /* Config MAC and DMA */ + ETH_MACDMAConfig(heth, err); + + heth->State= HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + return HAL_TIMEOUT; + } + + } while (((phyreg & PHY_AUTONEGO_COMPLETE) != PHY_AUTONEGO_COMPLETE)); + + /* Read the result of the auto-negotiation */ + if((HAL_ETH_ReadPHYRegister(heth, PHY_SR, &phyreg)) != HAL_OK) + { + /* In case of write timeout */ + err = ETH_ERROR; + + /* Config MAC and DMA */ + ETH_MACDMAConfig(heth, err); + + /* Set the ETH peripheral state to READY */ + heth->State = HAL_ETH_STATE_READY; + + /* Return HAL_ERROR */ + return HAL_ERROR; + } + + /* Configure the MAC with the Duplex Mode fixed by the auto-negotiation process */ + if((phyreg & PHY_DUPLEX_STATUS) != (uint32_t)RESET) + { + /* Set Ethernet duplex mode to Full-duplex following the auto-negotiation */ + (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX; + } + else + { + /* Set Ethernet duplex mode to Half-duplex following the auto-negotiation */ + (heth->Init).DuplexMode = ETH_MODE_HALFDUPLEX; + } + /* Configure the MAC with the speed fixed by the auto-negotiation process */ + if((phyreg & PHY_SPEED_STATUS) == PHY_SPEED_STATUS) + { + /* Set Ethernet speed to 10M following the auto-negotiation */ + (heth->Init).Speed = ETH_SPEED_10M; + } + else + { + /* Set Ethernet speed to 100M following the auto-negotiation */ + (heth->Init).Speed = ETH_SPEED_100M; + } + } + else /* AutoNegotiation Disable */ + { + /* Check parameters */ + assert_param(IS_ETH_SPEED(heth->Init.Speed)); + assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode)); + + /* Set MAC Speed and Duplex Mode */ + if(HAL_ETH_WritePHYRegister(heth, PHY_BCR, ((uint16_t)((heth->Init).DuplexMode >> 3) | + (uint16_t)((heth->Init).Speed >> 1))) != HAL_OK) + { + /* In case of write timeout */ + err = ETH_ERROR; + + /* Config MAC and DMA */ + ETH_MACDMAConfig(heth, err); + + /* Set the ETH peripheral state to READY */ + heth->State = HAL_ETH_STATE_READY; + + /* Return HAL_ERROR */ + return HAL_ERROR; + } + + /* Delay to assure PHY configuration */ + HAL_Delay(PHY_CONFIG_DELAY); + } + + /* Config MAC and DMA */ + ETH_MACDMAConfig(heth, err); + + /* Set ETH HAL State to Ready */ + heth->State= HAL_ETH_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief De-Initializes the ETH peripheral. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth) +{ + /* Set the ETH peripheral state to BUSY */ + heth->State = HAL_ETH_STATE_BUSY; + + /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */ + HAL_ETH_MspDeInit(heth); + + /* Set ETH HAL state to Disabled */ + heth->State= HAL_ETH_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(heth); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the DMA Tx descriptors in chain mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param DMATxDescTab: Pointer to the first Tx desc list + * @param TxBuff: Pointer to the first TxBuffer list + * @param TxBuffCount: Number of the used Tx desc in the list + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMATxDescTab, uint8_t *TxBuff, uint32_t TxBuffCount) +{ + uint32_t i = 0; + ETH_DMADescTypeDef *dmatxdesc; + + /* Process Locked */ + __HAL_LOCK(heth); + + /* Set the ETH peripheral state to BUSY */ + heth->State = HAL_ETH_STATE_BUSY; + + /* Set the DMATxDescToSet pointer with the first one of the DMATxDescTab list */ + heth->TxDesc = DMATxDescTab; + + /* Fill each DMATxDesc descriptor with the right values */ + for(i=0; i < TxBuffCount; i++) + { + /* Get the pointer on the ith member of the Tx Desc list */ + dmatxdesc = DMATxDescTab + i; + + /* Set Second Address Chained bit */ + dmatxdesc->Status = ETH_DMATXDESC_TCH; + + /* Set Buffer1 address pointer */ + dmatxdesc->Buffer1Addr = (uint32_t)(&TxBuff[i*ETH_TX_BUF_SIZE]); + + if ((heth->Init).ChecksumMode == ETH_CHECKSUM_BY_HARDWARE) + { + /* Set the DMA Tx descriptors checksum insertion */ + dmatxdesc->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL; + } + + /* Initialize the next descriptor with the Next Descriptor Polling Enable */ + if(i < (TxBuffCount-1)) + { + /* Set next descriptor address register with next descriptor base address */ + dmatxdesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab+i+1); + } + else + { + /* For last descriptor, set next descriptor address register equal to the first descriptor base address */ + dmatxdesc->Buffer2NextDescAddr = (uint32_t) DMATxDescTab; + } + } + + /* Set Transmit Descriptor List Address Register */ + (heth->Instance)->DMATDLAR = (uint32_t) DMATxDescTab; + + /* Set ETH HAL State to Ready */ + heth->State= HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the DMA Rx descriptors in chain mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param DMARxDescTab: Pointer to the first Rx desc list + * @param RxBuff: Pointer to the first RxBuffer list + * @param RxBuffCount: Number of the used Rx desc in the list + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_DMARxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount) +{ + uint32_t i = 0; + ETH_DMADescTypeDef *DMARxDesc; + + /* Process Locked */ + __HAL_LOCK(heth); + + /* Set the ETH peripheral state to BUSY */ + heth->State = HAL_ETH_STATE_BUSY; + + /* Set the Ethernet RxDesc pointer with the first one of the DMARxDescTab list */ + heth->RxDesc = DMARxDescTab; + + /* Fill each DMARxDesc descriptor with the right values */ + for(i=0; i < RxBuffCount; i++) + { + /* Get the pointer on the ith member of the Rx Desc list */ + DMARxDesc = DMARxDescTab+i; + + /* Set Own bit of the Rx descriptor Status */ + DMARxDesc->Status = ETH_DMARXDESC_OWN; + + /* Set Buffer1 size and Second Address Chained bit */ + DMARxDesc->ControlBufferSize = ETH_DMARXDESC_RCH | ETH_RX_BUF_SIZE; + + /* Set Buffer1 address pointer */ + DMARxDesc->Buffer1Addr = (uint32_t)(&RxBuff[i*ETH_RX_BUF_SIZE]); + + if((heth->Init).RxMode == ETH_RXINTERRUPT_MODE) + { + /* Enable Ethernet DMA Rx Descriptor interrupt */ + DMARxDesc->ControlBufferSize &= ~ETH_DMARXDESC_DIC; + } + + /* Initialize the next descriptor with the Next Descriptor Polling Enable */ + if(i < (RxBuffCount-1)) + { + /* Set next descriptor address register with next descriptor base address */ + DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab+i+1); + } + else + { + /* For last descriptor, set next descriptor address register equal to the first descriptor base address */ + DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab); + } + } + + /* Set Receive Descriptor List Address Register */ + (heth->Instance)->DMARDLAR = (uint32_t) DMARxDescTab; + + /* Set ETH HAL State to Ready */ + heth->State= HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the ETH MSP. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +__weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes ETH MSP. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +__weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup ETH_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * + @verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] This section provides functions allowing to: + (+) Transmit a frame + HAL_ETH_TransmitFrame(); + (+) Receive a frame + HAL_ETH_GetReceivedFrame(); + HAL_ETH_GetReceivedFrame_IT(); + (+) Read from an External PHY register + HAL_ETH_ReadPHYRegister(); + (+) Write to an External PHY register + HAL_ETH_WritePHYRegister(); + + @endverbatim + + * @{ + */ + +/** + * @brief Sends an Ethernet frame. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param FrameLength: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength) +{ + uint32_t bufcount = 0, size = 0, i = 0; + + /* Process Locked */ + __HAL_LOCK(heth); + + /* Set the ETH peripheral state to BUSY */ + heth->State = HAL_ETH_STATE_BUSY; + + if (FrameLength == 0) + { + /* Set ETH HAL state to READY */ + heth->State = HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + return HAL_ERROR; + } + + /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */ + if(((heth->TxDesc)->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET) + { + /* OWN bit set */ + heth->State = HAL_ETH_STATE_BUSY_TX; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + return HAL_ERROR; + } + + /* Get the number of needed Tx buffers for the current frame */ + if (FrameLength > ETH_TX_BUF_SIZE) + { + bufcount = FrameLength/ETH_TX_BUF_SIZE; + if (FrameLength % ETH_TX_BUF_SIZE) + { + bufcount++; + } + } + else + { + bufcount = 1; + } + if (bufcount == 1) + { + /* Set LAST and FIRST segment */ + heth->TxDesc->Status |=ETH_DMATXDESC_FS|ETH_DMATXDESC_LS; + /* Set frame size */ + heth->TxDesc->ControlBufferSize = (FrameLength & ETH_DMATXDESC_TBS1); + /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */ + heth->TxDesc->Status |= ETH_DMATXDESC_OWN; + /* Point to next descriptor */ + heth->TxDesc= (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr); + } + else + { + for (i=0; i< bufcount; i++) + { + /* Clear FIRST and LAST segment bits */ + heth->TxDesc->Status &= ~(ETH_DMATXDESC_FS | ETH_DMATXDESC_LS); + + if (i == 0) + { + /* Setting the first segment bit */ + heth->TxDesc->Status |= ETH_DMATXDESC_FS; + } + + /* Program size */ + heth->TxDesc->ControlBufferSize = (ETH_TX_BUF_SIZE & ETH_DMATXDESC_TBS1); + + if (i == (bufcount-1)) + { + /* Setting the last segment bit */ + heth->TxDesc->Status |= ETH_DMATXDESC_LS; + size = FrameLength - (bufcount-1)*ETH_TX_BUF_SIZE; + heth->TxDesc->ControlBufferSize = (size & ETH_DMATXDESC_TBS1); + } + + /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */ + heth->TxDesc->Status |= ETH_DMATXDESC_OWN; + /* point to next descriptor */ + heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr); + } + } + + /* When Tx Buffer unavailable flag is set: clear it and resume transmission */ + if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET) + { + /* Clear TBUS ETHERNET DMA flag */ + (heth->Instance)->DMASR = ETH_DMASR_TBUS; + /* Resume DMA transmission*/ + (heth->Instance)->DMATPDR = 0; + } + + /* Set ETH HAL State to Ready */ + heth->State = HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Checks for received frames. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_GetReceivedFrame(ETH_HandleTypeDef *heth) +{ + uint32_t framelength = 0; + + /* Process Locked */ + __HAL_LOCK(heth); + + /* Check the ETH state to BUSY */ + heth->State = HAL_ETH_STATE_BUSY; + + /* Check if segment is not owned by DMA */ + /* (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) && ((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET)) */ + if(((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET)) + { + /* Check if last segment */ + if(((heth->RxDesc->Status & ETH_DMARXDESC_LS) != (uint32_t)RESET)) + { + /* increment segment count */ + (heth->RxFrameInfos).SegCount++; + + /* Check if last segment is first segment: one segment contains the frame */ + if ((heth->RxFrameInfos).SegCount == 1) + { + (heth->RxFrameInfos).FSRxDesc =heth->RxDesc; + } + + heth->RxFrameInfos.LSRxDesc = heth->RxDesc; + + /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ + framelength = (((heth->RxDesc)->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4; + heth->RxFrameInfos.length = framelength; + + /* Get the address of the buffer start address */ + heth->RxFrameInfos.buffer = ((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr; + /* point to next descriptor */ + heth->RxDesc = (ETH_DMADescTypeDef*) ((heth->RxDesc)->Buffer2NextDescAddr); + + /* Set HAL State to Ready */ + heth->State = HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + /* Return function status */ + return HAL_OK; + } + /* Check if first segment */ + else if((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET) + { + (heth->RxFrameInfos).FSRxDesc = heth->RxDesc; + (heth->RxFrameInfos).LSRxDesc = NULL; + (heth->RxFrameInfos).SegCount = 1; + /* Point to next descriptor */ + heth->RxDesc = (ETH_DMADescTypeDef*) (heth->RxDesc->Buffer2NextDescAddr); + } + /* Check if intermediate segment */ + else + { + (heth->RxFrameInfos).SegCount++; + /* Point to next descriptor */ + heth->RxDesc = (ETH_DMADescTypeDef*) (heth->RxDesc->Buffer2NextDescAddr); + } + } + + /* Set ETH HAL State to Ready */ + heth->State = HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + /* Return function status */ + return HAL_ERROR; +} + +/** + * @brief Gets the Received frame in interrupt mode. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef *heth) +{ + uint32_t descriptorscancounter = 0; + + /* Process Locked */ + __HAL_LOCK(heth); + + /* Set ETH HAL State to BUSY */ + heth->State = HAL_ETH_STATE_BUSY; + + /* Scan descriptors owned by CPU */ + while (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) && (descriptorscancounter < ETH_RXBUFNB)) + { + /* Just for security */ + descriptorscancounter++; + + /* Check if first segment in frame */ + /* ((heth->RxDesc->Status & ETH_DMARXDESC_FS) != (uint32_t)RESET) && ((heth->RxDesc->Status & ETH_DMARXDESC_LS) == (uint32_t)RESET)) */ + if((heth->RxDesc->Status & (ETH_DMARXDESC_FS | ETH_DMARXDESC_LS)) == (uint32_t)ETH_DMARXDESC_FS) + { + heth->RxFrameInfos.FSRxDesc = heth->RxDesc; + heth->RxFrameInfos.SegCount = 1; + /* Point to next descriptor */ + heth->RxDesc = (ETH_DMADescTypeDef*) (heth->RxDesc->Buffer2NextDescAddr); + } + /* Check if intermediate segment */ + /* ((heth->RxDesc->Status & ETH_DMARXDESC_LS) == (uint32_t)RESET)&& ((heth->RxDesc->Status & ETH_DMARXDESC_FS) == (uint32_t)RESET)) */ + else if ((heth->RxDesc->Status & (ETH_DMARXDESC_LS | ETH_DMARXDESC_FS)) == (uint32_t)RESET) + { + /* Increment segment count */ + (heth->RxFrameInfos.SegCount)++; + /* Point to next descriptor */ + heth->RxDesc = (ETH_DMADescTypeDef*)(heth->RxDesc->Buffer2NextDescAddr); + } + /* Should be last segment */ + else + { + /* Last segment */ + heth->RxFrameInfos.LSRxDesc = heth->RxDesc; + + /* Increment segment count */ + (heth->RxFrameInfos.SegCount)++; + + /* Check if last segment is first segment: one segment contains the frame */ + if ((heth->RxFrameInfos.SegCount) == 1) + { + heth->RxFrameInfos.FSRxDesc = heth->RxDesc; + } + + /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ + heth->RxFrameInfos.length = (((heth->RxDesc)->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4; + + /* Get the address of the buffer start address */ + heth->RxFrameInfos.buffer =((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr; + + /* Point to next descriptor */ + heth->RxDesc = (ETH_DMADescTypeDef*) (heth->RxDesc->Buffer2NextDescAddr); + + /* Set HAL State to Ready */ + heth->State = HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + /* Return function status */ + return HAL_OK; + } + } + + /* Set HAL State to Ready */ + heth->State = HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + /* Return function status */ + return HAL_ERROR; +} + +/** + * @brief This function handles ETH interrupt request. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth) +{ + /* Frame received */ + if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_R)) + { + /* Receive complete callback */ + HAL_ETH_RxCpltCallback(heth); + + /* Clear the Eth DMA Rx IT pending bits */ + __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_R); + + /* Set HAL State to Ready */ + heth->State = HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + } + /* Frame transmitted */ + else if (__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_T)) + { + /* Transfer complete callback */ + HAL_ETH_TxCpltCallback(heth); + + /* Clear the Eth DMA Tx IT pending bits */ + __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_T); + + /* Set HAL State to Ready */ + heth->State = HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + } + + /* Clear the interrupt flags */ + __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_IT_NIS); + + /* ETH DMA Error */ + if(__HAL_ETH_DMA_GET_FLAG(heth, ETH_DMA_FLAG_AIS)) + { + /* Ethernet Error callback */ + HAL_ETH_ErrorCallback(heth); + + /* Clear the interrupt flags */ + __HAL_ETH_DMA_CLEAR_IT(heth, ETH_DMA_FLAG_AIS); + + /* Set HAL State to Ready */ + heth->State = HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + } +} + +/** + * @brief Tx Transfer completed callbacks. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +__weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callbacks. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +__weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Ethernet transfer error callbacks + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +__weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ETH_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Reads a PHY register + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param PHYReg: PHY register address, is the index of one of the 32 PHY register. + * This parameter can be one of the following values: + * PHY_BCR: Transceiver Basic Control Register, + * PHY_BSR: Transceiver Basic Status Register. + * More PHY register could be read depending on the used PHY + * @param RegValue: PHY register value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t *RegValue) +{ + uint32_t tmpreg1 = 0; + uint32_t tickstart = 0; + + /* Check parameters */ + assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress)); + + /* Check the ETH peripheral state */ + if(heth->State == HAL_ETH_STATE_BUSY_RD) + { + return HAL_BUSY; + } + /* Set ETH HAL State to BUSY_RD */ + heth->State = HAL_ETH_STATE_BUSY_RD; + + /* Get the ETHERNET MACMIIAR value */ + tmpreg1 = heth->Instance->MACMIIAR; + + /* Keep only the CSR Clock Range CR[2:0] bits value */ + tmpreg1 &= ~ETH_MACMIIAR_CR_MASK; + + /* Prepare the MII address register value */ + tmpreg1 |=(((uint32_t)heth->Init.PhyAddress << 11) & ETH_MACMIIAR_PA); /* Set the PHY device address */ + tmpreg1 |=(((uint32_t)PHYReg<<6) & ETH_MACMIIAR_MR); /* Set the PHY register address */ + tmpreg1 &= ~ETH_MACMIIAR_MW; /* Set the read mode */ + tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */ + + /* Write the result value into the MII Address register */ + heth->Instance->MACMIIAR = tmpreg1; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check for the Busy flag */ + while((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > PHY_READ_TO) + { + heth->State= HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + return HAL_TIMEOUT; + } + + tmpreg1 = heth->Instance->MACMIIAR; + } + + /* Get MACMIIDR value */ + *RegValue = (uint16_t)(heth->Instance->MACMIIDR); + + /* Set ETH HAL State to READY */ + heth->State = HAL_ETH_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Writes to a PHY register. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param PHYReg: PHY register address, is the index of one of the 32 PHY register. + * This parameter can be one of the following values: + * PHY_BCR: Transceiver Control Register. + * More PHY register could be written depending on the used PHY + * @param RegValue: the value to write + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue) +{ + uint32_t tmpreg1 = 0; + uint32_t tickstart = 0; + + /* Check parameters */ + assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress)); + + /* Check the ETH peripheral state */ + if(heth->State == HAL_ETH_STATE_BUSY_WR) + { + return HAL_BUSY; + } + /* Set ETH HAL State to BUSY_WR */ + heth->State = HAL_ETH_STATE_BUSY_WR; + + /* Get the ETHERNET MACMIIAR value */ + tmpreg1 = heth->Instance->MACMIIAR; + + /* Keep only the CSR Clock Range CR[2:0] bits value */ + tmpreg1 &= ~ETH_MACMIIAR_CR_MASK; + + /* Prepare the MII register address value */ + tmpreg1 |=(((uint32_t)heth->Init.PhyAddress<<11) & ETH_MACMIIAR_PA); /* Set the PHY device address */ + tmpreg1 |=(((uint32_t)PHYReg<<6) & ETH_MACMIIAR_MR); /* Set the PHY register address */ + tmpreg1 |= ETH_MACMIIAR_MW; /* Set the write mode */ + tmpreg1 |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */ + + /* Give the value to the MII data register */ + heth->Instance->MACMIIDR = (uint16_t)RegValue; + + /* Write the result value into the MII Address register */ + heth->Instance->MACMIIAR = tmpreg1; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check for the Busy flag */ + while((tmpreg1 & ETH_MACMIIAR_MB) == ETH_MACMIIAR_MB) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > PHY_WRITE_TO) + { + heth->State= HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + return HAL_TIMEOUT; + } + + tmpreg1 = heth->Instance->MACMIIAR; + } + + /* Set ETH HAL State to READY */ + heth->State = HAL_ETH_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Enable MAC and DMA transmission and reception. + HAL_ETH_Start(); + (+) Disable MAC and DMA transmission and reception. + HAL_ETH_Stop(); + (+) Set the MAC configuration in runtime mode + HAL_ETH_ConfigMAC(); + (+) Set the DMA configuration in runtime mode + HAL_ETH_ConfigDMA(); + +@endverbatim + * @{ + */ + + /** + * @brief Enables Ethernet MAC and DMA reception/transmission + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth) +{ + /* Process Locked */ + __HAL_LOCK(heth); + + /* Set the ETH peripheral state to BUSY */ + heth->State = HAL_ETH_STATE_BUSY; + + /* Enable transmit state machine of the MAC for transmission on the MII */ + ETH_MACTransmissionEnable(heth); + + /* Enable receive state machine of the MAC for reception from the MII */ + ETH_MACReceptionEnable(heth); + + /* Flush Transmit FIFO */ + ETH_FlushTransmitFIFO(heth); + + /* Start DMA transmission */ + ETH_DMATransmissionEnable(heth); + + /* Start DMA reception */ + ETH_DMAReceptionEnable(heth); + + /* Set the ETH state to READY*/ + heth->State= HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop Ethernet MAC and DMA reception/transmission + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth) +{ + /* Process Locked */ + __HAL_LOCK(heth); + + /* Set the ETH peripheral state to BUSY */ + heth->State = HAL_ETH_STATE_BUSY; + + /* Stop DMA transmission */ + ETH_DMATransmissionDisable(heth); + + /* Stop DMA reception */ + ETH_DMAReceptionDisable(heth); + + /* Disable receive state machine of the MAC for reception from the MII */ + ETH_MACReceptionDisable(heth); + + /* Flush Transmit FIFO */ + ETH_FlushTransmitFIFO(heth); + + /* Disable transmit state machine of the MAC for transmission on the MII */ + ETH_MACTransmissionDisable(heth); + + /* Set the ETH state*/ + heth->State = HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Set ETH MAC Configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param macconf: MAC Configuration structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef *macconf) +{ + uint32_t tmpreg1 = 0; + + /* Process Locked */ + __HAL_LOCK(heth); + + /* Set the ETH peripheral state to BUSY */ + heth->State= HAL_ETH_STATE_BUSY; + + assert_param(IS_ETH_SPEED(heth->Init.Speed)); + assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode)); + + if (macconf != NULL) + { + /* Check the parameters */ + assert_param(IS_ETH_WATCHDOG(macconf->Watchdog)); + assert_param(IS_ETH_JABBER(macconf->Jabber)); + assert_param(IS_ETH_INTER_FRAME_GAP(macconf->InterFrameGap)); + assert_param(IS_ETH_CARRIER_SENSE(macconf->CarrierSense)); + assert_param(IS_ETH_RECEIVE_OWN(macconf->ReceiveOwn)); + assert_param(IS_ETH_LOOPBACK_MODE(macconf->LoopbackMode)); + assert_param(IS_ETH_CHECKSUM_OFFLOAD(macconf->ChecksumOffload)); + assert_param(IS_ETH_RETRY_TRANSMISSION(macconf->RetryTransmission)); + assert_param(IS_ETH_AUTOMATIC_PADCRC_STRIP(macconf->AutomaticPadCRCStrip)); + assert_param(IS_ETH_BACKOFF_LIMIT(macconf->BackOffLimit)); + assert_param(IS_ETH_DEFERRAL_CHECK(macconf->DeferralCheck)); + assert_param(IS_ETH_RECEIVE_ALL(macconf->ReceiveAll)); + assert_param(IS_ETH_SOURCE_ADDR_FILTER(macconf->SourceAddrFilter)); + assert_param(IS_ETH_CONTROL_FRAMES(macconf->PassControlFrames)); + assert_param(IS_ETH_BROADCAST_FRAMES_RECEPTION(macconf->BroadcastFramesReception)); + assert_param(IS_ETH_DESTINATION_ADDR_FILTER(macconf->DestinationAddrFilter)); + assert_param(IS_ETH_PROMISCUOUS_MODE(macconf->PromiscuousMode)); + assert_param(IS_ETH_MULTICAST_FRAMES_FILTER(macconf->MulticastFramesFilter)); + assert_param(IS_ETH_UNICAST_FRAMES_FILTER(macconf->UnicastFramesFilter)); + assert_param(IS_ETH_PAUSE_TIME(macconf->PauseTime)); + assert_param(IS_ETH_ZEROQUANTA_PAUSE(macconf->ZeroQuantaPause)); + assert_param(IS_ETH_PAUSE_LOW_THRESHOLD(macconf->PauseLowThreshold)); + assert_param(IS_ETH_UNICAST_PAUSE_FRAME_DETECT(macconf->UnicastPauseFrameDetect)); + assert_param(IS_ETH_RECEIVE_FLOWCONTROL(macconf->ReceiveFlowControl)); + assert_param(IS_ETH_TRANSMIT_FLOWCONTROL(macconf->TransmitFlowControl)); + assert_param(IS_ETH_VLAN_TAG_COMPARISON(macconf->VLANTagComparison)); + assert_param(IS_ETH_VLAN_TAG_IDENTIFIER(macconf->VLANTagIdentifier)); + + /*------------------------ ETHERNET MACCR Configuration --------------------*/ + /* Get the ETHERNET MACCR value */ + tmpreg1 = (heth->Instance)->MACCR; + /* Clear WD, PCE, PS, TE and RE bits */ + tmpreg1 &= ETH_MACCR_CLEAR_MASK; + + tmpreg1 |= (uint32_t)(macconf->Watchdog | + macconf->Jabber | + macconf->InterFrameGap | + macconf->CarrierSense | + (heth->Init).Speed | + macconf->ReceiveOwn | + macconf->LoopbackMode | + (heth->Init).DuplexMode | + macconf->ChecksumOffload | + macconf->RetryTransmission | + macconf->AutomaticPadCRCStrip | + macconf->BackOffLimit | + macconf->DeferralCheck); + + /* Write to ETHERNET MACCR */ + (heth->Instance)->MACCR = (uint32_t)tmpreg1; + + /* Wait until the write operation will be taken into account : + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACCR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACCR = tmpreg1; + + /*----------------------- ETHERNET MACFFR Configuration --------------------*/ + /* Write to ETHERNET MACFFR */ + (heth->Instance)->MACFFR = (uint32_t)(macconf->ReceiveAll | + macconf->SourceAddrFilter | + macconf->PassControlFrames | + macconf->BroadcastFramesReception | + macconf->DestinationAddrFilter | + macconf->PromiscuousMode | + macconf->MulticastFramesFilter | + macconf->UnicastFramesFilter); + + /* Wait until the write operation will be taken into account : + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACFFR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACFFR = tmpreg1; + + /*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/ + /* Write to ETHERNET MACHTHR */ + (heth->Instance)->MACHTHR = (uint32_t)macconf->HashTableHigh; + + /* Write to ETHERNET MACHTLR */ + (heth->Instance)->MACHTLR = (uint32_t)macconf->HashTableLow; + /*----------------------- ETHERNET MACFCR Configuration --------------------*/ + + /* Get the ETHERNET MACFCR value */ + tmpreg1 = (heth->Instance)->MACFCR; + /* Clear xx bits */ + tmpreg1 &= ETH_MACFCR_CLEAR_MASK; + + tmpreg1 |= (uint32_t)((macconf->PauseTime << 16) | + macconf->ZeroQuantaPause | + macconf->PauseLowThreshold | + macconf->UnicastPauseFrameDetect | + macconf->ReceiveFlowControl | + macconf->TransmitFlowControl); + + /* Write to ETHERNET MACFCR */ + (heth->Instance)->MACFCR = (uint32_t)tmpreg1; + + /* Wait until the write operation will be taken into account : + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACFCR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACFCR = tmpreg1; + + /*----------------------- ETHERNET MACVLANTR Configuration -----------------*/ + (heth->Instance)->MACVLANTR = (uint32_t)(macconf->VLANTagComparison | + macconf->VLANTagIdentifier); + + /* Wait until the write operation will be taken into account : + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACVLANTR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACVLANTR = tmpreg1; + } + else /* macconf == NULL : here we just configure Speed and Duplex mode */ + { + /*------------------------ ETHERNET MACCR Configuration --------------------*/ + /* Get the ETHERNET MACCR value */ + tmpreg1 = (heth->Instance)->MACCR; + + /* Clear FES and DM bits */ + tmpreg1 &= ~((uint32_t)0x00004800); + + tmpreg1 |= (uint32_t)(heth->Init.Speed | heth->Init.DuplexMode); + + /* Write to ETHERNET MACCR */ + (heth->Instance)->MACCR = (uint32_t)tmpreg1; + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACCR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACCR = tmpreg1; + } + + /* Set the ETH state to Ready */ + heth->State= HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Sets ETH DMA Configuration. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param dmaconf: DMA Configuration structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef *dmaconf) +{ + uint32_t tmpreg1 = 0; + + /* Process Locked */ + __HAL_LOCK(heth); + + /* Set the ETH peripheral state to BUSY */ + heth->State= HAL_ETH_STATE_BUSY; + + /* Check parameters */ + assert_param(IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(dmaconf->DropTCPIPChecksumErrorFrame)); + assert_param(IS_ETH_RECEIVE_STORE_FORWARD(dmaconf->ReceiveStoreForward)); + assert_param(IS_ETH_FLUSH_RECEIVE_FRAME(dmaconf->FlushReceivedFrame)); + assert_param(IS_ETH_TRANSMIT_STORE_FORWARD(dmaconf->TransmitStoreForward)); + assert_param(IS_ETH_TRANSMIT_THRESHOLD_CONTROL(dmaconf->TransmitThresholdControl)); + assert_param(IS_ETH_FORWARD_ERROR_FRAMES(dmaconf->ForwardErrorFrames)); + assert_param(IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES(dmaconf->ForwardUndersizedGoodFrames)); + assert_param(IS_ETH_RECEIVE_THRESHOLD_CONTROL(dmaconf->ReceiveThresholdControl)); + assert_param(IS_ETH_SECOND_FRAME_OPERATE(dmaconf->SecondFrameOperate)); + assert_param(IS_ETH_ADDRESS_ALIGNED_BEATS(dmaconf->AddressAlignedBeats)); + assert_param(IS_ETH_FIXED_BURST(dmaconf->FixedBurst)); + assert_param(IS_ETH_RXDMA_BURST_LENGTH(dmaconf->RxDMABurstLength)); + assert_param(IS_ETH_TXDMA_BURST_LENGTH(dmaconf->TxDMABurstLength)); + assert_param(IS_ETH_ENHANCED_DESCRIPTOR_FORMAT(dmaconf->EnhancedDescriptorFormat)); + assert_param(IS_ETH_DMA_DESC_SKIP_LENGTH(dmaconf->DescriptorSkipLength)); + assert_param(IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(dmaconf->DMAArbitration)); + + /*----------------------- ETHERNET DMAOMR Configuration --------------------*/ + /* Get the ETHERNET DMAOMR value */ + tmpreg1 = (heth->Instance)->DMAOMR; + /* Clear xx bits */ + tmpreg1 &= ETH_DMAOMR_CLEAR_MASK; + + tmpreg1 |= (uint32_t)(dmaconf->DropTCPIPChecksumErrorFrame | + dmaconf->ReceiveStoreForward | + dmaconf->FlushReceivedFrame | + dmaconf->TransmitStoreForward | + dmaconf->TransmitThresholdControl | + dmaconf->ForwardErrorFrames | + dmaconf->ForwardUndersizedGoodFrames | + dmaconf->ReceiveThresholdControl | + dmaconf->SecondFrameOperate); + + /* Write to ETHERNET DMAOMR */ + (heth->Instance)->DMAOMR = (uint32_t)tmpreg1; + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->DMAOMR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->DMAOMR = tmpreg1; + + /*----------------------- ETHERNET DMABMR Configuration --------------------*/ + (heth->Instance)->DMABMR = (uint32_t)(dmaconf->AddressAlignedBeats | + dmaconf->FixedBurst | + dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */ + dmaconf->TxDMABurstLength | + dmaconf->EnhancedDescriptorFormat | + (dmaconf->DescriptorSkipLength << 2) | + dmaconf->DMAArbitration | + ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */ + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->DMABMR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->DMABMR = tmpreg1; + + /* Set the ETH state to Ready */ + heth->State= HAL_ETH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(heth); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup ETH_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * + @verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + (+) Get the ETH handle state: + HAL_ETH_GetState(); + + + @endverbatim + * @{ + */ + +/** + * @brief Return the ETH HAL state + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval HAL state + */ +HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth) +{ + /* Return ETH state */ + return heth->State; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup ETH_Private_Functions + * @{ + */ + +/** + * @brief Configures Ethernet MAC and DMA with default parameters. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param err: Ethernet Init error + * @retval HAL status + */ +static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err) +{ + ETH_MACInitTypeDef macinit; + ETH_DMAInitTypeDef dmainit; + uint32_t tmpreg1 = 0; + + if (err != ETH_SUCCESS) /* Auto-negotiation failed */ + { + /* Set Ethernet duplex mode to Full-duplex */ + (heth->Init).DuplexMode = ETH_MODE_FULLDUPLEX; + + /* Set Ethernet speed to 100M */ + (heth->Init).Speed = ETH_SPEED_100M; + } + + /* Ethernet MAC default initialization **************************************/ + macinit.Watchdog = ETH_WATCHDOG_ENABLE; + macinit.Jabber = ETH_JABBER_ENABLE; + macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT; + macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE; + macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE; + macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE; + if(heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE) + { + macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE; + } + else + { + macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE; + } + macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE; + macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE; + macinit.BackOffLimit = ETH_BACKOFFLIMIT_10; + macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE; + macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE; + macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE; + macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL; + macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE; + macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL; + macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE; + macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT; + macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT; + macinit.HashTableHigh = 0x0; + macinit.HashTableLow = 0x0; + macinit.PauseTime = 0x0; + macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE; + macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4; + macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE; + macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE; + macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE; + macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT; + macinit.VLANTagIdentifier = 0x0; + + /*------------------------ ETHERNET MACCR Configuration --------------------*/ + /* Get the ETHERNET MACCR value */ + tmpreg1 = (heth->Instance)->MACCR; + /* Clear WD, PCE, PS, TE and RE bits */ + tmpreg1 &= ETH_MACCR_CLEAR_MASK; + /* Set the WD bit according to ETH Watchdog value */ + /* Set the JD: bit according to ETH Jabber value */ + /* Set the IFG bit according to ETH InterFrameGap value */ + /* Set the DCRS bit according to ETH CarrierSense value */ + /* Set the FES bit according to ETH Speed value */ + /* Set the DO bit according to ETH ReceiveOwn value */ + /* Set the LM bit according to ETH LoopbackMode value */ + /* Set the DM bit according to ETH Mode value */ + /* Set the IPCO bit according to ETH ChecksumOffload value */ + /* Set the DR bit according to ETH RetryTransmission value */ + /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */ + /* Set the BL bit according to ETH BackOffLimit value */ + /* Set the DC bit according to ETH DeferralCheck value */ + tmpreg1 |= (uint32_t)(macinit.Watchdog | + macinit.Jabber | + macinit.InterFrameGap | + macinit.CarrierSense | + (heth->Init).Speed | + macinit.ReceiveOwn | + macinit.LoopbackMode | + (heth->Init).DuplexMode | + macinit.ChecksumOffload | + macinit.RetryTransmission | + macinit.AutomaticPadCRCStrip | + macinit.BackOffLimit | + macinit.DeferralCheck); + + /* Write to ETHERNET MACCR */ + (heth->Instance)->MACCR = (uint32_t)tmpreg1; + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACCR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACCR = tmpreg1; + + /*----------------------- ETHERNET MACFFR Configuration --------------------*/ + /* Set the RA bit according to ETH ReceiveAll value */ + /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */ + /* Set the PCF bit according to ETH PassControlFrames value */ + /* Set the DBF bit according to ETH BroadcastFramesReception value */ + /* Set the DAIF bit according to ETH DestinationAddrFilter value */ + /* Set the PR bit according to ETH PromiscuousMode value */ + /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */ + /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */ + /* Write to ETHERNET MACFFR */ + (heth->Instance)->MACFFR = (uint32_t)(macinit.ReceiveAll | + macinit.SourceAddrFilter | + macinit.PassControlFrames | + macinit.BroadcastFramesReception | + macinit.DestinationAddrFilter | + macinit.PromiscuousMode | + macinit.MulticastFramesFilter | + macinit.UnicastFramesFilter); + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACFFR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACFFR = tmpreg1; + + /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/ + /* Write to ETHERNET MACHTHR */ + (heth->Instance)->MACHTHR = (uint32_t)macinit.HashTableHigh; + + /* Write to ETHERNET MACHTLR */ + (heth->Instance)->MACHTLR = (uint32_t)macinit.HashTableLow; + /*----------------------- ETHERNET MACFCR Configuration -------------------*/ + + /* Get the ETHERNET MACFCR value */ + tmpreg1 = (heth->Instance)->MACFCR; + /* Clear xx bits */ + tmpreg1 &= ETH_MACFCR_CLEAR_MASK; + + /* Set the PT bit according to ETH PauseTime value */ + /* Set the DZPQ bit according to ETH ZeroQuantaPause value */ + /* Set the PLT bit according to ETH PauseLowThreshold value */ + /* Set the UP bit according to ETH UnicastPauseFrameDetect value */ + /* Set the RFE bit according to ETH ReceiveFlowControl value */ + /* Set the TFE bit according to ETH TransmitFlowControl value */ + tmpreg1 |= (uint32_t)((macinit.PauseTime << 16) | + macinit.ZeroQuantaPause | + macinit.PauseLowThreshold | + macinit.UnicastPauseFrameDetect | + macinit.ReceiveFlowControl | + macinit.TransmitFlowControl); + + /* Write to ETHERNET MACFCR */ + (heth->Instance)->MACFCR = (uint32_t)tmpreg1; + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACFCR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACFCR = tmpreg1; + + /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/ + /* Set the ETV bit according to ETH VLANTagComparison value */ + /* Set the VL bit according to ETH VLANTagIdentifier value */ + (heth->Instance)->MACVLANTR = (uint32_t)(macinit.VLANTagComparison | + macinit.VLANTagIdentifier); + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACVLANTR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACVLANTR = tmpreg1; + + /* Ethernet DMA default initialization ************************************/ + dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE; + dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE; + dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE; + dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE; + dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES; + dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE; + dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE; + dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES; + dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE; + dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE; + dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE; + dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT; + dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT; + dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE; + dmainit.DescriptorSkipLength = 0x0; + dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1; + + /* Get the ETHERNET DMAOMR value */ + tmpreg1 = (heth->Instance)->DMAOMR; + /* Clear xx bits */ + tmpreg1 &= ETH_DMAOMR_CLEAR_MASK; + + /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */ + /* Set the RSF bit according to ETH ReceiveStoreForward value */ + /* Set the DFF bit according to ETH FlushReceivedFrame value */ + /* Set the TSF bit according to ETH TransmitStoreForward value */ + /* Set the TTC bit according to ETH TransmitThresholdControl value */ + /* Set the FEF bit according to ETH ForwardErrorFrames value */ + /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */ + /* Set the RTC bit according to ETH ReceiveThresholdControl value */ + /* Set the OSF bit according to ETH SecondFrameOperate value */ + tmpreg1 |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame | + dmainit.ReceiveStoreForward | + dmainit.FlushReceivedFrame | + dmainit.TransmitStoreForward | + dmainit.TransmitThresholdControl | + dmainit.ForwardErrorFrames | + dmainit.ForwardUndersizedGoodFrames | + dmainit.ReceiveThresholdControl | + dmainit.SecondFrameOperate); + + /* Write to ETHERNET DMAOMR */ + (heth->Instance)->DMAOMR = (uint32_t)tmpreg1; + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->DMAOMR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->DMAOMR = tmpreg1; + + /*----------------------- ETHERNET DMABMR Configuration ------------------*/ + /* Set the AAL bit according to ETH AddressAlignedBeats value */ + /* Set the FB bit according to ETH FixedBurst value */ + /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */ + /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */ + /* Set the Enhanced DMA descriptors bit according to ETH EnhancedDescriptorFormat value*/ + /* Set the DSL bit according to ETH DesciptorSkipLength value */ + /* Set the PR and DA bits according to ETH DMAArbitration value */ + (heth->Instance)->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats | + dmainit.FixedBurst | + dmainit.RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */ + dmainit.TxDMABurstLength | + dmainit.EnhancedDescriptorFormat | + (dmainit.DescriptorSkipLength << 2) | + dmainit.DMAArbitration | + ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */ + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->DMABMR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->DMABMR = tmpreg1; + + if((heth->Init).RxMode == ETH_RXINTERRUPT_MODE) + { + /* Enable the Ethernet Rx Interrupt */ + __HAL_ETH_DMA_ENABLE_IT((heth), ETH_DMA_IT_NIS | ETH_DMA_IT_R); + } + + /* Initialize MAC address in ethernet MAC */ + ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr); +} + +/** + * @brief Configures the selected MAC address. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @param MacAddr: The MAC address to configure + * This parameter can be one of the following values: + * @arg ETH_MAC_Address0: MAC Address0 + * @arg ETH_MAC_Address1: MAC Address1 + * @arg ETH_MAC_Address2: MAC Address2 + * @arg ETH_MAC_Address3: MAC Address3 + * @param Addr: Pointer to MAC address buffer data (6 bytes) + * @retval HAL status + */ +static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr) +{ + uint32_t tmpreg1; + + /* Check the parameters */ + assert_param(IS_ETH_MAC_ADDRESS0123(MacAddr)); + + /* Calculate the selected MAC address high register */ + tmpreg1 = ((uint32_t)Addr[5] << 8) | (uint32_t)Addr[4]; + /* Load the selected MAC address high register */ + (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_HBASE + MacAddr))) = tmpreg1; + /* Calculate the selected MAC address low register */ + tmpreg1 = ((uint32_t)Addr[3] << 24) | ((uint32_t)Addr[2] << 16) | ((uint32_t)Addr[1] << 8) | Addr[0]; + + /* Load the selected MAC address low register */ + (*(__IO uint32_t *)((uint32_t)(ETH_MAC_ADDR_LBASE + MacAddr))) = tmpreg1; +} + +/** + * @brief Enables the MAC transmission. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth) +{ + __IO uint32_t tmpreg1 = 0; + + /* Enable the MAC transmission */ + (heth->Instance)->MACCR |= ETH_MACCR_TE; + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACCR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACCR = tmpreg1; +} + +/** + * @brief Disables the MAC transmission. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth) +{ + __IO uint32_t tmpreg1 = 0; + + /* Disable the MAC transmission */ + (heth->Instance)->MACCR &= ~ETH_MACCR_TE; + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACCR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACCR = tmpreg1; +} + +/** + * @brief Enables the MAC reception. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth) +{ + __IO uint32_t tmpreg1 = 0; + + /* Enable the MAC reception */ + (heth->Instance)->MACCR |= ETH_MACCR_RE; + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACCR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACCR = tmpreg1; +} + +/** + * @brief Disables the MAC reception. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth) +{ + __IO uint32_t tmpreg1 = 0; + + /* Disable the MAC reception */ + (heth->Instance)->MACCR &= ~ETH_MACCR_RE; + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->MACCR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->MACCR = tmpreg1; +} + +/** + * @brief Enables the DMA transmission. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth) +{ + /* Enable the DMA transmission */ + (heth->Instance)->DMAOMR |= ETH_DMAOMR_ST; +} + +/** + * @brief Disables the DMA transmission. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth) +{ + /* Disable the DMA transmission */ + (heth->Instance)->DMAOMR &= ~ETH_DMAOMR_ST; +} + +/** + * @brief Enables the DMA reception. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth) +{ + /* Enable the DMA reception */ + (heth->Instance)->DMAOMR |= ETH_DMAOMR_SR; +} + +/** + * @brief Disables the DMA reception. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth) +{ + /* Disable the DMA reception */ + (heth->Instance)->DMAOMR &= ~ETH_DMAOMR_SR; +} + +/** + * @brief Clears the ETHERNET transmit FIFO. + * @param heth: pointer to a ETH_HandleTypeDef structure that contains + * the configuration information for ETHERNET module + * @retval None + */ +static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth) +{ + __IO uint32_t tmpreg1 = 0; + + /* Set the Flush Transmit FIFO bit */ + (heth->Instance)->DMAOMR |= ETH_DMAOMR_FTF; + + /* Wait until the write operation will be taken into account: + at least four TX_CLK/RX_CLK clock cycles */ + tmpreg1 = (heth->Instance)->DMAOMR; + HAL_Delay(ETH_REG_WRITE_DELAY); + (heth->Instance)->DMAOMR = tmpreg1; +} + +/** + * @} + */ + +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +#endif /* HAL_ETH_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c new file mode 100644 index 0000000..4492f55 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c @@ -0,0 +1,761 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_flash.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief FLASH HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the internal FLASH memory: + * + Program operations functions + * + Memory Control functions + * + Peripheral Errors functions + * + @verbatim + ============================================================================== + ##### FLASH peripheral features ##### + ============================================================================== + + [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses + to the Flash memory. It implements the erase and program Flash memory operations + and the read and write protection mechanisms. + + [..] The Flash memory interface accelerates code execution with a system of instruction + prefetch and cache lines. + + [..] The FLASH main features are: + (+) Flash memory read operations + (+) Flash memory program/erase operations + (+) Read / write protections + (+) Prefetch on I-Code + (+) 64 cache lines of 128 bits on I-Code + (+) 8 cache lines of 128 bits on D-Code + + + ##### How to use this driver ##### + ============================================================================== + [..] + This driver provides functions and macros to configure and program the FLASH + memory of all STM32F4xx devices. + + (#) FLASH Memory IO Programming functions: + (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and + HAL_FLASH_Lock() functions + (++) Program functions: byte, half word, word and double word + (++) There Two modes of programming : + (+++) Polling mode using HAL_FLASH_Program() function + (+++) Interrupt mode using HAL_FLASH_Program_IT() function + + (#) Interrupts and flags management functions : + (++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler() + (++) Wait for last FLASH operation according to its status + (++) Get error flag status by calling HAL_SetErrorCode() + + [..] + In addition to these functions, this driver includes a set of macros allowing + to handle the following operations: + (+) Set the latency + (+) Enable/Disable the prefetch buffer + (+) Enable/Disable the Instruction cache and the Data cache + (+) Reset the Instruction cache and the Data cache + (+) Enable/Disable the FLASH interrupts + (+) Monitor the FLASH flags status + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 FLASH FLASH + * @brief FLASH HAL module driver + * @{ + */ + +#ifdef HAL_FLASH_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup FLASH_Private_Constants + * @{ + */ +#define SECTOR_MASK ((uint32_t)0xFFFFFF07) +#define FLASH_TIMEOUT_VALUE ((uint32_t)50000)/* 50 s */ +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @addtogroup FLASH_Private_Variables + * @{ + */ +/* Variable used for Erase sectors under interruption */ +FLASH_ProcessTypeDef pFlash; +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup FLASH_Private_Functions + * @{ + */ +/* Program operations */ +static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data); +static void FLASH_Program_Word(uint32_t Address, uint32_t Data); +static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data); +static void FLASH_Program_Byte(uint32_t Address, uint8_t Data); +static void FLASH_SetErrorCode(void); + +HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup FLASH_Exported_Functions FLASH Exported Functions + * @{ + */ + +/** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions + * @brief Programming operation functions + * +@verbatim + =============================================================================== + ##### Programming operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the FLASH + program operations. + +@endverbatim + * @{ + */ + +/** + * @brief Program byte, halfword, word or double word at a specified address + * @param TypeProgram: Indicate the way to program at a specified address. + * This parameter can be a value of @ref FLASH_Type_Program + * @param Address: specifies the address to be programmed. + * @param Data: specifies the data to be programmed + * + * @retval HAL_StatusTypeDef HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data) +{ + HAL_StatusTypeDef status = HAL_ERROR; + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Check the parameters */ + assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + if(TypeProgram == FLASH_TYPEPROGRAM_BYTE) + { + /*Program byte (8-bit) at a specified address.*/ + FLASH_Program_Byte(Address, (uint8_t) Data); + } + else if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD) + { + /*Program halfword (16-bit) at a specified address.*/ + FLASH_Program_HalfWord(Address, (uint16_t) Data); + } + else if(TypeProgram == FLASH_TYPEPROGRAM_WORD) + { + /*Program word (32-bit) at a specified address.*/ + FLASH_Program_Word(Address, (uint32_t) Data); + } + else + { + /*Program double word (64-bit) at a specified address.*/ + FLASH_Program_DoubleWord(Address, Data); + } + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + /* If the program operation is completed, disable the PG Bit */ + FLASH->CR &= (~FLASH_CR_PG); + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + return status; +} + +/** + * @brief Program byte, halfword, word or double word at a specified address with interrupt enabled. + * @param TypeProgram: Indicate the way to program at a specified address. + * This parameter can be a value of @ref FLASH_Type_Program + * @param Address: specifies the address to be programmed. + * @param Data: specifies the data to be programmed + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Check the parameters */ + assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); + + /* Enable End of FLASH Operation interrupt */ + __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP); + + /* Enable Error source interrupt */ + __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR); + + /* Clear pending flags (if any) */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |\ + FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR| FLASH_FLAG_PGSERR); + + pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM; + pFlash.Address = Address; + + if(TypeProgram == FLASH_TYPEPROGRAM_BYTE) + { + /*Program byte (8-bit) at a specified address.*/ + FLASH_Program_Byte(Address, (uint8_t) Data); + } + else if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD) + { + /*Program halfword (16-bit) at a specified address.*/ + FLASH_Program_HalfWord(Address, (uint16_t) Data); + } + else if(TypeProgram == FLASH_TYPEPROGRAM_WORD) + { + /*Program word (32-bit) at a specified address.*/ + FLASH_Program_Word(Address, (uint32_t) Data); + } + else + { + /*Program double word (64-bit) at a specified address.*/ + FLASH_Program_DoubleWord(Address, Data); + } + + return status; +} + +/** + * @brief This function handles FLASH interrupt request. + * @retval None + */ +void HAL_FLASH_IRQHandler(void) +{ + uint32_t temp; + + /* If the program operation is completed, disable the PG Bit */ + FLASH->CR &= (~FLASH_CR_PG); + + /* If the erase operation is completed, disable the SER Bit */ + FLASH->CR &= (~FLASH_CR_SER); + FLASH->CR &= SECTOR_MASK; + + /* if the erase operation is completed, disable the MER Bit */ + FLASH->CR &= (~FLASH_MER_BIT); + + /* Check FLASH End of Operation flag */ + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET) + { + if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE) + { + /*Nb of sector to erased can be decreased*/ + pFlash.NbSectorsToErase--; + + /* Check if there are still sectors to erase*/ + if(pFlash.NbSectorsToErase != 0) + { + temp = pFlash.Sector; + /*Indicate user which sector has been erased*/ + HAL_FLASH_EndOfOperationCallback(temp); + + /* Clear pending flags (if any) */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |\ + FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR| FLASH_FLAG_PGSERR); + + /*Increment sector number*/ + pFlash.Sector++; + temp = pFlash.Sector; + FLASH_Erase_Sector(temp, pFlash.VoltageForErase); + } + else + { + /*No more sectors to Erase, user callback can be called.*/ + /*Reset Sector and stop Erase sectors procedure*/ + pFlash.Sector = temp = 0xFFFFFFFF; + pFlash.ProcedureOnGoing = FLASH_PROC_NONE; + /* FLASH EOP interrupt user callback */ + HAL_FLASH_EndOfOperationCallback(temp); + /* Clear FLASH End of Operation pending bit */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); + } + } + else + { + if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE) + { + /*MassErase ended. Return the selected bank*/ + /* FLASH EOP interrupt user callback */ + HAL_FLASH_EndOfOperationCallback(pFlash.Bank); + } + else + { + /*Program ended. Return the selected address*/ + /* FLASH EOP interrupt user callback */ + HAL_FLASH_EndOfOperationCallback(pFlash.Address); + } + pFlash.ProcedureOnGoing = FLASH_PROC_NONE; + /* Clear FLASH End of Operation pending bit */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); + } + + } + + /* Check FLASH operation error flags */ + if(__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \ + FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_RDERR)) != RESET) + { + if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE) + { + /*return the faulty sector*/ + temp = pFlash.Sector; + pFlash.Sector = 0xFFFFFFFF; + } + else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE) + { + /*return the faulty bank*/ + temp = pFlash.Bank; + } + else + { + /*return the faulty address*/ + temp = pFlash.Address; + } + + /*Save the Error code*/ + FLASH_SetErrorCode(); + + /* FLASH error interrupt user callback */ + HAL_FLASH_OperationErrorCallback(temp); + /* Clear FLASH error pending bits */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR |\ + FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_RDERR); + + /*Stop the procedure ongoing*/ + pFlash.ProcedureOnGoing = FLASH_PROC_NONE; + } + + if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE) + { + /* Disable End of FLASH Operation interrupt */ + __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP); + + /* Disable Error source interrupt */ + __HAL_FLASH_DISABLE_IT(FLASH_IT_ERR); + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + } + +} + +/** + * @brief FLASH end of operation interrupt callback + * @param ReturnValue: The value saved in this parameter depends on the ongoing procedure + * Mass Erase: Bank number which has been requested to erase + * Sectors Erase: Sector which has been erased + * (if 0xFFFFFFFF, it means that all the selected sectors have been erased) + * Program: Address which was selected for data program + * @retval None + */ +__weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_FLASH_EndOfOperationCallback could be implemented in the user file + */ +} + +/** + * @brief FLASH operation error interrupt callback + * @param ReturnValue: The value saved in this parameter depends on the ongoing procedure + * Mass Erase: Bank number which has been requested to erase + * Sectors Erase: Sector number which returned an error + * Program: Address which was selected for data program + * @retval None + */ +__weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_FLASH_OperationErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions + * @brief management functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the FLASH + memory operations. + +@endverbatim + * @{ + */ + +/** + * @brief Unlock the FLASH control register access + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_Unlock(void) +{ + if((FLASH->CR & FLASH_CR_LOCK) != RESET) + { + /* Authorize the FLASH Registers access */ + FLASH->KEYR = FLASH_KEY1; + FLASH->KEYR = FLASH_KEY2; + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Locks the FLASH control register access + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_Lock(void) +{ + /* Set the LOCK Bit to lock the FLASH Registers access */ + FLASH->CR |= FLASH_CR_LOCK; + + return HAL_OK; +} + +/** + * @brief Unlock the FLASH Option Control Registers access. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void) +{ + if((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != RESET) + { + /* Authorizes the Option Byte register programming */ + FLASH->OPTKEYR = FLASH_OPT_KEY1; + FLASH->OPTKEYR = FLASH_OPT_KEY2; + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Lock the FLASH Option Control Registers access. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_OB_Lock(void) +{ + /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */ + FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK; + + return HAL_OK; +} + +/** + * @brief Launch the option byte loading. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASH_OB_Launch(void) +{ + /* Set the OPTSTRT bit in OPTCR register */ + *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS |= FLASH_OPTCR_OPTSTRT; + + /* Wait for last operation to be completed */ + return(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE)); +} + +/** + * @} + */ + +/** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief Peripheral Errors functions + * +@verbatim + =============================================================================== + ##### Peripheral Errors functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time Errors of the FLASH peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Get the specific FLASH error flag. + * @retval FLASH_ErrorCode: The returned value can be a combination of: + * @arg HAL_FLASH_ERROR_RD: FLASH Read Protection error flag (PCROP) + * @arg HAL_FLASH_ERROR_PGS: FLASH Programming Sequence error flag + * @arg HAL_FLASH_ERROR_PGP: FLASH Programming Parallelism error flag + * @arg HAL_FLASH_ERROR_PGA: FLASH Programming Alignment error flag + * @arg HAL_FLASH_ERROR_WRP: FLASH Write protected error flag + * @arg HAL_FLASH_ERROR_OPERATION: FLASH operation Error flag + */ +uint32_t HAL_FLASH_GetError(void) +{ + return pFlash.ErrorCode; +} + +/** + * @} + */ + +/** + * @brief Wait for a FLASH operation to complete. + * @param Timeout: maximum flash operationtimeout + * @retval HAL Status + */ +HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Clear Error Code */ + pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; + + /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset. + Even if the FLASH operation fails, the BUSY flag will be reset and an error + flag will be set */ + /* Get tick */ + tickstart = HAL_GetTick(); + + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET) + { + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + return HAL_TIMEOUT; + } + } + } + + if(__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \ + FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_RDERR)) != RESET) + { + /*Save the error code*/ + FLASH_SetErrorCode(); + return HAL_ERROR; + } + + /* If there is an error flag set */ + return HAL_OK; + +} + +/** + * @brief Program a double word (64-bit) at a specified address. + * @note This function must be used when the device voltage range is from + * 2.7V to 3.6V and an External Vpp is present. + * + * @note If an erase and a program operations are requested simultaneously, + * the erase operation is performed before the program one. + * + * @param Address: specifies the address to be programmed. + * @param Data: specifies the data to be programmed. + * @retval None + */ +static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data) +{ + /* Check the parameters */ + assert_param(IS_FLASH_ADDRESS(Address)); + + /* If the previous operation is completed, proceed to program the new data */ + FLASH->CR &= CR_PSIZE_MASK; + FLASH->CR |= FLASH_PSIZE_DOUBLE_WORD; + FLASH->CR |= FLASH_CR_PG; + + *(__IO uint64_t*)Address = Data; +} + + +/** + * @brief Program word (32-bit) at a specified address. + * @note This function must be used when the device voltage range is from + * 2.7V to 3.6V. + * + * @note If an erase and a program operations are requested simultaneously, + * the erase operation is performed before the program one. + * + * @param Address: specifies the address to be programmed. + * @param Data: specifies the data to be programmed. + * @retval None + */ +static void FLASH_Program_Word(uint32_t Address, uint32_t Data) +{ + /* Check the parameters */ + assert_param(IS_FLASH_ADDRESS(Address)); + + /* If the previous operation is completed, proceed to program the new data */ + FLASH->CR &= CR_PSIZE_MASK; + FLASH->CR |= FLASH_PSIZE_WORD; + FLASH->CR |= FLASH_CR_PG; + + *(__IO uint32_t*)Address = Data; +} + +/** + * @brief Program a half-word (16-bit) at a specified address. + * @note This function must be used when the device voltage range is from + * 2.7V to 3.6V. + * + * @note If an erase and a program operations are requested simultaneously, + * the erase operation is performed before the program one. + * + * @param Address: specifies the address to be programmed. + * @param Data: specifies the data to be programmed. + * @retval None + */ +static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data) +{ + /* Check the parameters */ + assert_param(IS_FLASH_ADDRESS(Address)); + + /* If the previous operation is completed, proceed to program the new data */ + FLASH->CR &= CR_PSIZE_MASK; + FLASH->CR |= FLASH_PSIZE_HALF_WORD; + FLASH->CR |= FLASH_CR_PG; + + *(__IO uint16_t*)Address = Data; +} + +/** + * @brief Program byte (8-bit) at a specified address. + * @note This function must be used when the device voltage range is from + * 2.7V to 3.6V. + * + * @note If an erase and a program operations are requested simultaneously, + * the erase operation is performed before the program one. + * + * @param Address: specifies the address to be programmed. + * @param Data: specifies the data to be programmed. + * @retval None + */ +static void FLASH_Program_Byte(uint32_t Address, uint8_t Data) +{ + /* Check the parameters */ + assert_param(IS_FLASH_ADDRESS(Address)); + + /* If the previous operation is completed, proceed to program the new data */ + FLASH->CR &= CR_PSIZE_MASK; + FLASH->CR |= FLASH_PSIZE_BYTE; + FLASH->CR |= FLASH_CR_PG; + + *(__IO uint8_t*)Address = Data; +} + +/** + * @brief Set the specific FLASH error flag. + * @retval None + */ +static void FLASH_SetErrorCode(void) +{ + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) != RESET) + { + pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP; + } + + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) != RESET) + { + pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA; + } + + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGPERR) != RESET) + { + pFlash.ErrorCode |= HAL_FLASH_ERROR_PGP; + } + + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR) != RESET) + { + pFlash.ErrorCode |= HAL_FLASH_ERROR_PGS; + } + + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) != RESET) + { + pFlash.ErrorCode |= HAL_FLASH_ERROR_RD; + } + + if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR) != RESET) + { + pFlash.ErrorCode |= HAL_FLASH_ERROR_OPERATION; + } +} + +/** + * @} + */ + +#endif /* HAL_FLASH_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c new file mode 100644 index 0000000..97ee094 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c @@ -0,0 +1,1316 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_flash_ex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Extended FLASH HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the FLASH extension peripheral: + * + Extended programming operations functions + * + @verbatim + ============================================================================== + ##### Flash Extension features ##### + ============================================================================== + + [..] Comparing to other previous devices, the FLASH interface for STM32F427xx/437xx and + STM32F429xx/439xx devices contains the following additional features + + (+) Capacity up to 2 Mbyte with dual bank architecture supporting read-while-write + capability (RWW) + (+) Dual bank memory organization + (+) PCROP protection for all banks + + ##### How to use this driver ##### + ============================================================================== + [..] This driver provides functions to configure and program the FLASH memory + of all STM32F427xx/437xx andSTM32F429xx/439xx devices. It includes + (#) FLASH Memory Erase functions: + (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and + HAL_FLASH_Lock() functions + (++) Erase function: Erase sector, erase all sectors + (++) There are two modes of erase : + (+++) Polling Mode using HAL_FLASHEx_Erase() + (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT() + + (#) Option Bytes Programming functions: Use HAL_FLASHEx_OBProgram() to : + (++) Set/Reset the write protection + (++) Set the Read protection Level + (++) Set the BOR level + (++) Program the user Option Bytes + (#) Advanced Option Bytes Programming functions: Use HAL_FLASHEx_AdvOBProgram() to : + (++) Extended space (bank 2) erase function + (++) Full FLASH space (2 Mo) erase (bank 1 and bank 2) + (++) Dual Boot activation + (++) Write protection configuration for bank 2 + (++) PCROP protection configuration and control for both banks + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 FLASHEx FLASHEx + * @brief FLASH HAL Extension module driver + * @{ + */ + +#ifdef HAL_FLASH_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup FLASHEx_Private_Constants + * @{ + */ +#define SECTOR_MASK ((uint32_t)0xFFFFFF07) +#define FLASH_TIMEOUT_VALUE ((uint32_t)50000)/* 50 s */ +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @addtogroup FLASHEx_Private_Variables + * @{ + */ +extern FLASH_ProcessTypeDef pFlash; +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup FLASHEx_Private_Functions + * @{ + */ +/* Option bytes control */ +static void FLASH_MassErase(uint8_t VoltageRange, uint32_t Banks); +static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks); +static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks); +static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t Level); +static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t Iwdg, uint8_t Stop, uint8_t Stdby); +static HAL_StatusTypeDef FLASH_OB_BOR_LevelConfig(uint8_t Level); +static uint8_t FLASH_OB_GetUser(void); +static uint16_t FLASH_OB_GetWRP(void); +static uint8_t FLASH_OB_GetRDP(void); +static uint8_t FLASH_OB_GetBOR(void); + +#if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) +static HAL_StatusTypeDef FLASH_OB_EnablePCROP(uint32_t Sector); +static HAL_StatusTypeDef FLASH_OB_DisablePCROP(uint32_t Sector); +#endif /* STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) +static HAL_StatusTypeDef FLASH_OB_EnablePCROP(uint32_t SectorBank1, uint32_t SectorBank2, uint32_t Banks); +static HAL_StatusTypeDef FLASH_OB_DisablePCROP(uint32_t SectorBank1, uint32_t SectorBank2, uint32_t Banks); +static HAL_StatusTypeDef FLASH_OB_BootConfig(uint8_t BootConfig); +#endif /* STM32F427xx || STM32F437xx || STM32F429xx|| STM32F439xx */ + +extern HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions + * @{ + */ + +/** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions + * @brief Extended IO operation functions + * +@verbatim + =============================================================================== + ##### Extended programming operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the Extension FLASH + programming operations Operations. + +@endverbatim + * @{ + */ +/** + * @brief Perform a mass erase or erase the specified FLASH memory sectors + * @param[in] pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that + * contains the configuration information for the erasing. + * + * @param[out] SectorError: pointer to variable that + * contains the configuration information on faulty sector in case of error + * (0xFFFFFFFF means that all the sectors have been correctly erased) + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError) +{ + HAL_StatusTypeDef status = HAL_ERROR; + uint32_t index = 0; + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Check the parameters */ + assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + /*Initialization of SectorError variable*/ + *SectorError = 0xFFFFFFFF; + + if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) + { + /*Mass erase to be done*/ + FLASH_MassErase((uint8_t) pEraseInit->VoltageRange, pEraseInit->Banks); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + /* if the erase operation is completed, disable the MER Bit */ + FLASH->CR &= (~FLASH_MER_BIT); + } + else + { + /* Check the parameters */ + assert_param(IS_FLASH_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector)); + + /* Erase by sector by sector to be done*/ + for(index = pEraseInit->Sector; index < (pEraseInit->NbSectors + pEraseInit->Sector); index++) + { + FLASH_Erase_Sector(index, (uint8_t) pEraseInit->VoltageRange); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + /* If the erase operation is completed, disable the SER Bit */ + FLASH->CR &= (~FLASH_CR_SER); + FLASH->CR &= SECTOR_MASK; + + if(status != HAL_OK) + { + /* In case of error, stop erase procedure and return the faulty sector*/ + *SectorError = index; + break; + } + } + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + return status; +} + +/** + * @brief Perform a mass erase or erase the specified FLASH memory sectors with interrupt enabled + * @param pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that + * contains the configuration information for the erasing. + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Check the parameters */ + assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); + + /* Enable End of FLASH Operation interrupt */ + __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP); + + /* Enable Error source interrupt */ + __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR); + + /* Clear pending flags (if any) */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |\ + FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR| FLASH_FLAG_PGSERR); + + if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) + { + /*Mass erase to be done*/ + pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE; + pFlash.Bank = pEraseInit->Banks; + FLASH_MassErase((uint8_t) pEraseInit->VoltageRange, pEraseInit->Banks); + } + else + { + /* Erase by sector to be done*/ + + /* Check the parameters */ + assert_param(IS_FLASH_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector)); + + pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE; + pFlash.NbSectorsToErase = pEraseInit->NbSectors; + pFlash.Sector = pEraseInit->Sector; + pFlash.VoltageForErase = (uint8_t)pEraseInit->VoltageRange; + + /*Erase 1st sector and wait for IT*/ + FLASH_Erase_Sector(pEraseInit->Sector, pEraseInit->VoltageRange); + } + + return status; +} + +/** + * @brief Program option bytes + * @param pOBInit: pointer to an FLASH_OBInitStruct structure that + * contains the configuration information for the programming. + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit) +{ + HAL_StatusTypeDef status = HAL_ERROR; + + /* Process Locked */ + __HAL_LOCK(&pFlash); + + /* Check the parameters */ + assert_param(IS_OPTIONBYTE(pOBInit->OptionType)); + + /*Write protection configuration*/ + if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP) + { + assert_param(IS_WRPSTATE(pOBInit->WRPState)); + if(pOBInit->WRPState == OB_WRPSTATE_ENABLE) + { + /*Enable of Write protection on the selected Sector*/ + status = FLASH_OB_EnableWRP(pOBInit->WRPSector, pOBInit->Banks); + } + else + { + /*Disable of Write protection on the selected Sector*/ + status = FLASH_OB_DisableWRP(pOBInit->WRPSector, pOBInit->Banks); + } + } + + /*Read protection configuration*/ + if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP) + { + status = FLASH_OB_RDP_LevelConfig(pOBInit->RDPLevel); + } + + /*USER configuration*/ + if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER) + { + status = FLASH_OB_UserConfig(pOBInit->USERConfig&OB_IWDG_SW, + pOBInit->USERConfig&OB_STOP_NO_RST, + pOBInit->USERConfig&OB_STDBY_NO_RST); + } + + /*BOR Level configuration*/ + if((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR) + { + status = FLASH_OB_BOR_LevelConfig(pOBInit->BORLevel); + } + + /* Process Unlocked */ + __HAL_UNLOCK(&pFlash); + + return status; +} + +/** + * @brief Get the Option byte configuration + * @param pOBInit: pointer to an FLASH_OBInitStruct structure that + * contains the configuration information for the programming. + * + * @retval None + */ +void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit) +{ + pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER | OPTIONBYTE_BOR; + + /*Get WRP*/ + pOBInit->WRPSector = (uint32_t)FLASH_OB_GetWRP(); + + /*Get RDP Level*/ + pOBInit->RDPLevel = (uint32_t)FLASH_OB_GetRDP(); + + /*Get USER*/ + pOBInit->USERConfig = (uint8_t)FLASH_OB_GetUser(); + + /*Get BOR Level*/ + pOBInit->BORLevel = (uint32_t)FLASH_OB_GetBOR(); +} + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) +/** + * @brief Program option bytes + * @param pAdvOBInit: pointer to an FLASH_AdvOBProgramInitTypeDef structure that + * contains the configuration information for the programming. + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_AdvOBProgram (FLASH_AdvOBProgramInitTypeDef *pAdvOBInit) +{ + HAL_StatusTypeDef status = HAL_ERROR; + + /* Check the parameters */ + assert_param(IS_OBEX(pAdvOBInit->OptionType)); + + /*Program PCROP option byte*/ + if(((pAdvOBInit->OptionType) & OPTIONBYTE_PCROP) == OPTIONBYTE_PCROP) + { + /* Check the parameters */ + assert_param(IS_PCROPSTATE(pAdvOBInit->PCROPState)); + if((pAdvOBInit->PCROPState) == OB_PCROP_STATE_ENABLE) + { + /*Enable of Write protection on the selected Sector*/ +#if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) + status = FLASH_OB_EnablePCROP(pAdvOBInit->Sectors); +#else /* STM32F427xx || STM32F437xx || STM32F429xx|| STM32F439xx */ + status = FLASH_OB_EnablePCROP(pAdvOBInit->SectorsBank1, pAdvOBInit->SectorsBank2, pAdvOBInit->Banks); +#endif /* STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx */ + } + else + { + /*Disable of Write protection on the selected Sector*/ +#if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) + status = FLASH_OB_DisablePCROP(pAdvOBInit->Sectors); +#else /* STM32F427xx || STM32F437xx || STM32F429xx|| STM32F439xx */ + status = FLASH_OB_DisablePCROP(pAdvOBInit->SectorsBank1, pAdvOBInit->SectorsBank2, pAdvOBInit->Banks); +#endif /* STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx */ + } + } + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) + /*Program BOOT config option byte*/ + if(((pAdvOBInit->OptionType) & OPTIONBYTE_BOOTCONFIG) == OPTIONBYTE_BOOTCONFIG) + { + status = FLASH_OB_BootConfig(pAdvOBInit->BootConfig); + } +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + + return status; +} + +/** + * @brief Get the OBEX byte configuration + * @param pAdvOBInit: pointer to an FLASH_AdvOBProgramInitTypeDef structure that + * contains the configuration information for the programming. + * + * @retval None + */ +void HAL_FLASHEx_AdvOBGetConfig(FLASH_AdvOBProgramInitTypeDef *pAdvOBInit) +{ +#if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) + /*Get Sector*/ + pAdvOBInit->Sectors = (*(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS)); +#else /* STM32F427xx || STM32F437xx || STM32F429xx|| STM32F439xx */ + /*Get Sector for Bank1*/ + pAdvOBInit->SectorsBank1 = (*(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS)); + + /*Get Sector for Bank2*/ + pAdvOBInit->SectorsBank2 = (*(__IO uint16_t *)(OPTCR1_BYTE2_ADDRESS)); + + /*Get Boot config OB*/ + pAdvOBInit->BootConfig = *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS; +#endif /* STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx */ +} + +/** + * @brief Select the Protection Mode + * + * @note After PCROP activated Option Byte modification NOT POSSIBLE! excepted + * Global Read Out Protection modification (from level1 to level0) + * @note Once SPRMOD bit is active unprotection of a protected sector is not possible + * @note Read a protected sector will set RDERR Flag and write a protected sector will set WRPERR Flag + * @note This function can be used only for STM32F42xxx/STM32F43xxx/STM32F401xx/STM32F411xx/STM32F446xx devices. + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_OB_SelectPCROP(void) +{ + uint8_t optiontmp = 0xFF; + + /* Mask SPRMOD bit */ + optiontmp = (uint8_t)((*(__IO uint8_t *)OPTCR_BYTE3_ADDRESS) & (uint8_t)0x7F); + + /* Update Option Byte */ + *(__IO uint8_t *)OPTCR_BYTE3_ADDRESS = (uint8_t)(OB_PCROP_SELECTED | optiontmp); + + return HAL_OK; +} + +/** + * @brief Deselect the Protection Mode + * + * @note After PCROP activated Option Byte modification NOT POSSIBLE! excepted + * Global Read Out Protection modification (from level1 to level0) + * @note Once SPRMOD bit is active unprotection of a protected sector is not possible + * @note Read a protected sector will set RDERR Flag and write a protected sector will set WRPERR Flag + * @note This function can be used only for STM32F42xxx/STM32F43xxx/STM32F401xx/STM32F411xx/STM32F446xx devices. + * + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_FLASHEx_OB_DeSelectPCROP(void) +{ + uint8_t optiontmp = 0xFF; + + /* Mask SPRMOD bit */ + optiontmp = (uint8_t)((*(__IO uint8_t *)OPTCR_BYTE3_ADDRESS) & (uint8_t)0x7F); + + /* Update Option Byte */ + *(__IO uint8_t *)OPTCR_BYTE3_ADDRESS = (uint8_t)(OB_PCROP_DESELECTED | optiontmp); + + return HAL_OK; +} +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F401xC || STM32F401xE || STM32F411xE */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) +/** + * @brief Returns the FLASH Write Protection Option Bytes value for Bank 2 + * @note This function can be used only for STM32F427X and STM32F429X devices. + * @retval The FLASH Write Protection Option Bytes value + */ +uint16_t HAL_FLASHEx_OB_GetBank2WRP(void) +{ + /* Return the FLASH write protection Register value */ + return (*(__IO uint16_t *)(OPTCR1_BYTE2_ADDRESS)); +} +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +/** + * @} + */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) +/** + * @brief Full erase of FLASH memory sectors + * @param VoltageRange: The device voltage range which defines the erase parallelism. + * This parameter can be one of the following values: + * @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V, + * the operation will be done by byte (8-bit) + * @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V, + * the operation will be done by half word (16-bit) + * @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V, + * the operation will be done by word (32-bit) + * @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp, + * the operation will be done by double word (64-bit) + * + * @param Banks: Banks to be erased + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: Bank1 to be erased + * @arg FLASH_BANK_2: Bank2 to be erased + * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased + * + * @retval HAL Status + */ +static void FLASH_MassErase(uint8_t VoltageRange, uint32_t Banks) +{ + uint32_t tmp_psize = 0; + + /* Check the parameters */ + assert_param(IS_VOLTAGERANGE(VoltageRange)); + assert_param(IS_FLASH_BANK(Banks)); + + /* if the previous operation is completed, proceed to erase all sectors */ + FLASH->CR &= CR_PSIZE_MASK; + FLASH->CR |= tmp_psize; + if(Banks == FLASH_BANK_BOTH) + { + /* bank1 & bank2 will be erased*/ + FLASH->CR |= FLASH_MER_BIT; + } + else if(Banks == FLASH_BANK_1) + { + /*Only bank1 will be erased*/ + FLASH->CR |= FLASH_CR_MER1; + } + else + { + /*Only bank2 will be erased*/ + FLASH->CR |= FLASH_CR_MER2; + } + FLASH->CR |= FLASH_CR_STRT; +} + +/** + * @brief Erase the specified FLASH memory sector + * @param Sector: FLASH sector to erase + * The value of this parameter depend on device used within the same series + * @param VoltageRange: The device voltage range which defines the erase parallelism. + * This parameter can be one of the following values: + * @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V, + * the operation will be done by byte (8-bit) + * @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V, + * the operation will be done by half word (16-bit) + * @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V, + * the operation will be done by word (32-bit) + * @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp, + * the operation will be done by double word (64-bit) + * + * @retval None + */ +void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange) +{ + uint32_t tmp_psize = 0; + + /* Check the parameters */ + assert_param(IS_FLASH_SECTOR(Sector)); + assert_param(IS_VOLTAGERANGE(VoltageRange)); + + if(VoltageRange == FLASH_VOLTAGE_RANGE_1) + { + tmp_psize = FLASH_PSIZE_BYTE; + } + else if(VoltageRange == FLASH_VOLTAGE_RANGE_2) + { + tmp_psize = FLASH_PSIZE_HALF_WORD; + } + else if(VoltageRange == FLASH_VOLTAGE_RANGE_3) + { + tmp_psize = FLASH_PSIZE_WORD; + } + else + { + tmp_psize = FLASH_PSIZE_DOUBLE_WORD; + } + + /* Need to add offset of 4 when sector higher than FLASH_SECTOR_11 */ + if(Sector > FLASH_SECTOR_11) + { + Sector += 4; + } + /* If the previous operation is completed, proceed to erase the sector */ + FLASH->CR &= CR_PSIZE_MASK; + FLASH->CR |= tmp_psize; + FLASH->CR &= SECTOR_MASK; + FLASH->CR |= FLASH_CR_SER | (Sector << POSITION_VAL(FLASH_CR_SNB)); + FLASH->CR |= FLASH_CR_STRT; +} + +/** + * @brief Enable the write protection of the desired bank1 or bank 2 sectors + * + * @note When the memory read protection level is selected (RDP level = 1), + * it is not possible to program or erase the flash sector i if CortexM4 + * debug features are connected or boot code is executed in RAM, even if nWRPi = 1 + * @note Active value of nWRPi bits is inverted when PCROP mode is active (SPRMOD =1). + * + * @param WRPSector: specifies the sector(s) to be write protected. + * This parameter can be one of the following values: + * @arg WRPSector: A value between OB_WRP_SECTOR_0 and OB_WRP_SECTOR_23 + * @arg OB_WRP_SECTOR_All + * @note BANK2 starts from OB_WRP_SECTOR_12 + * + * @param Banks: Enable write protection on all the sectors for the specific bank + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: WRP on all sectors of bank1 + * @arg FLASH_BANK_2: WRP on all sectors of bank2 + * @arg FLASH_BANK_BOTH: WRP on all sectors of bank1 & bank2 + * + * @retval HAL FLASH State + */ +static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_OB_WRP_SECTOR(WRPSector)); + assert_param(IS_FLASH_BANK(Banks)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + if(((WRPSector == OB_WRP_SECTOR_All) && ((Banks == FLASH_BANK_1) || (Banks == FLASH_BANK_BOTH))) || + (WRPSector < OB_WRP_SECTOR_12)) + { + if(WRPSector == OB_WRP_SECTOR_All) + { + /*Write protection on all sector of BANK1*/ + *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS &= (~(WRPSector>>12)); + } + else + { + /*Write protection done on sectors of BANK1*/ + *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS &= (~WRPSector); + } + } + else + { + /*Write protection done on sectors of BANK2*/ + *(__IO uint16_t*)OPTCR1_BYTE2_ADDRESS &= (~(WRPSector>>12)); + } + + /*Write protection on all sector of BANK2*/ + if((WRPSector == OB_WRP_SECTOR_All) && (Banks == FLASH_BANK_BOTH)) + { + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + *(__IO uint16_t*)OPTCR1_BYTE2_ADDRESS &= (~(WRPSector>>12)); + } + } + + } + return status; +} + +/** + * @brief Disable the write protection of the desired bank1 or bank 2 sectors + * + * @note When the memory read protection level is selected (RDP level = 1), + * it is not possible to program or erase the flash sector i if CortexM4 + * debug features are connected or boot code is executed in RAM, even if nWRPi = 1 + * @note Active value of nWRPi bits is inverted when PCROP mode is active (SPRMOD =1). + * + * @param WRPSector: specifies the sector(s) to be write protected. + * This parameter can be one of the following values: + * @arg WRPSector: A value between OB_WRP_SECTOR_0 and OB_WRP_SECTOR_23 + * @arg OB_WRP_Sector_All + * @note BANK2 starts from OB_WRP_SECTOR_12 + * + * @param Banks: Disable write protection on all the sectors for the specific bank + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: Bank1 to be erased + * @arg FLASH_BANK_2: Bank2 to be erased + * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased + * + * @retval HAL Status + */ +static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_OB_WRP_SECTOR(WRPSector)); + assert_param(IS_FLASH_BANK(Banks)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + if(((WRPSector == OB_WRP_SECTOR_All) && ((Banks == FLASH_BANK_1) || (Banks == FLASH_BANK_BOTH))) || + (WRPSector < OB_WRP_SECTOR_12)) + { + if(WRPSector == OB_WRP_SECTOR_All) + { + /*Write protection on all sector of BANK1*/ + *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS |= (uint16_t)(WRPSector>>12); + } + else + { + /*Write protection done on sectors of BANK1*/ + *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS |= (uint16_t)WRPSector; + } + } + else + { + /*Write protection done on sectors of BANK2*/ + *(__IO uint16_t*)OPTCR1_BYTE2_ADDRESS |= (uint16_t)(WRPSector>>12); + } + + /*Write protection on all sector of BANK2*/ + if((WRPSector == OB_WRP_SECTOR_All) && (Banks == FLASH_BANK_BOTH)) + { + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + *(__IO uint16_t*)OPTCR1_BYTE2_ADDRESS |= (uint16_t)(WRPSector>>12); + } + } + + } + + return status; +} + +/** + * @brief Configure the Dual Bank Boot. + * + * @note This function can be used only for STM32F42xxx/43xxx devices. + * + * @param BootConfig specifies the Dual Bank Boot Option byte. + * This parameter can be one of the following values: + * @arg OB_Dual_BootEnabled: Dual Bank Boot Enable + * @arg OB_Dual_BootDisabled: Dual Bank Boot Disabled + * @retval None + */ +static HAL_StatusTypeDef FLASH_OB_BootConfig(uint8_t BootConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_OB_BOOT(BootConfig)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + /* Set Dual Bank Boot */ + *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS &= (~FLASH_OPTCR_BFB2); + *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS |= BootConfig; + } + + return status; +} + +/** + * @brief Enable the read/write protection (PCROP) of the desired + * sectors of Bank 1 and/or Bank 2. + * @note This function can be used only for STM32F42xxx/43xxx devices. + * @param SectorBank1 Specifies the sector(s) to be read/write protected or unprotected for bank1. + * This parameter can be one of the following values: + * @arg OB_PCROP: A value between OB_PCROP_SECTOR_0 and OB_PCROP_SECTOR_11 + * @arg OB_PCROP_SECTOR__All + * @param SectorBank2 Specifies the sector(s) to be read/write protected or unprotected for bank2. + * This parameter can be one of the following values: + * @arg OB_PCROP: A value between OB_PCROP_SECTOR_12 and OB_PCROP_SECTOR_23 + * @arg OB_PCROP_SECTOR__All + * @param Banks Enable PCROP protection on all the sectors for the specific bank + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: WRP on all sectors of bank1 + * @arg FLASH_BANK_2: WRP on all sectors of bank2 + * @arg FLASH_BANK_BOTH: WRP on all sectors of bank1 & bank2 + * + * @retval HAL Status + */ +static HAL_StatusTypeDef FLASH_OB_EnablePCROP(uint32_t SectorBank1, uint32_t SectorBank2, uint32_t Banks) +{ + HAL_StatusTypeDef status = HAL_OK; + + assert_param(IS_FLASH_BANK(Banks)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + if((Banks == FLASH_BANK_1) || (Banks == FLASH_BANK_BOTH)) + { + assert_param(IS_OB_PCROP(SectorBank1)); + /*Write protection done on sectors of BANK1*/ + *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS |= (uint16_t)SectorBank1; + } + else + { + assert_param(IS_OB_PCROP(SectorBank2)); + /*Write protection done on sectors of BANK2*/ + *(__IO uint16_t*)OPTCR1_BYTE2_ADDRESS |= (uint16_t)SectorBank2; + } + + /*Write protection on all sector of BANK2*/ + if(Banks == FLASH_BANK_BOTH) + { + assert_param(IS_OB_PCROP(SectorBank2)); + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + /*Write protection done on sectors of BANK2*/ + *(__IO uint16_t*)OPTCR1_BYTE2_ADDRESS |= (uint16_t)SectorBank2; + } + } + + } + + return status; +} + + +/** + * @brief Disable the read/write protection (PCROP) of the desired + * sectors of Bank 1 and/or Bank 2. + * @note This function can be used only for STM32F42xxx/43xxx devices. + * @param SectorBank1 specifies the sector(s) to be read/write protected or unprotected for bank1. + * This parameter can be one of the following values: + * @arg OB_PCROP: A value between OB_PCROP_SECTOR_0 and OB_PCROP_SECTOR_11 + * @arg OB_PCROP_SECTOR__All + * @param SectorBank2 Specifies the sector(s) to be read/write protected or unprotected for bank2. + * This parameter can be one of the following values: + * @arg OB_PCROP: A value between OB_PCROP_SECTOR_12 and OB_PCROP_SECTOR_23 + * @arg OB_PCROP_SECTOR__All + * @param Banks Disable PCROP protection on all the sectors for the specific bank + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: WRP on all sectors of bank1 + * @arg FLASH_BANK_2: WRP on all sectors of bank2 + * @arg FLASH_BANK_BOTH: WRP on all sectors of bank1 & bank2 + * + * @retval HAL Status + */ +static HAL_StatusTypeDef FLASH_OB_DisablePCROP(uint32_t SectorBank1, uint32_t SectorBank2, uint32_t Banks) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_FLASH_BANK(Banks)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + if((Banks == FLASH_BANK_1) || (Banks == FLASH_BANK_BOTH)) + { + assert_param(IS_OB_PCROP(SectorBank1)); + /*Write protection done on sectors of BANK1*/ + *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS &= (~SectorBank1); + } + else + { + /*Write protection done on sectors of BANK2*/ + assert_param(IS_OB_PCROP(SectorBank2)); + *(__IO uint16_t*)OPTCR1_BYTE2_ADDRESS &= (~SectorBank2); + } + + /*Write protection on all sector of BANK2*/ + if(Banks == FLASH_BANK_BOTH) + { + assert_param(IS_OB_PCROP(SectorBank2)); + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + /*Write protection done on sectors of BANK2*/ + *(__IO uint16_t*)OPTCR1_BYTE2_ADDRESS &= (~SectorBank2); + } + } + + } + + return status; + +} + +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) +/** + * @brief Mass erase of FLASH memory + * @param VoltageRange: The device voltage range which defines the erase parallelism. + * This parameter can be one of the following values: + * @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V, + * the operation will be done by byte (8-bit) + * @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V, + * the operation will be done by half word (16-bit) + * @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V, + * the operation will be done by word (32-bit) + * @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp, + * the operation will be done by double word (64-bit) + * + * @param Banks: Banks to be erased + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: Bank1 to be erased + * + * @retval None + */ +static void FLASH_MassErase(uint8_t VoltageRange, uint32_t Banks) +{ + uint32_t tmp_psize = 0; + + /* Check the parameters */ + assert_param(IS_VOLTAGERANGE(VoltageRange)); + assert_param(IS_FLASH_BANK(Banks)); + + /* If the previous operation is completed, proceed to erase all sectors */ + FLASH->CR &= CR_PSIZE_MASK; + FLASH->CR |= tmp_psize; + FLASH->CR |= FLASH_CR_MER; + FLASH->CR |= FLASH_CR_STRT; +} + +/** + * @brief Erase the specified FLASH memory sector + * @param Sector: FLASH sector to erase + * The value of this parameter depend on device used within the same series + * @param VoltageRange: The device voltage range which defines the erase parallelism. + * This parameter can be one of the following values: + * @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V, + * the operation will be done by byte (8-bit) + * @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V, + * the operation will be done by half word (16-bit) + * @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V, + * the operation will be done by word (32-bit) + * @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp, + * the operation will be done by double word (64-bit) + * + * @retval None + */ +void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange) +{ + uint32_t tmp_psize = 0; + + /* Check the parameters */ + assert_param(IS_FLASH_SECTOR(Sector)); + assert_param(IS_VOLTAGERANGE(VoltageRange)); + + if(VoltageRange == FLASH_VOLTAGE_RANGE_1) + { + tmp_psize = FLASH_PSIZE_BYTE; + } + else if(VoltageRange == FLASH_VOLTAGE_RANGE_2) + { + tmp_psize = FLASH_PSIZE_HALF_WORD; + } + else if(VoltageRange == FLASH_VOLTAGE_RANGE_3) + { + tmp_psize = FLASH_PSIZE_WORD; + } + else + { + tmp_psize = FLASH_PSIZE_DOUBLE_WORD; + } + + /* If the previous operation is completed, proceed to erase the sector */ + FLASH->CR &= CR_PSIZE_MASK; + FLASH->CR |= tmp_psize; + FLASH->CR &= SECTOR_MASK; + FLASH->CR |= FLASH_CR_SER | (Sector << POSITION_VAL(FLASH_CR_SNB)); + FLASH->CR |= FLASH_CR_STRT; +} + +/** + * @brief Enable the write protection of the desired bank 1 sectors + * + * @note When the memory read protection level is selected (RDP level = 1), + * it is not possible to program or erase the flash sector i if CortexM4 + * debug features are connected or boot code is executed in RAM, even if nWRPi = 1 + * @note Active value of nWRPi bits is inverted when PCROP mode is active (SPRMOD =1). + * + * @param WRPSector: specifies the sector(s) to be write protected. + * The value of this parameter depend on device used within the same series + * + * @param Banks: Enable write protection on all the sectors for the specific bank + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: WRP on all sectors of bank1 + * + * @retval HAL Status + */ +static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_OB_WRP_SECTOR(WRPSector)); + assert_param(IS_FLASH_BANK(Banks)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS &= (~WRPSector); + } + + return status; +} + +/** + * @brief Disable the write protection of the desired bank 1 sectors + * + * @note When the memory read protection level is selected (RDP level = 1), + * it is not possible to program or erase the flash sector i if CortexM4 + * debug features are connected or boot code is executed in RAM, even if nWRPi = 1 + * @note Active value of nWRPi bits is inverted when PCROP mode is active (SPRMOD =1). + * + * @param WRPSector: specifies the sector(s) to be write protected. + * The value of this parameter depend on device used within the same series + * + * @param Banks: Enable write protection on all the sectors for the specific bank + * This parameter can be one of the following values: + * @arg FLASH_BANK_1: WRP on all sectors of bank1 + * + * @retval HAL Status + */ +static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_OB_WRP_SECTOR(WRPSector)); + assert_param(IS_FLASH_BANK(Banks)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS |= (uint16_t)WRPSector; + } + + return status; +} +#endif /* STM32F40xxx || STM32F41xxx || STM32F401xx || STM32F411xE || STM32F446xx */ + +#if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) +/** + * @brief Enable the read/write protection (PCROP) of the desired sectors. + * @note This function can be used only for STM32F401xx devices. + * @param Sector specifies the sector(s) to be read/write protected or unprotected. + * This parameter can be one of the following values: + * @arg OB_PCROP: A value between OB_PCROP_Sector0 and OB_PCROP_Sector5 + * @arg OB_PCROP_Sector_All + * @retval HAL Status + */ +static HAL_StatusTypeDef FLASH_OB_EnablePCROP(uint32_t Sector) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_OB_PCROP(Sector)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS |= (uint16_t)Sector; + } + + return status; +} + + +/** + * @brief Disable the read/write protection (PCROP) of the desired sectors. + * @note This function can be used only for STM32F401xx devices. + * @param Sector specifies the sector(s) to be read/write protected or unprotected. + * This parameter can be one of the following values: + * @arg OB_PCROP: A value between OB_PCROP_Sector0 and OB_PCROP_Sector5 + * @arg OB_PCROP_Sector_All + * @retval HAL Status + */ +static HAL_StatusTypeDef FLASH_OB_DisablePCROP(uint32_t Sector) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_OB_PCROP(Sector)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS &= (~Sector); + } + + return status; + +} +#endif /* STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx */ + +/** + * @brief Set the read protection level. + * @param Level: specifies the read protection level. + * This parameter can be one of the following values: + * @arg OB_RDP_LEVEL_0: No protection + * @arg OB_RDP_LEVEL_1: Read protection of the memory + * @arg OB_RDP_LEVEL_2: Full chip protection + * + * @note WARNING: When enabling OB_RDP level 2 it's no more possible to go back to level 1 or 0 + * + * @retval HAL Status + */ +static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t Level) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_OB_RDP_LEVEL(Level)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + *(__IO uint8_t*)OPTCR_BYTE1_ADDRESS = Level; + } + + return status; +} + +/** + * @brief Program the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY. + * @param Iwdg: Selects the IWDG mode + * This parameter can be one of the following values: + * @arg OB_IWDG_SW: Software IWDG selected + * @arg OB_IWDG_HW: Hardware IWDG selected + * @param Stop: Reset event when entering STOP mode. + * This parameter can be one of the following values: + * @arg OB_STOP_NO_RST: No reset generated when entering in STOP + * @arg OB_STOP_RST: Reset generated when entering in STOP + * @param Stdby: Reset event when entering Standby mode. + * This parameter can be one of the following values: + * @arg OB_STDBY_NO_RST: No reset generated when entering in STANDBY + * @arg OB_STDBY_RST: Reset generated when entering in STANDBY + * @retval HAL Status + */ +static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t Iwdg, uint8_t Stop, uint8_t Stdby) +{ + uint8_t optiontmp = 0xFF; + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_OB_IWDG_SOURCE(Iwdg)); + assert_param(IS_OB_STOP_SOURCE(Stop)); + assert_param(IS_OB_STDBY_SOURCE(Stdby)); + + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); + + if(status == HAL_OK) + { + /* Mask OPTLOCK, OPTSTRT, BOR_LEV and BFB2 bits */ + optiontmp = (uint8_t)((*(__IO uint8_t *)OPTCR_BYTE0_ADDRESS) & (uint8_t)0x1F); + + /* Update User Option Byte */ + *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS = Iwdg | (uint8_t)(Stdby | (uint8_t)(Stop | ((uint8_t)optiontmp))); + } + + return status; +} + +/** + * @brief Set the BOR Level. + * @param Level: specifies the Option Bytes BOR Reset Level. + * This parameter can be one of the following values: + * @arg OB_BOR_LEVEL3: Supply voltage ranges from 2.7 to 3.6 V + * @arg OB_BOR_LEVEL2: Supply voltage ranges from 2.4 to 2.7 V + * @arg OB_BOR_LEVEL1: Supply voltage ranges from 2.1 to 2.4 V + * @arg OB_BOR_OFF: Supply voltage ranges from 1.62 to 2.1 V + * @retval HAL Status + */ +static HAL_StatusTypeDef FLASH_OB_BOR_LevelConfig(uint8_t Level) +{ + /* Check the parameters */ + assert_param(IS_OB_BOR_LEVEL(Level)); + + /* Set the BOR Level */ + *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS &= (~FLASH_OPTCR_BOR_LEV); + *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS |= Level; + + return HAL_OK; +} + +/** + * @brief Return the FLASH User Option Byte value. + * @retval uint8_t FLASH User Option Bytes values: IWDG_SW(Bit0), RST_STOP(Bit1) + * and RST_STDBY(Bit2). + */ +static uint8_t FLASH_OB_GetUser(void) +{ + /* Return the User Option Byte */ + return ((uint8_t)(FLASH->OPTCR & 0xE0)); +} + +/** + * @brief Return the FLASH Write Protection Option Bytes value. + * @retval uint16_t FLASH Write Protection Option Bytes value + */ +static uint16_t FLASH_OB_GetWRP(void) +{ + /* Return the FLASH write protection Register value */ + return (*(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS)); +} + +/** + * @brief Returns the FLASH Read Protection level. + * @retval FLASH ReadOut Protection Status: + * This parameter can be one of the following values: + * @arg OB_RDP_LEVEL_0: No protection + * @arg OB_RDP_LEVEL_1: Read protection of the memory + * @arg OB_RDP_LEVEL_2: Full chip protection + */ +static uint8_t FLASH_OB_GetRDP(void) +{ + uint8_t readstatus = OB_RDP_LEVEL_0; + + if((*(__IO uint8_t*)(OPTCR_BYTE1_ADDRESS) == (uint8_t)OB_RDP_LEVEL_2)) + { + readstatus = OB_RDP_LEVEL_2; + } + else if((*(__IO uint8_t*)(OPTCR_BYTE1_ADDRESS) == (uint8_t)OB_RDP_LEVEL_1)) + { + readstatus = OB_RDP_LEVEL_1; + } + else + { + readstatus = OB_RDP_LEVEL_0; + } + + return readstatus; +} + +/** + * @brief Returns the FLASH BOR level. + * @retval uint8_t The FLASH BOR level: + * - OB_BOR_LEVEL3: Supply voltage ranges from 2.7 to 3.6 V + * - OB_BOR_LEVEL2: Supply voltage ranges from 2.4 to 2.7 V + * - OB_BOR_LEVEL1: Supply voltage ranges from 2.1 to 2.4 V + * - OB_BOR_OFF : Supply voltage ranges from 1.62 to 2.1 V + */ +static uint8_t FLASH_OB_GetBOR(void) +{ + /* Return the FLASH BOR level */ + return (uint8_t)(*(__IO uint8_t *)(OPTCR_BYTE0_ADDRESS) & (uint8_t)0x0C); +} + +/** + * @} + */ + +#endif /* HAL_FLASH_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c new file mode 100644 index 0000000..1bfb475 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c @@ -0,0 +1,194 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_flash_ramfunc.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief FLASH RAMFUNC module driver. + * This file provides a FLASH firmware functions which should be + * executed from internal SRAM + * + Stop/Start the flash interface while System Run + * + Enable/Disable the flash sleep while System Run + @verbatim + ============================================================================== + ##### APIs executed from Internal RAM ##### + ============================================================================== + [..] + *** ARM Compiler *** + -------------------- + [..] RAM functions are defined using the toolchain options. + Functions that are be executed in RAM should reside in a separate + source module. Using the 'Options for File' dialog you can simply change + the 'Code / Const' area of a module to a memory space in physical RAM. + Available memory areas are declared in the 'Target' tab of the + Options for Target' dialog. + + *** ICCARM Compiler *** + ----------------------- + [..] RAM functions are defined using a specific toolchain keyword "__ramfunc". + + *** GNU Compiler *** + -------------------- + [..] RAM functions are defined using a specific toolchain attribute + "__attribute__((section(".RamFunc")))". + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 FLASHRAMFUNC FLASH RAMFUNC + * @brief FLASH functions executed from RAM + * @{ + */ + +#ifdef HAL_FLASH_MODULE_ENABLED + +#if defined(STM32F411xE) || defined(STM32F446xx) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup FLASHRAMFUNC_Exported_Functions FLASH RAMFUNC Exported Functions + * @{ + */ + +/** @defgroup FLASHRAMFUNC_Exported_Functions_Group1 Peripheral features functions executed from internal RAM + * @brief Peripheral Extended features functions + * +@verbatim + + =============================================================================== + ##### ramfunc functions ##### + =============================================================================== + [..] + This subsection provides a set of functions that should be executed from RAM + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Stop the flash interface while System Run + * @note This mode is only available for STM32F411xx devices. + * @note This mode couldn't be set while executing with the flash itself. + * It should be done with specific routine executed from RAM. + * @retval None + */ +__RAM_FUNC HAL_FLASHEx_StopFlashInterfaceClk(void) +{ + /* Enable Power ctrl clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + /* Stop the flash interface while System Run */ + SET_BIT(PWR->CR, PWR_CR_FISSR); + + return HAL_OK; +} + +/** + * @brief Start the flash interface while System Run + * @note This mode is only available for STM32F411xx devices. + * @note This mode couldn't be set while executing with the flash itself. + * It should be done with specific routine executed from RAM. + * @retval None + */ +__RAM_FUNC HAL_FLASHEx_StartFlashInterfaceClk(void) +{ + /* Enable Power ctrl clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + /* Start the flash interface while System Run */ + CLEAR_BIT(PWR->CR, PWR_CR_FISSR); + + return HAL_OK; +} + +/** + * @brief Enable the flash sleep while System Run + * @note This mode is only available for STM32F411xx devices. + * @note This mode could n't be set while executing with the flash itself. + * It should be done with specific routine executed from RAM. + * @retval None + */ +__RAM_FUNC HAL_FLASHEx_EnableFlashSleepMode(void) +{ + /* Enable Power ctrl clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + /* Enable the flash sleep while System Run */ + SET_BIT(PWR->CR, PWR_CR_FMSSR); + + return HAL_OK; +} + +/** + * @brief Disable the flash sleep while System Run + * @note This mode is only available for STM32F411xx devices. + * @note This mode couldn't be set while executing with the flash itself. + * It should be done with specific routine executed from RAM. + * @retval None + */ +__RAM_FUNC HAL_FLASHEx_DisableFlashSleepMode(void) +{ + /* Enable Power ctrl clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + /* Disable the flash sleep while System Run */ + CLEAR_BIT(PWR->CR, PWR_CR_FMSSR); + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* STM32F411xE || STM32F446xx */ +#endif /* HAL_FLASH_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_fmpi2c.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_fmpi2c.c new file mode 100644 index 0000000..79b1c5b --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_fmpi2c.c @@ -0,0 +1,4098 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_fmpi2c.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief FMPI2C HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the Inter Integrated Circuit (FMPI2C) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The FMPI2C HAL driver can be used as follows: + + (#) Declare a FMPI2C_HandleTypeDef handle structure, for example: + FMPI2C_HandleTypeDef hfmpi2c; + + (#)Initialize the FMPI2C low level resources by implement the HAL_FMPI2C_MspInit ()API: + (##) Enable the FMPI2Cx interface clock + (##) FMPI2C pins configuration + (+++) Enable the clock for the FMPI2C GPIOs + (+++) Configure FMPI2C pins as alternate function open-drain + (##) NVIC configuration if you need to use interrupt process + (+++) Configure the FMPI2Cx interrupt priority + (+++) Enable the NVIC FMPI2C IRQ Channel + (##) DMA Configuration if you need to use DMA process + (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive stream + (+++) Enable the DMAx interface clock using + (+++) Configure the DMA handle parameters + (+++) Configure the DMA Tx or Rx Stream + (+++) Associate the initilalized DMA handle to the hfmpi2c DMA Tx or Rx handle + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx or Rx Stream + + (#) Configure the Communication Clock Timing, Own Address1, Master Adressing Mode, Dual Addressing mode, + Own Address2, Own Address2 Mask, General call and Nostretch mode in the hfmpi2c Init structure. + + (#) Initialize the FMPI2C registers by calling the HAL_FMPI2C_Init() API: + (+++) These API's configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) + by calling the customed HAL_FMPI2C_MspInit(&hfmpi2c) API. + + (#) To check if target device is ready for communication, use the function HAL_FMPI2C_IsDeviceReady() + + (#) For FMPI2C IO and IO MEM operations, three mode of operations are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Transmit in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Transmit() + (+) Receive in master mode an amount of data in blocking mode using HAL_FMPI2C_Master_Receive() + (+) Transmit in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Transmit() + (+) Receive in slave mode an amount of data in blocking mode using HAL_FMPI2C_Slave_Receive() + + *** Polling mode IO MEM operation *** + ===================================== + [..] + (+) Write an amount of data in blocking mode to a specific memory address using HAL_FMPI2C_Mem_Write() + (+) Read an amount of data in blocking mode from a specific memory address using HAL_FMPI2C_Mem_Read() + + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Transmit in master mode an amount of data in non blocking mode using HAL_FMPI2C_Master_Transmit_IT() + (+) At transmission end of transfer HAL_FMPI2C_MasterTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback + (+) Receive in master mode an amount of data in non blocking mode using HAL_FMPI2C_Master_Receive_IT() + (+) At reception end of transfer HAL_FMPI2C_MasterRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback + (+) Transmit in slave mode an amount of data in non blocking mode using HAL_FMPI2C_Slave_Transmit_IT() + (+) At transmission end of transfer HAL_FMPI2C_SlaveTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback + (+) Receive in slave mode an amount of data in non blocking mode using HAL_FMPI2C_Slave_Receive_IT() + (+) At reception end of transfer HAL_FMPI2C_SlaveRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback + (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback + + *** Interrupt mode IO MEM operation *** + ======================================= + [..] + (+) Write an amount of data in no-blocking mode with Interrupt to a specific memory address using + HAL_FMPI2C_Mem_Write_IT() + (+) At MEM end of write transfer HAL_FMPI2C_MemTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback + (+) Read an amount of data in no-blocking mode with Interrupt from a specific memory address using + HAL_FMPI2C_Mem_Read_IT() + (+) At MEM end of read transfer HAL_FMPI2C_MemRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback + (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback + + *** DMA mode IO operation *** + ============================== + [..] + (+) Transmit in master mode an amount of data in non blocking mode (DMA) using + HAL_FMPI2C_Master_Transmit_DMA() + (+) At transmission end of transfer HAL_FMPI2C_MasterTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_FMPI2C_MasterTxCpltCallback + (+) Receive in master mode an amount of data in non blocking mode (DMA) using + HAL_FMPI2C_Master_Receive_DMA() + (+) At reception end of transfer HAL_FMPI2C_MasterRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_FMPI2C_MasterRxCpltCallback + (+) Transmit in slave mode an amount of data in non blocking mode (DMA) using + HAL_FMPI2C_Slave_Transmit_DMA() + (+) At transmission end of transfer HAL_FMPI2C_SlaveTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_FMPI2C_SlaveTxCpltCallback + (+) Receive in slave mode an amount of data in non blocking mode (DMA) using + HAL_FMPI2C_Slave_Receive_DMA() + (+) At reception end of transfer HAL_FMPI2C_SlaveRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_FMPI2C_SlaveRxCpltCallback + (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback + + *** DMA mode IO MEM operation *** + ================================= + [..] + (+) Write an amount of data in no-blocking mode with DMA to a specific memory address using + HAL_FMPI2C_Mem_Write_DMA() + (+) At MEM end of write transfer HAL_FMPI2C_MemTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_FMPI2C_MemTxCpltCallback + (+) Read an amount of data in no-blocking mode with DMA from a specific memory address using + HAL_FMPI2C_Mem_Read_DMA() + (+) At MEM end of read transfer HAL_FMPI2C_MemRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_FMPI2C_MemRxCpltCallback + (+) In case of transfer Error, HAL_FMPI2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_FMPI2C_ErrorCallback + + + *** FMPI2C HAL driver macros list *** + ================================== + [..] + Below the list of most used macros in FMPI2C HAL driver. + + (+) __HAL_FMPI2C_ENABLE: Enable the FMPI2C peripheral + (+) __HAL_FMPI2C_DISABLE: Disable the FMPI2C peripheral + (+) __HAL_FMPI2C_GET_FLAG : Checks whether the specified FMPI2C flag is set or not + (+) __HAL_FMPI2C_CLEAR_FLAG : Clears the specified FMPI2C pending flag + (+) __HAL_FMPI2C_ENABLE_IT: Enables the specified FMPI2C interrupt + (+) __HAL_FMPI2C_DISABLE_IT: Disables the specified FMPI2C interrupt + + [..] + (@) You can refer to the FMPI2C HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 FMPI2C FMPI2C + * @brief FMPI2C HAL module driver + * @{ + */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + +#if defined(STM32F446xx) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup FMPI2C_Private_Constants + * @{ + */ +#define TIMING_CLEAR_MASK ((uint32_t)0xF0FFFFFF) /*Instance)); + assert_param(IS_FMPI2C_OWN_ADDRESS1(hfmpi2c->Init.OwnAddress1)); + assert_param(IS_FMPI2C_ADDRESSING_MODE(hfmpi2c->Init.AddressingMode)); + assert_param(IS_FMPI2C_DUAL_ADDRESS(hfmpi2c->Init.DualAddressMode)); + assert_param(IS_FMPI2C_OWN_ADDRESS2(hfmpi2c->Init.OwnAddress2)); + assert_param(IS_FMPI2C_OWN_ADDRESS2_MASK(hfmpi2c->Init.OwnAddress2Masks)); + assert_param(IS_FMPI2C_GENERAL_CALL(hfmpi2c->Init.GeneralCallMode)); + assert_param(IS_FMPI2C_NO_STRETCH(hfmpi2c->Init.NoStretchMode)); + + if(hfmpi2c->State == HAL_FMPI2C_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hfmpi2c->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + HAL_FMPI2C_MspInit(hfmpi2c); + } + + hfmpi2c->State = HAL_FMPI2C_STATE_BUSY; + + /* Disable the selected FMPI2C peripheral */ + __HAL_FMPI2C_DISABLE(hfmpi2c); + + /*---------------------------- FMPI2Cx TIMINGR Configuration ------------------*/ + /* Configure FMPI2Cx: Frequency range */ + hfmpi2c->Instance->TIMINGR = hfmpi2c->Init.Timing & TIMING_CLEAR_MASK; + + /*---------------------------- FMPI2Cx OAR1 Configuration ---------------------*/ + /* Configure FMPI2Cx: Own Address1 and ack own address1 mode */ + hfmpi2c->Instance->OAR1 &= ~FMPI2C_OAR1_OA1EN; + if(hfmpi2c->Init.OwnAddress1 != 0) + { + if(hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_7BIT) + { + hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | hfmpi2c->Init.OwnAddress1); + } + else /* FMPI2C_ADDRESSINGMODE_10BIT */ + { + hfmpi2c->Instance->OAR1 = (FMPI2C_OAR1_OA1EN | FMPI2C_OAR1_OA1MODE | hfmpi2c->Init.OwnAddress1); + } + } + + /*---------------------------- FMPI2Cx CR2 Configuration ----------------------*/ + /* Configure FMPI2Cx: Addressing Master mode */ + if(hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT) + { + hfmpi2c->Instance->CR2 = (FMPI2C_CR2_ADD10); + } + /* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process */ + hfmpi2c->Instance->CR2 |= (FMPI2C_CR2_AUTOEND | FMPI2C_CR2_NACK); + + /*---------------------------- FMPI2Cx OAR2 Configuration ---------------------*/ + /* Configure FMPI2Cx: Dual mode and Own Address2 */ + hfmpi2c->Instance->OAR2 = (hfmpi2c->Init.DualAddressMode | hfmpi2c->Init.OwnAddress2 | (hfmpi2c->Init.OwnAddress2Masks << 8)); + + /*---------------------------- FMPI2Cx CR1 Configuration ----------------------*/ + /* Configure FMPI2Cx: Generalcall and NoStretch mode */ + hfmpi2c->Instance->CR1 = (hfmpi2c->Init.GeneralCallMode | hfmpi2c->Init.NoStretchMode); + + /* Enable the selected FMPI2C peripheral */ + __HAL_FMPI2C_ENABLE(hfmpi2c); + + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the FMPI2C peripheral. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_DeInit(FMPI2C_HandleTypeDef *hfmpi2c) +{ + /* Check the FMPI2C handle allocation */ + if(hfmpi2c == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance)); + + hfmpi2c->State = HAL_FMPI2C_STATE_BUSY; + + /* Disable the FMPI2C Peripheral Clock */ + __HAL_FMPI2C_DISABLE(hfmpi2c); + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_FMPI2C_MspDeInit(hfmpi2c); + + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + hfmpi2c->State = HAL_FMPI2C_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; +} + +/** + * @brief FMPI2C MSP Init. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @retval None + */ + __weak void HAL_FMPI2C_MspInit(FMPI2C_HandleTypeDef *hfmpi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_FMPI2C_MspInit could be implemented in the user file + */ +} + +/** + * @brief FMPI2C MSP DeInit + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @retval None + */ + __weak void HAL_FMPI2C_MspDeInit(FMPI2C_HandleTypeDef *hfmpi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_FMPI2C_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup FMPI2C_Exported_Functions_Group2 I/O operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the FMPI2C data + transfers. + + (#) There is two mode of transfer: + (++) Blocking mode : The communication is performed in the polling mode. + The status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode : The communication is performed using Interrupts + or DMA. These functions return the status of the transfer startup. + The end of the data processing will be indicated through the + dedicated FMPI2C IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + + (#) Blocking mode functions are : + (++) HAL_FMPI2C_Master_Transmit() + (++) HAL_FMPI2C_Master_Receive() + (++) HAL_FMPI2C_Slave_Transmit() + (++) HAL_FMPI2C_Slave_Receive() + (++) HAL_FMPI2C_Mem_Write() + (++) HAL_FMPI2C_Mem_Read() + (++) HAL_FMPI2C_IsDeviceReady() + + (#) No-Blocking mode functions with Interrupt are : + (++) HAL_FMPI2C_Master_Transmit_IT() + (++) HAL_FMPI2C_Master_Receive_IT() + (++) HAL_FMPI2C_Slave_Transmit_IT() + (++) HAL_FMPI2C_Slave_Receive_IT() + (++) HAL_FMPI2C_Mem_Write_IT() + (++) HAL_FMPI2C_Mem_Read_IT() + + (#) No-Blocking mode functions with DMA are : + (++) HAL_FMPI2C_Master_Transmit_DMA() + (++) HAL_FMPI2C_Master_Receive_DMA() + (++) HAL_FMPI2C_Slave_Transmit_DMA() + (++) HAL_FMPI2C_Slave_Receive_DMA() + (++) HAL_FMPI2C_Mem_Write_DMA() + (++) HAL_FMPI2C_Mem_Read_DMA() + + (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode: + (++) HAL_FMPI2C_MemTxCpltCallback() + (++) HAL_FMPI2C_MemRxCpltCallback() + (++) HAL_FMPI2C_MasterTxCpltCallback() + (++) HAL_FMPI2C_MasterRxCpltCallback() + (++) HAL_FMPI2C_SlaveTxCpltCallback() + (++) HAL_FMPI2C_SlaveRxCpltCallback() + (++) HAL_FMPI2C_ErrorCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Transmits in master mode an amount of data in blocking mode. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param DevAddress: Target device address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t sizetmp = 0; + + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_MASTER_BUSY_TX; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + /* Send Slave Address */ + /* Set NBYTES to write and reload if size > 255 and generate RESTART */ + /* Size > 255, need to set RELOAD bit */ + if(Size > 255) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE); + sizetmp = 255; + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,Size, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_WRITE); + sizetmp = Size; + } + + do + { + /* Wait until TXIS flag is set */ + if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + /* Write data to TXDR */ + hfmpi2c->Instance->TXDR = (*pData++); + sizetmp--; + Size--; + + if((sizetmp == 0)&&(Size!=0)) + { + /* Wait until TXE flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + if(Size > 255) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); + sizetmp = 255; + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,Size, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); + sizetmp = Size; + } + } + + }while(Size > 0); + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is set */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receives in master mode an amount of data in blocking mode. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param DevAddress: Target device address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Master_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t sizetmp = 0; + + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_MASTER_BUSY_RX; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + /* Send Slave Address */ + /* Set NBYTES to write and reload if size > 255 and generate RESTART */ + /* Size > 255, need to set RELOAD bit */ + if(Size > 255) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ); + sizetmp = 255; + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,Size, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ); + sizetmp = Size; + } + + do + { + /* Wait until RXNE flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Write data to RXDR */ + (*pData++) =hfmpi2c->Instance->RXDR; + sizetmp--; + Size--; + + if((sizetmp == 0)&&(Size!=0)) + { + /* Wait until TCR flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + if(Size > 255) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); + sizetmp = 255; + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,Size, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); + sizetmp = Size; + } + } + + }while(Size > 0); + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is set */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmits in slave mode an amount of data in blocking mode. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_SLAVE_BUSY_RX; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; + + /* Wait until ADDR flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_ADDR); + + /* If 10bit addressing mode is selected */ + if(hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT) + { + /* Wait until ADDR flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_ADDR); + } + + /* Wait until DIR flag is set Transmitter mode */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, RESET, Timeout) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + return HAL_TIMEOUT; + } + + do + { + /* Wait until TXIS flag is set */ + if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Read data from TXDR */ + hfmpi2c->Instance->TXDR = (*pData++); + Size--; + }while(Size > 0); + + /* Wait until STOP flag is set */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + /* Normal use case for Transmitter mode */ + /* A NACK is generated to confirm the end of transfer */ + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear STOP flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_STOPF); + + /* Wait until BUSY flag is reset */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + return HAL_TIMEOUT; + } + + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in blocking mode + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_SLAVE_BUSY_RX; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; + + /* Wait until ADDR flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, Timeout) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_ADDR); + + /* Wait until DIR flag is reset Receiver mode */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, SET, Timeout) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + return HAL_TIMEOUT; + } + + while(Size > 0) + { + /* Wait until RXNE flag is set */ + if(FMPI2C_WaitOnRXNEFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_TIMEOUT) + { + return HAL_TIMEOUT; + } + else + { + return HAL_ERROR; + } + } + + /* Read data from RXDR */ + (*pData++) = hfmpi2c->Instance->RXDR; + Size--; + } + + /* Wait until STOP flag is set */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear STOP flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_STOPF); + + /* Wait until BUSY flag is reset */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, Timeout) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + return HAL_TIMEOUT; + } + + + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in master mode an amount of data in no-blocking mode with Interrupt + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param DevAddress: Target device address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_MASTER_BUSY_TX; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + hfmpi2c->pBuffPtr = pData; + hfmpi2c->XferCount = Size; + if(Size > 255) + { + hfmpi2c->XferSize = 255; + } + else + { + hfmpi2c->XferSize = Size; + } + + /* Send Slave Address */ + /* Set NBYTES to write and reload if size > 255 and generate RESTART */ + if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) ) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE); + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_WRITE); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + /* Note : The FMPI2C interrupts must be enabled after unlocking current process + to avoid the risk of FMPI2C interrupt handle execution before current + process unlock */ + + + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ + __HAL_FMPI2C_ENABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_TXI ); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in master mode an amount of data in no-blocking mode with Interrupt + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param DevAddress: Target device address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_MASTER_BUSY_RX; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + hfmpi2c->pBuffPtr = pData; + hfmpi2c->XferCount = Size; + if(Size > 255) + { + hfmpi2c->XferSize = 255; + } + else + { + hfmpi2c->XferSize = Size; + } + + /* Send Slave Address */ + /* Set NBYTES to write and reload if size > 255 and generate RESTART */ + if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) ) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ); + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + /* Note : The FMPI2C interrupts must be enabled after unlocking current process + to avoid the risk of FMPI2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, RXI interrupt */ + /* possible to enable all of these */ + /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ + __HAL_FMPI2C_ENABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_RXI ); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in slave mode an amount of data in no-blocking mode with Interrupt + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size) +{ + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_SLAVE_BUSY_TX; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; + + hfmpi2c->pBuffPtr = pData; + hfmpi2c->XferSize = Size; + hfmpi2c->XferCount = Size; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + /* Note : The FMPI2C interrupts must be enabled after unlocking current process + to avoid the risk of FMPI2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ + __HAL_FMPI2C_ENABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_TXI ); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in no-blocking mode with Interrupt + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size) +{ + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_SLAVE_BUSY_RX; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; + + hfmpi2c->pBuffPtr = pData; + hfmpi2c->XferSize = Size; + hfmpi2c->XferCount = Size; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + /* Note : The FMPI2C interrupts must be enabled after unlocking current process + to avoid the risk of FMPI2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, RXI interrupt */ + /* possible to enable all of these */ + /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ + __HAL_FMPI2C_ENABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in master mode an amount of data in no-blocking mode with DMA + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param DevAddress: Target device address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Master_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_MASTER_BUSY_TX; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + hfmpi2c->pBuffPtr = pData; + hfmpi2c->XferCount = Size; + if(Size > 255) + { + hfmpi2c->XferSize = 255; + } + else + { + hfmpi2c->XferSize = Size; + } + + /* Set the FMPI2C DMA transfer complete callback */ + hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMasterTransmitCplt; + + /* Set the DMA error callback */ + hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError; + + /* Enable the DMA channel */ + HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize); + + /* Send Slave Address */ + /* Set NBYTES to write and reload if size > 255 and generate RESTART */ + if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) ) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE); + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_WRITE); + } + + /* Wait until TXIS flag is set */ + if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_TXIS) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + + /* Enable DMA Request */ + hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in master mode an amount of data in no-blocking mode with DMA + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param DevAddress: Target device address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Master_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_MASTER_BUSY_RX; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + hfmpi2c->pBuffPtr = pData; + hfmpi2c->XferCount = Size; + if(Size > 255) + { + hfmpi2c->XferSize = 255; + } + else + { + hfmpi2c->XferSize = Size; + } + + /* Set the FMPI2C DMA transfer complete callback */ + hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMasterReceiveCplt; + + /* Set the DMA error callback */ + hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError; + + /* Enable the DMA channel */ + HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, hfmpi2c->XferSize); + + /* Send Slave Address */ + /* Set NBYTES to write and reload if size > 255 and generate RESTART */ + if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) ) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ); + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ); + } + + /* Wait until RXNE flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, FMPI2C_TIMEOUT_RXNE) != HAL_OK) + { + return HAL_TIMEOUT; + } + + + /* Enable DMA Request */ + hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in slave mode an amount of data in no-blocking mode with DMA + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Slave_Transmit_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size) +{ + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_SLAVE_BUSY_TX; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + hfmpi2c->pBuffPtr = pData; + hfmpi2c->XferCount = Size; + hfmpi2c->XferSize = Size; + + /* Set the FMPI2C DMA transfer complete callback */ + hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMASlaveTransmitCplt; + + /* Set the DMA error callback */ + hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError; + + /* Enable the DMA channel */ + HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize); + + /* Enable Address Acknowledge */ + hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; + + /* Wait until ADDR flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, FMPI2C_TIMEOUT_ADDR) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_ADDR); + + /* If 10bits addressing mode is selected */ + if(hfmpi2c->Init.AddressingMode == FMPI2C_ADDRESSINGMODE_10BIT) + { + /* Wait until ADDR flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, FMPI2C_TIMEOUT_ADDR) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_ADDR); + } + + /* Wait until DIR flag is set Transmitter mode */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, RESET, FMPI2C_TIMEOUT_BUSY) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + return HAL_TIMEOUT; + } + + /* Enable DMA Request */ + hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in no-blocking mode with DMA + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Slave_Receive_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint8_t *pData, uint16_t Size) +{ + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_SLAVE_BUSY_RX; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + hfmpi2c->pBuffPtr = pData; + hfmpi2c->XferSize = Size; + hfmpi2c->XferCount = Size; + + /* Set the FMPI2C DMA transfer complete callback */ + hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMASlaveReceiveCplt; + + /* Set the DMA error callback */ + hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError; + + /* Enable the DMA channel */ + HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, Size); + + /* Enable Address Acknowledge */ + hfmpi2c->Instance->CR2 &= ~FMPI2C_CR2_NACK; + + /* Wait until ADDR flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_ADDR, RESET, FMPI2C_TIMEOUT_ADDR) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_ADDR); + + /* Wait until DIR flag is set Receiver mode */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_DIR, SET, FMPI2C_TIMEOUT_DIR) != HAL_OK) + { + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + return HAL_TIMEOUT; + } + + /* Enable DMA Request */ + hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +/** + * @brief Write an amount of data in blocking mode to a specific memory address + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param DevAddress: Target device address + * @param MemAddress: Internal memory address + * @param MemAddSize: Size of internal memory address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Mem_Write(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t Sizetmp = 0; + + /* Check the parameters */ + assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); + + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_MEM_BUSY_TX; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + /* Send Slave Address and Memory Address */ + if(FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + return HAL_TIMEOUT; + } + } + + /* Set NBYTES to write and reload if size > 255 */ + /* Size > 255, need to set RELOAD bit */ + if(Size > 255) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); + Sizetmp = 255; + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,Size, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); + Sizetmp = Size; + } + + do + { + /* Wait until TXIS flag is set */ + if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Write data to DR */ + hfmpi2c->Instance->TXDR = (*pData++); + Sizetmp--; + Size--; + + if((Sizetmp == 0)&&(Size!=0)) + { + /* Wait until TCR flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + + if(Size > 255) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); + Sizetmp = 255; + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,Size, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); + Sizetmp = Size; + } + } + + }while(Size > 0); + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Read an amount of data in blocking mode from a specific memory address + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param DevAddress: Target device address + * @param MemAddress: Internal memory address + * @param MemAddSize: Size of internal memory address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Mem_Read(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t Sizetmp = 0; + + /* Check the parameters */ + assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); + + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_MEM_BUSY_RX; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + /* Send Slave Address and Memory Address */ + if(FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, Timeout) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + return HAL_TIMEOUT; + } + } + + /* Send Slave Address */ + /* Set NBYTES to write and reload if size > 255 and generate RESTART */ + /* Size > 255, need to set RELOAD bit */ + if(Size > 255) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ); + Sizetmp = 255; + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,Size, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ); + Sizetmp = Size; + } + + do + { + /* Wait until RXNE flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Read data from RXDR */ + (*pData++) = hfmpi2c->Instance->RXDR; + + /* Decrement the Size counter */ + Sizetmp--; + Size--; + + if((Sizetmp == 0)&&(Size!=0)) + { + /* Wait until TCR flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + if(Size > 255) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); + Sizetmp = 255; + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,Size, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); + Sizetmp = Size; + } + } + + }while(Size > 0); + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +/** + * @brief Write an amount of data in no-blocking mode with Interrupt to a specific memory address + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param DevAddress: Target device address + * @param MemAddress: Internal memory address + * @param MemAddSize: Size of internal memory address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + /* Check the parameters */ + assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); + + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_MEM_BUSY_TX; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + hfmpi2c->pBuffPtr = pData; + hfmpi2c->XferCount = Size; + if(Size > 255) + { + hfmpi2c->XferSize = 255; + } + else + { + hfmpi2c->XferSize = Size; + } + + /* Send Slave Address and Memory Address */ + if(FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + return HAL_TIMEOUT; + } + } + + /* Set NBYTES to write and reload if size > 255 */ + /* Size > 255, need to set RELOAD bit */ + if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) ) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + /* Note : The FMPI2C interrupts must be enabled after unlocking current process + to avoid the risk of FMPI2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, TXI interrupt */ + /* possible to enable all of these */ + /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ + __HAL_FMPI2C_ENABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_TXI ); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Read an amount of data in no-blocking mode with Interrupt from a specific memory address + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param DevAddress: Target device address + * @param MemAddress: Internal memory address + * @param MemAddSize: Size of internal memory address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_IT(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + /* Check the parameters */ + assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); + + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_MEM_BUSY_RX; + + hfmpi2c->pBuffPtr = pData; + hfmpi2c->XferCount = Size; + if(Size > 255) + { + hfmpi2c->XferSize = 255; + } + else + { + hfmpi2c->XferSize = Size; + } + + /* Send Slave Address and Memory Address */ + if(FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + return HAL_TIMEOUT; + } + } + + /* Set NBYTES to write and reload if size > 255 and generate RESTART */ + /* Size > 255, need to set RELOAD bit */ + if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) ) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ); + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + /* Note : The FMPI2C interrupts must be enabled after unlocking current process + to avoid the risk of FMPI2C interrupt handle execution before current + process unlock */ + + /* Enable ERR, TC, STOP, NACK, RXI interrupt */ + /* possible to enable all of these */ + /* FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI */ + __HAL_FMPI2C_ENABLE_IT(hfmpi2c, FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_RXI ); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +/** + * @brief Write an amount of data in no-blocking mode with DMA to a specific memory address + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param DevAddress: Target device address + * @param MemAddress: Internal memory address + * @param MemAddSize: Size of internal memory address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Mem_Write_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + /* Check the parameters */ + assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); + + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_MEM_BUSY_TX; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + hfmpi2c->pBuffPtr = pData; + hfmpi2c->XferCount = Size; + if(Size > 255) + { + hfmpi2c->XferSize = 255; + } + else + { + hfmpi2c->XferSize = Size; + } + + /* Set the FMPI2C DMA transfer complete callback */ + hfmpi2c->hdmatx->XferCpltCallback = FMPI2C_DMAMemTransmitCplt; + + /* Set the DMA error callback */ + hfmpi2c->hdmatx->XferErrorCallback = FMPI2C_DMAError; + + /* Enable the DMA channel */ + HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)pData, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize); + + /* Send Slave Address and Memory Address */ + if(FMPI2C_RequestMemoryWrite(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + return HAL_TIMEOUT; + } + } + + /* Send Slave Address */ + /* Set NBYTES to write and reload if size > 255 */ + if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) ) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); + } + + /* Wait until TXIS flag is set */ + if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_TXIS) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Enable DMA Request */ + hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Reads an amount of data in no-blocking mode with DMA from a specific memory address. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param DevAddress: Target device address + * @param MemAddress: Internal memory address + * @param MemAddSize: Size of internal memory address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be read + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_Mem_Read_DMA(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + /* Check the parameters */ + assert_param(IS_FMPI2C_MEMADD_SIZE(MemAddSize)); + + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_MEM_BUSY_RX; + + hfmpi2c->pBuffPtr = pData; + hfmpi2c->XferCount = Size; + if(Size > 255) + { + hfmpi2c->XferSize = 255; + } + else + { + hfmpi2c->XferSize = Size; + } + + /* Set the FMPI2C DMA transfer complete callback */ + hfmpi2c->hdmarx->XferCpltCallback = FMPI2C_DMAMemReceiveCplt; + + /* Set the DMA error callback */ + hfmpi2c->hdmarx->XferErrorCallback = FMPI2C_DMAError; + + /* Enable the DMA channel */ + HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)pData, hfmpi2c->XferSize); + + /* Send Slave Address and Memory Address */ + if(FMPI2C_RequestMemoryRead(hfmpi2c, DevAddress, MemAddress, MemAddSize, FMPI2C_TIMEOUT_FLAG) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + return HAL_TIMEOUT; + } + } + + /* Set NBYTES to write and reload if size > 255 and generate RESTART */ + if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) ) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_READ); + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_GENERATE_START_READ); + } + + /* Wait until RXNE flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, FMPI2C_TIMEOUT_RXNE) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Enable DMA Request */ + hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Checks if target device is ready for communication. + * @note This function is used with Memory devices + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param DevAddress: Target device address + * @param Trials: Number of trials + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2C_IsDeviceReady(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + __IO uint32_t FMPI2C_Trials = 0; + + if(hfmpi2c->State == HAL_FMPI2C_STATE_READY) + { + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BUSY) == SET) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_BUSY; + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + + do + { + /* Generate Start */ + hfmpi2c->Instance->CR2 = __HAL_FMPI2C_GENERATE_START(hfmpi2c->Init.AddressingMode,DevAddress); + + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is set or a NACK flag is set*/ + tickstart = HAL_GetTick(); + while((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET) && (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == RESET) && (hfmpi2c->State != HAL_FMPI2C_STATE_TIMEOUT)) + { + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Device is ready */ + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + return HAL_TIMEOUT; + } + } + } + + /* Check if the NACKF flag has not been set */ + if (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == RESET) + { + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Device is ready */ + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; + } + else + { + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear NACK Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); + + /* Clear STOP Flag, auto generated with autoend*/ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + } + + /* Check if the maximum allowed number of trials has been reached */ + if (FMPI2C_Trials++ == Trials) + { + /* Generate Stop */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP; + + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_STOPF, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + } + }while(FMPI2C_Trials < Trials); + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_TIMEOUT; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief This function handles FMPI2C event interrupt request. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @retval None + */ +void HAL_FMPI2C_EV_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c) +{ + /* FMPI2C in mode Transmitter ---------------------------------------------------*/ + if (((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TCR) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TC) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR) == SET)) && (__HAL_FMPI2C_GET_IT_SOURCE(hfmpi2c, (FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_TXI | FMPI2C_IT_ADDRI)) == SET)) + { + /* Slave mode selected */ + if (hfmpi2c->State == HAL_FMPI2C_STATE_SLAVE_BUSY_TX) + { + FMPI2C_SlaveTransmit_ISR(hfmpi2c); + } + } + + if (((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TCR) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TC) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET)) && (__HAL_FMPI2C_GET_IT_SOURCE(hfmpi2c, (FMPI2C_IT_TCI | FMPI2C_IT_STOPI | FMPI2C_IT_NACKI | FMPI2C_IT_TXI)) == SET)) + { + /* Master mode selected */ + if ((hfmpi2c->State == HAL_FMPI2C_STATE_MASTER_BUSY_TX) || (hfmpi2c->State == HAL_FMPI2C_STATE_MEM_BUSY_TX)) + { + FMPI2C_MasterTransmit_ISR(hfmpi2c); + } + } + + /* FMPI2C in mode Receiver ----------------------------------------------------*/ + if (((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TCR) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TC) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR) == SET)) && (__HAL_FMPI2C_GET_IT_SOURCE(hfmpi2c, (FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_RXI | FMPI2C_IT_ADDRI)) == SET)) + { + /* Slave mode selected */ + if (hfmpi2c->State == HAL_FMPI2C_STATE_SLAVE_BUSY_RX) + { + FMPI2C_SlaveReceive_ISR(hfmpi2c); + } + } + if (((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TCR) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TC) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) || (__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET)) && (__HAL_FMPI2C_GET_IT_SOURCE(hfmpi2c, (FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_RXI)) == SET)) + { + /* Master mode selected */ + if ((hfmpi2c->State == HAL_FMPI2C_STATE_MASTER_BUSY_RX) || (hfmpi2c->State == HAL_FMPI2C_STATE_MEM_BUSY_RX)) + { + FMPI2C_MasterReceive_ISR(hfmpi2c); + } + } +} + +/** + * @brief This function handles FMPI2C error interrupt request. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @retval None + */ +void HAL_FMPI2C_ER_IRQHandler(FMPI2C_HandleTypeDef *hfmpi2c) +{ + /* FMPI2C Bus error interrupt occurred ------------------------------------*/ + if((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_BERR) == SET) && (__HAL_FMPI2C_GET_IT_SOURCE(hfmpi2c, FMPI2C_IT_ERRI) == SET)) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_BERR; + + /* Clear BERR flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_BERR); + } + + /* FMPI2C Over-Run/Under-Run interrupt occurred ----------------------------------------*/ + if((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_OVR) == SET) && (__HAL_FMPI2C_GET_IT_SOURCE(hfmpi2c, FMPI2C_IT_ERRI) == SET)) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_OVR; + + /* Clear OVR flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_OVR); + } + + /* FMPI2C Arbitration Loss error interrupt occurred -------------------------------------*/ + if((__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_ARLO) == SET) && (__HAL_FMPI2C_GET_IT_SOURCE(hfmpi2c, FMPI2C_IT_ERRI) == SET)) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_ARLO; + + /* Clear ARLO flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ARLO); + } + + /* Call the Error Callback in case of Error detected */ + if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) + { + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } +} + +/** + * @brief Master Tx Transfer completed callbacks. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @retval None + */ + __weak void HAL_FMPI2C_MasterTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_FMPI2C_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Master Rx Transfer completed callbacks. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @retval None + */ +__weak void HAL_FMPI2C_MasterRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_FMPI2C_TxCpltCallback could be implemented in the user file + */ +} + +/** @brief Slave Tx Transfer completed callbacks. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @retval None + */ + __weak void HAL_FMPI2C_SlaveTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_FMPI2C_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Slave Rx Transfer completed callbacks. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @retval None + */ +__weak void HAL_FMPI2C_SlaveRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_FMPI2C_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Memory Tx Transfer completed callbacks. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @retval None + */ + __weak void HAL_FMPI2C_MemTxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_FMPI2C_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Memory Rx Transfer completed callbacks. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @retval None + */ +__weak void HAL_FMPI2C_MemRxCpltCallback(FMPI2C_HandleTypeDef *hfmpi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_FMPI2C_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief FMPI2C error callbacks. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @retval None + */ + __weak void HAL_FMPI2C_ErrorCallback(FMPI2C_HandleTypeDef *hfmpi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_FMPI2C_ErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup FMPI2C_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief Peripheral State and Errors functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection permit to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the FMPI2C state. + * @param hfmpi2c : FMPI2C handle + * @retval HAL state + */ +HAL_FMPI2C_StateTypeDef HAL_FMPI2C_GetState(FMPI2C_HandleTypeDef *hfmpi2c) +{ + return hfmpi2c->State; +} + +/** +* @brief Return the FMPI2C error code +* @param hfmpi2c : pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. +* @retval FMPI2C Error Code +*/ +uint32_t HAL_FMPI2C_GetError(FMPI2C_HandleTypeDef *hfmpi2c) +{ + return hfmpi2c->ErrorCode; +} + +/** + * @} + */ + +/** + * @brief Handle Interrupt Flags Master Transmit Mode + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @retval HAL status + */ +static HAL_StatusTypeDef FMPI2C_MasterTransmit_ISR(FMPI2C_HandleTypeDef *hfmpi2c) +{ + uint16_t DevAddress; + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == SET) + { + /* Write data to TXDR */ + hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++); + hfmpi2c->XferSize--; + hfmpi2c->XferCount--; + } + else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TCR) == SET) + { + if((hfmpi2c->XferSize == 0)&&(hfmpi2c->XferCount!=0)) + { + DevAddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD); + + if(hfmpi2c->XferCount > 255) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); + hfmpi2c->XferSize = 255; + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferCount, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); + hfmpi2c->XferSize = hfmpi2c->XferCount; + } + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + /* Wrong size Status regarding TCR flag event */ + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_SIZE; + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + } + else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TC) == SET) + { + if(hfmpi2c->XferCount == 0) + { + /* Generate Stop */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + /* Wrong size Status regarding TCR flag event */ + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_SIZE; + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + } + else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) + { + /* Disable ERR, TC, STOP, NACK, TXI interrupt */ + __HAL_FMPI2C_DISABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_TXI ); + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + if(hfmpi2c->State == HAL_FMPI2C_STATE_MEM_BUSY_TX) + { + HAL_FMPI2C_MemTxCpltCallback(hfmpi2c); + } + else + { + HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c); + } + } + else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET) + { + /* Clear NACK Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; +} + +/** + * @brief Handle Interrupt Flags Master Receive Mode + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @retval HAL status + */ +static HAL_StatusTypeDef FMPI2C_MasterReceive_ISR(FMPI2C_HandleTypeDef *hfmpi2c) +{ + uint16_t DevAddress; + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) + { + /* Read data from RXDR */ + (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; + hfmpi2c->XferSize--; + hfmpi2c->XferCount--; + } + else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TCR) == SET) + { + if((hfmpi2c->XferSize == 0)&&(hfmpi2c->XferCount!=0)) + { + DevAddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD); + + if(hfmpi2c->XferCount > 255) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,255, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); + hfmpi2c->XferSize = 255; + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferCount, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); + hfmpi2c->XferSize = hfmpi2c->XferCount; + } + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + /* Wrong size Status regarding TCR flag event */ + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_SIZE; + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + } + else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TC) == SET) + { + if(hfmpi2c->XferCount == 0) + { + /* Generate Stop */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + /* Wrong size Status regarding TCR flag event */ + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_SIZE; + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + } + else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) + { + /* Disable ERR, TC, STOP, NACK, TXI interrupt */ + __HAL_FMPI2C_DISABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_RXI ); + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + if(hfmpi2c->State == HAL_FMPI2C_STATE_MEM_BUSY_RX) + { + HAL_FMPI2C_MemRxCpltCallback(hfmpi2c); + } + else + { + HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c); + } + } + else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET) + { + /* Clear NACK Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; + +} + +/** + * @brief Handle Interrupt Flags Slave Transmit Mode + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @retval HAL status + */ +static HAL_StatusTypeDef FMPI2C_SlaveTransmit_ISR(FMPI2C_HandleTypeDef *hfmpi2c) +{ + /* Process locked */ + __HAL_LOCK(hfmpi2c); + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) != RESET) + { + /* Check that FMPI2C transfer finished */ + /* if yes, normal usecase, a NACK is sent by the MASTER when Transfer is finished */ + /* Mean XferCount == 0*/ + /* So clear Flag NACKF only */ + if(hfmpi2c->XferCount == 0) + { + /* Clear NACK Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + } + else + { + /* if no, error usecase, a Non-Acknowledge of last Data is generated by the MASTER*/ + /* Clear NACK Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); + + /* Set ErrorCode corresponding to a Non-Acknowledge */ + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + /* Call the Error callback to prevent upper layer */ + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + } + else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR) == SET) + { + /* Clear ADDR flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); + } + /* Check first if STOPF is set */ + /* to prevent a Write Data in TX buffer */ + /* which is stuck in TXDR until next */ + /* communication with Master */ + else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) + { + /* Disable ERRI, TCI, STOPI, NACKI, ADDRI, RXI, TXI interrupt */ + __HAL_FMPI2C_DISABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_TXI ); + + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c); + } + else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == SET) + { + /* Write data to TXDR only if XferCount not reach "0" */ + /* A TXIS flag can be set, during STOP treatment */ + if(hfmpi2c->XferCount > 0) + { + /* Write data to TXDR */ + hfmpi2c->Instance->TXDR = (*hfmpi2c->pBuffPtr++); + hfmpi2c->XferCount--; + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; +} + +/** + * @brief Handle Interrupt Flags Slave Receive Mode + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @retval HAL status + */ +static HAL_StatusTypeDef FMPI2C_SlaveReceive_ISR(FMPI2C_HandleTypeDef *hfmpi2c) +{ + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) != RESET) + { + /* Clear NACK Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR) == SET) + { + /* Clear ADDR flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_ADDR); + } + else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == SET) + { + /* Read data from RXDR */ + (*hfmpi2c->pBuffPtr++) = hfmpi2c->Instance->RXDR; + hfmpi2c->XferSize--; + hfmpi2c->XferCount--; + } + else if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) + { + /* Disable ERRI, TCI, STOPI, NACKI, ADDRI, RXI, TXI interrupt */ + __HAL_FMPI2C_DISABLE_IT(hfmpi2c,FMPI2C_IT_ERRI | FMPI2C_IT_TCI| FMPI2C_IT_STOPI| FMPI2C_IT_NACKI | FMPI2C_IT_ADDRI | FMPI2C_IT_RXI | FMPI2C_IT_RXI ); + + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; +} + +/** + * @brief Master sends target device address followed by internal memory address for write request. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param DevAddress: Target device address + * @param MemAddress: Internal memory address + * @param MemAddSize: Size of internal memory address + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef FMPI2C_RequestMemoryWrite(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout) +{ + FMPI2C_TransferConfig(hfmpi2c,DevAddress,MemAddSize, FMPI2C_RELOAD_MODE, FMPI2C_GENERATE_START_WRITE); + + /* Wait until TXIS flag is set */ + if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* If Memory address size is 8Bit */ + if(MemAddSize == FMPI2C_MEMADD_SIZE_8BIT) + { + /* Send Memory Address */ + hfmpi2c->Instance->TXDR = __HAL_FMPI2C_MEM_ADD_LSB(MemAddress); + } + /* If Memory address size is 16Bit */ + else + { + /* Send MSB of Memory Address */ + hfmpi2c->Instance->TXDR = __HAL_FMPI2C_MEM_ADD_MSB(MemAddress); + + /* Wait until TXIS flag is set */ + if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Send LSB of Memory Address */ + hfmpi2c->Instance->TXDR = __HAL_FMPI2C_MEM_ADD_LSB(MemAddress); + } + + /* Wait until TCR flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + +return HAL_OK; +} + +/** + * @brief Master sends target device address followed by internal memory address for read request. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param DevAddress: Target device address + * @param MemAddress: Internal memory address + * @param MemAddSize: Size of internal memory address + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef FMPI2C_RequestMemoryRead(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout) +{ + FMPI2C_TransferConfig(hfmpi2c,DevAddress,MemAddSize, FMPI2C_SOFTEND_MODE, FMPI2C_GENERATE_START_WRITE); + + /* Wait until TXIS flag is set */ + if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* If Memory address size is 8Bit */ + if(MemAddSize == FMPI2C_MEMADD_SIZE_8BIT) + { + /* Send Memory Address */ + hfmpi2c->Instance->TXDR = __HAL_FMPI2C_MEM_ADD_LSB(MemAddress); + } + /* If Mememory address size is 16Bit */ + else + { + /* Send MSB of Memory Address */ + hfmpi2c->Instance->TXDR = __HAL_FMPI2C_MEM_ADD_MSB(MemAddress); + + /* Wait until TXIS flag is set */ + if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, Timeout) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Send LSB of Memory Address */ + hfmpi2c->Instance->TXDR = __HAL_FMPI2C_MEM_ADD_LSB(MemAddress); + } + + /* Wait until TC flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TC, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + return HAL_OK; +} + + +/** + * @brief DMA FMPI2C master transmit process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void FMPI2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma) +{ + uint16_t DevAddress; + FMPI2C_HandleTypeDef* hfmpi2c = (FMPI2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Check if last DMA request was done with RELOAD */ + /* Set NBYTES to write and reload if size > 255 */ + if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) ) + { + /* Wait until TCR flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, FMPI2C_TIMEOUT_TCR) != HAL_OK) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + + /* Disable DMA Request */ + hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; + + /* Check if Errors has been detected during transfer */ + if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) + { + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + } + else + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + hfmpi2c->XferCount = 0; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + else + { + hfmpi2c->pBuffPtr += hfmpi2c->XferSize; + hfmpi2c->XferCount -= hfmpi2c->XferSize; + if(hfmpi2c->XferCount > 255) + { + hfmpi2c->XferSize = 255; + } + else + { + hfmpi2c->XferSize = hfmpi2c->XferCount; + } + + DevAddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD); + + /* Enable the DMA channel */ + HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)hfmpi2c->pBuffPtr, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize); + + /* Send Slave Address */ + /* Set NBYTES to write and reload if size > 255 */ + if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) ) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); + } + + /* Wait until TXIS flag is set */ + if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_TXIS) != HAL_OK) + { + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + } + else + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + hfmpi2c->XferCount = 0; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + else + { + /* Enable DMA Request */ + hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; + } + } + } + else + { + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + } + else + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + /* Disable DMA Request */ + hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; + + hfmpi2c->XferCount = 0; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Check if Errors has been detected during transfer */ + if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) + { + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + else + { + HAL_FMPI2C_MasterTxCpltCallback(hfmpi2c); + } + } +} + +/** + * @brief DMA FMPI2C slave transmit process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void FMPI2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma) +{ + FMPI2C_HandleTypeDef* hfmpi2c = (FMPI2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Wait until STOP flag is set */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + /* Normal Use case, a AF is generated by master */ + /* to inform slave the end of transfer */ + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + } + else + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + } + + /* Clear STOP flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c,FMPI2C_FLAG_STOPF); + + /* Wait until BUSY flag is reset */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY) != HAL_OK) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + + /* Disable DMA Request */ + hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; + + hfmpi2c->XferCount = 0; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Check if Errors has been detected during transfer */ + if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) + { + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + else + { + HAL_FMPI2C_SlaveTxCpltCallback(hfmpi2c); + } +} + +/** + * @brief DMA FMPI2C master receive process complete callback + * @param hdma: DMA handle + * @retval None + */ +static void FMPI2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma) +{ + FMPI2C_HandleTypeDef* hfmpi2c = (FMPI2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + uint16_t DevAddress; + + /* Check if last DMA request was done with RELOAD */ + /* Set NBYTES to write and reload if size > 255 */ + if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) ) + { + /* Wait until TCR flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, FMPI2C_TIMEOUT_TCR) != HAL_OK) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + + /* Disable DMA Request */ + hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; + + /* Check if Errors has been detected during transfer */ + if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) + { + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + } + else + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + hfmpi2c->XferCount = 0; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + else + { + hfmpi2c->pBuffPtr += hfmpi2c->XferSize; + hfmpi2c->XferCount -= hfmpi2c->XferSize; + if(hfmpi2c->XferCount > 255) + { + hfmpi2c->XferSize = 255; + } + else + { + hfmpi2c->XferSize = hfmpi2c->XferCount; + } + + DevAddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD); + + /* Enable the DMA channel */ + HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)hfmpi2c->pBuffPtr, hfmpi2c->XferSize); + + /* Send Slave Address */ + /* Set NBYTES to write and reload if size > 255 */ + if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) ) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); + } + + /* Wait until RXNE flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, FMPI2C_TIMEOUT_RXNE) != HAL_OK) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + + /* Check if Errors has been detected during transfer */ + if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) + { + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + } + else + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + hfmpi2c->XferCount = 0; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + else + { + /* Enable DMA Request */ + hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; + } + } + } + else + { + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + } + else + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + /* Disable DMA Request */ + hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; + + hfmpi2c->XferCount = 0; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Check if Errors has been detected during transfer */ + if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) + { + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + else + { + HAL_FMPI2C_MasterRxCpltCallback(hfmpi2c); + } + } +} + +/** + * @brief DMA FMPI2C slave receive process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void FMPI2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma) +{ + FMPI2C_HandleTypeDef* hfmpi2c = (FMPI2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + } + else + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + } + + /* Clear STOPF flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Wait until BUSY flag is reset */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_BUSY, SET, FMPI2C_TIMEOUT_BUSY) != HAL_OK) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + + /* Disable DMA Request */ + hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; + + /* Disable Address Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + + hfmpi2c->XferCount = 0; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Check if Errors has been detected during transfer */ + if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) + { + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + else + { + HAL_FMPI2C_SlaveRxCpltCallback(hfmpi2c); + } +} + +/** + * @brief DMA FMPI2C Memory Write process complete callback + * @param hdma : DMA handle + * @retval None + */ +static void FMPI2C_DMAMemTransmitCplt(DMA_HandleTypeDef *hdma) +{ + uint16_t DevAddress; + FMPI2C_HandleTypeDef* hfmpi2c = ( FMPI2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Check if last DMA request was done with RELOAD */ + /* Set NBYTES to write and reload if size > 255 */ + if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) ) + { + /* Wait until TCR flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, FMPI2C_TIMEOUT_TCR) != HAL_OK) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + + /* Disable DMA Request */ + hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; + + /* Check if Errors has been detected during transfer */ + if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) + { + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + } + else + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + hfmpi2c->XferCount = 0; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + else + { + hfmpi2c->pBuffPtr += hfmpi2c->XferSize; + hfmpi2c->XferCount -= hfmpi2c->XferSize; + if(hfmpi2c->XferCount > 255) + { + hfmpi2c->XferSize = 255; + } + else + { + hfmpi2c->XferSize = hfmpi2c->XferCount; + } + + DevAddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD); + + /* Enable the DMA channel */ + HAL_DMA_Start_IT(hfmpi2c->hdmatx, (uint32_t)hfmpi2c->pBuffPtr, (uint32_t)&hfmpi2c->Instance->TXDR, hfmpi2c->XferSize); + + /* Send Slave Address */ + /* Set NBYTES to write and reload if size > 255 */ + if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) ) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); + } + + /* Wait until TXIS flag is set */ + if(FMPI2C_WaitOnTXISFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_TXIS) != HAL_OK) + { + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + } + else + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + hfmpi2c->XferCount = 0; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + else + { + /* Enable DMA Request */ + hfmpi2c->Instance->CR1 |= FMPI2C_CR1_TXDMAEN; + } + } + } + else + { + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + } + else + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + /* Disable DMA Request */ + hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_TXDMAEN; + + hfmpi2c->XferCount = 0; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Check if Errors has been detected during transfer */ + if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) + { + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + else + { + HAL_FMPI2C_MemTxCpltCallback(hfmpi2c); + } + } +} + +/** + * @brief DMA FMPI2C Memory Read process complete callback + * @param hdma: DMA handle + * @retval None + */ +static void FMPI2C_DMAMemReceiveCplt(DMA_HandleTypeDef *hdma) +{ + FMPI2C_HandleTypeDef* hfmpi2c = ( FMPI2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + uint16_t DevAddress; + + /* Check if last DMA request was done with RELOAD */ + /* Set NBYTES to write and reload if size > 255 */ + if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) ) + { + /* Wait until TCR flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_TCR, RESET, FMPI2C_TIMEOUT_TCR) != HAL_OK) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + + /* Disable DMA Request */ + hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; + + /* Check if Errors has been detected during transfer */ + if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) + { + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + } + else + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + hfmpi2c->XferCount = 0; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + else + { + hfmpi2c->pBuffPtr += hfmpi2c->XferSize; + hfmpi2c->XferCount -= hfmpi2c->XferSize; + if(hfmpi2c->XferCount > 255) + { + hfmpi2c->XferSize = 255; + } + else + { + hfmpi2c->XferSize = hfmpi2c->XferCount; + } + + DevAddress = (hfmpi2c->Instance->CR2 & FMPI2C_CR2_SADD); + + /* Enable the DMA channel */ + HAL_DMA_Start_IT(hfmpi2c->hdmarx, (uint32_t)&hfmpi2c->Instance->RXDR, (uint32_t)hfmpi2c->pBuffPtr, hfmpi2c->XferSize); + + /* Send Slave Address */ + /* Set NBYTES to write and reload if size > 255 */ + if( (hfmpi2c->XferSize == 255) && (hfmpi2c->XferSize < hfmpi2c->XferCount) ) + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_RELOAD_MODE, FMPI2C_NO_STARTSTOP); + } + else + { + FMPI2C_TransferConfig(hfmpi2c,DevAddress,hfmpi2c->XferSize, FMPI2C_AUTOEND_MODE, FMPI2C_NO_STARTSTOP); + } + + /* Wait until RXNE flag is set */ + if(FMPI2C_WaitOnFlagUntilTimeout(hfmpi2c, FMPI2C_FLAG_RXNE, RESET, FMPI2C_TIMEOUT_RXNE) != HAL_OK) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + + /* Check if Errors has been detected during transfer */ + if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) + { + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + } + else + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + hfmpi2c->XferCount = 0; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + else + { + /* Enable DMA Request */ + hfmpi2c->Instance->CR1 |= FMPI2C_CR1_RXDMAEN; + } + } + } + else + { + /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */ + /* Wait until STOPF flag is reset */ + if(FMPI2C_WaitOnSTOPFlagUntilTimeout(hfmpi2c, FMPI2C_TIMEOUT_STOPF) != HAL_OK) + { + if(hfmpi2c->ErrorCode == HAL_FMPI2C_ERROR_AF) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_AF; + } + else + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + } + } + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + /* Disable DMA Request */ + hfmpi2c->Instance->CR1 &= ~FMPI2C_CR1_RXDMAEN; + + hfmpi2c->XferCount = 0; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Check if Errors has been detected during transfer */ + if(hfmpi2c->ErrorCode != HAL_FMPI2C_ERROR_NONE) + { + HAL_FMPI2C_ErrorCallback(hfmpi2c); + } + else + { + HAL_FMPI2C_MemRxCpltCallback(hfmpi2c); + } + } +} + +/** + * @brief DMA FMPI2C communication error callback. + * @param hdma : DMA handle + * @retval None + */ +static void FMPI2C_DMAError(DMA_HandleTypeDef *hdma) +{ + FMPI2C_HandleTypeDef* hfmpi2c = ( FMPI2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Disable Acknowledge */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_NACK; + + hfmpi2c->XferCount = 0; + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_DMA; + + HAL_FMPI2C_ErrorCallback(hfmpi2c); +} + +/** + * @brief This function handles FMPI2C Communication Timeout. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param Flag: specifies the FMPI2C flag to check. + * @param Status: The new Flag status (SET or RESET). + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef FMPI2C_WaitOnFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout) +{ + uint32_t tickstart = HAL_GetTick(); + + /* Wait until flag is set */ + if(Status == RESET) + { + while(__HAL_FMPI2C_GET_FLAG(hfmpi2c, Flag) == RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hfmpi2c->State= HAL_FMPI2C_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + return HAL_TIMEOUT; + } + } + } + } + else + { + while(__HAL_FMPI2C_GET_FLAG(hfmpi2c, Flag) != RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hfmpi2c->State= HAL_FMPI2C_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + return HAL_TIMEOUT; + } + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles FMPI2C Communication Timeout for specific usage of TXIS flag. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef FMPI2C_WaitOnTXISFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout) +{ + uint32_t tickstart = HAL_GetTick(); + + while(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_TXIS) == RESET) + { + /* Check if a NACK is detected */ + if(FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + hfmpi2c->State= HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles FMPI2C Communication Timeout for specific usage of STOP flag. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef FMPI2C_WaitOnSTOPFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout) +{ + uint32_t tickstart = 0x00; + tickstart = HAL_GetTick(); + + while(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET) + { + /* Check if a NACK is detected */ + if(FMPI2C_IsAcknowledgeFailed(hfmpi2c, Timeout) != HAL_OK) + { + return HAL_ERROR; + } + + /* Check for the Timeout */ + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + hfmpi2c->State= HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_TIMEOUT; + } + } + return HAL_OK; +} + +/** + * @brief This function handles FMPI2C Communication Timeout for specific usage of RXNE flag. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef FMPI2C_WaitOnRXNEFlagUntilTimeout(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout) +{ + uint32_t tickstart = 0x00; + tickstart = HAL_GetTick(); + + while(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_RXNE) == RESET) + { + /* Check if a STOPF is detected */ + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == SET) + { + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_NONE; + hfmpi2c->State= HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_ERROR; + } + + /* Check for the Timeout */ + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hfmpi2c->ErrorCode |= HAL_FMPI2C_ERROR_TIMEOUT; + hfmpi2c->State= HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_TIMEOUT; + } + } + return HAL_OK; +} + +/** + * @brief This function handles Acknowledge failed detection during an FMPI2C Communication. + * @param hfmpi2c : Pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2C. + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef FMPI2C_IsAcknowledgeFailed(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t Timeout) +{ + uint32_t tickstart = 0x00; + tickstart = HAL_GetTick(); + + if(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_AF) == SET) + { + /* Generate stop if necessary only in case of FMPI2C peripheral in MASTER mode */ + if((hfmpi2c->State == HAL_FMPI2C_STATE_MASTER_BUSY_TX) || (hfmpi2c->State == HAL_FMPI2C_STATE_MEM_BUSY_TX) + || (hfmpi2c->State == HAL_FMPI2C_STATE_MEM_BUSY_RX)) + { + /* No need to generate the STOP condition if AUTOEND mode is enabled */ + /* Generate the STOP condition only in case of SOFTEND mode is enabled */ + if((hfmpi2c->Instance->CR2 & FMPI2C_AUTOEND_MODE) != FMPI2C_AUTOEND_MODE) + { + /* Generate Stop */ + hfmpi2c->Instance->CR2 |= FMPI2C_CR2_STOP; + } + } + + /* Wait until STOP Flag is reset */ + /* AutoEnd should be initiate after AF */ + while(__HAL_FMPI2C_GET_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF) == RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hfmpi2c->State= HAL_FMPI2C_STATE_READY; + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + return HAL_TIMEOUT; + } + } + } + + /* Clear NACKF Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_AF); + + /* Clear STOP Flag */ + __HAL_FMPI2C_CLEAR_FLAG(hfmpi2c, FMPI2C_FLAG_STOPF); + + /* Clear Configuration Register 2 */ + __HAL_FMPI2C_RESET_CR2(hfmpi2c); + + hfmpi2c->ErrorCode = HAL_FMPI2C_ERROR_AF; + hfmpi2c->State= HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_ERROR; + } + return HAL_OK; +} + +/** + * @brief Handles FMPI2Cx communication when starting transfer or during transfer (TC or TCR flag are set). + * @param hfmpi2c: FMPI2C handle. + * @param DevAddress: specifies the slave address to be programmed. + * @param Size: specifies the number of bytes to be programmed. + * This parameter must be a value between 0 and 255. + * @param Mode: new state of the FMPI2C START condition generation. + * This parameter can be one of the following values: + * @arg FMPI2C_RELOAD_MODE: Enable Reload mode . + * @arg FMPI2C_AUTOEND_MODE: Enable Automatic end mode. + * @arg FMPI2C_SOFTEND_MODE: Enable Software end mode. + * @param Request: new state of the FMPI2C START condition generation. + * This parameter can be one of the following values: + * @arg FMPI2C_NO_STARTSTOP: Don't Generate stop and start condition. + * @arg FMPI2C_GENERATE_STOP: Generate stop condition (Size should be set to 0). + * @arg FMPI2C_GENERATE_START_READ: Generate Restart for read request. + * @arg FMPI2C_GENERATE_START_WRITE: Generate Restart for write request. + * @retval None + */ +static void FMPI2C_TransferConfig(FMPI2C_HandleTypeDef *hfmpi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, uint32_t Request) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance)); + assert_param(IS_TRANSFER_MODE(Mode)); + assert_param(IS_TRANSFER_REQUEST(Request)); + + /* Get the CR2 register value */ + tmpreg = hfmpi2c->Instance->CR2; + + /* clear tmpreg specific bits */ + tmpreg &= (uint32_t)~((uint32_t)(FMPI2C_CR2_SADD | FMPI2C_CR2_NBYTES | FMPI2C_CR2_RELOAD | FMPI2C_CR2_AUTOEND | FMPI2C_CR2_RD_WRN | FMPI2C_CR2_START | FMPI2C_CR2_STOP)); + + /* update tmpreg */ + tmpreg |= (uint32_t)(((uint32_t)DevAddress & FMPI2C_CR2_SADD) | (((uint32_t)Size << 16 ) & FMPI2C_CR2_NBYTES) | \ + (uint32_t)Mode | (uint32_t)Request); + + /* update CR2 register */ + hfmpi2c->Instance->CR2 = tmpreg; +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F446xx */ +#endif /* HAL_FMPI2C_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_fmpi2c_ex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_fmpi2c_ex.c new file mode 100644 index 0000000..431b1a1 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_fmpi2c_ex.c @@ -0,0 +1,326 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_fmpi2c_ex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Extended FMPI2C HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the Inter Integrated Circuit (FMPI2C) peripheral: + * + Extended Control methods + * + @verbatim + ============================================================================== + ##### FMPI2C peripheral extended features ##### + ============================================================================== + + [..] Comparing to other previous devices, the FMPI2C interface for STM32L4XX + devices contains the following additional features + + (+) Possibility to disable or enable Analog Noise Filter + (+) Use of a configured Digital Noise Filter + (+) Disable or enable wakeup from Stop mode + + ##### How to use this driver ##### + ============================================================================== + [..] This driver provides functions to configure Noise Filter + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 FMPI2CEx FMPI2CEx + * @brief FMPI2C HAL module driver + * @{ + */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + +#if defined(STM32F446xx) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup FMPI2CEx_Exported_Functions FMPI2C Extended Exported Functions + * @{ + */ + + +/** @defgroup FMPI2CEx_Exported_Functions_Group1 Peripheral Control methods + * @brief management functions + * +@verbatim + =============================================================================== + ##### Extension features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure Noise Filters + +@endverbatim + * @{ + */ + +/** + * @brief Configures FMPI2C Analog noise filter. + * @param hfmpi2c : pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2Cx peripheral. + * @param AnalogFilter : new state of the Analog filter. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2CEx_AnalogFilter_Config(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t AnalogFilter) +{ + /* Check the parameters */ + assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance)); + assert_param(IS_FMPI2C_ANALOG_FILTER(AnalogFilter)); + + if((hfmpi2c->State == HAL_FMPI2C_STATE_BUSY) || (hfmpi2c->State == HAL_FMPI2C_STATE_MASTER_BUSY_TX) || (hfmpi2c->State == HAL_FMPI2C_STATE_MASTER_BUSY_RX) + || (hfmpi2c->State == HAL_FMPI2C_STATE_SLAVE_BUSY_TX) || (hfmpi2c->State == HAL_FMPI2C_STATE_SLAVE_BUSY_RX)) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_BUSY; + + /* Disable the selected FMPI2C peripheral */ + __HAL_FMPI2C_DISABLE(hfmpi2c); + + /* Reset FMPI2Cx ANOFF bit */ + hfmpi2c->Instance->CR1 &= ~(FMPI2C_CR1_ANFOFF); + + /* Set analog filter bit*/ + hfmpi2c->Instance->CR1 |= AnalogFilter; + + __HAL_FMPI2C_ENABLE(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; +} + +/** + * @brief Configures FMPI2C Digital noise filter. + * @param hfmpi2c : pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2Cx peripheral. + * @param DigitalFilter : Coefficient of digital noise filter between 0x00 and 0x0F. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2CEx_DigitalFilter_Config(FMPI2C_HandleTypeDef *hfmpi2c, uint32_t DigitalFilter) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance)); + assert_param(IS_FMPI2C_DIGITAL_FILTER(DigitalFilter)); + + if((hfmpi2c->State == HAL_FMPI2C_STATE_BUSY) || (hfmpi2c->State == HAL_FMPI2C_STATE_MASTER_BUSY_TX) || (hfmpi2c->State == HAL_FMPI2C_STATE_MASTER_BUSY_RX) + || (hfmpi2c->State == HAL_FMPI2C_STATE_SLAVE_BUSY_TX) || (hfmpi2c->State == HAL_FMPI2C_STATE_SLAVE_BUSY_RX)) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_BUSY; + + /* Disable the selected FMPI2C peripheral */ + __HAL_FMPI2C_DISABLE(hfmpi2c); + + /* Get the old register value */ + tmpreg = hfmpi2c->Instance->CR1; + + /* Reset FMPI2Cx DNF bits [11:8] */ + tmpreg &= ~(FMPI2C_CR1_DFN); + + /* Set FMPI2Cx DNF coefficient */ + tmpreg |= DigitalFilter << 8; + + /* Store the new register value */ + hfmpi2c->Instance->CR1 = tmpreg; + + __HAL_FMPI2C_ENABLE(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; +} + +/** + * @brief Enables FMPI2C wakeup from stop mode. + * @param hfmpi2c : pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2Cx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2CEx_EnableWakeUp (FMPI2C_HandleTypeDef *hfmpi2c) +{ + /* Check the parameters */ + assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance)); + + if((hfmpi2c->State == HAL_FMPI2C_STATE_BUSY) || (hfmpi2c->State == HAL_FMPI2C_STATE_MASTER_BUSY_TX) || (hfmpi2c->State == HAL_FMPI2C_STATE_MASTER_BUSY_RX) + || (hfmpi2c->State == HAL_FMPI2C_STATE_SLAVE_BUSY_TX) || (hfmpi2c->State == HAL_FMPI2C_STATE_SLAVE_BUSY_RX)) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_BUSY; + + /* Disable the selected FMPI2C peripheral */ + __HAL_FMPI2C_DISABLE(hfmpi2c); + + /* Enable wakeup from stop mode */ + hfmpi2c->Instance->CR1 |= FMPI2C_CR1_WUPEN; + + __HAL_FMPI2C_ENABLE(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; +} + + +/** + * @brief Disables FMPI2C wakeup from stop mode. + * @param hfmpi2c : pointer to a FMPI2C_HandleTypeDef structure that contains + * the configuration information for the specified FMPI2Cx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FMPI2CEx_DisableWakeUp (FMPI2C_HandleTypeDef *hfmpi2c) +{ + /* Check the parameters */ + assert_param(IS_FMPI2C_ALL_INSTANCE(hfmpi2c->Instance)); + + if((hfmpi2c->State == HAL_FMPI2C_STATE_BUSY) || (hfmpi2c->State == HAL_FMPI2C_STATE_MASTER_BUSY_TX) || (hfmpi2c->State == HAL_FMPI2C_STATE_MASTER_BUSY_RX) + || (hfmpi2c->State == HAL_FMPI2C_STATE_SLAVE_BUSY_TX) || (hfmpi2c->State == HAL_FMPI2C_STATE_SLAVE_BUSY_RX)) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_BUSY; + + /* Disable the selected FMPI2C peripheral */ + __HAL_FMPI2C_DISABLE(hfmpi2c); + + /* Enable wakeup from stop mode */ + hfmpi2c->Instance->CR1 &= ~(FMPI2C_CR1_WUPEN); + + __HAL_FMPI2C_ENABLE(hfmpi2c); + + hfmpi2c->State = HAL_FMPI2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hfmpi2c); + + return HAL_OK; +} + +/** + * @brief Enable the FMPI2C1 fast mode plus driving capability. + * @param ConfigFastModePlus: selects the pin. + * This parameter can be one of the @ref FMPI2CEx_FastModePlus values + * @retval None + */ +void HAL_FMPI2CEx_EnableFastModePlus(uint32_t ConfigFastModePlus) +{ + /* Check the parameter */ + assert_param(IS_FMPI2C_FASTMODEPLUS(ConfigFastModePlus)); + + /* Enable SYSCFG clock */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + + /* Enable fast mode plus driving capability for selected pin */ + SET_BIT(SYSCFG->CFGR, (uint32_t)ConfigFastModePlus); +} + +/** + * @brief Disable the FMPI2C1 fast mode plus driving capability. + * @param ConfigFastModePlus: selects the pin. + * This parameter can be one of the @ref FMPI2CEx_FastModePlus values + * @retval None + */ +void HAL_FMPI2CEx_DisableFastModePlus(uint32_t ConfigFastModePlus) +{ + /* Check the parameter */ + assert_param(IS_FMPI2C_FASTMODEPLUS(ConfigFastModePlus)); + + /* Enable SYSCFG clock */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + + /* Disable fast mode plus driving capability for selected pin */ + CLEAR_BIT(SYSCFG->CFGR, (uint32_t)ConfigFastModePlus); +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F446xx */ +#endif /* HAL_FMPI2C_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c new file mode 100644 index 0000000..56275fe --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c @@ -0,0 +1,545 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_gpio.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief GPIO HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the General Purpose Input/Output (GPIO) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + @verbatim + ============================================================================== + ##### GPIO Peripheral features ##### + ============================================================================== + [..] + Subject to the specific hardware characteristics of each I/O port listed in the datasheet, each + port bit of the General Purpose IO (GPIO) Ports, can be individually configured by software + in several modes: + (+) Input mode + (+) Analog mode + (+) Output mode + (+) Alternate function mode + (+) External interrupt/event lines + + [..] + During and just after reset, the alternate functions and external interrupt + lines are not active and the I/O ports are configured in input floating mode. + + [..] + All GPIO pins have weak internal pull-up and pull-down resistors, which can be + activated or not. + + [..] + In Output or Alternate mode, each IO can be configured on open-drain or push-pull + type and the IO speed can be selected depending on the VDD value. + + [..] + All ports have external interrupt/event capability. To use external interrupt + lines, the port must be configured in input mode. All available GPIO pins are + connected to the 16 external interrupt/event lines from EXTI0 to EXTI15. + + [..] + The external interrupt/event controller consists of up to 23 edge detectors + (16 lines are connected to GPIO) for generating event/interrupt requests (each + input line can be independently configured to select the type (interrupt or event) + and the corresponding trigger event (rising or falling or both). Each line can + also be masked independently. + + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Enable the GPIO AHB clock using the following function: __HAL_RCC_GPIOx_CLK_ENABLE(). + + (#) Configure the GPIO pin(s) using HAL_GPIO_Init(). + (++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure + (++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef + structure. + (++) In case of Output or alternate function mode selection: the speed is + configured through "Speed" member from GPIO_InitTypeDef structure. + (++) In alternate mode is selection, the alternate function connected to the IO + is configured through "Alternate" member from GPIO_InitTypeDef structure. + (++) Analog mode is required when a pin is to be used as ADC channel + or DAC output. + (++) In case of external interrupt/event selection the "Mode" member from + GPIO_InitTypeDef structure select the type (interrupt or event) and + the corresponding trigger event (rising or falling or both). + + (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority + mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using + HAL_NVIC_EnableIRQ(). + + (#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin(). + + (#) To set/reset the level of a pin configured in output mode use + HAL_GPIO_WritePin()/HAL_GPIO_TogglePin(). + + (#) To lock pin configuration until next reset use HAL_GPIO_LockPin(). + + + (#) During and just after reset, the alternate functions are not + active and the GPIO pins are configured in input floating mode (except JTAG + pins). + + (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose + (PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has + priority over the GPIO function. + + (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as + general purpose PH0 and PH1, respectively, when the HSE oscillator is off. + The HSE has priority over the GPIO function. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 GPIO GPIO + * @brief GPIO HAL module driver + * @{ + */ + +#ifdef HAL_GPIO_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup GPIO_Private_Constants GPIO Private Constants + * @{ + */ +#define GPIO_MODE ((uint32_t)0x00000003) +#define EXTI_MODE ((uint32_t)0x10000000) +#define GPIO_MODE_IT ((uint32_t)0x00010000) +#define GPIO_MODE_EVT ((uint32_t)0x00020000) +#define RISING_EDGE ((uint32_t)0x00100000) +#define FALLING_EDGE ((uint32_t)0x00200000) +#define GPIO_OUTPUT_TYPE ((uint32_t)0x00000010) + +#define GPIO_NUMBER ((uint32_t)16) +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup GPIO_Exported_Functions GPIO Exported Functions + * @{ + */ + +/** @defgroup GPIO_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 and de-initialize the GPIOs + to be ready for use. + +@endverbatim + * @{ + */ + + +/** + * @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init. + * @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F429X device or + * x can be (A..I) to select the GPIO peripheral for STM32F40XX and STM32F427X devices. + * @param GPIO_Init: pointer to a GPIO_InitTypeDef structure that contains + * the configuration information for the specified GPIO peripheral. + * @retval None + */ +void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) +{ + uint32_t position; + uint32_t ioposition = 0x00; + uint32_t iocurrent = 0x00; + uint32_t temp = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Init->Pin)); + assert_param(IS_GPIO_MODE(GPIO_Init->Mode)); + assert_param(IS_GPIO_PULL(GPIO_Init->Pull)); + + /* Configure the port pins */ + for(position = 0; position < GPIO_NUMBER; position++) + { + /* Get the IO position */ + ioposition = ((uint32_t)0x01) << position; + /* Get the current IO position */ + iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition; + + if(iocurrent == ioposition) + { + /*--------------------- GPIO Mode Configuration ------------------------*/ + /* In case of Alternate function mode selection */ + if((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) + { + /* Check the Alternate function parameter */ + assert_param(IS_GPIO_AF(GPIO_Init->Alternate)); + /* Configure Alternate function mapped with the current IO */ + temp = GPIOx->AFR[position >> 3]; + temp &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ; + temp |= ((uint32_t)(GPIO_Init->Alternate) << (((uint32_t)position & (uint32_t)0x07) * 4)); + GPIOx->AFR[position >> 3] = temp; + } + + /* Configure IO Direction mode (Input, Output, Alternate or Analog) */ + temp = GPIOx->MODER; + temp &= ~(GPIO_MODER_MODER0 << (position * 2)); + temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2)); + GPIOx->MODER = temp; + + /* In case of Output or Alternate function mode selection */ + if((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) || + (GPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) + { + /* Check the Speed parameter */ + assert_param(IS_GPIO_SPEED(GPIO_Init->Speed)); + /* Configure the IO Speed */ + temp = GPIOx->OSPEEDR; + temp &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2)); + temp |= (GPIO_Init->Speed << (position * 2)); + GPIOx->OSPEEDR = temp; + + /* Configure the IO Output Type */ + temp = GPIOx->OTYPER; + temp &= ~(GPIO_OTYPER_OT_0 << position) ; + temp |= (((GPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4) << position); + GPIOx->OTYPER = temp; + } + + /* Activate the Pull-up or Pull down resistor for the current IO */ + temp = GPIOx->PUPDR; + temp &= ~(GPIO_PUPDR_PUPDR0 << (position * 2)); + temp |= ((GPIO_Init->Pull) << (position * 2)); + GPIOx->PUPDR = temp; + + /*--------------------- EXTI Mode Configuration ------------------------*/ + /* Configure the External Interrupt or event for the current IO */ + if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE) + { + /* Enable SYSCFG Clock */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + + temp = SYSCFG->EXTICR[position >> 2]; + temp &= ~(((uint32_t)0x0F) << (4 * (position & 0x03))); + temp |= ((uint32_t)(GPIO_GET_INDEX(GPIOx)) << (4 * (position & 0x03))); + SYSCFG->EXTICR[position >> 2] = temp; + + /* Clear EXTI line configuration */ + temp = EXTI->IMR; + temp &= ~((uint32_t)iocurrent); + if((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT) + { + temp |= iocurrent; + } + EXTI->IMR = temp; + + temp = EXTI->EMR; + temp &= ~((uint32_t)iocurrent); + if((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT) + { + temp |= iocurrent; + } + EXTI->EMR = temp; + + /* Clear Rising Falling edge configuration */ + temp = EXTI->RTSR; + temp &= ~((uint32_t)iocurrent); + if((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE) + { + temp |= iocurrent; + } + EXTI->RTSR = temp; + + temp = EXTI->FTSR; + temp &= ~((uint32_t)iocurrent); + if((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE) + { + temp |= iocurrent; + } + EXTI->FTSR = temp; + } + } + } +} + +/** + * @brief De-initializes the GPIOx peripheral registers to their default reset values. + * @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F429X device or + * x can be (A..I) to select the GPIO peripheral for STM32F40XX and STM32F427X devices. + * @param GPIO_Pin: specifies the port bit to be written. + * This parameter can be one of GPIO_PIN_x where x can be (0..15). + * @retval None + */ +void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) +{ + uint32_t position; + uint32_t ioposition = 0x00; + uint32_t iocurrent = 0x00; + uint32_t tmp = 0x00; + + /* Check the parameters */ + assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); + + /* Configure the port pins */ + for(position = 0; position < GPIO_NUMBER; position++) + { + /* Get the IO position */ + ioposition = ((uint32_t)0x01) << position; + /* Get the current IO position */ + iocurrent = (GPIO_Pin) & ioposition; + + if(iocurrent == ioposition) + { + /*------------------------- GPIO Mode Configuration --------------------*/ + /* Configure IO Direction in Input Floating Mode */ + GPIOx->MODER &= ~(GPIO_MODER_MODER0 << (position * 2)); + + /* Configure the default Alternate Function in current IO */ + GPIOx->AFR[position >> 3] &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ; + + /* Configure the default value for IO Speed */ + GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2)); + + /* Configure the default value IO Output Type */ + GPIOx->OTYPER &= ~(GPIO_OTYPER_OT_0 << position) ; + + /* Deactivate the Pull-up and Pull-down resistor for the current IO */ + GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << (position * 2)); + + /*------------------------- EXTI Mode Configuration --------------------*/ + tmp = SYSCFG->EXTICR[position >> 2]; + tmp &= (((uint32_t)0x0F) << (4 * (position & 0x03))); + if(tmp == ((uint32_t)(GPIO_GET_INDEX(GPIOx)) << (4 * (position & 0x03)))) + { + /* Configure the External Interrupt or event for the current IO */ + tmp = ((uint32_t)0x0F) << (4 * (position & 0x03)); + SYSCFG->EXTICR[position >> 2] &= ~tmp; + + /* Clear EXTI line configuration */ + EXTI->IMR &= ~((uint32_t)iocurrent); + EXTI->EMR &= ~((uint32_t)iocurrent); + + /* Clear Rising Falling edge configuration */ + EXTI->RTSR &= ~((uint32_t)iocurrent); + EXTI->FTSR &= ~((uint32_t)iocurrent); + } + } + } +} + +/** + * @} + */ + +/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions + * @brief GPIO Read and Write + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Reads the specified input port pin. + * @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F429X device or + * x can be (A..I) to select the GPIO peripheral for STM32F40XX and STM32F427X devices. + * @param GPIO_Pin: specifies the port bit to read. + * This parameter can be GPIO_PIN_x where x can be (0..15). + * @retval The input port pin value. + */ +GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + GPIO_PinState bitstatus; + + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + if((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET) + { + bitstatus = GPIO_PIN_SET; + } + else + { + bitstatus = GPIO_PIN_RESET; + } + return bitstatus; +} + +/** + * @brief Sets or clears the selected data port bit. + * + * @note This function uses GPIOx_BSRR register to allow atomic read/modify + * accesses. In this way, there is no risk of an IRQ occurring between + * the read and the modify access. + * + * @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F429X device or + * x can be (A..I) to select the GPIO peripheral for STM32F40XX and STM32F427X devices. + * @param GPIO_Pin: specifies the port bit to be written. + * This parameter can be one of GPIO_PIN_x where x can be (0..15). + * @param PinState: specifies the value to be written to the selected bit. + * This parameter can be one of the GPIO_PinState enum values: + * @arg GPIO_PIN_RESET: to clear the port pin + * @arg GPIO_PIN_SET: to set the port pin + * @retval None + */ +void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + assert_param(IS_GPIO_PIN_ACTION(PinState)); + + if(PinState != GPIO_PIN_RESET) + { + GPIOx->BSRR = GPIO_Pin; + } + else + { + GPIOx->BSRR = (uint32_t)GPIO_Pin << 16; + } +} + +/** + * @brief Toggles the specified GPIO pins. + * @param GPIOx: Where x can be (A..K) to select the GPIO peripheral for STM32F429X device or + * x can be (A..I) to select the GPIO peripheral for STM32F40XX and STM32F427X devices. + * @param GPIO_Pin: Specifies the pins to be toggled. + * @retval None + */ +void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + GPIOx->ODR ^= GPIO_Pin; +} + +/** + * @brief Locks GPIO Pins configuration registers. + * @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR, + * GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH. + * @note The configuration of the locked GPIO pins can no longer be modified + * until the next reset. + * @param GPIOx: where x can be (A..F) to select the GPIO peripheral for STM32F4 family + * @param GPIO_Pin: specifies the port bit to be locked. + * This parameter can be any combination of GPIO_PIN_x where x can be (0..15). + * @retval None + */ +HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + __IO uint32_t tmp = GPIO_LCKR_LCKK; + + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + /* Apply lock key write sequence */ + tmp |= GPIO_Pin; + /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */ + GPIOx->LCKR = tmp; + /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */ + GPIOx->LCKR = GPIO_Pin; + /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */ + GPIOx->LCKR = tmp; + /* Read LCKK bit*/ + tmp = GPIOx->LCKR; + + if((GPIOx->LCKR & GPIO_LCKR_LCKK) != RESET) + { + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief This function handles EXTI interrupt request. + * @param GPIO_Pin: Specifies the pins connected EXTI line + * @retval None + */ +void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin) +{ + /* EXTI line interrupt detected */ + if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET) + { + __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); + HAL_GPIO_EXTI_Callback(GPIO_Pin); + } +} + +/** + * @brief EXTI line detection callbacks. + * @param GPIO_Pin: Specifies the pins connected EXTI line + * @retval None + */ +__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_GPIO_EXTI_Callback could be implemented in the user file + */ +} + +/** + * @} + */ + + +/** + * @} + */ + +#endif /* HAL_GPIO_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash.c new file mode 100644 index 0000000..1dc145a --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash.c @@ -0,0 +1,1862 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_hash.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-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 + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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) + +/* 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 */ +#endif /* HAL_HASH_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash_ex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash_ex.c new file mode 100644 index 0000000..1daa4b5 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash_ex.c @@ -0,0 +1,1642 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_hash_ex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief HASH HAL Extension module driver. + * This file provides firmware functions to manage the following + * functionalities of HASH peripheral: + * + Extended HASH processing functions based on SHA224 Algorithm + * + Extended HASH processing functions based on SHA256 Algorithm + * + @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_HMACEx_SHA224_Start()) + (+++) 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_HMACEx_SH224_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: 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_HASHEx_SHA224_Start() + (##) Interrupt mode: encryption and decryption APIs are not blocking functions + i.e. they process the data under interrupt + e.g. HAL_HASHEx_SHA224_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_HASHEx_SHA224_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_HASHEx_SHA224_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_HASHEx_SHA224_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_HASHEx_SHA224_Start_DMA(). + After that, call the finish function in order to get the digest value + e.g. HAL_HASHEx_SHA224_Finish() + (#)Call HAL_HASH_DeInit() to deinitialize the HASH peripheral. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 HASHEx HASHEx + * @brief HASH Extension HAL module driver. + * @{ + */ + +#ifdef HAL_HASH_MODULE_ENABLED + +#if defined(STM32F437xx) || defined(STM32F439xx) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup HASHEx_Private_Functions + * @{ + */ +static void HASHEx_DMAXferCplt(DMA_HandleTypeDef *hdma); +static void HASHEx_WriteData(uint8_t *pInBuffer, uint32_t Size); +static void HASHEx_GetDigest(uint8_t *pMsgDigest, uint8_t Size); +static void HASHEx_DMAError(DMA_HandleTypeDef *hdma); +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ + +/** @addtogroup HASHEx_Private_Functions + * @{ + */ + +/** + * @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 HASHEx_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 HASHEx_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; + } +} + +/** + * @brief DMA HASH Input Data complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void HASHEx_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 = HASHEx_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 HASHEx_DMAError(DMA_HandleTypeDef *hdma) +{ + HASH_HandleTypeDef* hhash = ( HASH_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + hhash->State= HAL_HASH_STATE_READY; + HAL_HASH_ErrorCallback(hhash); +} + + /** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup HASHEx_Exported_Functions + * @{ + */ + +/** @defgroup HASHEx_Group1 HASH processing functions + * @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: + (+) SHA224 + (+) SHA256 + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the HASH peripheral in SHA224 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 28 bytes. + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASHEx_SHA224_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 SHA224 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_SHA224 | 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 */ + HASHEx_WriteData(pInBuffer, Size); + + /* Start the digest calculation */ + __HAL_HASH_START_DIGEST(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((HASH->SR & HASH_FLAG_BUSY) == 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 */ + HASHEx_GetDigest(pOutBuffer, 28); + + /* 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 SHA256 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 32 bytes. + * @param Timeout: Specify Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASHEx_SHA256_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 SHA256 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_SHA256 | 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 */ + HASHEx_WriteData(pInBuffer, Size); + + /* Start the digest calculation */ + __HAL_HASH_START_DIGEST(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((HASH->SR & HASH_FLAG_BUSY) == 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 */ + HASHEx_GetDigest(pOutBuffer, 32); + + /* 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 SHA224 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. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASHEx_SHA224_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 SHA224 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_SHA224 | 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 */ + HASHEx_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 SHA256 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. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASHEx_SHA256_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 SHA256 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_SHA256 | 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 */ + HASHEx_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 HASHEx_Group2 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: + (+) SHA224 + (+) SHA256 + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the HASH peripheral in HMAC SHA224 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_HMACEx_SHA224_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 SHA224 mode */ + HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT); + } + else + { + /* Select the HMAC SHA224 mode */ + HASH->CR |= (HASH_ALGOSELECTION_SHA224 | 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 */ + HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize); + + /* Start the digest calculation */ + __HAL_HASH_START_DIGEST(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((HASH->SR & HASH_FLAG_BUSY) == 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 */ + HASHEx_WriteData(pInBuffer, Size); + + /* Start the digest calculation */ + __HAL_HASH_START_DIGEST(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((HASH->SR & HASH_FLAG_BUSY) == 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 */ + HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize); + + /* Start the digest calculation */ + __HAL_HASH_START_DIGEST(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((HASH->SR & HASH_FLAG_BUSY) == 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 */ + HASHEx_GetDigest(pOutBuffer, 28); + + /* 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 SHA256 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_HMACEx_SHA256_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 SHA256 mode */ + HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY); + } + else + { + /* Select the HMAC SHA256 mode */ + HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC); + } + /* 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; + } + + /* 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 */ + HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize); + + /* Start the digest calculation */ + __HAL_HASH_START_DIGEST(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((HASH->SR & HASH_FLAG_BUSY) == 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 */ + HASHEx_WriteData(pInBuffer, Size); + + /* Start the digest calculation */ + __HAL_HASH_START_DIGEST(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((HASH->SR & HASH_FLAG_BUSY) == 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 */ + HASHEx_WriteData(hhash->Init.pKey, hhash->Init.KeySize); + + /* Start the digest calculation */ + __HAL_HASH_START_DIGEST(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((HASH->SR & HASH_FLAG_BUSY) == 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 */ + HASHEx_GetDigest(pOutBuffer, 32); + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hhash); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup HASHEx_Group3 HASH processing functions using interrupt mode + * @brief processing functions using interrupt mode. + * +@verbatim + =============================================================================== + ##### HASH processing using interrupt functions ##### + =============================================================================== + [..] This section provides functions allowing to calculate in interrupt mode + the hash value using one of the following algorithms: + (+) SHA224 + (+) SHA256 + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the HASH peripheral in SHA224 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_HASHEx_SHA224_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer) +{ + uint32_t inputaddr; + 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 SHA224 mode */ + HASH->CR |= HASH_ALGOSELECTION_SHA224; + /* 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)) + { + /* Read the message digest */ + HASHEx_GetDigest(hhash->pHashOutBuffPtr, 28); + 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 SHA256 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_HASHEx_SHA256_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer) +{ + uint32_t inputaddr; + 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 SHA256 mode */ + HASH->CR |= HASH_ALGOSELECTION_SHA256; + /* 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)) + { + /* Read the message digest */ + HASHEx_GetDigest(hhash->pHashOutBuffPtr, 32); + 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_HASHEx_IRQHandler(HASH_HandleTypeDef *hhash) +{ + switch(HASH->CR & HASH_CR_ALGO) + { + + case HASH_ALGOSELECTION_SHA224: + HAL_HASHEx_SHA224_Start_IT(hhash, NULL, 0, NULL); + break; + + case HASH_ALGOSELECTION_SHA256: + HAL_HASHEx_SHA256_Start_IT(hhash, NULL, 0, NULL); + break; + + default: + break; + } +} + +/** + * @} + */ + +/** @defgroup HASHEx_Group4 HASH processing functions using DMA mode + * @brief processing functions using DMA mode. + * +@verbatim + =============================================================================== + ##### HASH processing using DMA functions ##### + =============================================================================== + [..] This section provides functions allowing to calculate in DMA mode + the hash value using one of the following algorithms: + (+) SHA224 + (+) SHA256 + +@endverbatim + * @{ + */ + + +/** + * @brief Initializes the HASH peripheral in SHA224 mode then enables DMA to + control data transfer. Use HAL_HASH_SHA224_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_HASHEx_SHA224_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 SHA224 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_SHA224 | 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 = HASHEx_DMAXferCplt; + /* Set the DMA error callback */ + hhash->hdmain->XferErrorCallback = HASHEx_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 SHA224 + * @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 28 bytes. + * @param Timeout: Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASHEx_SHA224_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 */ + HASHEx_GetDigest(pOutBuffer, 28); + + /* 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 SHA256 mode then enables DMA to + control data transfer. Use HAL_HASH_SHA256_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_HASHEx_SHA256_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 SHA256 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_SHA256 | 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 = HASHEx_DMAXferCplt; + /* Set the DMA error callback */ + hhash->hdmain->XferErrorCallback = HASHEx_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 UnLock */ + __HAL_UNLOCK(hhash); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Returns the computed digest in SHA256. + * @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 32 bytes. + * @param Timeout: Timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HASHEx_SHA256_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 */ + HASHEx_GetDigest(pOutBuffer, 32); + + /* Change HASH peripheral state */ + hhash->State = HAL_HASH_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hhash); + + /* Return function status */ + return HAL_OK; +} + + +/** + * @} + */ +/** @defgroup HASHEx_Group5 HMAC processing functions using DMA mode + * @brief HMAC processing functions using DMA mode . + * +@verbatim + =============================================================================== + ##### HMAC processing using DMA functions ##### + =============================================================================== + [..] This section provides functions allowing to calculate in DMA mode + the HMAC value using one of the following algorithms: + (+) SHA224 + (+) SHA256 + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the HASH peripheral in HMAC SHA224 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_HMACEx_SHA224_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size) +{ + uint32_t inputaddr; + + /* 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 SHA224 mode */ + HASH->CR |= (HASH_ALGOSELECTION_SHA224 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT); + } + else + { + /* Select the HMAC SHA224 mode */ + HASH->CR |= (HASH_ALGOSELECTION_SHA224 | 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 = HASHEx_DMAXferCplt; + /* Set the DMA error callback */ + hhash->hdmain->XferErrorCallback = HASHEx_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 SHA256 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_HMACEx_SHA256_Start_DMA(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size) +{ + uint32_t inputaddr; + + /* 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 SHA256 mode */ + HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY); + } + else + { + /* Select the HMAC SHA256 mode */ + HASH->CR |= (HASH_ALGOSELECTION_SHA256 | HASH_ALGOMODE_HMAC); + } + /* 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; + } + + /* 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 = HASHEx_DMAXferCplt; + /* Set the DMA error callback */ + hhash->hdmain->XferErrorCallback = HASHEx_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; +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F437xx || STM32F439xx */ + +#endif /* HAL_HASH_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c new file mode 100644 index 0000000..b78ca19 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hcd.c @@ -0,0 +1,1316 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_hcd.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief HCD HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#)Declare a HCD_HandleTypeDef handle structure, for example: + HCD_HandleTypeDef hhcd; + + (#)Fill parameters of Init structure in HCD handle + + (#)Call HAL_HCD_Init() API to initialize the HCD peripheral (Core, Host core, ...) + + (#)Initialize the HCD low level resources through the HAL_HCD_MspInit() API: + (##) Enable the HCD/USB Low Level interface clock using the following macros + (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode) + (+++) __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); (For High Speed Mode) + + (##) Initialize the related GPIO clocks + (##) Configure HCD pin-out + (##) Configure HCD NVIC interrupt + + (#)Associate the Upper USB Host stack to the HAL HCD Driver: + (##) hhcd.pData = phost; + + (#)Enable HCD transmission and reception: + (##) HAL_HCD_Start(); + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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. + * + ****************************************************************************** + * + * Modifications by Robert Fisk + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup HCD HCD + * @brief HCD HAL module driver + * @{ + */ + +#ifdef HAL_HCD_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup HCD_Private_Functions HCD Private Functions + * @{ + */ +static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum); +static void HCD_HC_OUT_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum); +static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd); +static void HCD_Port_IRQHandler(HCD_HandleTypeDef *hhcd); +static void HAL_HCD_OUT_RewindUnsentPackets(HCD_HandleTypeDef *hhcd, uint8_t chnum); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup HCD_Exported_Functions HCD Exported Functions + * @{ + */ + +/** @defgroup HCD_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: + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the host driver. + * @param hhcd: HCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd) +{ + /* Check the HCD handle allocation */ + if(hhcd == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_HCD_ALL_INSTANCE(hhcd->Instance)); + + hhcd->State = HAL_HCD_STATE_BUSY; + + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + HAL_HCD_MspInit(hhcd); + + /* Disable the Interrupts */ + __HAL_HCD_DISABLE(hhcd); + + /* Init the Core (common init.) */ + USB_CoreInit(hhcd->Instance, hhcd->Init); + + /* Force Host Mode*/ + USB_SetCurrentMode(hhcd->Instance , USB_OTG_HOST_MODE); + + /* Init Host */ + USB_HostInit(hhcd->Instance, hhcd->Init); + + hhcd->State= HAL_HCD_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Initialize a host channel. + * @param hhcd: HCD handle + * @param ch_num: Channel number. + * This parameter can be a value from 1 to 15 + * @param epnum: Endpoint number. + * This parameter can be a value from 1 to 15 + * @param dev_address : Current device address + * This parameter can be a value from 0 to 255 + * @param speed: Current device speed. + * This parameter can be one of these values: + * HCD_SPEED_HIGH: High speed mode, + * HCD_SPEED_FULL: Full speed mode, + * HCD_SPEED_LOW: Low speed mode + * @param ep_type: Endpoint Type. + * This parameter can be one of these values: + * EP_TYPE_CTRL: Control type, + * EP_TYPE_ISOC: Isochronous type, + * EP_TYPE_BULK: Bulk type, + * EP_TYPE_INTR: Interrupt type + * @param mps: Max Packet Size. + * This parameter can be a value from 0 to32K + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, + uint8_t ch_num, + uint8_t epnum, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps) +{ + HAL_StatusTypeDef status = HAL_OK; + + __HAL_LOCK(hhcd); + + hhcd->hc[ch_num].dev_addr = dev_address; + hhcd->hc[ch_num].max_packet = mps; + hhcd->hc[ch_num].ch_num = ch_num; + hhcd->hc[ch_num].ep_type = ep_type; + hhcd->hc[ch_num].ep_num = epnum & 0x7F; + hhcd->hc[ch_num].ep_is_in = ((epnum & 0x80) == 0x80); + hhcd->hc[ch_num].speed = speed; + hhcd->hc[ch_num].xfer_len = 0; + hhcd->hc[ch_num].xfer_count = 0; + + status = USB_HC_Init(hhcd->Instance, + ch_num, + epnum, + dev_address, + speed, + ep_type, + mps); + __HAL_UNLOCK(hhcd); + + return status; +} + +/** + * @brief Halt a host channel. + * @param hhcd: HCD handle + * @param ch_num: Channel number. + * This parameter can be a value from 1 to 15 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num) +{ + HAL_StatusTypeDef status = HAL_OK; + + __HAL_LOCK(hhcd); + USB_HC_Halt(hhcd->Instance, ch_num); + __HAL_UNLOCK(hhcd); + + return status; +} + +/** + * @brief DeInitialize the host driver. + * @param hhcd: HCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd) +{ + /* Check the HCD handle allocation */ + if(hhcd == NULL) + { + return HAL_ERROR; + } + + hhcd->State = HAL_HCD_STATE_BUSY; + + /* DeInit the low level hardware */ + HAL_HCD_MspDeInit(hhcd); + + __HAL_HCD_DISABLE(hhcd); + + hhcd->State = HAL_HCD_STATE_RESET; + + return HAL_OK; +} + +/** + * @brief Initialize the HCD MSP. + * @param hhcd: HCD handle + * @retval None + */ +__weak void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCD_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitialize the HCD MSP. + * @param hhcd: HCD handle + * @retval None + */ +__weak void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCD_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup HCD_Exported_Functions_Group2 Input and Output operation functions + * @brief HCD IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to manage the USB Host Data + Transfer + +@endverbatim + * @{ + */ + +/** + * @brief Submit a new URB for processing. + * @param hhcd: HCD handle + * @param ch_num: Channel number. + * This parameter can be a value from 1 to 15 + * @param direction: Channel number. + * This parameter can be one of these values: + * 0 : Output / 1 : Input + * @param ep_type: Endpoint Type. + * This parameter can be one of these values: + * EP_TYPE_CTRL: Control type/ + * EP_TYPE_ISOC: Isochronous type/ + * EP_TYPE_BULK: Bulk type/ + * EP_TYPE_INTR: Interrupt type/ + * @param token: Endpoint Type. + * This parameter can be one of these values: + * 0: HC_PID_SETUP / 1: HC_PID_DATA1 + * @param pbuff: pointer to URB data + * @param length: Length of URB data + * @param do_ping: activate do ping protocol (for high speed only). + * This parameter can be one of these values: + * 0 : do ping inactive / 1 : do ping active + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, + uint8_t ch_num, + uint8_t direction, + uint8_t ep_type, + uint8_t token, + uint8_t* pbuff, + uint16_t length, + uint8_t do_ping) +{ + hhcd->hc[ch_num].ep_is_in = direction; + hhcd->hc[ch_num].ep_type = ep_type; + + if(token == 0) + { + hhcd->hc[ch_num].data_pid = HC_PID_SETUP; + } + else + { + hhcd->hc[ch_num].data_pid = HC_PID_DATA1; + } + + /* Manage Data Toggle */ + switch(ep_type) + { + case EP_TYPE_CTRL: + if((token == 1) && (direction == 0)) /*send data */ + { + if ( length == 0 ) + { /* For Status OUT stage, Length==0, Status Out PID = 1 */ + hhcd->hc[ch_num].toggle_out = 1; + } + + /* Set the Data Toggle bit as per the Flag */ + if ( hhcd->hc[ch_num].toggle_out == 0) + { /* Put the PID 0 */ + hhcd->hc[ch_num].data_pid = HC_PID_DATA0; + } + else + { /* Put the PID 1 */ + hhcd->hc[ch_num].data_pid = HC_PID_DATA1; + } + if(hhcd->hc[ch_num].urb_state != URB_NOTREADY) + { + hhcd->hc[ch_num].do_ping = do_ping; + } + } + break; + + case EP_TYPE_BULK: + if(direction == 0) + { + /* Set the Data Toggle bit as per the Flag */ + if ( hhcd->hc[ch_num].toggle_out == 0) + { /* Put the PID 0 */ + hhcd->hc[ch_num].data_pid = HC_PID_DATA0; + } + else + { /* Put the PID 1 */ + hhcd->hc[ch_num].data_pid = HC_PID_DATA1; + } + if(hhcd->hc[ch_num].urb_state != URB_NOTREADY) + { + hhcd->hc[ch_num].do_ping = do_ping; + } + } + else + { + if( hhcd->hc[ch_num].toggle_in == 0) + { + hhcd->hc[ch_num].data_pid = HC_PID_DATA0; + } + else + { + hhcd->hc[ch_num].data_pid = HC_PID_DATA1; + } + } + + break; + case EP_TYPE_INTR: + if(direction == 0) + { + /* Set the Data Toggle bit as per the Flag */ + if ( hhcd->hc[ch_num].toggle_out == 0) + { /* Put the PID 0 */ + hhcd->hc[ch_num].data_pid = HC_PID_DATA0; + } + else + { /* Put the PID 1 */ + hhcd->hc[ch_num].data_pid = HC_PID_DATA1; + } + } + else + { + if( hhcd->hc[ch_num].toggle_in == 0) + { + hhcd->hc[ch_num].data_pid = HC_PID_DATA0; + } + else + { + hhcd->hc[ch_num].data_pid = HC_PID_DATA1; + } + } + break; + + case EP_TYPE_ISOC: + hhcd->hc[ch_num].data_pid = HC_PID_DATA0; + break; + } + + hhcd->hc[ch_num].xfer_buff = pbuff; + hhcd->hc[ch_num].xfer_len = length; + hhcd->hc[ch_num].urb_state = URB_IDLE; + hhcd->hc[ch_num].xfer_count = 0; + hhcd->hc[ch_num].ch_num = ch_num; + hhcd->hc[ch_num].state = HC_IDLE; + + return USB_HC_StartXfer(hhcd->Instance, &(hhcd->hc[ch_num]), hhcd->Init.dma_enable); +} + +/** + * @brief Handle HCD interrupt request. + * @param hhcd: HCD handle + * @retval None + */ +void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd) +{ + USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; + uint32_t i = 0 , interrupt = 0; + + /* Ensure that we are in host mode */ + if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST) + { + /* Avoid spurious interrupt */ + if(__HAL_HCD_IS_INVALID_INTERRUPT(hhcd)) + { + return; + } + + /* Handle Rx Queue Level Interrupts */ + if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL)) + { + USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL); + + HCD_RXQLVL_IRQHandler (hhcd); + + USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL); + } + + /* Handle Host Disconnect Interrupts */ + if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT)) + { + /* Handle Host Port Interrupts */ + if (HAL_HCD_Disconnect_Callback(hhcd) == HAL_OK) + { + /* Cleanup HPRT */ + USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ + USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); + USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ ); + } + __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT); + } + + /* Handle Host Port Interrupts */ + if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT)) + { + HCD_Port_IRQHandler (hhcd); + } + + /* Handle Host SOF Interrupts */ + if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF)) + { + HAL_HCD_SOF_Callback(hhcd); + __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF); + } + + /* Handle Host channel Interrupts */ + if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT)) + { + interrupt = USB_HC_ReadInterrupt(hhcd->Instance); + for (i = 0; i < hhcd->Init.Host_channels; i++) + { + if (interrupt & (1 << i)) + { + if ((USBx_HC(i)->HCCHAR) & USB_OTG_HCCHAR_EPDIR) + { + HCD_HC_IN_IRQHandler(hhcd, i); + } + else + { + HCD_HC_OUT_IRQHandler (hhcd, i); + } + } + } + __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT); + } + + if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT)) + { + /* Incorrect mode, acknowledge the interrupt */ + __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT); + } + + if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR)) + { + /* Incorrect mode, acknowledge the interrupt */ + __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR); + } + + if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS)) + { + /* Incorrect mode, acknowledge the interrupt */ + __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS); + } + +//If I needed FIFO (half-)empty interrupt handlers, this is what they would look like: +// +// if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_NPTXFE)) +// { +// halResult = HAL_OK; +// +// //Find a channel that wants to write something: +// for (i = 0; i < hhcd->Init.Host_channels; i++) +// { +// if (hhcd->hc[i].ep_is_in == 0) +// { +// if ((hhcd->hc[i].ep_type == EP_TYPE_CTRL) || +// (hhcd->hc[i].ep_type == EP_TYPE_BULK)) +// { +// if (hhcd->hc[i].xfer_count < hhcd->hc[i].xfer_len) +// { +// halResult = USB_HC_WriteEmptyTxFifo(hhcd->Instance, &hhcd->hc[i], 0); +// if (halResult == HAL_BUSY) break; //Fifo is full, so bail out now +// } +// } +// } +// } +// if (halResult != HAL_BUSY) +// { +// //Fifo is not full, ergo we have sent all the data we have to transmit. +// //So we can disable the fifo interrupt now: +// USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTMSK_NPTXFEM); +// } +// } +// +// if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE)) +// { +// halResult = HAL_OK; +// +// //Find a channel that wants to write something: +// for (i = 0; i < hhcd->Init.Host_channels; i++) +// { +// if (hhcd->hc[i].ep_is_in == 0) +// { +// if ((hhcd->hc[i].ep_type == EP_TYPE_INTR) || +// (hhcd->hc[i].ep_type == EP_TYPE_ISOC)) +// { +// if (hhcd->hc[i].xfer_count < hhcd->hc[i].xfer_len) +// { +// halResult = USB_HC_WriteEmptyTxFifo(hhcd->Instance, &hhcd->hc[i], 1); +// if (halResult == HAL_BUSY) break; //Fifo is full, so bail out now +// } +// } +// } +// } +// +// if (halResult != HAL_BUSY) +// { +// //Fifo is not full, ergo we have sent all the data we have to transmit. +// //So we can disable the fifo interrupt now: +// USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTMSK_PTXFEM); +// } +// } + + } +} + +/** + * @brief SOF callback. + * @param hhcd: HCD handle + * @retval None + */ +__weak void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_HCD_SOF_Callback could be implemented in the user file + */ +} + +/** + * @brief Connection Event callback. + * @param hhcd: HCD handle + * @retval None + */ +__weak void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_HCD_Connect_Callback could be implemented in the user file + */ +} + +__weak void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd) +{ + +} + +/** + * @brief Disconnection Event callback. + * @param hhcd: HCD handle + * @retval None + */ +__weak HAL_StatusTypeDef HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_HCD_Disconnect_Callback could be implemented in the user file + */ +} + +/** + * @brief Notify URB state change callback. + * @param hhcd: HCD handle + * @param chnum: Channel number. + * This parameter can be a value from 1 to 15 + * @param urb_state: + * This parameter can be one of these values: + * URB_IDLE/ + * URB_DONE/ + * URB_NOTREADY/ + * URB_NYET/ + * URB_ERROR/ + * URB_STALL/ + * @retval None + */ +__weak void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_HCD_HC_NotifyURBChange_Callback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup HCD_Exported_Functions_Group3 Peripheral Control functions + * @brief Management functions + * +@verbatim + =============================================================================== + ##### Host Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the HCD data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Start the host driver. + * @param hhcd: HCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd) +{ + __HAL_LOCK(hhcd); + __HAL_HCD_ENABLE(hhcd); + USB_DriveVbus(hhcd->Instance, 1); + __HAL_UNLOCK(hhcd); + return HAL_OK; +} + +/** + * @brief Stop the host driver. + * @param hhcd: HCD handle + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd) +{ + __HAL_LOCK(hhcd); + USB_StopHost(hhcd->Instance); + __HAL_UNLOCK(hhcd); + return HAL_OK; +} + +/** + * @brief Reset the host port. + * @param hhcd: HCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd) +{ + return (USB_ResetPort(hhcd->Instance)); +} + +/** + * @} + */ + +/** @defgroup HCD_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the HCD handle state. + * @param hhcd: HCD handle + * @retval HAL state + */ +HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef *hhcd) +{ + return hhcd->State; +} + +/** + * @brief Return URB state for a channel. + * @param hhcd: HCD handle + * @param chnum: Channel number. + * This parameter can be a value from 1 to 15 + * @retval URB state. + * This parameter can be one of these values: + * URB_IDLE/ + * URB_DONE/ + * URB_NOTREADY/ + * URB_NYET/ + * URB_ERROR/ + * URB_STALL + */ +HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef *hhcd, uint8_t chnum) +{ + return hhcd->hc[chnum].urb_state; +} + + +/** + * @brief Return the last host transfer size. + * @param hhcd: HCD handle + * @param chnum: Channel number. + * This parameter can be a value from 1 to 15 + * @retval last transfer size in byte + */ +uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef *hhcd, uint8_t chnum) +{ + return hhcd->hc[chnum].xfer_count; +} + +/** + * @brief Return the Host Channel state. + * @param hhcd: HCD handle + * @param chnum: Channel number. + * This parameter can be a value from 1 to 15 + * @retval Host channel state + * This parameter can be one of these values: + * HC_IDLE/ + * HC_XFRC/ + * HC_HALTED/ + * HC_NYET/ + * HC_NAK/ + * HC_STALL/ + * HC_XACTERR/ + * HC_BBLERR/ + * HC_DATATGLERR + */ +HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef *hhcd, uint8_t chnum) +{ + return hhcd->hc[chnum].state; +} + +/** + * @brief Return the current Host frame number. + * @param hhcd: HCD handle + * @retval Current Host frame number + */ +uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd) +{ + return (USB_GetCurrentFrame(hhcd->Instance)); +} + +/** + * @brief Return the Host enumeration speed. + * @param hhcd: HCD handle + * @retval Enumeration speed + */ +uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd) +{ + return (USB_GetHostSpeed(hhcd->Instance)); +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup HCD_Private_Functions + * @{ + */ +/** + * @brief Handle Host Channel IN interrupt requests. + * @param hhcd: HCD handle + * @param chnum: Channel number. + * This parameter can be a value from 1 to 15 + * @retval None + */ +static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum) +{ + USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; + uint32_t tmpreg = 0; + + if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR) + { + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR); + __HAL_HCD_UNMASK_HALT_HC_INT(chnum); + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK) + { + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK); + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL) + { + __HAL_HCD_UNMASK_HALT_HC_INT(chnum); + hhcd->hc[chnum].state = HC_STALL; + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL); + USB_HC_Halt(hhcd->Instance, chnum); + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR) + { + __HAL_HCD_UNMASK_HALT_HC_INT(chnum); + USB_HC_Halt(hhcd->Instance, chnum); + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); + hhcd->hc[chnum].state = HC_DATATGLERR; + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR); + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR) + { + __HAL_HCD_UNMASK_HALT_HC_INT(chnum); + USB_HC_Halt(hhcd->Instance, chnum); + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR); + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC) + { + if (hhcd->Init.dma_enable) + { + hhcd->hc[chnum].xfer_count = hhcd->hc[chnum].xfer_len - \ + (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ); + } + + hhcd->hc[chnum].state = HC_XFRC; + hhcd->hc[chnum].ErrCnt = 0; + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC); + + + if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)|| + (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)) + { + __HAL_HCD_UNMASK_HALT_HC_INT(chnum); + USB_HC_Halt(hhcd->Instance, chnum); + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); + + } + else if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR) + { + USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM; + hhcd->hc[chnum].urb_state = URB_DONE; + HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); + } +// hhcd->hc[chnum].toggle_in ^= 1; + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH) + { + __HAL_HCD_MASK_HALT_HC_INT(chnum); + + if(hhcd->hc[chnum].state == HC_XFRC) + { + hhcd->hc[chnum].urb_state = URB_DONE; + } + + else if (hhcd->hc[chnum].state == HC_STALL) + { + hhcd->hc[chnum].urb_state = URB_STALL; + } + + else if((hhcd->hc[chnum].state == HC_XACTERR) || + (hhcd->hc[chnum].state == HC_DATATGLERR) || + (hhcd->hc[chnum].state == HC_NAK)) + { + if(hhcd->hc[chnum].ErrCnt++ > 3) + { + hhcd->hc[chnum].ErrCnt = 0; + hhcd->hc[chnum].urb_state = URB_ERROR; + } + else + { + hhcd->hc[chnum].urb_state = URB_NOTREADY; + } + + if (hhcd->hc[chnum].ep_type != EP_TYPE_INTR) //DON'T re-enable an interrupt-in transaction + { + /* re-activate the channel */ + tmpreg = USBx_HC(chnum)->HCCHAR; + tmpreg &= ~USB_OTG_HCCHAR_CHDIS; + tmpreg |= USB_OTG_HCCHAR_CHENA; + USBx_HC(chnum)->HCCHAR = tmpreg; + } + } + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH); + HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR) + { + __HAL_HCD_UNMASK_HALT_HC_INT(chnum); + hhcd->hc[chnum].ErrCnt++; + hhcd->hc[chnum].state = HC_XACTERR; + USB_HC_Halt(hhcd->Instance, chnum); + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR); + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK) + { + hhcd->hc[chnum].ErrCnt = 0; +// if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR) +// { + __HAL_HCD_UNMASK_HALT_HC_INT(chnum); + USB_HC_Halt(hhcd->Instance, chnum); +// } +// else if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)|| +// (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)) +// { +// /* re-activate the channel */ +// tmpreg = USBx_HC(chnum)->HCCHAR; +// tmpreg &= ~USB_OTG_HCCHAR_CHDIS; +// tmpreg |= USB_OTG_HCCHAR_CHENA; +// USBx_HC(chnum)->HCCHAR = tmpreg; +// } + hhcd->hc[chnum].state = HC_NAK; + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); + } +} + +/** + * @brief Handle Host Channel OUT interrupt requests. + * @param hhcd: HCD handle + * @param chnum: Channel number. + * This parameter can be a value from 1 to 15 + * @retval None + */ +static void HCD_HC_OUT_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum) +{ + USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; + uint32_t tmpreg = 0; + + if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR) + { + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR); + __HAL_HCD_UNMASK_HALT_HC_INT(chnum); + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK) + { + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK); + + if( hhcd->hc[chnum].do_ping == 1) + { + hhcd->hc[chnum].state = HC_NYET; + __HAL_HCD_UNMASK_HALT_HC_INT(chnum); + USB_HC_Halt(hhcd->Instance, chnum); + hhcd->hc[chnum].urb_state = URB_NOTREADY; + } + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NYET) + { + HAL_HCD_OUT_RewindUnsentPackets(hhcd, chnum); + hhcd->hc[chnum].state = HC_NYET; + hhcd->hc[chnum].ErrCnt= 0; + __HAL_HCD_UNMASK_HALT_HC_INT(chnum); + USB_HC_Halt(hhcd->Instance, chnum); + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET); + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR) + { + __HAL_HCD_UNMASK_HALT_HC_INT(chnum); + USB_HC_Halt(hhcd->Instance, chnum); + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR); + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC) + { + hhcd->hc[chnum].ErrCnt = 0; + __HAL_HCD_UNMASK_HALT_HC_INT(chnum); + USB_HC_Halt(hhcd->Instance, chnum); + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC); + hhcd->hc[chnum].state = HC_XFRC; + + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL) + { + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL); + __HAL_HCD_UNMASK_HALT_HC_INT(chnum); + USB_HC_Halt(hhcd->Instance, chnum); + hhcd->hc[chnum].state = HC_STALL; + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK) + { + HAL_HCD_OUT_RewindUnsentPackets(hhcd, chnum); + hhcd->hc[chnum].ErrCnt = 0; + __HAL_HCD_UNMASK_HALT_HC_INT(chnum); + USB_HC_Halt(hhcd->Instance, chnum); + hhcd->hc[chnum].state = HC_NAK; + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR) + { + HAL_HCD_OUT_RewindUnsentPackets(hhcd, chnum); + __HAL_HCD_UNMASK_HALT_HC_INT(chnum); + USB_HC_Halt(hhcd->Instance, chnum); + hhcd->hc[chnum].state = HC_XACTERR; + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR); + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR) + { + HAL_HCD_OUT_RewindUnsentPackets(hhcd, chnum); + __HAL_HCD_UNMASK_HALT_HC_INT(chnum); + USB_HC_Halt(hhcd->Instance, chnum); + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK); + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR); + hhcd->hc[chnum].state = HC_DATATGLERR; + } + + else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH) + { + __HAL_HCD_MASK_HALT_HC_INT(chnum); + + if(hhcd->hc[chnum].state == HC_XFRC) + { + hhcd->hc[chnum].urb_state = URB_DONE; + if (hhcd->hc[chnum].ep_type == EP_TYPE_BULK) + { + if (hhcd->hc[chnum].packet_count & 1) + { + hhcd->hc[chnum].toggle_out ^= 1; + } + } + } + else if (hhcd->hc[chnum].state == HC_NAK) + { + hhcd->hc[chnum].urb_state = URB_NOTREADY; + } + + else if (hhcd->hc[chnum].state == HC_NYET) + { + hhcd->hc[chnum].urb_state = URB_NOTREADY; + hhcd->hc[chnum].do_ping = 0; + } + + else if (hhcd->hc[chnum].state == HC_STALL) + { + hhcd->hc[chnum].urb_state = URB_STALL; + } + + else if((hhcd->hc[chnum].state == HC_XACTERR) || + (hhcd->hc[chnum].state == HC_DATATGLERR)) + { + if(hhcd->hc[chnum].ErrCnt++ > 3) + { + hhcd->hc[chnum].ErrCnt = 0; + hhcd->hc[chnum].urb_state = URB_ERROR; + } + else + { + hhcd->hc[chnum].urb_state = URB_NOTREADY; + } + +// /* re-activate the channel */ +// tmpreg = USBx_HC(chnum)->HCCHAR; +// tmpreg &= ~USB_OTG_HCCHAR_CHDIS; +// tmpreg |= USB_OTG_HCCHAR_CHENA; +// USBx_HC(chnum)->HCCHAR = tmpreg; + } + + __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH); + HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); + } +} + + +static void HAL_HCD_OUT_RewindUnsentPackets(HCD_HandleTypeDef *hhcd, uint8_t chnum) +{ + USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; + uint32_t unsentByteCount; + + if (hhcd->hc[chnum].xfer_len == 0) + { + return; + } + + //Calculate bytes actually transferred by URB from channel's remaining packet count. + //Most flash drives do not need this! + //Sent packet count must be rounded DOWN to the nearest 2 packets. Wanna know why? Ask Transcend!!! + unsentByteCount = ((((USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19) + 1) & ~1) * hhcd->hc[chnum].max_packet; + if (unsentByteCount > hhcd->hc[chnum].xfer_len) + { + unsentByteCount = hhcd->hc[chnum].xfer_len; + } + hhcd->hc[chnum].xfer_count = hhcd->hc[chnum].xfer_len - unsentByteCount; +} + + + + +/** + * @brief Handle Rx Queue Level interrupt requests. + * @param hhcd: HCD handle + * @retval None + */ +static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd) +{ + USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; + uint8_t channelnum = 0; + uint32_t pktsts; + uint32_t pktcnt; + uint32_t temp = 0; + uint32_t tmpreg = 0; + + temp = hhcd->Instance->GRXSTSP; + channelnum = temp & USB_OTG_GRXSTSP_EPNUM; + pktsts = (temp & USB_OTG_GRXSTSP_PKTSTS) >> 17; + pktcnt = (temp & USB_OTG_GRXSTSP_BCNT) >> 4; + + switch (pktsts) + { + case GRXSTS_PKTSTS_IN: + if((USBx_HC(channelnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) > 0) + { + /* re-activate the channel when more packets are expected */ + tmpreg = USBx_HC(channelnum)->HCCHAR; + tmpreg &= ~USB_OTG_HCCHAR_CHDIS; + tmpreg |= USB_OTG_HCCHAR_CHENA; + USBx_HC(channelnum)->HCCHAR = tmpreg; + } + + /* Read the data into the host buffer. */ + if ((pktcnt > 0) && (hhcd->hc[channelnum].xfer_buff != (void *)0)) + { + USB_ReadPacket(hhcd->Instance, hhcd->hc[channelnum].xfer_buff, pktcnt); //Todo: buffer overflow here! + hhcd->hc[channelnum].toggle_in ^= 1; + + /*manage multiple Xfer */ + hhcd->hc[channelnum].xfer_buff += pktcnt; + hhcd->hc[channelnum].xfer_count += pktcnt; + } + break; + + case GRXSTS_PKTSTS_DATA_TOGGLE_ERR: + break; + case GRXSTS_PKTSTS_IN_XFER_COMP: + case GRXSTS_PKTSTS_CH_HALTED: + default: + break; + } +} + +/** + * @brief Handle Host Port interrupt requests. + * @param hhcd: HCD handle + * @retval None + */ +static void HCD_Port_IRQHandler (HCD_HandleTypeDef *hhcd) +{ + USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; + __IO uint32_t hprt0, hprt0_dup; + + /* Handle Host Port Interrupts */ + hprt0 = USBx_HPRT0; + hprt0_dup = USBx_HPRT0; + + hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ + USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); + + /* Check whether Port Connect Detected */ + if((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET) + { + if((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS) + { + USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT); + HAL_HCD_Connect_Callback(hhcd); + } + hprt0_dup |= USB_OTG_HPRT_PCDET; + + } + + /* Check whether Port Enable Changed */ + if((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG) + { + hprt0_dup |= USB_OTG_HPRT_PENCHNG; + + if((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA) + { + if(hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY) + { + if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17)) + { + USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_6_MHZ ); + } + else + { + USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ ); + } + } + else + { + if(hhcd->Init.speed == HCD_SPEED_FULL) + { + USBx_HOST->HFIR = (uint32_t)60000; + } + } + HAL_HCD_PortEnabled_Callback(hhcd); + + if(hhcd->Init.speed == HCD_SPEED_HIGH) + { + USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT); + } + } + else + { + /* Cleanup HPRT */ + USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ + USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); + + USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT); + } + } + + /* Check for an overcurrent */ + if((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG) + { + hprt0_dup |= USB_OTG_HPRT_POCCHNG; + } + + /* Clear Port Interrupts */ + USBx_HPRT0 = hprt0_dup; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_HCD_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c new file mode 100644 index 0000000..179b608 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c @@ -0,0 +1,3649 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2c.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief I2C HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Inter Integrated Circuit (I2C) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The I2C HAL driver can be used as follows: + + (#) Declare a I2C_HandleTypeDef handle structure, for example: + I2C_HandleTypeDef hi2c; + + (#)Initialize the I2C low level resources by implement the HAL_I2C_MspInit() API: + (##) Enable the I2Cx interface clock + (##) I2C pins configuration + (+++) Enable the clock for the I2C GPIOs + (+++) Configure I2C pins as alternate function open-drain + (##) NVIC configuration if you need to use interrupt process + (+++) Configure the I2Cx interrupt priority + (+++) Enable the NVIC I2C IRQ Channel + (##) DMA Configuration if you need to use DMA process + (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive stream + (+++) Enable the DMAx interface clock using + (+++) Configure the DMA handle parameters + (+++) Configure the DMA Tx or Rx Stream + (+++) Associate the initialized DMA handle to the hi2c DMA Tx or Rx handle + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on + the DMA Tx or Rx Stream + + (#) Configure the Communication Speed, Duty cycle, Addressing mode, Own Address1, + Dual Addressing mode, Own Address2, General call and Nostretch mode in the hi2c Init structure. + + (#) Initialize the I2C registers by calling the HAL_I2C_Init(), configures also the low level Hardware + (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_I2C_MspInit(&hi2c) API. + + (#) To check if target device is ready for communication, use the function HAL_I2C_IsDeviceReady() + + (#) For I2C IO and IO MEM operations, three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Transmit in master mode an amount of data in blocking mode using HAL_I2C_Master_Transmit() + (+) Receive in master mode an amount of data in blocking mode using HAL_I2C_Master_Receive() + (+) Transmit in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Transmit() + (+) Receive in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Receive() + + *** Polling mode IO MEM operation *** + ===================================== + [..] + (+) Write an amount of data in blocking mode to a specific memory address using HAL_I2C_Mem_Write() + (+) Read an amount of data in blocking mode from a specific memory address using HAL_I2C_Mem_Read() + + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Transmit in master mode an amount of data in non blocking mode using HAL_I2C_Master_Transmit_IT() + (+) At transmission end of transfer HAL_I2C_MasterTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback + (+) Receive in master mode an amount of data in non blocking mode using HAL_I2C_Master_Receive_IT() + (+) At reception end of transfer HAL_I2C_MasterRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback + (+) Transmit in slave mode an amount of data in non blocking mode using HAL_I2C_Slave_Transmit_IT() + (+) At transmission end of transfer HAL_I2C_SlaveTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback + (+) Receive in slave mode an amount of data in non blocking mode using HAL_I2C_Slave_Receive_IT() + (+) At reception end of transfer HAL_I2C_SlaveRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback + (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2C_ErrorCallback + + *** Interrupt mode IO MEM operation *** + ======================================= + [..] + (+) Write an amount of data in no-blocking mode with Interrupt to a specific memory address using + HAL_I2C_Mem_Write_IT() + (+) At MEM end of write transfer HAL_I2C_MemTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback + (+) Read an amount of data in no-blocking mode with Interrupt from a specific memory address using + HAL_I2C_Mem_Read_IT() + (+) At MEM end of read transfer HAL_I2C_MemRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback + (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2C_ErrorCallback + + *** DMA mode IO operation *** + ============================== + [..] + (+) Transmit in master mode an amount of data in non blocking mode (DMA) using + HAL_I2C_Master_Transmit_DMA() + (+) At transmission end of transfer HAL_I2C_MasterTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback + (+) Receive in master mode an amount of data in non blocking mode (DMA) using + HAL_I2C_Master_Receive_DMA() + (+) At reception end of transfer HAL_I2C_MasterRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback + (+) Transmit in slave mode an amount of data in non blocking mode (DMA) using + HAL_I2C_Slave_Transmit_DMA() + (+) At transmission end of transfer HAL_I2C_SlaveTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback + (+) Receive in slave mode an amount of data in non blocking mode (DMA) using + HAL_I2C_Slave_Receive_DMA() + (+) At reception end of transfer HAL_I2C_SlaveRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback + (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2C_ErrorCallback + + *** DMA mode IO MEM operation *** + ================================= + [..] + (+) Write an amount of data in no-blocking mode with DMA to a specific memory address using + HAL_I2C_Mem_Write_DMA() + (+) At MEM end of write transfer HAL_I2C_MemTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback + (+) Read an amount of data in no-blocking mode with DMA from a specific memory address using + HAL_I2C_Mem_Read_DMA() + (+) At MEM end of read transfer HAL_I2C_MemRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback + (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2C_ErrorCallback + + + *** I2C HAL driver macros list *** + ================================== + [..] + Below the list of most used macros in I2C HAL driver. + + (+) __HAL_I2C_ENABLE: Enable the I2C peripheral + (+) __HAL_I2C_DISABLE: Disable the I2C peripheral + (+) __HAL_I2C_GET_FLAG : Checks whether the specified I2C flag is set or not + (+) __HAL_I2C_CLEAR_FLAG : Clear the specified I2C pending flag + (+) __HAL_I2C_ENABLE_IT: Enable the specified I2C interrupt + (+) __HAL_I2C_DISABLE_IT: Disable the specified I2C interrupt + + [..] + (@) You can refer to the I2C HAL driver header file for more useful macros + + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 I2C I2C + * @brief I2C HAL module driver + * @{ + */ + +#ifdef HAL_I2C_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup I2C_Private_Constants + * @{ + */ +#define I2C_TIMEOUT_FLAG ((uint32_t)35) /* 35 ms */ +#define I2C_TIMEOUT_ADDR_SLAVE ((uint32_t)10000) /* 10 s */ +#define I2C_TIMEOUT_BUSY_FLAG ((uint32_t)10000) /* 10 s */ +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup I2C_Private_Functions + * @{ + */ +static void I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma); +static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma); +static void I2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma); +static void I2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma); +static void I2C_DMAMemTransmitCplt(DMA_HandleTypeDef *hdma); +static void I2C_DMAMemReceiveCplt(DMA_HandleTypeDef *hdma); +static void I2C_DMAError(DMA_HandleTypeDef *hdma); + +static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout); +static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout); +static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout); +static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout); +static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout); +static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout); + +static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c); + +static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Slave_AF(I2C_HandleTypeDef *hi2c); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup I2C_Exported_Functions I2C Exported Functions + * @{ + */ + +/** @defgroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the I2Cx peripheral: + + (+) User must Implement HAL_I2C_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC). + + (+) Call the function HAL_I2C_Init() to configure the selected device with + the selected configuration: + (++) Communication Speed + (++) Duty cycle + (++) Addressing mode + (++) Own Address 1 + (++) Dual Addressing mode + (++) Own Address 2 + (++) General call mode + (++) Nostretch mode + + (+) Call the function HAL_I2C_DeInit() to restore the default configuration + of the selected I2Cx peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the I2C according to the specified parameters + * in the I2C_InitTypeDef and create the associated handle. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) +{ + uint32_t freqrange = 0; + uint32_t pclk1 = 0; + + /* Check the I2C handle allocation */ + if(hi2c == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_I2C_CLOCK_SPEED(hi2c->Init.ClockSpeed)); + assert_param(IS_I2C_DUTY_CYCLE(hi2c->Init.DutyCycle)); + assert_param(IS_I2C_OWN_ADDRESS1(hi2c->Init.OwnAddress1)); + assert_param(IS_I2C_ADDRESSING_MODE(hi2c->Init.AddressingMode)); + assert_param(IS_I2C_DUAL_ADDRESS(hi2c->Init.DualAddressMode)); + assert_param(IS_I2C_OWN_ADDRESS2(hi2c->Init.OwnAddress2)); + assert_param(IS_I2C_GENERAL_CALL(hi2c->Init.GeneralCallMode)); + assert_param(IS_I2C_NO_STRETCH(hi2c->Init.NoStretchMode)); + + if(hi2c->State == HAL_I2C_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hi2c->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + HAL_I2C_MspInit(hi2c); + } + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Get PCLK1 frequency */ + pclk1 = HAL_RCC_GetPCLK1Freq(); + + /* Calculate frequency range */ + freqrange = I2C_FREQRANGE(pclk1); + + /*---------------------------- I2Cx CR2 Configuration ----------------------*/ + /* Configure I2Cx: Frequency range */ + hi2c->Instance->CR2 = freqrange; + + /*---------------------------- I2Cx TRISE Configuration --------------------*/ + /* Configure I2Cx: Rise Time */ + hi2c->Instance->TRISE = I2C_RISE_TIME(freqrange, hi2c->Init.ClockSpeed); + + /*---------------------------- I2Cx CCR Configuration ----------------------*/ + /* Configure I2Cx: Speed */ + hi2c->Instance->CCR = I2C_SPEED(pclk1, hi2c->Init.ClockSpeed, hi2c->Init.DutyCycle); + + /*---------------------------- I2Cx CR1 Configuration ----------------------*/ + /* Configure I2Cx: Generalcall and NoStretch mode */ + hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode); + + /*---------------------------- I2Cx OAR1 Configuration ---------------------*/ + /* Configure I2Cx: Own Address1 and addressing mode */ + hi2c->Instance->OAR1 = (hi2c->Init.AddressingMode | hi2c->Init.OwnAddress1); + + /*---------------------------- I2Cx OAR2 Configuration ---------------------*/ + /* Configure I2Cx: Dual mode and Own Address2 */ + hi2c->Instance->OAR2 = (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2); + + /* Enable the selected I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + hi2c->State = HAL_I2C_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the I2C peripheral. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c) +{ + /* Check the I2C handle allocation */ + if(hi2c == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the I2C Peripheral Clock */ + __HAL_I2C_DISABLE(hi2c); + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_I2C_MspDeInit(hi2c); + + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + hi2c->State = HAL_I2C_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; +} + +/** + * @brief I2C MSP Init. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval None + */ + __weak void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2C_MspInit could be implemented in the user file + */ +} + +/** + * @brief I2C MSP DeInit + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval None + */ + __weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2C_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup I2C_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the I2C data + transfers. + + (#) There are two modes of transfer: + (++) Blocking mode : The communication is performed in the polling mode. + The status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode : The communication is performed using Interrupts + or DMA. These functions return the status of the transfer startup. + The end of the data processing will be indicated through the + dedicated I2C IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + + (#) Blocking mode functions are : + (++) HAL_I2C_Master_Transmit() + (++) HAL_I2C_Master_Receive() + (++) HAL_I2C_Slave_Transmit() + (++) HAL_I2C_Slave_Receive() + (++) HAL_I2C_Mem_Write() + (++) HAL_I2C_Mem_Read() + (++) HAL_I2C_IsDeviceReady() + + (#) No-Blocking mode functions with Interrupt are : + (++) HAL_I2C_Master_Transmit_IT() + (++) HAL_I2C_Master_Receive_IT() + (++) HAL_I2C_Slave_Transmit_IT() + (++) HAL_I2C_Slave_Receive_IT() + (++) HAL_I2C_Mem_Write_IT() + (++) HAL_I2C_Mem_Read_IT() + + (#) No-Blocking mode functions with DMA are : + (++) HAL_I2C_Master_Transmit_DMA() + (++) HAL_I2C_Master_Receive_DMA() + (++) HAL_I2C_Slave_Transmit_DMA() + (++) HAL_I2C_Slave_Receive_DMA() + (++) HAL_I2C_Mem_Write_DMA() + (++) HAL_I2C_Mem_Read_DMA() + + (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) HAL_I2C_MemTxCpltCallback() + (++) HAL_I2C_MemRxCpltCallback() + (++) HAL_I2C_MasterTxCpltCallback() + (++) HAL_I2C_MasterRxCpltCallback() + (++) HAL_I2C_SlaveTxCpltCallback() + (++) HAL_I2C_SlaveRxCpltCallback() + (++) HAL_I2C_ErrorCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Transmits in master mode an amount of data in blocking mode. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Send Slave Address */ + if(I2C_MasterRequestWrite(hi2c, DevAddress, Timeout) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + while(Size > 0) + { + /* Wait until TXE flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Write data to DR */ + hi2c->Instance->DR = (*pData++); + Size--; + + if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (Size != 0)) + { + /* Write data to DR */ + hi2c->Instance->DR = (*pData++); + Size--; + } + } + + /* Wait until TXE flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receives in master mode an amount of data in blocking mode. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Send Slave Address */ + if(I2C_MasterRequestRead(hi2c, DevAddress, Timeout) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + if(Size == 1) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(Size == 2) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Enable Pos */ + hi2c->Instance->CR1 |= I2C_CR1_POS; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + while(Size > 0) + { + if(Size <= 3) + { + /* One byte */ + if(Size == 1) + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + } + /* Two bytes */ + else if(Size == 2) + { + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + } + /* 3 Last bytes */ + else + { + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + } + } + else + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) + { + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + } + } + } + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmits in slave mode an amount of data in blocking mode. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* If 10bit addressing mode is selected */ + if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) + { + /* Wait until ADDR flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + while(Size > 0) + { + /* Wait until TXE flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Write data to DR */ + hi2c->Instance->DR = (*pData++); + Size--; + + if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (Size != 0)) + { + /* Write data to DR */ + hi2c->Instance->DR = (*pData++); + Size--; + } + } + + /* Wait until AF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_AF, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear AF flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in blocking mode + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + while(Size > 0) + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + + if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (Size != 0)) + { + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + } + } + + /* Wait until STOP flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear STOP flag */ + __HAL_I2C_CLEAR_STOPFLAG(hi2c); + + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in master mode an amount of data in no-blocking mode with Interrupt + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + + /* Send Slave Address */ + if(I2C_MasterRequestWrite(hi2c, DevAddress, I2C_TIMEOUT_FLAG) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in master mode an amount of data in no-blocking mode with Interrupt + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + + /* Send Slave Address */ + if(I2C_MasterRequestRead(hi2c, DevAddress, I2C_TIMEOUT_FLAG) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + if(hi2c->XferCount == 1) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferCount == 2) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Enable Pos */ + hi2c->Instance->CR1 |= I2C_CR1_POS; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in slave mode an amount of data in no-blocking mode with Interrupt + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in no-blocking mode with Interrupt + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in master mode an amount of data in no-blocking mode with DMA + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMAMasterTransmitCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->DR, Size); + + /* Send Slave Address */ + if(I2C_MasterRequestWrite(hi2c, DevAddress, I2C_TIMEOUT_FLAG) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in master mode an amount of data in no-blocking mode with DMA + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMAMasterReceiveCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)pData, Size); + + /* Send Slave Address */ + if(I2C_MasterRequestRead(hi2c, DevAddress, I2C_TIMEOUT_FLAG) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + if(Size == 1) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + } + else + { + /* Enable Last DMA bit */ + hi2c->Instance->CR2 |= I2C_CR2_LAST; + } + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in slave mode an amount of data in no-blocking mode with DMA + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMASlaveTransmitCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->DR, Size); + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, I2C_TIMEOUT_ADDR_SLAVE) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* If 7bit addressing mode is selected */ + if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, I2C_TIMEOUT_ADDR_SLAVE) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in no-blocking mode with DMA + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMASlaveReceiveCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)pData, Size); + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, I2C_TIMEOUT_ADDR_SLAVE) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +/** + * @brief Write an amount of data in blocking mode to a specific memory address + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param MemAddress: Internal memory address + * @param MemAddSize: Size of internal memory address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_MEM_BUSY_TX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + while(Size > 0) + { + /* Wait until TXE flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Write data to DR */ + hi2c->Instance->DR = (*pData++); + Size--; + + if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (Size != 0)) + { + /* Write data to DR */ + hi2c->Instance->DR = (*pData++); + Size--; + } + } + + /* Wait until TXE flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Read an amount of data in blocking mode from a specific memory address + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param MemAddress: Internal memory address + * @param MemAddSize: Size of internal memory address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_MEM_BUSY_RX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + if(Size == 1) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(Size == 2) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Enable Pos */ + hi2c->Instance->CR1 |= I2C_CR1_POS; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + while(Size > 0) + { + if(Size <= 3) + { + /* One byte */ + if(Size== 1) + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + } + /* Two bytes */ + else if(Size == 2) + { + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + } + /* 3 Last bytes */ + else + { + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + } + } + else + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) + { + /* Read data from DR */ + (*pData++) = hi2c->Instance->DR; + Size--; + } + } + } + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +/** + * @brief Write an amount of data in no-blocking mode with Interrupt to a specific memory address + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param MemAddress: Internal memory address + * @param MemAddSize: Size of internal memory address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_MEM_BUSY_TX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Read an amount of data in no-blocking mode with Interrupt from a specific memory address + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param MemAddress: Internal memory address + * @param MemAddSize: Size of internal memory address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_MEM_BUSY_RX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + if(hi2c->XferCount == 1) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferCount == 2) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Enable Pos */ + hi2c->Instance->CR1 |= I2C_CR1_POS; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +/** + * @brief Write an amount of data in no-blocking mode with DMA to a specific memory address + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param MemAddress: Internal memory address + * @param MemAddSize: Size of internal memory address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_MEM_BUSY_TX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMAMemTransmitCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)pData, (uint32_t)&hi2c->Instance->DR, Size); + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Reads an amount of data in no-blocking mode with DMA from a specific memory address. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param MemAddress: Internal memory address + * @param MemAddSize: Size of internal memory address + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be read + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_MEM_BUSY_RX; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMAMemReceiveCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)pData, Size); + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + if(Size == 1) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + } + else + { + /* Enable Last DMA bit */ + hi2c->Instance->CR2 |= I2C_CR2_LAST; + } + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Checks if target device is ready for communication. + * @note This function is used with Memory devices + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param Trials: Number of trials + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout) +{ + uint32_t tickstart = 0, tmp1 = 0, tmp2 = 0, tmp3 = 0, I2C_Trials = 1; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + do + { + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); + + /* Wait until ADDR or AF flag are set */ + /* Get tick */ + tickstart = HAL_GetTick(); + + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); + tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); + tmp3 = hi2c->State; + while((tmp1 == RESET) && (tmp2 == RESET) && (tmp3 != HAL_I2C_STATE_TIMEOUT)) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hi2c->State = HAL_I2C_STATE_TIMEOUT; + } + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); + tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); + tmp3 = hi2c->State; + } + + hi2c->State = HAL_I2C_STATE_READY; + + /* Check if the ADDR flag has been set */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == SET) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Clear ADDR Flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_TIMEOUT; + } + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Clear AF Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) + { + return HAL_TIMEOUT; + } + + } + }while(I2C_Trials++ < Trials); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief This function handles I2C event interrupt request. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c) +{ + uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0; + /* Master mode selected */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_MSL) == SET) + { + /* I2C in mode Transmitter -----------------------------------------------*/ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TRA) == SET) + { + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE); + tmp2 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_BUF); + tmp3 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF); + tmp4 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_EVT); + /* TXE set and BTF reset -----------------------------------------------*/ + if((tmp1 == SET) && (tmp2 == SET) && (tmp3 == RESET)) + { + I2C_MasterTransmit_TXE(hi2c); + } + /* BTF set -------------------------------------------------------------*/ + else if((tmp3 == SET) && (tmp4 == SET)) + { + I2C_MasterTransmit_BTF(hi2c); + } + } + /* I2C in mode Receiver --------------------------------------------------*/ + else + { + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE); + tmp2 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_BUF); + tmp3 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF); + tmp4 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_EVT); + /* RXNE set and BTF reset -----------------------------------------------*/ + if((tmp1 == SET) && (tmp2 == SET) && (tmp3 == RESET)) + { + I2C_MasterReceive_RXNE(hi2c); + } + /* BTF set -------------------------------------------------------------*/ + else if((tmp3 == SET) && (tmp4 == SET)) + { + I2C_MasterReceive_BTF(hi2c); + } + } + } + /* Slave mode selected */ + else + { + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); + tmp2 = __HAL_I2C_GET_IT_SOURCE(hi2c, (I2C_IT_EVT)); + tmp3 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF); + tmp4 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TRA); + /* ADDR set --------------------------------------------------------------*/ + if((tmp1 == SET) && (tmp2 == SET)) + { + I2C_Slave_ADDR(hi2c); + } + /* STOPF set --------------------------------------------------------------*/ + else if((tmp3 == SET) && (tmp2 == SET)) + { + I2C_Slave_STOPF(hi2c); + } + /* I2C in mode Transmitter -----------------------------------------------*/ + else if(tmp4 == SET) + { + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE); + tmp2 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_BUF); + tmp3 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF); + tmp4 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_EVT); + /* TXE set and BTF reset -----------------------------------------------*/ + if((tmp1 == SET) && (tmp2 == SET) && (tmp3 == RESET)) + { + I2C_SlaveTransmit_TXE(hi2c); + } + /* BTF set -------------------------------------------------------------*/ + else if((tmp3 == SET) && (tmp4 == SET)) + { + I2C_SlaveTransmit_BTF(hi2c); + } + } + /* I2C in mode Receiver --------------------------------------------------*/ + else + { + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE); + tmp2 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_BUF); + tmp3 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF); + tmp4 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_EVT); + /* RXNE set and BTF reset ----------------------------------------------*/ + if((tmp1 == SET) && (tmp2 == SET) && (tmp3 == RESET)) + { + I2C_SlaveReceive_RXNE(hi2c); + } + /* BTF set -------------------------------------------------------------*/ + else if((tmp3 == SET) && (tmp4 == SET)) + { + I2C_SlaveReceive_BTF(hi2c); + } + } + } +} + +/** + * @brief This function handles I2C error interrupt request. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c) +{ + uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0; + + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BERR); + tmp2 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_ERR); + /* I2C Bus error interrupt occurred ----------------------------------------*/ + if((tmp1 == SET) && (tmp2 == SET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_BERR; + + /* Clear BERR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR); + } + + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ARLO); + tmp2 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_ERR); + /* I2C Arbitration Loss error interrupt occurred ---------------------------*/ + if((tmp1 == SET) && (tmp2 == SET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_ARLO; + + /* Clear ARLO flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO); + } + + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); + tmp2 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_ERR); + /* I2C Acknowledge failure error interrupt occurred ------------------------*/ + if((tmp1 == SET) && (tmp2 == SET)) + { + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_MSL); + tmp2 = hi2c->XferCount; + tmp3 = hi2c->State; + if((tmp1 == RESET) && (tmp2 == 0) && (tmp3 == HAL_I2C_STATE_BUSY_TX)) + { + I2C_Slave_AF(hi2c); + } + else + { + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + /* Clear AF flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + } + } + + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_OVR); + tmp2 = __HAL_I2C_GET_IT_SOURCE(hi2c, I2C_IT_ERR); + /* I2C Over-Run/Under-Run interrupt occurred -------------------------------*/ + if((tmp1 == SET) && (tmp2 == SET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_OVR; + /* Clear OVR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR); + } + + if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + hi2c->State = HAL_I2C_STATE_READY; + + /* Disable Pos bit in I2C CR1 when error occurred in Master/Mem Receive IT Process */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + HAL_I2C_ErrorCallback(hi2c); + } +} + +/** + * @brief Master Tx Transfer completed callbacks. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval None + */ + __weak void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2C_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Master Rx Transfer completed callbacks. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval None + */ +__weak void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2C_TxCpltCallback could be implemented in the user file + */ +} + +/** @brief Slave Tx Transfer completed callbacks. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval None + */ + __weak void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2C_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Slave Rx Transfer completed callbacks. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval None + */ +__weak void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2C_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Memory Tx Transfer completed callbacks. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval None + */ + __weak void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2C_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Memory Rx Transfer completed callbacks. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval None + */ +__weak void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2C_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief I2C error callbacks. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval None + */ + __weak void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2C_ErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup I2C_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief Peripheral State and Errors functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the I2C state. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL state + */ +HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c) +{ + return hi2c->State; +} + +/** + * @brief Return the I2C error code + * @param hi2c : pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. +* @retval I2C Error Code +*/ +uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c) +{ + return hi2c->ErrorCode; +} + +/** + * @} + */ + +/** + * @brief Handle TXE flag for Master + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c) +{ + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + + if(hi2c->XferCount == 0) + { + /* Disable BUF interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); + } + + return HAL_OK; +} + +/** + * @brief Handle BTF flag for Master transmitter + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->XferCount != 0) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + } + else + { + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + if(hi2c->State == HAL_I2C_STATE_MEM_BUSY_TX) + { + hi2c->State = HAL_I2C_STATE_READY; + + HAL_I2C_MemTxCpltCallback(hi2c); + } + else + { + hi2c->State = HAL_I2C_STATE_READY; + + HAL_I2C_MasterTxCpltCallback(hi2c); + } + } + return HAL_OK; +} + +/** + * @brief Handle RXNE flag for Master + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c) +{ + uint32_t tmp = 0; + + tmp = hi2c->XferCount; + if(tmp > 3) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + else if((tmp == 2) || (tmp == 3)) + { + /* Disable BUF interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); + } + else + { + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + + if(hi2c->State == HAL_I2C_STATE_MEM_BUSY_RX) + { + hi2c->State = HAL_I2C_STATE_READY; + + HAL_I2C_MemRxCpltCallback(hi2c); + } + else + { + hi2c->State = HAL_I2C_STATE_READY; + + HAL_I2C_MasterRxCpltCallback(hi2c); + } + } + return HAL_OK; +} + +/** + * @brief Handle BTF flag for Master receiver + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->XferCount == 3) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + else if(hi2c->XferCount == 2) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + + /* Disable EVT and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + + if(hi2c->State == HAL_I2C_STATE_MEM_BUSY_RX) + { + hi2c->State = HAL_I2C_STATE_READY; + + HAL_I2C_MemRxCpltCallback(hi2c); + } + else + { + hi2c->State = HAL_I2C_STATE_READY; + + HAL_I2C_MasterRxCpltCallback(hi2c); + } + } + else + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + return HAL_OK; +} + +/** + * @brief Handle TXE flag for Slave + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->XferCount != 0) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + } + return HAL_OK; +} + +/** + * @brief Handle BTF flag for Slave transmitter + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->XferCount != 0) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + } + return HAL_OK; +} + +/** + * @brief Handle RXNE flag for Slave + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->XferCount != 0) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + return HAL_OK; +} + +/** + * @brief Handle BTF flag for Slave receiver + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->XferCount != 0) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + return HAL_OK; +} + +/** + * @brief Handle ADD flag for Slave + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c) +{ + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + return HAL_OK; +} + +/** + * @brief Handle STOPF flag for Slave + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c) +{ + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Clear STOPF flag */ + __HAL_I2C_CLEAR_STOPFLAG(hi2c); + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + hi2c->State = HAL_I2C_STATE_READY; + + HAL_I2C_SlaveRxCpltCallback(hi2c); + + return HAL_OK; +} + +/** + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Slave_AF(I2C_HandleTypeDef *hi2c) +{ + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Clear AF flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + hi2c->State = HAL_I2C_STATE_READY; + + HAL_I2C_SlaveTxCpltCallback(hi2c); + + return HAL_OK; +} + +/** + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout) +{ + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) + { + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); + } + else + { + /* Send header of slave address */ + hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress); + + /* Wait until ADD10 flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress); + } + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +/** + * @brief Master sends target device address for read request. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout) +{ + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) + { + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress); + } + else + { + /* Send header of slave address */ + hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress); + + /* Wait until ADD10 flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress); + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Restart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send header of slave address */ + hi2c->Instance->DR = I2C_10BIT_HEADER_READ(DevAddress); + } + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +/** + * @brief Master sends target device address followed by internal memory address for write request. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param MemAddress: Internal memory address + * @param MemAddSize: Size of internal memory address + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout) +{ + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Wait until TXE flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* If Memory address size is 8Bit */ + if(MemAddSize == I2C_MEMADD_SIZE_8BIT) + { + /* Send Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); + } + /* If Memory address size is 16Bit */ + else + { + /* Send MSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress); + + /* Wait until TXE flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send LSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); + } + + return HAL_OK; +} + +/** + * @brief Master sends target device address followed by internal memory address for read request. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress: Target device address + * @param MemAddress: Internal memory address + * @param MemAddSize: Size of internal memory address + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout) +{ + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Wait until TXE flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* If Memory address size is 8Bit */ + if(MemAddSize == I2C_MEMADD_SIZE_8BIT) + { + /* Send Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); + } + /* If Memory address size is 16Bit */ + else + { + /* Send MSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress); + + /* Wait until TXE flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send LSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); + } + + /* Wait until TXE flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Restart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress); + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +/** + * @brief DMA I2C master transmit process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void I2C_DMAMasterTransmitCplt(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Wait until BTF flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, I2C_TIMEOUT_FLAG) != HAL_OK) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Disable DMA Request */ + hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; + + hi2c->XferCount = 0; + + hi2c->State = HAL_I2C_STATE_READY; + + /* Check if Errors has been detected during transfer */ + if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + HAL_I2C_ErrorCallback(hi2c); + } + else + { + HAL_I2C_MasterTxCpltCallback(hi2c); + } +} + +/** + * @brief DMA I2C slave transmit process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void I2C_DMASlaveTransmitCplt(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Wait until AF flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_AF, RESET, I2C_TIMEOUT_FLAG) != HAL_OK) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + } + + /* Clear AF flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Disable DMA Request */ + hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; + + hi2c->XferCount = 0; + + hi2c->State = HAL_I2C_STATE_READY; + + /* Check if Errors has been detected during transfer */ + if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + HAL_I2C_ErrorCallback(hi2c); + } + else + { + HAL_I2C_SlaveTxCpltCallback(hi2c); + } +} + +/** + * @brief DMA I2C master receive process complete callback + * @param hdma: DMA handle + * @retval None + */ +static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Disable Last DMA */ + hi2c->Instance->CR2 &= ~I2C_CR2_LAST; + + /* Disable DMA Request */ + hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; + + hi2c->XferCount = 0; + + hi2c->State = HAL_I2C_STATE_READY; + + /* Check if Errors has been detected during transfer */ + if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + HAL_I2C_ErrorCallback(hi2c); + } + else + { + HAL_I2C_MasterRxCpltCallback(hi2c); + } +} + +/** + * @brief DMA I2C slave receive process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void I2C_DMASlaveReceiveCplt(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Wait until STOPF flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_STOPF, RESET, I2C_TIMEOUT_FLAG) != HAL_OK) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + } + + /* Clear STOPF flag */ + __HAL_I2C_CLEAR_STOPFLAG(hi2c); + + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Disable DMA Request */ + hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; + + hi2c->XferCount = 0; + + hi2c->State = HAL_I2C_STATE_READY; + + /* Check if Errors has been detected during transfer */ + if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + HAL_I2C_ErrorCallback(hi2c); + } + else + { + HAL_I2C_SlaveRxCpltCallback(hi2c); + } +} + +/** + * @brief DMA I2C Memory Write process complete callback + * @param hdma: DMA handle + * @retval None + */ +static void I2C_DMAMemTransmitCplt(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Wait until BTF flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, I2C_TIMEOUT_FLAG) != HAL_OK) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Disable DMA Request */ + hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; + + hi2c->XferCount = 0; + + hi2c->State = HAL_I2C_STATE_READY; + + /* Check if Errors has been detected during transfer */ + if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + HAL_I2C_ErrorCallback(hi2c); + } + else + { + HAL_I2C_MemTxCpltCallback(hi2c); + } +} + +/** + * @brief DMA I2C Memory Read process complete callback + * @param hdma: DMA handle + * @retval None + */ +static void I2C_DMAMemReceiveCplt(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Disable Last DMA */ + hi2c->Instance->CR2 &= ~I2C_CR2_LAST; + + /* Disable DMA Request */ + hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; + + hi2c->XferCount = 0; + + hi2c->State = HAL_I2C_STATE_READY; + + /* Check if Errors has been detected during transfer */ + if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + HAL_I2C_ErrorCallback(hi2c); + } + else + { + HAL_I2C_MemRxCpltCallback(hi2c); + } +} + +/** + * @brief DMA I2C communication error callback. + * @param hdma: DMA handle + * @retval None + */ +static void I2C_DMAError(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + hi2c->XferCount = 0; + + hi2c->State = HAL_I2C_STATE_READY; + + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + HAL_I2C_ErrorCallback(hi2c); +} + +/** + * @brief This function handles I2C Communication Timeout. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param Flag: specifies the I2C flag to check. + * @param Status: The new Flag status (SET or RESET). + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until flag is set */ + if(Status == RESET) + { + while(__HAL_I2C_GET_FLAG(hi2c, Flag) == RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + } + else + { + while(__HAL_I2C_GET_FLAG(hi2c, Flag) != RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for Master addressing phase. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param Flag: specifies the I2C flag to check. + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(__HAL_I2C_GET_FLAG(hi2c, Flag) == RESET) + { + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Clear AF Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + hi2c->ErrorCode = HAL_I2C_ERROR_AF; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @} + */ + +#endif /* HAL_I2C_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c new file mode 100644 index 0000000..b829d3b --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c @@ -0,0 +1,204 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2c_ex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief I2C Extension HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of I2C extension peripheral: + * + Extension features functions + * + @verbatim + ============================================================================== + ##### I2C peripheral extension features ##### + ============================================================================== + + [..] Comparing to other previous devices, the I2C interface for STM32F427xx/437xx/ + 429xx/439xx devices contains the following additional features : + + (+) Possibility to disable or enable Analog Noise Filter + (+) Use of a configured Digital Noise Filter + + ##### How to use this driver ##### + ============================================================================== + [..] This driver provides functions to configure Noise Filter + (#) Configure I2C Analog noise filter using the function HAL_I2C_AnalogFilter_Config() + (#) Configure I2C Digital noise filter using the function HAL_I2C_DigitalFilter_Config() + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 I2CEx I2CEx + * @brief I2C HAL module driver + * @{ + */ + +#ifdef HAL_I2C_MODULE_ENABLED + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup I2CEx_Exported_Functions I2C Exported Functions + * @{ + */ + + +/** @defgroup I2CEx_Exported_Functions_Group1 Extension features functions + * @brief Extension features functions + * +@verbatim + =============================================================================== + ##### Extension features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure Noise Filters + +@endverbatim + * @{ + */ + +/** + * @brief Configures I2C Analog noise filter. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2Cx peripheral. + * @param AnalogFilter: new state of the Analog filter. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter) +{ + uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter)); + + tmp = hi2c->State; + if((tmp == HAL_I2C_STATE_BUSY) || (tmp == HAL_I2C_STATE_BUSY_TX) || (tmp == HAL_I2C_STATE_BUSY_RX)) + { + return HAL_BUSY; + } + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Reset I2Cx ANOFF bit */ + hi2c->Instance->FLTR &= ~(I2C_FLTR_ANOFF); + + /* Disable the analog filter */ + hi2c->Instance->FLTR |= AnalogFilter; + + __HAL_I2C_ENABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Configures I2C Digital noise filter. + * @param hi2c: pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2Cx peripheral. + * @param DigitalFilter: Coefficient of digital noise filter between 0x00 and 0x0F. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter) +{ + uint16_t tmpreg = 0; + uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter)); + + tmp = hi2c->State; + if((tmp == HAL_I2C_STATE_BUSY) || (tmp == HAL_I2C_STATE_BUSY_TX) || (tmp == HAL_I2C_STATE_BUSY_RX)) + { + return HAL_BUSY; + } + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Get the old register value */ + tmpreg = hi2c->Instance->FLTR; + + /* Reset I2Cx DNF bit [3:0] */ + tmpreg &= ~(I2C_FLTR_DNF); + + /* Set I2Cx DNF coefficient */ + tmpreg |= DigitalFilter; + + /* Store the new register value */ + hi2c->Instance->FLTR = tmpreg; + + __HAL_I2C_ENABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F401xC || STM32F401xE || STM32F446xx */ + +#endif /* HAL_I2C_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s.c new file mode 100644 index 0000000..487b12b --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s.c @@ -0,0 +1,1408 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2s.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief I2S HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Integrated Interchip Sound (I2S) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State and Errors functions + @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + The I2S HAL driver can be used as follow: + + (#) Declare a I2S_HandleTypeDef handle structure. + (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API: + (##) Enable the SPIx interface clock. + (##) I2S pins configuration: + (+++) Enable the clock for the I2S GPIOs. + (+++) Configure these I2S pins as alternate function pull-up. + (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT() + and HAL_I2S_Receive_IT() APIs). + (+++) Configure the I2Sx interrupt priority. + (+++) Enable the NVIC I2S IRQ handle. + (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA() + and HAL_I2S_Receive_DMA() APIs: + (+++) Declare a DMA handle structure for the Tx/Rx stream. + (+++) Enable the DMAx interface clock. + (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. + (+++) Configure the DMA Tx/Rx Stream. + (+++) Associate the initialized DMA handle to the I2S DMA Tx/Rx handle. + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the + DMA Tx/Rx Stream. + + (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity + using HAL_I2S_Init() function. + + -@- The specific I2S interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) will be managed using the macros + __I2S_ENABLE_IT() and __I2S_DISABLE_IT() inside the transmit and receive process. + -@- Make sure that either: + (+@) I2S PLL is configured or + (+@) External clock source is configured after setting correctly + the define constant EXTERNAL_CLOCK_VALUE in the stm32f4xx_hal_conf.h file. + + (#) Three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Send an amount of data in blocking mode using HAL_I2S_Transmit() + (+) Receive an amount of data in blocking mode using HAL_I2S_Receive() + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT() + (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback + (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_TxCpltCallback + (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT() + (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback + (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_RxCpltCallback + (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2S_ErrorCallback + + *** DMA mode IO operation *** + ============================== + [..] + (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA() + (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback + (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_TxCpltCallback + (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA() + (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback + (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_RxCpltCallback + (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2S_ErrorCallback + (+) Pause the DMA Transfer using HAL_I2S_DMAPause() + (+) Resume the DMA Transfer using HAL_I2S_DMAResume() + (+) Stop the DMA Transfer using HAL_I2S_DMAStop() + + *** I2S HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in USART HAL driver. + + (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode) + (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode) + (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts + (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts + (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not + + [..] + (@) You can refer to the I2S HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 I2S I2S + * @brief I2S HAL module driver + * @{ + */ + +#ifdef HAL_I2S_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup I2S_Private_Functions + * @{ + */ + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup I2S_Exported_Functions I2S Exported Functions + * @{ + */ + +/** @defgroup I2S_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the I2Sx peripheral in simplex mode: + + (+) User must Implement HAL_I2S_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). + + (+) Call the function HAL_I2S_Init() to configure the selected device with + the selected configuration: + (++) Mode + (++) Standard + (++) Data Format + (++) MCLK Output + (++) Audio frequency + (++) Polarity + + (+) Call the function HAL_I2S_DeInit() to restore the default configuration + of the selected I2Sx peripheral. +@endverbatim + * @{ + */ + +/** + * @brief Initializes the I2S according to the specified parameters + * in the I2S_InitTypeDef and create the associated handle. + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +__weak HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s) +{ + uint32_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1; + uint32_t tmp = 0, i2sclk = 0; + + /* Check the I2S handle allocation */ + if(hi2s == NULL) + { + return HAL_ERROR; + } + + /* Check the I2S parameters */ + assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance)); + assert_param(IS_I2S_MODE(hi2s->Init.Mode)); + assert_param(IS_I2S_STANDARD(hi2s->Init.Standard)); + assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat)); + assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput)); + assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq)); + assert_param(IS_I2S_CPOL(hi2s->Init.CPOL)); + assert_param(IS_I2S_CLOCKSOURCE(hi2s->Init.ClockSource)); + + if(hi2s->State == HAL_I2S_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hi2s->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + HAL_I2S_MspInit(hi2s); + } + + hi2s->State = HAL_I2S_STATE_BUSY; + + /*----------------------- SPIx I2SCFGR & I2SPR Configuration ---------------*/ + /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */ + hi2s->Instance->I2SCFGR &= ~(SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \ + SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \ + SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD); + hi2s->Instance->I2SPR = 0x0002; + + /* Get the I2SCFGR register value */ + tmpreg = hi2s->Instance->I2SCFGR; + + /* If the default frequency value has to be written, reinitialize i2sdiv and i2sodd */ + /* If the requested audio frequency is not the default, compute the prescaler */ + if(hi2s->Init.AudioFreq != I2S_AUDIOFREQ_DEFAULT) + { + /* Check the frame length (For the Prescaler computing) *******************/ + if(hi2s->Init.DataFormat != I2S_DATAFORMAT_16B) + { + /* Packet length is 32 bits */ + packetlength = 2; + } + + /* Get I2S source Clock frequency ****************************************/ + /* If an external I2S clock has to be used, the specific define should be set + in the project configuration or in the stm32f4xx_conf.h file */ + i2sclk = I2S_GetInputClock(hi2s); + + /* Compute the Real divider depending on the MCLK output state, with a floating point */ + if(hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE) + { + /* MCLK output is enabled */ + tmp = (uint32_t)(((((i2sclk / 256) * 10) / hi2s->Init.AudioFreq)) + 5); + } + else + { + /* MCLK output is disabled */ + tmp = (uint32_t)(((((i2sclk / (32 * packetlength)) *10 ) / hi2s->Init.AudioFreq)) + 5); + } + + /* Remove the flatting point */ + tmp = tmp / 10; + + /* Check the parity of the divider */ + i2sodd = (uint32_t)(tmp & (uint32_t)1); + + /* Compute the i2sdiv prescaler */ + i2sdiv = (uint32_t)((tmp - i2sodd) / 2); + + /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */ + i2sodd = (uint32_t) (i2sodd << 8); + } + + /* Test if the divider is 1 or 0 or greater than 0xFF */ + if((i2sdiv < 2) || (i2sdiv > 0xFF)) + { + /* Set the default values */ + i2sdiv = 2; + i2sodd = 0; + } + + /* Write to SPIx I2SPR register the computed value */ + hi2s->Instance->I2SPR = (uint32_t)((uint32_t)i2sdiv | (uint32_t)(i2sodd | (uint32_t)hi2s->Init.MCLKOutput)); + + /* Configure the I2S with the I2S_InitStruct values */ + tmpreg |= (uint32_t)(SPI_I2SCFGR_I2SMOD | hi2s->Init.Mode | hi2s->Init.Standard | hi2s->Init.DataFormat | hi2s->Init.CPOL); + +#if defined(SPI_I2SCFGR_ASTRTEN) + if (hi2s->Init.Standard == I2S_STANDARD_PCM_SHORT) + { + /* Write to SPIx I2SCFGR */ + hi2s->Instance->I2SCFGR = tmpreg | SPI_I2SCFGR_ASTRTEN; + } + else + { + /* Write to SPIx I2SCFGR */ + hi2s->Instance->I2SCFGR = tmpreg; + } +#else + /* Write to SPIx I2SCFGR */ + hi2s->Instance->I2SCFGR = tmpreg; +#endif + + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + hi2s->State= HAL_I2S_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the I2S peripheral + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s) +{ + /* Check the I2S handle allocation */ + if(hi2s == NULL) + { + return HAL_ERROR; + } + + hi2s->State = HAL_I2S_STATE_BUSY; + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ + HAL_I2S_MspDeInit(hi2s); + + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + hi2s->State = HAL_I2S_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; +} + +/** + * @brief I2S MSP Init + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ + __weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2S_MspInit could be implemented in the user file + */ +} + +/** + * @brief I2S MSP DeInit + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ + __weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2S_MspDeInit could be implemented in the user file + */ +} +/** + * @} + */ + +/** @defgroup I2S_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the I2S data + transfers. + + (#) There are two modes of transfer: + (++) Blocking mode : The communication is performed in the polling mode. + The status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode : The communication is performed using Interrupts + or DMA. These functions return the status of the transfer startup. + The end of the data processing will be indicated through the + dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + + (#) Blocking mode functions are : + (++) HAL_I2S_Transmit() + (++) HAL_I2S_Receive() + + (#) No-Blocking mode functions with Interrupt are : + (++) HAL_I2S_Transmit_IT() + (++) HAL_I2S_Receive_IT() + + (#) No-Blocking mode functions with DMA are : + (++) HAL_I2S_Transmit_DMA() + (++) HAL_I2S_Receive_DMA() + + (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) HAL_I2S_TxCpltCallback() + (++) HAL_I2S_RxCpltCallback() + (++) HAL_I2S_ErrorCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Transmit an amount of data in blocking mode + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pData: a 16-bit pointer to data buffer. + * @param Size: number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @param Timeout: Timeout duration + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tmp1 = 0, tmp2 = 0; + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + if(hi2s->State == HAL_I2S_STATE_READY) + { + tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + if((tmp1 == I2S_DATAFORMAT_24B)|| \ + (tmp2 == I2S_DATAFORMAT_32B)) + { + hi2s->TxXferSize = Size*2; + hi2s->TxXferCount = Size*2; + } + else + { + hi2s->TxXferSize = Size; + hi2s->TxXferCount = Size; + } + + /* Process Locked */ + __HAL_LOCK(hi2s); + + hi2s->State = HAL_I2S_STATE_BUSY_TX; + + /* Check if the I2S is already enabled */ + if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + while(hi2s->TxXferCount > 0) + { + hi2s->Instance->DR = (*pData++); + hi2s->TxXferCount--; + /* Wait until TXE flag is set */ + if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + } + /* Check if Slave mode is selected */ + if(((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX) || ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_RX)) + { + /* Wait until Busy flag is reset */ + if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, SET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + } + hi2s->State = HAL_I2S_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in blocking mode + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pData: a 16-bit pointer to data buffer. + * @param Size: number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @param Timeout: Timeout duration + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @note In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate + * in continuous way and as the I2S is not disabled at the end of the I2S transaction. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tmp1 = 0, tmp2 = 0; + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + if(hi2s->State == HAL_I2S_STATE_READY) + { + tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + if((tmp1 == I2S_DATAFORMAT_24B)|| \ + (tmp2 == I2S_DATAFORMAT_32B)) + { + hi2s->RxXferSize = Size*2; + hi2s->RxXferCount = Size*2; + } + else + { + hi2s->RxXferSize = Size; + hi2s->RxXferCount = Size; + } + /* Process Locked */ + __HAL_LOCK(hi2s); + + hi2s->State = HAL_I2S_STATE_BUSY_RX; + + /* Check if the I2S is already enabled */ + if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + /* Check if Master Receiver mode is selected */ + if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) + { + /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read + access to the SPI_SR register. */ + __HAL_I2S_CLEAR_OVRFLAG(hi2s); + } + + /* Receive data */ + while(hi2s->RxXferCount > 0) + { + /* Wait until RXNE flag is set */ + if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + (*pData++) = hi2s->Instance->DR; + hi2s->RxXferCount--; + } + + hi2s->State = HAL_I2S_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit an amount of data in non-blocking mode with Interrupt + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pData: a 16-bit pointer to data buffer. + * @param Size: number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size) +{ + uint32_t tmp1 = 0, tmp2 = 0; + if(hi2s->State == HAL_I2S_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + hi2s->pTxBuffPtr = pData; + tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + if((tmp1 == I2S_DATAFORMAT_24B)|| \ + (tmp2 == I2S_DATAFORMAT_32B)) + { + hi2s->TxXferSize = Size*2; + hi2s->TxXferCount = Size*2; + } + else + { + hi2s->TxXferSize = Size; + hi2s->TxXferCount = Size; + } + + /* Process Locked */ + __HAL_LOCK(hi2s); + + hi2s->State = HAL_I2S_STATE_BUSY_TX; + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + + /* Enable TXE and ERR interrupt */ + __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); + + /* Check if the I2S is already enabled */ + if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in non-blocking mode with Interrupt + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pData: a 16-bit pointer to the Receive data buffer. + * @param Size: number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @note It is recommended to use DMA for the I2S receiver to avoid de-synchronisation + * between Master and Slave otherwise the I2S interrupt should be optimized. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size) +{ + uint32_t tmp1 = 0, tmp2 = 0; + if(hi2s->State == HAL_I2S_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + hi2s->pRxBuffPtr = pData; + tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + if((tmp1 == I2S_DATAFORMAT_24B)||\ + (tmp2 == I2S_DATAFORMAT_32B)) + { + hi2s->RxXferSize = Size*2; + hi2s->RxXferCount = Size*2; + } + else + { + hi2s->RxXferSize = Size; + hi2s->RxXferCount = Size; + } + /* Process Locked */ + __HAL_LOCK(hi2s); + + hi2s->State = HAL_I2S_STATE_BUSY_RX; + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + + /* Enable TXE and ERR interrupt */ + __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); + + /* Check if the I2S is already enabled */ + if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; + } + + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit an amount of data in non-blocking mode with DMA + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pData: a 16-bit pointer to the Transmit data buffer. + * @param Size: number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size) +{ + uint32_t *tmp; + uint32_t tmp1 = 0, tmp2 = 0; + + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + if(hi2s->State == HAL_I2S_STATE_READY) + { + hi2s->pTxBuffPtr = pData; + tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + if((tmp1 == I2S_DATAFORMAT_24B)|| \ + (tmp2 == I2S_DATAFORMAT_32B)) + { + hi2s->TxXferSize = Size*2; + hi2s->TxXferCount = Size*2; + } + else + { + hi2s->TxXferSize = Size; + hi2s->TxXferCount = Size; + } + + /* Process Locked */ + __HAL_LOCK(hi2s); + + hi2s->State = HAL_I2S_STATE_BUSY_TX; + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + + /* Set the I2S Tx DMA Half transfer complete callback */ + hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt; + + /* Set the I2S Tx DMA transfer complete callback */ + hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt; + + /* Set the DMA error callback */ + hi2s->hdmatx->XferErrorCallback = I2S_DMAError; + + /* Enable the Tx DMA Stream */ + tmp = (uint32_t*)&pData; + HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize); + + /* Check if the I2S is already enabled */ + if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + /* Check if the I2S Tx request is already enabled */ + if((hi2s->Instance->CR2 & SPI_CR2_TXDMAEN) != SPI_CR2_TXDMAEN) + { + /* Enable Tx DMA Request */ + hi2s->Instance->CR2 |= SPI_CR2_TXDMAEN; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in non-blocking mode with DMA + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pData: a 16-bit pointer to the Receive data buffer. + * @param Size: number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size) +{ + uint32_t *tmp; + uint32_t tmp1 = 0, tmp2 = 0; + + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + if(hi2s->State == HAL_I2S_STATE_READY) + { + hi2s->pRxBuffPtr = pData; + tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + if((tmp1 == I2S_DATAFORMAT_24B)|| \ + (tmp2 == I2S_DATAFORMAT_32B)) + { + hi2s->RxXferSize = Size*2; + hi2s->RxXferCount = Size*2; + } + else + { + hi2s->RxXferSize = Size; + hi2s->RxXferCount = Size; + } + /* Process Locked */ + __HAL_LOCK(hi2s); + + hi2s->State = HAL_I2S_STATE_BUSY_RX; + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + + /* Set the I2S Rx DMA Half transfer complete callback */ + hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt; + + /* Set the I2S Rx DMA transfer complete callback */ + hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt; + + /* Set the DMA error callback */ + hi2s->hdmarx->XferErrorCallback = I2S_DMAError; + + /* Check if Master Receiver mode is selected */ + if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) + { + /* Clear the Overrun Flag by a read operation to the SPI_DR register followed by a read + access to the SPI_SR register. */ + __HAL_I2S_CLEAR_OVRFLAG(hi2s); + } + + /* Enable the Rx DMA Stream */ + tmp = (uint32_t*)&pData; + HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t*)tmp, hi2s->RxXferSize); + + /* Check if the I2S is already enabled */ + if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + /* Check if the I2S Rx request is already enabled */ + if((hi2s->Instance->CR2 &SPI_CR2_RXDMAEN) != SPI_CR2_RXDMAEN) + { + /* Enable Rx DMA Request */ + hi2s->Instance->CR2 |= SPI_CR2_RXDMAEN; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Pauses the audio stream playing from the Media. + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +__weak HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s) +{ + /* Process Locked */ + __HAL_LOCK(hi2s); + + if(hi2s->State == HAL_I2S_STATE_BUSY_TX) + { + /* Disable the I2S DMA Tx request */ + hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN); + } + else if(hi2s->State == HAL_I2S_STATE_BUSY_RX) + { + /* Disable the I2S DMA Rx request */ + hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN); + } + else if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) + { + if((hi2s->Init.Mode == I2S_MODE_SLAVE_TX)||(hi2s->Init.Mode == I2S_MODE_MASTER_TX)) + { + /* Disable the I2S DMA Tx request */ + hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN); + } + else + { + /* Disable the I2S DMA Rx request */ + hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN); + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; +} + +/** + * @brief Resumes the audio stream playing from the Media. + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +__weak HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s) +{ + /* Process Locked */ + __HAL_LOCK(hi2s); + + if(hi2s->State == HAL_I2S_STATE_BUSY_TX) + { + /* Enable the I2S DMA Tx request */ + hi2s->Instance->CR2 |= SPI_CR2_TXDMAEN; + } + else if(hi2s->State == HAL_I2S_STATE_BUSY_RX) + { + /* Enable the I2S DMA Rx request */ + hi2s->Instance->CR2 |= SPI_CR2_RXDMAEN; + } + else if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) + { + if((hi2s->Init.Mode == I2S_MODE_SLAVE_TX)||(hi2s->Init.Mode == I2S_MODE_MASTER_TX)) + { + /* Enable the I2S DMA Tx request */ + hi2s->Instance->CR2 |= SPI_CR2_TXDMAEN; + } + else + { + /* Enable the I2S DMA Rx request */ + hi2s->Instance->CR2 |= SPI_CR2_RXDMAEN; + } + } + + /* If the I2S peripheral is still not enabled, enable it */ + if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) == 0) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; +} + +/** + * @brief Resumes the audio stream playing from the Media. + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +__weak HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s) +{ + /* Process Locked */ + __HAL_LOCK(hi2s); + + /* Disable the I2S Tx/Rx DMA requests */ + hi2s->Instance->CR2 &= ~SPI_CR2_TXDMAEN; + hi2s->Instance->CR2 &= ~SPI_CR2_RXDMAEN; + + /* Abort the I2S DMA Stream tx */ + if(hi2s->hdmatx != NULL) + { + HAL_DMA_Abort(hi2s->hdmatx); + } + /* Abort the I2S DMA Stream rx */ + if(hi2s->hdmarx != NULL) + { + HAL_DMA_Abort(hi2s->hdmarx); + } + + /* Disable I2S peripheral */ + __HAL_I2S_DISABLE(hi2s); + + hi2s->State = HAL_I2S_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; +} + +/** + * @brief This function handles I2S interrupt request. + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +__weak void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s) +{ + uint32_t tmp1 = 0, tmp2 = 0; + + if(hi2s->State == HAL_I2S_STATE_BUSY_RX) + { + tmp1 = __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_RXNE); + tmp2 = __HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_RXNE); + /* I2S in mode Receiver ------------------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + I2S_Receive_IT(hi2s); + } + + tmp1 = __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR); + tmp2 = __HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR); + /* I2S Overrun error interrupt occurred ---------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_I2S_CLEAR_OVRFLAG(hi2s); + hi2s->ErrorCode |= HAL_I2S_ERROR_OVR; + } + } + + if(hi2s->State == HAL_I2S_STATE_BUSY_TX) + { + tmp1 = __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXE); + tmp2 = __HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_TXE); + /* I2S in mode Transmitter -----------------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + I2S_Transmit_IT(hi2s); + } + + tmp1 = __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR); + tmp2 = __HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR); + /* I2S Underrun error interrupt occurred --------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_I2S_CLEAR_UDRFLAG(hi2s); + hi2s->ErrorCode |= HAL_I2S_ERROR_UDR; + } + } + + /* Call the Error call Back in case of Errors */ + if(hi2s->ErrorCode != HAL_I2S_ERROR_NONE) + { + /* Set the I2S state ready to be able to start again the process */ + hi2s->State= HAL_I2S_STATE_READY; + HAL_I2S_ErrorCallback(hi2s); + } +} + +/** + * @brief Tx Transfer Half completed callbacks + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ + __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2S_TxHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Tx Transfer completed callbacks + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ + __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2S_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer half completed callbacks + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +__weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2S_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callbacks + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +__weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2S_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief I2S error callbacks + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ + __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2S_ErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief Peripheral State functions +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the I2S state + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL state + */ +HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s) +{ + return hi2s->State; +} + +/** + * @brief Return the I2S error code + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval I2S Error Code + */ +uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s) +{ + return hi2s->ErrorCode; +} +/** + * @} + */ + +/** + * @brief DMA I2S transmit process half complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ + void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma) +{ + I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + HAL_I2S_TxHalfCpltCallback(hi2s); +} + +/** + * @brief DMA I2S receive process half complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma) +{ + I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + HAL_I2S_RxHalfCpltCallback(hi2s); +} + +/** + * @brief DMA I2S communication error callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +void I2S_DMAError(DMA_HandleTypeDef *hdma) +{ + I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + hi2s->TxXferCount = 0; + hi2s->RxXferCount = 0; + + hi2s->State= HAL_I2S_STATE_READY; + + hi2s->ErrorCode |= HAL_I2S_ERROR_DMA; + HAL_I2S_ErrorCallback(hi2s); +} + +/** + * @brief Transmit an amount of data in non-blocking mode with Interrupt + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +HAL_StatusTypeDef I2S_Transmit_IT(I2S_HandleTypeDef *hi2s) +{ + if(hi2s->State == HAL_I2S_STATE_BUSY_TX) + { + /* Process Locked */ + __HAL_LOCK(hi2s); + + /* Transmit data */ + hi2s->Instance->DR = (*hi2s->pTxBuffPtr++); + + hi2s->TxXferCount--; + + if(hi2s->TxXferCount == 0) + { + /* Disable TXE and ERR interrupt */ + __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); + + hi2s->State = HAL_I2S_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + HAL_I2S_TxCpltCallback(hi2s); + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + } + + return HAL_OK; + } + + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in non-blocking mode with Interrupt + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +HAL_StatusTypeDef I2S_Receive_IT(I2S_HandleTypeDef *hi2s) +{ + if(hi2s->State == HAL_I2S_STATE_BUSY_RX) + { + /* Process Locked */ + __HAL_LOCK(hi2s); + + /* Receive data */ + (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR; + + hi2s->RxXferCount--; + + /* Check if Master Receiver mode is selected */ + if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) + { + /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read + access to the SPI_SR register. */ + __HAL_I2S_CLEAR_OVRFLAG(hi2s); + } + + if(hi2s->RxXferCount == 0) + { + /* Disable RXNE and ERR interrupt */ + __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_RXNE | I2S_IT_ERR); + + hi2s->State = HAL_I2S_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + HAL_I2S_RxCpltCallback(hi2s); + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief This function handles I2S Communication Timeout. + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param Flag: Flag checked + * @param Status: Value of the flag expected + * @param Timeout: Duration of the timeout + * @retval HAL status + */ +HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, uint32_t Status, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until flag is set */ + if(Status == RESET) + { + while(__HAL_I2S_GET_FLAG(hi2s, Flag) == RESET) + { + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Set the I2S State ready */ + hi2s->State= HAL_I2S_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_TIMEOUT; + } + } + } + } + else + { + while(__HAL_I2S_GET_FLAG(hi2s, Flag) != RESET) + { + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Set the I2S State ready */ + hi2s->State= HAL_I2S_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_TIMEOUT; + } + } + } + } + return HAL_OK; +} + +/** + * @} + */ + +#endif /* HAL_I2S_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s_ex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s_ex.c new file mode 100644 index 0000000..7b90324 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s_ex.c @@ -0,0 +1,1479 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2s_ex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief I2S HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of I2S extension peripheral: + * + Extension features Functions + * + @verbatim + ============================================================================== + ##### I2S Extension features ##### + ============================================================================== + [..] + (#) In I2S full duplex mode, each SPI peripheral is able to manage sending and receiving + data simultaneously using two data lines. Each SPI peripheral has an extended block + called I2Sxext (i.e I2S2ext for SPI2 and I2S3ext for SPI3). + (#) The extension block is not a full SPI IP, it is used only as I2S slave to + implement full duplex mode. The extension block uses the same clock sources + as its master. + + (#) Both I2Sx and I2Sx_ext can be configured as transmitters or receivers. + + [..] + (@) Only I2Sx can deliver SCK and WS to I2Sx_ext in full duplex mode, where + I2Sx can be I2S2 or I2S3. + + ##### How to use this driver ##### + =============================================================================== + [..] + Three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Send and receive in the same time an amount of data in blocking mode using HAL_I2S_TransmitReceive() + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Send and receive in the same time an amount of data in non blocking mode using HAL_I2S_TransmitReceive_IT() + (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback + (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_TxCpltCallback + (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback + (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_RxCpltCallback + (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2S_ErrorCallback + + *** DMA mode IO operation *** + ============================== + [..] + (+) Send and receive an amount of data in non blocking mode (DMA) using HAL_I2S_TransmitReceive_DMA() + (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback + (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_TxCpltCallback + (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback + (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2S_RxCpltCallback + (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2S_ErrorCallback + (+) Pause the DMA Transfer using HAL_I2S_DMAPause() + (+) Resume the DMA Transfer using HAL_I2S_DMAResume() + (+) Stop the DMA Transfer using HAL_I2S_DMAStop() + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 I2SEx I2SEx + * @brief I2S HAL module driver + * @{ + */ + +#ifdef HAL_I2S_MODULE_ENABLED + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup I2SEx_Private_Functions + * @{ + */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup I2SEx_Exported_Functions I2S Exported Functions + * @{ + */ + +/** @defgroup I2SEx_Group1 Extension features functions + * @brief Extension features functions + * +@verbatim + =============================================================================== + ##### Extension features Functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the I2S data + transfers. + + (#) There are two modes of transfer: + (++) Blocking mode : The communication is performed in the polling mode. + The status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode : The communication is performed using Interrupts + or DMA. These functions return the status of the transfer startup. + The end of the data processing will be indicated through the + dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + + (#) Blocking mode functions are : + (++) HAL_I2S_TransmitReceive() + + (#) No-Blocking mode functions with Interrupt are : + (++) HAL_I2S_TransmitReceive_IT() + + (#) No-Blocking mode functions with DMA are : + (++) HAL_I2S_TransmitReceive_DMA() + + (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) HAL_I2S_TxCpltCallback() + (++) HAL_I2S_RxCpltCallback() + (++) HAL_I2S_ErrorCallback() + +@endverbatim + * @{ + */ +/** + * @brief Initializes the I2S according to the specified parameters + * in the I2S_InitTypeDef and create the associated handle. + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s) +{ + uint32_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1; + uint32_t tmp = 0, i2sclk = 0; + + /* Check the I2S handle allocation */ + if(hi2s == NULL) + { + return HAL_ERROR; + } + + /* Check the I2S parameters */ + assert_param(IS_I2S_MODE(hi2s->Init.Mode)); + assert_param(IS_I2S_STANDARD(hi2s->Init.Standard)); + assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat)); + assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput)); + assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq)); + assert_param(IS_I2S_CPOL(hi2s->Init.CPOL)); + assert_param(IS_I2S_CLOCKSOURCE(hi2s->Init.ClockSource)); + + if(hi2s->State == HAL_I2S_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hi2s->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, CORTEX */ + HAL_I2S_MspInit(hi2s); + } + + hi2s->State = HAL_I2S_STATE_BUSY; + + /*----------------------- SPIx I2SCFGR & I2SPR Configuration ---------------*/ + /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */ + hi2s->Instance->I2SCFGR &= ~(SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \ + SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \ + SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD); + hi2s->Instance->I2SPR = 0x0002; + + /* Get the I2SCFGR register value */ + tmpreg = hi2s->Instance->I2SCFGR; + + /* If the default frequency value has to be written, reinitialize i2sdiv and i2sodd */ + /* If the requested audio frequency is not the default, compute the prescaler */ + if(hi2s->Init.AudioFreq != I2S_AUDIOFREQ_DEFAULT) + { + /* Check the frame length (For the Prescaler computing) *******************/ + if(hi2s->Init.DataFormat != I2S_DATAFORMAT_16B) + { + /* Packet length is 32 bits */ + packetlength = 2; + } + + /* Get I2S source Clock frequency ****************************************/ + i2sclk = I2S_GetInputClock(hi2s); + + /* Compute the Real divider depending on the MCLK output state, with a floating point */ + if(hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE) + { + /* MCLK output is enabled */ + tmp = (uint32_t)(((((i2sclk / 256) * 10) / hi2s->Init.AudioFreq)) + 5); + } + else + { + /* MCLK output is disabled */ + tmp = (uint32_t)(((((i2sclk / (32 * packetlength)) *10 ) / hi2s->Init.AudioFreq)) + 5); + } + + /* Remove the flatting point */ + tmp = tmp / 10; + + /* Check the parity of the divider */ + i2sodd = (uint32_t)(tmp & (uint32_t)1); + + /* Compute the i2sdiv prescaler */ + i2sdiv = (uint32_t)((tmp - i2sodd) / 2); + + /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */ + i2sodd = (uint32_t) (i2sodd << 8); + } + + /* Test if the divider is 1 or 0 or greater than 0xFF */ + if((i2sdiv < 2) || (i2sdiv > 0xFF)) + { + /* Set the default values */ + i2sdiv = 2; + i2sodd = 0; + } + + /* Write to SPIx I2SPR register the computed value */ + hi2s->Instance->I2SPR = (uint32_t)((uint32_t)i2sdiv | (uint32_t)(i2sodd | (uint32_t)hi2s->Init.MCLKOutput)); + + /* Configure the I2S with the I2S_InitStruct values */ + tmpreg |= (uint32_t)(SPI_I2SCFGR_I2SMOD | hi2s->Init.Mode | hi2s->Init.Standard | hi2s->Init.DataFormat | hi2s->Init.CPOL); + +#if defined(SPI_I2SCFGR_ASTRTEN) + if (hi2s->Init.Standard == I2S_STANDARD_PCM_SHORT) + { + /* Write to SPIx I2SCFGR */ + hi2s->Instance->I2SCFGR = tmpreg | SPI_I2SCFGR_ASTRTEN; + } + else + { + /* Write to SPIx I2SCFGR */ + hi2s->Instance->I2SCFGR = tmpreg; + } +#else + /* Write to SPIx I2SCFGR */ + hi2s->Instance->I2SCFGR = tmpreg; +#endif + + /* Configure the I2S extended if the full duplex mode is enabled */ + assert_param(IS_I2S_FULLDUPLEX_MODE(hi2s->Init.FullDuplexMode)); + if(hi2s->Init.FullDuplexMode == I2S_FULLDUPLEXMODE_ENABLE) + { + /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */ + I2SxEXT(hi2s->Instance)->I2SCFGR &= ~(SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \ + SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \ + SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD); + I2SxEXT(hi2s->Instance)->I2SPR = 2; + + /* Get the I2SCFGR register value */ + tmpreg = I2SxEXT(hi2s->Instance)->I2SCFGR; + + /* Get the mode to be configured for the extended I2S */ + if((hi2s->Init.Mode == I2S_MODE_MASTER_TX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_TX)) + { + tmp = I2S_MODE_SLAVE_RX; + } + else + { + if((hi2s->Init.Mode == I2S_MODE_MASTER_RX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_RX)) + { + tmp = I2S_MODE_SLAVE_TX; + } + } + + /* Configure the I2S Slave with the I2S Master parameter values */ + tmpreg |= (uint32_t)(SPI_I2SCFGR_I2SMOD | tmp | hi2s->Init.Standard | hi2s->Init.DataFormat | hi2s->Init.CPOL); + + /* Write to SPIx I2SCFGR */ + I2SxEXT(hi2s->Instance)->I2SCFGR = tmpreg; + } + + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + hi2s->State= HAL_I2S_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Full-Duplex Transmit/Receive data in blocking mode. + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pTxData: a 16-bit pointer to the Transmit data buffer. + * @param pRxData: a 16-bit pointer to the Receive data buffer. + * @param Size: number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @param Timeout: Timeout duration + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = 0; + uint32_t tmp1 = 0, tmp2 = 0; + + if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Check the I2S State */ + if(hi2s->State == HAL_I2S_STATE_READY) + { + tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended + is selected during the I2S configuration phase, the Size parameter means the number + of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data + frame is selected the Size parameter means the number of 16-bit data length. */ + if((tmp1 == I2S_DATAFORMAT_24B)|| \ + (tmp2 == I2S_DATAFORMAT_32B)) + { + hi2s->TxXferSize = Size*2; + hi2s->TxXferCount = Size*2; + hi2s->RxXferSize = Size*2; + hi2s->RxXferCount = Size*2; + } + else + { + hi2s->TxXferSize = Size; + hi2s->TxXferCount = Size; + hi2s->RxXferSize = Size; + hi2s->RxXferCount = Size; + } + + /* Process Locked */ + __HAL_LOCK(hi2s); + + /* Set the I2S State busy TX/RX */ + hi2s->State = HAL_I2S_STATE_BUSY_TX_RX; + + tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */ + if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX)) + { + /* Check if the I2S is already enabled: The I2S is kept enabled at the end of transaction + to avoid the clock de-synchronization between Master and Slave. */ + if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) + { + /* Enable I2Sext(receiver) before enabling I2Sx peripheral */ + I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE; + + /* Enable I2Sx peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + while(hi2s->TxXferCount > 0) + { + /* Wait until TXE flag is set */ + if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + hi2s->Instance->DR = (*pTxData++); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until RXNE flag is set */ + while((I2SxEXT(hi2s->Instance)->SR & SPI_SR_RXNE) != SPI_SR_RXNE) + { + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_TIMEOUT; + } + } + } + (*pRxData++) = I2SxEXT(hi2s->Instance)->DR; + + hi2s->TxXferCount--; + hi2s->RxXferCount--; + } + } + /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */ + else + { + /* Check if the I2S is already enabled */ + if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) + { + /* Enable I2S peripheral before the I2Sext*/ + __HAL_I2S_ENABLE(hi2s); + + /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */ + I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE; + } + else + { + /* Check if Master Receiver mode is selected */ + if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) + { + /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read + access to the SPI_SR register. */ + __HAL_I2S_CLEAR_OVRFLAG(hi2s); + } + } + while(hi2s->TxXferCount > 0) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until TXE flag is set */ + while((I2SxEXT(hi2s->Instance)->SR & SPI_SR_TXE) != SPI_SR_TXE) + { + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_TIMEOUT; + } + } + } + I2SxEXT(hi2s->Instance)->DR = (*pTxData++); + + /* Wait until RXNE flag is set */ + if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + (*pRxData++) = hi2s->Instance->DR; + + hi2s->TxXferCount--; + hi2s->RxXferCount--; + } + } + + /* Set the I2S State ready */ + hi2s->State = HAL_I2S_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pTxData: a 16-bit pointer to the Transmit data buffer. + * @param pRxData: a 16-bit pointer to the Receive data buffer. + * @param Size: number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size) +{ + uint32_t tmp1 = 0, tmp2 = 0; + + if(hi2s->State == HAL_I2S_STATE_READY) + { + if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + hi2s->pTxBuffPtr = pTxData; + hi2s->pRxBuffPtr = pRxData; + + tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended + is selected during the I2S configuration phase, the Size parameter means the number + of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data + frame is selected the Size parameter means the number of 16-bit data length. */ + if((tmp1 == I2S_DATAFORMAT_24B)||\ + (tmp2 == I2S_DATAFORMAT_32B)) + { + hi2s->TxXferSize = Size*2; + hi2s->TxXferCount = Size*2; + hi2s->RxXferSize = Size*2; + hi2s->RxXferCount = Size*2; + } + else + { + hi2s->TxXferSize = Size; + hi2s->TxXferCount = Size; + hi2s->RxXferSize = Size; + hi2s->RxXferCount = Size; + } + + /* Process Locked */ + __HAL_LOCK(hi2s); + + hi2s->State = HAL_I2S_STATE_BUSY_TX_RX; + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + + tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */ + if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX)) + { + /* Enable I2Sext RXNE and ERR interrupts */ + I2SxEXT(hi2s->Instance)->CR2 |= (I2S_IT_RXNE | I2S_IT_ERR); + + /* Enable I2Sx TXE and ERR interrupts */ + __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); + + /* Check if the I2S is already enabled */ + if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) + { + /* Enable I2Sext(receiver) before enabling I2Sx peripheral */ + I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE; + + /* Enable I2Sx peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + } + /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */ + else + { + /* Enable I2Sext TXE and ERR interrupts */ + I2SxEXT(hi2s->Instance)->CR2 |= (I2S_IT_TXE |I2S_IT_ERR); + + /* Enable I2Sext RXNE and ERR interrupts */ + __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); + + /* Check if the I2S is already enabled */ + if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) + { + /* Check if the I2S_MODE_MASTER_RX is selected */ + if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) + { + /* Prepare the First Data before enabling the I2S */ + if(hi2s->TxXferCount != 0) + { + /* Transmit First data */ + I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++); + hi2s->TxXferCount--; + + if(hi2s->TxXferCount == 0) + { + /* Disable I2Sext TXE interrupt */ + I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_TXE; + } + } + } + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + + /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */ + I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE; + } + } + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Full-Duplex Transmit/Receive data in non-blocking mode using DMA + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @param pTxData: a 16-bit pointer to the Transmit data buffer. + * @param pRxData: a 16-bit pointer to the Receive data buffer. + * @param Size: number of data sample to be sent: + * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S + * configuration phase, the Size parameter means the number of 16-bit data length + * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected + * the Size parameter means the number of 16-bit data length. + * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization + * between Master and Slave(example: audio streaming). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size) +{ + uint32_t *tmp; + uint32_t tmp1 = 0, tmp2 = 0; + + if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + if(hi2s->State == HAL_I2S_STATE_READY) + { + hi2s->pTxBuffPtr = pTxData; + hi2s->pRxBuffPtr = pRxData; + + tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); + /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended + is selected during the I2S configuration phase, the Size parameter means the number + of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data + frame is selected the Size parameter means the number of 16-bit data length. */ + if((tmp1 == I2S_DATAFORMAT_24B)||\ + (tmp2 == I2S_DATAFORMAT_32B)) + { + hi2s->TxXferSize = Size*2; + hi2s->TxXferCount = Size*2; + hi2s->RxXferSize = Size*2; + hi2s->RxXferCount = Size*2; + } + else + { + hi2s->TxXferSize = Size; + hi2s->TxXferCount = Size; + hi2s->RxXferSize = Size; + hi2s->RxXferCount = Size; + } + + /* Process Locked */ + __HAL_LOCK(hi2s); + + hi2s->State = HAL_I2S_STATE_BUSY_TX_RX; + hi2s->ErrorCode = HAL_I2S_ERROR_NONE; + + /* Set the I2S Rx DMA Half transfer complete callback */ + hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt; + + /* Set the I2S Rx DMA transfer complete callback */ + hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt; + + /* Set the I2S Rx DMA error callback */ + hi2s->hdmarx->XferErrorCallback = I2S_DMAError; + + /* Set the I2S Tx DMA Half transfer complete callback */ + hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt; + + /* Set the I2S Tx DMA transfer complete callback */ + hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt; + + /* Set the I2S Tx DMA error callback */ + hi2s->hdmatx->XferErrorCallback = I2S_DMAError; + + tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */ + if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX)) + { + /* Enable the Rx DMA Stream */ + tmp = (uint32_t*)&pRxData; + HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, *(uint32_t*)tmp, hi2s->RxXferSize); + + /* Enable Rx DMA Request */ + I2SxEXT(hi2s->Instance)->CR2 |= SPI_CR2_RXDMAEN; + + /* Enable the Tx DMA Stream */ + tmp = (uint32_t*)&pTxData; + HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize); + + /* Enable Tx DMA Request */ + hi2s->Instance->CR2 |= SPI_CR2_TXDMAEN; + + /* Check if the I2S is already enabled */ + if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) + { + /* Enable I2Sext(receiver) before enabling I2Sx peripheral */ + I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE; + + /* Enable I2S peripheral after the I2Sext */ + __HAL_I2S_ENABLE(hi2s); + } + } + else + { + /* Enable the Tx DMA Stream */ + tmp = (uint32_t*)&pTxData; + HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, hi2s->TxXferSize); + + /* Enable Tx DMA Request */ + I2SxEXT(hi2s->Instance)->CR2 |= SPI_CR2_TXDMAEN; + + /* Enable the Rx DMA Stream */ + tmp = (uint32_t*)&pRxData; + HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t*)tmp, hi2s->RxXferSize); + + /* Enable Rx DMA Request */ + hi2s->Instance->CR2 |= SPI_CR2_RXDMAEN; + + /* Check if the I2S is already enabled */ + if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) + { + /* Enable I2S peripheral before the I2Sext */ + __HAL_I2S_ENABLE(hi2s); + + /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */ + I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE; + } + else + { + /* Check if Master Receiver mode is selected */ + if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) + { + /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read + access to the SPI_SR register. */ + __HAL_I2S_CLEAR_OVRFLAG(hi2s); + } + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Pauses the audio stream playing from the Media. + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s) +{ + /* Process Locked */ + __HAL_LOCK(hi2s); + + if(hi2s->State == HAL_I2S_STATE_BUSY_TX) + { + /* Disable the I2S DMA Tx request */ + hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN); + } + else if(hi2s->State == HAL_I2S_STATE_BUSY_RX) + { + /* Disable the I2S DMA Rx request */ + hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN); + } + else if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) + { + if((hi2s->Init.Mode == I2S_MODE_SLAVE_TX)||(hi2s->Init.Mode == I2S_MODE_MASTER_TX)) + { + /* Disable the I2S DMA Tx request */ + hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN); + /* Disable the I2SEx Rx DMA Request */ + I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN); + } + else + { + /* Disable the I2S DMA Rx request */ + hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN); + /* Disable the I2SEx Tx DMA Request */ + I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN); + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; +} + +/** + * @brief Resumes the audio stream playing from the Media. + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s) +{ + /* Process Locked */ + __HAL_LOCK(hi2s); + + if(hi2s->State == HAL_I2S_STATE_BUSY_TX) + { + /* Enable the I2S DMA Tx request */ + hi2s->Instance->CR2 |= SPI_CR2_TXDMAEN; + } + else if(hi2s->State == HAL_I2S_STATE_BUSY_RX) + { + /* Enable the I2S DMA Rx request */ + hi2s->Instance->CR2 |= SPI_CR2_RXDMAEN; + } + else if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) + { + if((hi2s->Init.Mode == I2S_MODE_SLAVE_TX)||(hi2s->Init.Mode == I2S_MODE_MASTER_TX)) + { + /* Enable the I2S DMA Tx request */ + hi2s->Instance->CR2 |= SPI_CR2_TXDMAEN; + /* Disable the I2SEx Rx DMA Request */ + I2SxEXT(hi2s->Instance)->CR2 |= SPI_CR2_RXDMAEN; + } + else + { + /* Enable the I2S DMA Rx request */ + hi2s->Instance->CR2 |= SPI_CR2_RXDMAEN; + /* Enable the I2SEx Tx DMA Request */ + I2SxEXT(hi2s->Instance)->CR2 |= SPI_CR2_TXDMAEN; + } + } + + /* If the I2S peripheral is still not enabled, enable it */ + if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) == 0) + { + /* Enable I2S peripheral */ + __HAL_I2S_ENABLE(hi2s); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; +} + +/** + * @brief Resumes the audio stream playing from the Media. + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s) +{ + /* Process Locked */ + __HAL_LOCK(hi2s); + + /* Disable the I2S Tx/Rx DMA requests */ + hi2s->Instance->CR2 &= ~SPI_CR2_TXDMAEN; + hi2s->Instance->CR2 &= ~SPI_CR2_RXDMAEN; + + if(hi2s->Init.FullDuplexMode == I2S_FULLDUPLEXMODE_ENABLE) + { + /* Disable the I2S extended Tx/Rx DMA requests */ + I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN); + I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN); + } + + /* Abort the I2S DMA Stream tx */ + if(hi2s->hdmatx != NULL) + { + HAL_DMA_Abort(hi2s->hdmatx); + } + /* Abort the I2S DMA Stream rx */ + if(hi2s->hdmarx != NULL) + { + HAL_DMA_Abort(hi2s->hdmarx); + } + + /* Disable I2S peripheral */ + __HAL_I2S_DISABLE(hi2s); + + if(hi2s->Init.FullDuplexMode == I2S_FULLDUPLEXMODE_ENABLE) + { + /* Disable the I2Sext peripheral */ + I2SxEXT(hi2s->Instance)->I2SCFGR &= ~SPI_I2SCFGR_I2SE; + } + hi2s->State = HAL_I2S_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; +} + +/** + * @brief This function handles I2S interrupt request. + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval None + */ +void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s) +{ + uint32_t tmp1 = 0, tmp2 = 0; + __IO uint32_t tmpreg1 = 0; + if(hi2s->Init.FullDuplexMode != I2S_FULLDUPLEXMODE_ENABLE) + { + if(hi2s->State == HAL_I2S_STATE_BUSY_RX) + { + tmp1 = __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_RXNE); + tmp2 = __HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_RXNE); + /* I2S in mode Receiver ------------------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + I2S_Receive_IT(hi2s); + } + + tmp1 = __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR); + tmp2 = __HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR); + /* I2S Overrun error interrupt occurred ---------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_I2S_CLEAR_OVRFLAG(hi2s); + hi2s->ErrorCode |= HAL_I2S_ERROR_OVR; + } + } + + if(hi2s->State == HAL_I2S_STATE_BUSY_TX) + { + tmp1 = __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXE); + tmp2 = __HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_TXE); + /* I2S in mode Tramitter -----------------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + I2S_Transmit_IT(hi2s); + } + + tmp1 = __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR); + tmp2 = __HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR); + /* I2S Underrun error interrupt occurred --------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_I2S_CLEAR_UDRFLAG(hi2s); + hi2s->ErrorCode |= HAL_I2S_ERROR_UDR; + } + } + } + else + { + tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */ + if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX)) + { + tmp1 = I2SxEXT(hi2s->Instance)->SR & SPI_SR_RXNE; + tmp2 = I2SxEXT(hi2s->Instance)->CR2 & I2S_IT_RXNE; + /* I2Sext in mode Receiver ---------------------------------------------*/ + if((tmp1 == SPI_SR_RXNE) && (tmp2 == I2S_IT_RXNE)) + { + tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + /* When the I2S mode is configured as I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX, + the I2Sext RXNE interrupt will be generated to manage the full-duplex receive phase. */ + if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX)) + { + I2SEx_TransmitReceive_IT(hi2s); + } + } + + tmp1 = I2SxEXT(hi2s->Instance)->SR & SPI_SR_OVR; + tmp2 = I2SxEXT(hi2s->Instance)->CR2 & I2S_IT_ERR; + /* I2Sext Overrun error interrupt occurred ------------------------------*/ + if((tmp1 == SPI_SR_OVR) && (tmp2 == I2S_IT_ERR)) + { + /* Clear I2Sext OVR Flag */ + tmpreg1 = I2SxEXT(hi2s->Instance)->DR; + tmpreg1 = I2SxEXT(hi2s->Instance)->SR; + hi2s->ErrorCode |= HAL_I2SEX_ERROR_OVR; + UNUSED(tmpreg1); + } + + tmp1 = __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXE); + tmp2 = __HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_TXE); + /* I2S in mode Tramitter -----------------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + /* When the I2S mode is configured as I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX, + the I2S TXE interrupt will be generated to manage the full-duplex transmit phase. */ + if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX)) + { + I2SEx_TransmitReceive_IT(hi2s); + } + } + + tmp1 = __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR); + tmp2 = __HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR); + /* I2S Underrun error interrupt occurred --------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_I2S_CLEAR_UDRFLAG(hi2s); + hi2s->ErrorCode |= HAL_I2S_ERROR_UDR; + } + } + /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */ + else + { + tmp1 = __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_RXNE); + tmp2 = __HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_RXNE); + /* I2S in mode Receiver ------------------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + /* When the I2S mode is configured as I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX, + the I2S RXNE interrupt will be generated to manage the full-duplex receive phase. */ + if((tmp1 == I2S_MODE_MASTER_RX) || (tmp2 == I2S_MODE_SLAVE_RX)) + { + I2SEx_TransmitReceive_IT(hi2s); + } + } + + tmp1 = __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR); + tmp2 = __HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR); + /* I2S Overrun error interrupt occurred ---------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_I2S_CLEAR_OVRFLAG(hi2s); + hi2s->ErrorCode |= HAL_I2S_ERROR_OVR; + } + + tmp1 = I2SxEXT(hi2s->Instance)->SR & SPI_SR_TXE; + tmp2 = I2SxEXT(hi2s->Instance)->CR2 & I2S_IT_TXE; + /* I2Sext in mode Tramitter --------------------------------------------*/ + if((tmp1 == SPI_SR_TXE) && (tmp2 == I2S_IT_TXE)) + { + tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + /* When the I2S mode is configured as I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX, + the I2Sext TXE interrupt will be generated to manage the full-duplex transmit phase. */ + if((tmp1 == I2S_MODE_MASTER_RX) || (tmp2 == I2S_MODE_SLAVE_RX)) + { + I2SEx_TransmitReceive_IT(hi2s); + } + } + + tmp1 = I2SxEXT(hi2s->Instance)->SR & SPI_SR_UDR; + tmp2 = I2SxEXT(hi2s->Instance)->CR2 & I2S_IT_ERR; + /* I2Sext Underrun error interrupt occurred -----------------------------*/ + if((tmp1 == SPI_SR_UDR) && (tmp2 == I2S_IT_ERR)) + { + /* Clear I2Sext UDR Flag */ + tmpreg1 = I2SxEXT(hi2s->Instance)->SR; + hi2s->ErrorCode |= HAL_I2SEX_ERROR_UDR; + UNUSED(tmpreg1); + } + } + } + + /* Call the Error call Back in case of Errors */ + if(hi2s->ErrorCode != HAL_I2S_ERROR_NONE) + { + /* Set the I2S state ready to be able to start again the process */ + hi2s->State= HAL_I2S_STATE_READY; + HAL_I2S_ErrorCallback(hi2s); + } +} + +/** + * @} + */ + + +/** + * @brief Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval HAL status + */ +HAL_StatusTypeDef I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s) +{ + uint32_t tmp1 = 0, tmp2 = 0; + + if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) + { + /* Process Locked */ + __HAL_LOCK(hi2s); + + tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; + /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */ + if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX)) + { + if(hi2s->TxXferCount != 0) + { + if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXE) != RESET) + { + /* Transmit data */ + hi2s->Instance->DR = (*hi2s->pTxBuffPtr++); + hi2s->TxXferCount--; + + if(hi2s->TxXferCount == 0) + { + /* Disable TXE interrupt */ + __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_TXE); + } + } + } + + if(hi2s->RxXferCount != 0) + { + if((I2SxEXT(hi2s->Instance)->SR & SPI_SR_RXNE) == SPI_SR_RXNE) + { + /* Receive data */ + (*hi2s->pRxBuffPtr++) = I2SxEXT(hi2s->Instance)->DR; + hi2s->RxXferCount--; + + if(hi2s->RxXferCount == 0) + { + /* Disable I2Sext RXNE interrupt */ + I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_RXNE; + } + } + } + } + /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */ + else + { + if(hi2s->TxXferCount != 0) + { + if((I2SxEXT(hi2s->Instance)->SR & SPI_SR_TXE) == SPI_SR_TXE) + { + /* Transmit data */ + I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++); + hi2s->TxXferCount--; + + if(hi2s->TxXferCount == 0) + { + /* Disable I2Sext TXE interrupt */ + I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_TXE; + + HAL_I2S_TxCpltCallback(hi2s); + } + } + } + if(hi2s->RxXferCount != 0) + { + if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_RXNE) != RESET) + { + /* Receive data */ + (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR; + hi2s->RxXferCount--; + + if(hi2s->RxXferCount == 0) + { + /* Disable RXNE interrupt */ + __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_RXNE); + + HAL_I2S_RxCpltCallback(hi2s); + } + } + } + } + + tmp1 = hi2s->RxXferCount; + tmp2 = hi2s->TxXferCount; + if((tmp1 == 0) && (tmp2 == 0)) + { + /* Disable I2Sx ERR interrupt */ + __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_ERR); + /* Disable I2Sext ERR interrupt */ + I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_ERR; + + hi2s->State = HAL_I2S_STATE_READY; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2s); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +#endif /* STM32F40xxx/ STM32F41xxx/ STM32F42xxx/ STM32F43xxx/ STM32F401xx/ STM32F411xx */ +/** + * @brief DMA I2S transmit process complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +void I2S_DMATxCplt(DMA_HandleTypeDef *hdma) +{ + I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) + { + hi2s->TxXferCount = 0; + + /* Disable Tx DMA Request */ + hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN); +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) + if(hi2s->Init.FullDuplexMode == I2S_FULLDUPLEXMODE_ENABLE) + { + /* Disable Rx DMA Request for the slave*/ + I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN); + } +#endif /* STM32F40xxx/ STM32F41xxx/ STM32F42xxx/ STM32F43xxx/ STM32F401xx/ STM32F411xx */ + if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) + { + if(hi2s->RxXferCount == 0) + { + hi2s->State = HAL_I2S_STATE_READY; + } + } + else + { + hi2s->State = HAL_I2S_STATE_READY; + } + } + HAL_I2S_TxCpltCallback(hi2s); +} + +/** + * @brief DMA I2S receive process complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +void I2S_DMARxCplt(DMA_HandleTypeDef *hdma) +{ + I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) + { + /* Disable Rx DMA Request */ + hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN); +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) + if(hi2s->Init.FullDuplexMode == I2S_FULLDUPLEXMODE_ENABLE) + { + /* Disable Tx DMA Request for the slave*/ + I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN); + } +#endif /* STM32F40xxx/ STM32F41xxx/ STM32F42xxx/ STM32F43xxx/ STM32F401xx/ STM32F411xx */ + hi2s->RxXferCount = 0; + if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) + { + if(hi2s->TxXferCount == 0) + { + hi2s->State = HAL_I2S_STATE_READY; + } + } + else + { + hi2s->State = HAL_I2S_STATE_READY; + } + } + HAL_I2S_RxCpltCallback(hi2s); +} + +/** + * @brief Get I2S clock Input based on Source clock selection in RCC + * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains + * the configuration information for I2S module + * @retval I2S Clock Input + */ +uint32_t I2S_GetInputClock(I2S_HandleTypeDef *hi2s) +{ + /* This variable used to store the VCO Input (value in Hz) */ + uint32_t vcoinput = 0; + /* This variable used to store the VCO Output (value in Hz) */ + uint32_t vcooutput = 0; + /* This variable used to store the I2S_CK_x (value in Hz) */ + uint32_t i2ssourceclock = 0; + + /* Configure SAI Clock based on SAI source clock selection */ +#if defined(STM32F446xx) + switch(hi2s->Init.ClockSource) + { + case I2S_CLOCK_EXTERNAL : + { + /* Set the I2S clock to the external clock value */ + i2ssourceclock = EXTERNAL_CLOCK_VALUE; + break; + } + case I2S_CLOCK_PLL : + { + /* Configure the PLLI2S division factor */ + /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ + if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) + { + /* Get the I2S source clock value */ + vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); + } + else + { + /* Get the I2S source clock value */ + vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); + } + + /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ + vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6) & (RCC_PLLI2SCFGR_PLLI2SN >> 6))); + /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ + i2ssourceclock = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28) & (RCC_PLLI2SCFGR_PLLI2SR >> 28))); + break; + } + case I2S_CLOCK_PLLR : + { + /* Configure the PLLI2S division factor */ + /* PLL_VCO Input = PLL_SOURCE/PLLM */ + if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) + { + /* Get the I2S source clock value */ + vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); + } + else + { + /* Get the I2S source clock value */ + vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); + } + + /* PLL_VCO Output = PLL_VCO Input * PLLN */ + vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6) & (RCC_PLLCFGR_PLLN >> 6))); + /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ + i2ssourceclock = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28) & (RCC_PLLCFGR_PLLR >> 28))); + break; + } + case I2S_CLOCK_PLLSRC : + { + /* Configure the PLLI2S division factor */ + /* PLL_VCO Input = PLL_SOURCE/PLLM */ + if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) + { + /* Get the I2S source clock value */ + i2ssourceclock = (uint32_t)(HSE_VALUE); + } + else + { + /* Get the I2S source clock value */ + i2ssourceclock = (uint32_t)(HSI_VALUE); + } + break; + } + default : + { + break; + } + } +#endif /* STM32F446xx */ +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) + + /* If an external I2S clock has to be used, the specific define should be set + in the project configuration or in the stm32f4xx_conf.h file */ + if(hi2s->Init.ClockSource == I2S_CLOCK_EXTERNAL) + { + /* Enable the External Clock selection */ + __HAL_RCC_I2S_CONFIG(RCC_I2SCLKSOURCE_EXT); + + /* Set the I2S clock to the external clock value */ + i2ssourceclock = EXTERNAL_CLOCK_VALUE; + } + else + { + /* Configure the PLLI2S division factor */ + /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */ + if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) + { + /* Get the I2S source clock value */ + vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); + } + else + { + /* Get the I2S source clock value */ + vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); + } + + /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ + vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6) & (RCC_PLLI2SCFGR_PLLI2SN >> 6))); + /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ + i2ssourceclock = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28) & (RCC_PLLI2SCFGR_PLLI2SR >> 28))); + } +#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx */ + +#if defined(STM32F411xE) + + /* If an external I2S clock has to be used, the specific define should be set + in the project configuration or in the stm32f4xx_conf.h file */ + if(hi2s->Init.ClockSource == I2S_CLOCK_EXTERNAL) + { + /* Enable the External Clock selection */ + __HAL_RCC_I2S_CONFIG(RCC_I2SCLKSOURCE_EXT); + + /* Set the I2S clock to the external clock value */ + i2ssourceclock = EXTERNAL_CLOCK_VALUE; + } + else + { + /* Configure the PLLI2S division factor */ + /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ + if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) + { + /* Get the I2S source clock value */ + vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); + } + else + { + /* Get the I2S source clock value */ + vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); + } + + /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ + vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6) & (RCC_PLLI2SCFGR_PLLI2SN >> 6))); + /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ + i2ssourceclock = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28) & (RCC_PLLI2SCFGR_PLLI2SR >> 28))); + } +#endif /* STM32F411xE */ + + /* the return result is the value of SAI clock */ + return i2ssourceclock; + +} +/** + * @} + */ + +#endif /* HAL_I2S_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_irda.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_irda.c new file mode 100644 index 0000000..17d6f48 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_irda.c @@ -0,0 +1,1504 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_irda.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief IRDA HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the IrDA SIR ENDEC block (IrDA): + * + Initialization and de-initialization methods + * + IO operation methods + * + Peripheral Control methods + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The IRDA HAL driver can be used as follows: + + (#) Declare a IRDA_HandleTypeDef handle structure. + (#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API: + (##) Enable the USARTx interface clock. + (##) IRDA pins configuration: + (+++) Enable the clock for the IRDA GPIOs. + (+++) Configure these IRDA pins as alternate function pull-up. + (##) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT() + and HAL_IRDA_Receive_IT() APIs): + (+++) Configure the USARTx interrupt priority. + (+++) Enable the NVIC USART IRQ handle. + (##) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA() + and HAL_IRDA_Receive_DMA() APIs): + (+++) Declare a DMA handle structure for the Tx/Rx stream. + (+++) Enable the DMAx interface clock. + (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. + (+++) Configure the DMA Tx/Rx Stream. + (+++) Associate the initialized DMA handle to the IRDA DMA Tx/Rx handle. + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream. + + (#) Program the Baud Rate, Word Length, Parity, IrDA Mode, Prescaler + and Mode(Receiver/Transmitter) in the hirda Init structure. + + (#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API: + (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) + by calling the customized HAL_IRDA_MspInit() API. + -@@- The specific IRDA interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) will be managed using the macros + __HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process. + + (#) Three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Send an amount of data in blocking mode using HAL_IRDA_Transmit() + (+) Receive an amount of data in blocking mode using HAL_IRDA_Receive() + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Send an amount of data in non blocking mode using HAL_IRDA_Transmit_IT() + (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_IRDA_TxCpltCallback + (+) Receive an amount of data in non blocking mode using HAL_IRDA_Receive_IT() + (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_IRDA_RxCpltCallback + (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_IRDA_ErrorCallback + + *** DMA mode IO operation *** + ============================= + [..] + (+) Send an amount of data in non blocking mode (DMA) using HAL_IRDA_Transmit_DMA() + (+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_IRDA_TxCpltCallback + (+) Receive an amount of data in non blocking mode (DMA) using HAL_IRDA_Receive_DMA() + (+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_IRDA_RxCpltCallback + (+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_IRDA_ErrorCallback + + *** IRDA HAL driver macros list *** + =================================== + [..] + Below the list of most used macros in IRDA HAL driver. + + (+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral + (+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral + (+) __HAL_IRDA_GET_FLAG : Checks whether the specified IRDA flag is set or not + (+) __HAL_IRDA_CLEAR_FLAG : Clears the specified IRDA pending flag + (+) __HAL_IRDA_ENABLE_IT: Enables the specified IRDA interrupt + (+) __HAL_IRDA_DISABLE_IT: Disables the specified IRDA interrupt + + (@) You can refer to the IRDA HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 IRDA IRDA + * @brief HAL IRDA module driver + * @{ + */ + +#ifdef HAL_IRDA_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup IRDA_Private_Constants + * @{ + */ +#define IRDA_TIMEOUT_VALUE 22000 +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup IRDA_Private_Functions + * @{ + */ +static void IRDA_SetConfig (IRDA_HandleTypeDef *hirda); +static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda); +static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda); +static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda); +static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma); +static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma); +static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma); +static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma); +static void IRDA_DMAError(DMA_HandleTypeDef *hdma); +static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Timeout); +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup IRDA_Exported_Functions IrDA Exported Functions + * @{ + */ + +/** @defgroup IRDA_Exported_Functions_Group1 IrDA Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + +=============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the USARTx or the UARTy + in IrDA mode. + (+) For the asynchronous mode only these parameters can be configured: + (++) BaudRate + (++) WordLength + (++) Parity: If the parity is enabled, then the MSB bit of the data written + in the data register is transmitted but is changed by the parity bit. + Depending on the frame length defined by the M bit (8-bits or 9-bits), + please refer to Reference manual for possible IRDA frame formats. + (++) Prescaler: A pulse of width less than two and greater than one PSC period(s) may or may + not be rejected. The receiver set up time should be managed by software. The IrDA physical layer + specification specifies a minimum of 10 ms delay between transmission and + reception (IrDA is a half duplex protocol). + (++) Mode: Receiver/transmitter modes + (++) IrDAMode: the IrDA can operate in the Normal mode or in the Low power mode. + [..] + The HAL_IRDA_Init() API follows IRDA configuration procedures (details for the procedures + are available in reference manual). + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the IRDA mode according to the specified + * parameters in the IRDA_InitTypeDef and create the associated handle. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda) +{ + /* Check the IRDA handle allocation */ + if(hirda == NULL) + { + return HAL_ERROR; + } + + /* Check the IRDA instance parameters */ + assert_param(IS_IRDA_INSTANCE(hirda->Instance)); + /* Check the IRDA mode parameter in the IRDA handle */ + assert_param(IS_IRDA_POWERMODE(hirda->Init.IrDAMode)); + + if(hirda->State == HAL_IRDA_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hirda->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + HAL_IRDA_MspInit(hirda); + } + + hirda->State = HAL_IRDA_STATE_BUSY; + + /* Disable the IRDA peripheral */ + __HAL_IRDA_DISABLE(hirda); + + /* Set the IRDA communication parameters */ + IRDA_SetConfig(hirda); + + /* In IrDA mode, the following bits must be kept cleared: + - LINEN, STOP and CLKEN bits in the USART_CR2 register, + - SCEN and HDSEL bits in the USART_CR3 register.*/ + hirda->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_STOP | USART_CR2_CLKEN); + hirda->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL); + + /* Enable the IRDA peripheral */ + __HAL_IRDA_ENABLE(hirda); + + /* Set the prescaler */ + MODIFY_REG(hirda->Instance->GTPR, USART_GTPR_PSC, hirda->Init.Prescaler); + + /* Configure the IrDA mode */ + MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.IrDAMode); + + /* Enable the IrDA mode by setting the IREN bit in the CR3 register */ + hirda->Instance->CR3 |= USART_CR3_IREN; + + /* Initialize the IRDA state*/ + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + hirda->State= HAL_IRDA_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the IRDA peripheral + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda) +{ + /* Check the IRDA handle allocation */ + if(hirda == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_IRDA_INSTANCE(hirda->Instance)); + + hirda->State = HAL_IRDA_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_IRDA_DISABLE(hirda); + + /* DeInit the low level hardware */ + HAL_IRDA_MspDeInit(hirda); + + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + + hirda->State = HAL_IRDA_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hirda); + + return HAL_OK; +} + +/** + * @brief IRDA MSP Init. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ + __weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_IRDA_MspInit could be implemented in the user file + */ +} + +/** + * @brief IRDA MSP DeInit. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ + __weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_IRDA_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup IRDA_Exported_Functions_Group2 IO operation functions + * @brief IRDA Transmit/Receive functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + This subsection provides a set of functions allowing to manage the IRDA data transfers. + [..] + IrDA is a half duplex communication protocol. If the Transmitter is busy, any data + on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver + is busy, data on the TX from the USART to IrDA will not be encoded by IrDA. + While receiving data, transmission should be avoided as the data to be transmitted + could be corrupted. + + (#) There are two modes of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode: The communication is performed using Interrupts + or DMA, These APIs return the HAL status. + The end of the data processing will be indicated through the + dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks + will be executed respectively at the end of the transmit or Receive process + The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected + + (#) Blocking mode API's are : + (++) HAL_IRDA_Transmit() + (++) HAL_IRDA_Receive() + + (#) Non Blocking mode APIs with Interrupt are : + (++) HAL_IRDA_Transmit_IT() + (++) HAL_IRDA_Receive_IT() + (++) HAL_IRDA_IRQHandler() + + (#) Non Blocking mode functions with DMA are : + (++) HAL_IRDA_Transmit_DMA() + (++) HAL_IRDA_Receive_DMA() + + (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) HAL_IRDA_TxCpltCallback() + (++) HAL_IRDA_RxCpltCallback() + (++) HAL_IRDA_ErrorCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Sends an amount of data in blocking mode. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @param Timeout: Specify timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint16_t* tmp; + uint32_t tmp1 = 0; + + tmp1 = hirda->State; + if((tmp1 == HAL_IRDA_STATE_READY) || (tmp1 == HAL_IRDA_STATE_BUSY_RX)) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hirda); + + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + if(hirda->State == HAL_IRDA_STATE_BUSY_RX) + { + hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; + } + else + { + hirda->State = HAL_IRDA_STATE_BUSY_TX; + } + + hirda->TxXferSize = Size; + hirda->TxXferCount = Size; + while(hirda->TxXferCount > 0) + { + hirda->TxXferCount--; + if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B) + { + if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + tmp = (uint16_t*) pData; + hirda->Instance->DR = (*tmp & (uint16_t)0x01FF); + if(hirda->Init.Parity == IRDA_PARITY_NONE) + { + pData +=2; + } + else + { + pData +=1; + } + } + else + { + if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + hirda->Instance->DR = (*pData++ & (uint8_t)0xFF); + } + } + + if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) + { + hirda->State = HAL_IRDA_STATE_BUSY_RX; + } + else + { + hirda->State = HAL_IRDA_STATE_READY; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in blocking mode. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be received + * @param Timeout: Specify timeout value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint16_t* tmp; + uint32_t tmp1 = 0; + + tmp1 = hirda->State; + if((tmp1 == HAL_IRDA_STATE_READY) || (tmp1 == HAL_IRDA_STATE_BUSY_TX)) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hirda); + + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + if(hirda->State == HAL_IRDA_STATE_BUSY_TX) + { + hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; + } + else + { + hirda->State = HAL_IRDA_STATE_BUSY_RX; + } + hirda->RxXferSize = Size; + hirda->RxXferCount = Size; + /* Check the remain data to be received */ + while(hirda->RxXferCount > 0) + { + hirda->RxXferCount--; + if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B) + { + if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + tmp = (uint16_t*) pData ; + if(hirda->Init.Parity == IRDA_PARITY_NONE) + { + *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x01FF); + pData +=2; + } + else + { + *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x00FF); + pData +=1; + } + } + else + { + if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + if(hirda->Init.Parity == IRDA_PARITY_NONE) + { + *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x00FF); + } + else + { + *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x007F); + } + } + } + if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) + { + hirda->State = HAL_IRDA_STATE_BUSY_TX; + } + else + { + hirda->State = HAL_IRDA_STATE_READY; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Send an amount of data in non blocking mode. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) +{ + uint32_t tmp1 = 0; + + tmp1 = hirda->State; + if((tmp1 == HAL_IRDA_STATE_READY) || (tmp1 == HAL_IRDA_STATE_BUSY_RX)) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(hirda); + + hirda->pTxBuffPtr = pData; + hirda->TxXferSize = Size; + hirda->TxXferCount = Size; + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + if(hirda->State == HAL_IRDA_STATE_BUSY_RX) + { + hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; + } + else + { + hirda->State = HAL_IRDA_STATE_BUSY_TX; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR); + + /* Enable the IRDA Transmit Data Register Empty Interrupt */ + __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TXE); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receives an amount of data in non blocking mode. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) +{ + uint32_t tmp1 = 0; + + tmp1 = hirda->State; + if((tmp1 == HAL_IRDA_STATE_READY) || (tmp1 == HAL_IRDA_STATE_BUSY_TX)) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hirda); + + hirda->pRxBuffPtr = pData; + hirda->RxXferSize = Size; + hirda->RxXferCount = Size; + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + if(hirda->State == HAL_IRDA_STATE_BUSY_TX) + { + hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; + } + else + { + hirda->State = HAL_IRDA_STATE_BUSY_RX; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + /* Enable the IRDA Data Register not empty Interrupt */ + __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_RXNE); + + /* Enable the IRDA Parity Error Interrupt */ + __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_PE); + + /* Enable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sends an amount of data in non blocking mode. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) +{ + uint32_t *tmp; + uint32_t tmp1 = 0; + + tmp1 = hirda->State; + if((tmp1 == HAL_IRDA_STATE_READY) || (tmp1 == HAL_IRDA_STATE_BUSY_RX)) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hirda); + + hirda->pTxBuffPtr = pData; + hirda->TxXferSize = Size; + hirda->TxXferCount = Size; + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + + if(hirda->State == HAL_IRDA_STATE_BUSY_RX) + { + hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; + } + else + { + hirda->State = HAL_IRDA_STATE_BUSY_TX; + } + + /* Set the IRDA DMA transfer complete callback */ + hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt; + + /* Set the IRDA DMA half transfer complete callback */ + hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt; + + /* Set the DMA error callback */ + hirda->hdmatx->XferErrorCallback = IRDA_DMAError; + + /* Enable the IRDA transmit DMA Stream */ + tmp = (uint32_t*)&pData; + HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t*)tmp, (uint32_t)&hirda->Instance->DR, Size); + + /* Clear the TC flag in the SR register by writing 0 to it */ + __HAL_IRDA_CLEAR_FLAG(hirda, IRDA_FLAG_TC); + + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the USART CR3 register */ + hirda->Instance->CR3 |= USART_CR3_DMAT; + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receives an amount of data in non blocking mode. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be received + * @note When the IRDA parity is enabled (PCE = 1) the data received contain the parity bit. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size) +{ + uint32_t *tmp; + uint32_t tmp1 = 0; + + tmp1 = hirda->State; + if((tmp1 == HAL_IRDA_STATE_READY) || (tmp1 == HAL_IRDA_STATE_BUSY_TX)) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hirda); + + hirda->pRxBuffPtr = pData; + hirda->RxXferSize = Size; + hirda->ErrorCode = HAL_IRDA_ERROR_NONE; + if(hirda->State == HAL_IRDA_STATE_BUSY_TX) + { + hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; + } + else + { + hirda->State = HAL_IRDA_STATE_BUSY_RX; + } + + /* Set the IRDA DMA transfer complete callback */ + hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt; + + /* Set the IRDA DMA half transfer complete callback */ + hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt; + + /* Set the DMA error callback */ + hirda->hdmarx->XferErrorCallback = IRDA_DMAError; + + /* Enable the DMA Stream */ + tmp = (uint32_t*)&pData; + HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->DR, *(uint32_t*)tmp, Size); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the USART CR3 register */ + hirda->Instance->CR3 |= USART_CR3_DMAR; + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Pauses the DMA Transfer. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda) +{ + /* Process Locked */ + __HAL_LOCK(hirda); + + if(hirda->State == HAL_IRDA_STATE_BUSY_TX) + { + /* Disable the UART DMA Tx request */ + hirda->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT); + } + else if(hirda->State == HAL_IRDA_STATE_BUSY_RX) + { + /* Disable the UART DMA Rx request */ + hirda->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR); + } + else if (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) + { + /* Disable the UART DMA Tx & Rx requests */ + hirda->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT); + hirda->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR); + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + return HAL_ERROR; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + return HAL_OK; +} + +/** + * @brief Resumes the DMA Transfer. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda) +{ + /* Process Locked */ + __HAL_LOCK(hirda); + + if(hirda->State == HAL_IRDA_STATE_BUSY_TX) + { + /* Enable the UART DMA Tx request */ + hirda->Instance->CR3 |= USART_CR3_DMAT; + } + else if(hirda->State == HAL_IRDA_STATE_BUSY_RX) + { + /* Clear the Overrun flag before resuming the Rx transfer */ + __HAL_IRDA_CLEAR_OREFLAG(hirda); + /* Enable the UART DMA Rx request */ + hirda->Instance->CR3 |= USART_CR3_DMAR; + } + else if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) + { + /* Clear the Overrun flag before resuming the Rx transfer */ + __HAL_IRDA_CLEAR_OREFLAG(hirda); + /* Enable the UART DMA Tx & Rx request */ + hirda->Instance->CR3 |= USART_CR3_DMAT; + hirda->Instance->CR3 |= USART_CR3_DMAR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + return HAL_ERROR; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + return HAL_OK; +} + +/** + * @brief Stops the DMA Transfer. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda) +{ + /* The Lock is not implemented on this API to allow the user application + to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback(): + when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated + and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() + */ + + /* Disable the UART Tx/Rx DMA requests */ + hirda->Instance->CR3 &= ~USART_CR3_DMAT; + hirda->Instance->CR3 &= ~USART_CR3_DMAR; + + /* Abort the UART DMA tx Stream */ + if(hirda->hdmatx != NULL) + { + HAL_DMA_Abort(hirda->hdmatx); + } + /* Abort the UART DMA rx Stream */ + if(hirda->hdmarx != NULL) + { + HAL_DMA_Abort(hirda->hdmarx); + } + + hirda->State = HAL_IRDA_STATE_READY; + + return HAL_OK; +} + +/** + * @brief This function handles IRDA interrupt request. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda) +{ + uint32_t tmp1 = 0, tmp2 =0; + + tmp1 = __HAL_IRDA_GET_FLAG(hirda, IRDA_FLAG_PE); + tmp2 = __HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_PE); + /* IRDA parity error interrupt occurred -------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_IRDA_CLEAR_PEFLAG(hirda); + hirda->ErrorCode |= HAL_IRDA_ERROR_PE; + } + + tmp1 = __HAL_IRDA_GET_FLAG(hirda, IRDA_FLAG_FE); + tmp2 = __HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR); + /* IRDA frame error interrupt occurred --------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_IRDA_CLEAR_FEFLAG(hirda); + hirda->ErrorCode |= HAL_IRDA_ERROR_FE; + } + + tmp1 = __HAL_IRDA_GET_FLAG(hirda, IRDA_FLAG_NE); + tmp2 = __HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR); + /* IRDA noise error interrupt occurred --------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_IRDA_CLEAR_NEFLAG(hirda); + hirda->ErrorCode |= HAL_IRDA_ERROR_NE; + } + + tmp1 = __HAL_IRDA_GET_FLAG(hirda, IRDA_FLAG_ORE); + tmp2 = __HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_ERR); + /* IRDA Over-Run interrupt occurred -----------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_IRDA_CLEAR_OREFLAG(hirda); + hirda->ErrorCode |= HAL_IRDA_ERROR_ORE; + } + + /* Call the Error call Back in case of Errors */ + if(hirda->ErrorCode != HAL_IRDA_ERROR_NONE) + { + /* Set the IRDA state ready to be able to start again the process */ + hirda->State = HAL_IRDA_STATE_READY; + HAL_IRDA_ErrorCallback(hirda); + } + + tmp1 = __HAL_IRDA_GET_FLAG(hirda, IRDA_FLAG_RXNE); + tmp2 = __HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_RXNE); + /* IRDA in mode Receiver ---------------------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + IRDA_Receive_IT(hirda); + } + + tmp1 = __HAL_IRDA_GET_FLAG(hirda, IRDA_FLAG_TXE); + tmp2 = __HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TXE); + /* IRDA in mode Transmitter ------------------------------------------------*/ + if((tmp1 != RESET) &&(tmp2 != RESET)) + { + IRDA_Transmit_IT(hirda); + } + + tmp1 = __HAL_IRDA_GET_FLAG(hirda, IRDA_FLAG_TC); + tmp2 = __HAL_IRDA_GET_IT_SOURCE(hirda, IRDA_IT_TC); + /* IRDA in mode Transmitter (transmission end) -----------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + IRDA_EndTransmit_IT(hirda); + } +} + +/** + * @brief Tx Transfer complete callbacks. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ + __weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_IRDA_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Tx Half Transfer completed callbacks. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval None + */ + __weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_IRDA_TxHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer complete callbacks. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +__weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_IRDA_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Half Transfer complete callbacks. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +__weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_IRDA_RxHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief IRDA error callbacks. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ + __weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_IRDA_ErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup IRDA_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief IRDA State and Errors functions + * +@verbatim + ============================================================================== + ##### Peripheral State and Errors functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to return the State of IrDA + communication process and also return Peripheral Errors occurred during communication process + (+) HAL_IRDA_GetState() API can be helpful to check in run-time the state of the IrDA peripheral. + (+) HAL_IRDA_GetError() check in run-time errors that could be occurred during communication. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the IRDA state. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval HAL state + */ +HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda) +{ + return hirda->State; +} + +/** + * @brief Return the IARDA error code + * @param hirda : pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA. + * @retval IRDA Error Code + */ +uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda) +{ + return hirda->ErrorCode; +} + +/** + * @} + */ + +/** + * @brief DMA IRDA transmit process complete callback. + * @param hdma : DMA handle + * @retval None + */ +static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + /* DMA Normal mode */ + if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) + { + hirda->TxXferCount = 0; + + /* Disable the DMA transfer for transmit request by setting the DMAT bit + in the IRDA CR3 register */ + hirda->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_DMAT); + + /* Enable the IRDA Transmit Complete Interrupt */ + __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC); + } + /* DMA Circular mode */ + else + { + HAL_IRDA_TxCpltCallback(hirda); + } +} + +/** + * @brief DMA IRDA receive process half complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + HAL_IRDA_TxHalfCpltCallback(hirda); +} + +/** + * @brief DMA IRDA receive process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + /* DMA Normal mode */ + if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) + { + hirda->RxXferCount = 0; + + /* Disable the DMA transfer for the receiver request by setting the DMAR bit + in the IRDA CR3 register */ + hirda->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_DMAR); + + if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) + { + hirda->State = HAL_IRDA_STATE_BUSY_TX; + } + else + { + hirda->State = HAL_IRDA_STATE_READY; + } + } + + HAL_IRDA_RxCpltCallback(hirda); +} + +/** + * @brief DMA IRDA receive process half complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + HAL_IRDA_RxHalfCpltCallback(hirda); +} + +/** + * @brief DMA IRDA communication error callback. + * @param hdma: DMA handle + * @retval None + */ +static void IRDA_DMAError(DMA_HandleTypeDef *hdma) +{ + IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + hirda->RxXferCount = 0; + hirda->TxXferCount = 0; + hirda->ErrorCode |= HAL_IRDA_ERROR_DMA; + hirda->State= HAL_IRDA_STATE_READY; + + HAL_IRDA_ErrorCallback(hirda); +} + +/** + * @brief This function handles IRDA Communication Timeout. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @param Flag: specifies the IRDA flag to check. + * @param Status: The new Flag status (SET or RESET). + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until flag is set */ + if(Status == RESET) + { + while(__HAL_IRDA_GET_FLAG(hirda, Flag) == RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ + __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE); + __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE); + __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE); + __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR); + + hirda->State= HAL_IRDA_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + return HAL_TIMEOUT; + } + } + } + } + else + { + while(__HAL_IRDA_GET_FLAG(hirda, Flag) != RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ + __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE); + __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE); + __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE); + __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR); + + hirda->State= HAL_IRDA_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hirda); + + return HAL_TIMEOUT; + } + } + } + } + return HAL_OK; +} + + /** + * @brief Send an amount of data in non blocking mode. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval HAL status + */ +static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda) +{ + uint16_t* tmp; + uint32_t tmp1 = 0; + + tmp1 = hirda->State; + if((tmp1 == HAL_IRDA_STATE_BUSY_TX) || (tmp1 == HAL_IRDA_STATE_BUSY_TX_RX)) + { + if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B) + { + tmp = (uint16_t*) hirda->pTxBuffPtr; + hirda->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF); + if(hirda->Init.Parity == IRDA_PARITY_NONE) + { + hirda->pTxBuffPtr += 2; + } + else + { + hirda->pTxBuffPtr += 1; + } + } + else + { + hirda->Instance->DR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0x00FF); + } + + if(--hirda->TxXferCount == 0) + { + /* Disable the IRDA Transmit Data Register Empty Interrupt */ + __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE); + + /* Enable the IRDA Transmit Complete Interrupt */ + __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Wraps up transmission in non blocking mode. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval HAL status + */ +static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda) +{ + /* Disable the IRDA Transmit Complete Interrupt */ + __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TC); + + /* Check if a receive process is ongoing or not */ + if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) + { + hirda->State = HAL_IRDA_STATE_BUSY_RX; + } + else + { + /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR); + + hirda->State = HAL_IRDA_STATE_READY; + } + + HAL_IRDA_TxCpltCallback(hirda); + + return HAL_OK; +} + +/** + * @brief Receives an amount of data in non blocking mode. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval HAL status + */ +static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda) +{ + uint16_t* tmp; + uint32_t tmp1 = 0; + + tmp1 = hirda->State; + if((tmp1 == HAL_IRDA_STATE_BUSY_RX) || (tmp1 == HAL_IRDA_STATE_BUSY_TX_RX)) + { + if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B) + { + tmp = (uint16_t*) hirda->pRxBuffPtr; + if(hirda->Init.Parity == IRDA_PARITY_NONE) + { + *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x01FF); + hirda->pRxBuffPtr += 2; + } + else + { + *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x00FF); + hirda->pRxBuffPtr += 1; + } + } + else + { + if(hirda->Init.Parity == IRDA_PARITY_NONE) + { + *hirda->pRxBuffPtr++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x00FF); + } + else + { + *hirda->pRxBuffPtr++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x007F); + } + } + + if(--hirda->RxXferCount == 0) + { + + __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE); + + if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) + { + hirda->State = HAL_IRDA_STATE_BUSY_TX; + } + else + { + /* Disable the IRDA Parity Error Interrupt */ + __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE); + + /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR); + + hirda->State = HAL_IRDA_STATE_READY; + } + HAL_IRDA_RxCpltCallback(hirda); + + return HAL_OK; + } + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Configures the IRDA peripheral. + * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains + * the configuration information for the specified IRDA module. + * @retval None + */ +static void IRDA_SetConfig(IRDA_HandleTypeDef *hirda) +{ + uint32_t tmpreg = 0x00; + + /* Check the parameters */ + assert_param(IS_IRDA_INSTANCE(hirda->Instance)); + assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate)); + assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength)); + assert_param(IS_IRDA_PARITY(hirda->Init.Parity)); + assert_param(IS_IRDA_MODE(hirda->Init.Mode)); + + /*-------------------------- IRDA CR2 Configuration ------------------------*/ + /* Clear STOP[13:12] bits */ + hirda->Instance->CR2 &= (uint32_t)~((uint32_t)USART_CR2_STOP); + + /*-------------------------- USART CR1 Configuration -----------------------*/ + tmpreg = hirda->Instance->CR1; + + /* Clear M, PCE, PS, TE and RE bits */ + tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \ + USART_CR1_RE)); + + /* Configure the USART Word Length, Parity and mode: + Set the M bits according to hirda->Init.WordLength value + Set PCE and PS bits according to hirda->Init.Parity value + Set TE and RE bits according to hirda->Init.Mode value */ + tmpreg |= (uint32_t)hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode; + + /* Write to USART CR1 */ + hirda->Instance->CR1 = (uint32_t)tmpreg; + + /*-------------------------- USART CR3 Configuration -----------------------*/ + /* Clear CTSE and RTSE bits */ + hirda->Instance->CR3 &= (uint32_t)~((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE)); + + /*-------------------------- USART BRR Configuration -----------------------*/ + if((hirda->Instance == USART1) || (hirda->Instance == USART6)) + { + hirda->Instance->BRR = IRDA_BRR(HAL_RCC_GetPCLK2Freq(), hirda->Init.BaudRate); + } + else + { + hirda->Instance->BRR = IRDA_BRR(HAL_RCC_GetPCLK1Freq(), hirda->Init.BaudRate); + } +} +/** + * @} + */ + +#endif /* HAL_IRDA_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c new file mode 100644 index 0000000..9ac08fb --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c @@ -0,0 +1,361 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_iwdg.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief IWDG HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Independent Watchdog (IWDG) peripheral: + * + Initialization and Configuration functions + * + IO operation functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### IWDG Specific features ##### + ============================================================================== + [..] + (+) The IWDG can be started by either software or hardware (configurable + through option byte). + + (+) The IWDG is clocked by its own dedicated Low-Speed clock (LSI) and + thus stays active even if the main clock fails. + Once the IWDG is started, the LSI is forced ON and cannot be disabled + (LSI cannot be disabled too), and the counter starts counting down from + the reset value of 0xFFF. When it reaches the end of count value (0x000) + a system reset is generated. + + (+) The IWDG counter should be refreshed at regular intervals, otherwise the + watchdog generates an MCU reset when the counter reaches 0. + + (+) The IWDG is implemented in the VDD voltage domain that is still functional + in STOP and STANDBY mode (IWDG reset can wake-up from STANDBY). + IWDGRST flag in RCC_CSR register can be used to inform when an IWDG + reset occurs. + + (+) Min-max timeout value @32KHz (LSI): ~125us / ~32.7s + The IWDG timeout may vary due to LSI frequency dispersion. STM32F4xx + devices provide the capability to measure the LSI frequency (LSI clock + connected internally to TIM5 CH4 input capture). The measured value + can be used to have an IWDG timeout with an acceptable accuracy. + + + ##### How to use this driver ##### + ============================================================================== + [..] + If Window option is disabled + (+) Use IWDG using HAL_IWDG_Init() function to : + (++) Enable write access to IWDG_PR, IWDG_RLR. + (++) Configure the IWDG prescaler, counter reload value. + This reload value will be loaded in the IWDG counter each time the counter + is reloaded, then the IWDG will start counting down from this value. + [..] + (+) Use IWDG using HAL_IWDG_Start() function to: + (++) Reload IWDG counter with value defined in the IWDG_RLR register. + (++) Start the IWDG, when the IWDG is used in software mode (no need + to enable the LSI, it will be enabled by hardware). + (+) Then the application program must refresh the IWDG counter at regular + intervals during normal operation to prevent an MCU reset, using + HAL_IWDG_Refresh() function. + [..] + if Window option is enabled: + + (+) Use IWDG using HAL_IWDG_Start() function to enable IWDG downcounter + (+) Use IWDG using HAL_IWDG_Init() function to : + (++) Enable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers. + (++) Configure the IWDG prescaler, reload value and window value. + (+) Then the application program must refresh the IWDG counter at regular + intervals during normal operation to prevent an MCU reset, using + HAL_IWDG_Refresh() function. + + *** IWDG HAL driver macros list *** + ==================================== + [..] + Below the list of most used macros in IWDG HAL driver. + + (+) __HAL_IWDG_START: Enable the IWDG peripheral + (+) __HAL_IWDG_RELOAD_COUNTER: Reloads IWDG counter with value defined in the reload register + (+) __HAL_IWDG_GET_FLAG: Get the selected IWDG's flag status + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 IWDG IWDG + * @brief IWDG HAL module driver. + * @{ + */ + +#ifdef HAL_IWDG_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + /** @addtogroup IWDG_Private_Constants + * @{ + */ +#define IWDG_TIMEOUT_FLAG ((uint32_t)1000) /* 1 s */ +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup IWDG_Exported_Functions IWDG Exported Functions + * @{ + */ + +/** @defgroup IWDG_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 IWDG according to the specified parameters + in the IWDG_InitTypeDef and create the associated handle + (+) Initialize the IWDG MSP + (+) DeInitialize IWDG MSP + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the IWDG according to the specified + * parameters in the IWDG_InitTypeDef and creates the associated handle. + * @param hiwdg: pointer to a IWDG_HandleTypeDef structure that contains + * the configuration information for the specified IWDG module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg) +{ + /* Check the IWDG handle allocation */ + if(hiwdg == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_IWDG_ALL_INSTANCE(hiwdg->Instance)); + assert_param(IS_IWDG_PRESCALER(hiwdg->Init.Prescaler)); + assert_param(IS_IWDG_RELOAD(hiwdg->Init.Reload)); + + if(hiwdg->State == HAL_IWDG_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hiwdg->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_IWDG_MspInit(hiwdg); + } + + /* Change IWDG peripheral state */ + hiwdg->State = HAL_IWDG_STATE_BUSY; + + /* Enable write access to IWDG_PR and IWDG_RLR registers */ + IWDG_ENABLE_WRITE_ACCESS(hiwdg); + + /* Write to IWDG registers the IWDG_Prescaler & IWDG_Reload values to work with */ + MODIFY_REG(hiwdg->Instance->PR, IWDG_PR_PR, hiwdg->Init.Prescaler); + MODIFY_REG(hiwdg->Instance->RLR, IWDG_RLR_RL, hiwdg->Init.Reload); + + /* Change IWDG peripheral state */ + hiwdg->State = HAL_IWDG_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the IWDG MSP. + * @param hiwdg: pointer to a IWDG_HandleTypeDef structure that contains + * the configuration information for the specified IWDG module. + * @retval None + */ +__weak void HAL_IWDG_MspInit(IWDG_HandleTypeDef *hiwdg) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_IWDG_MspInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup IWDG_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Start the IWDG. + (+) Refresh the IWDG. + +@endverbatim + * @{ + */ + +/** + * @brief Starts the IWDG. + * @param hiwdg: pointer to a IWDG_HandleTypeDef structure that contains + * the configuration information for the specified IWDG module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IWDG_Start(IWDG_HandleTypeDef *hiwdg) +{ + /* Process Locked */ + __HAL_LOCK(hiwdg); + + /* Change IWDG peripheral state */ + hiwdg->State = HAL_IWDG_STATE_BUSY; + + /* Start the IWDG peripheral */ + __HAL_IWDG_START(hiwdg); + + /* Reload IWDG counter with value defined in the RLR register */ + __HAL_IWDG_RELOAD_COUNTER(hiwdg); + + /* Change IWDG peripheral state */ + hiwdg->State = HAL_IWDG_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hiwdg); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Refreshes the IWDG. + * @param hiwdg: pointer to a IWDG_HandleTypeDef structure that contains + * the configuration information for the specified IWDG module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg) +{ + uint32_t tickstart = 0; + + /* Process Locked */ + __HAL_LOCK(hiwdg); + + /* Change IWDG peripheral state */ + hiwdg->State = HAL_IWDG_STATE_BUSY; + + tickstart = HAL_GetTick(); + + /* Wait until RVU flag is RESET */ + while(__HAL_IWDG_GET_FLAG(hiwdg, IWDG_FLAG_RVU) != RESET) + { + if((HAL_GetTick() - tickstart ) > IWDG_TIMEOUT_FLAG) + { + /* Set IWDG state */ + hiwdg->State = HAL_IWDG_STATE_TIMEOUT; + + /* Process unlocked */ + __HAL_UNLOCK(hiwdg); + + return HAL_TIMEOUT; + } + } + + /* Reload IWDG counter with value defined in the reload register */ + __HAL_IWDG_RELOAD_COUNTER(hiwdg); + + /* Change IWDG peripheral state */ + hiwdg->State = HAL_IWDG_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hiwdg); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup IWDG_Exported_Functions_Group3 Peripheral State functions + * @brief Peripheral State functions. + * +@verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the IWDG state. + * @param hiwdg: pointer to a IWDG_HandleTypeDef structure that contains + * the configuration information for the specified IWDG module. + * @retval HAL state + */ +HAL_IWDG_StateTypeDef HAL_IWDG_GetState(IWDG_HandleTypeDef *hiwdg) +{ + return hiwdg->State; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_IWDG_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_ltdc.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_ltdc.c new file mode 100644 index 0000000..596a896 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_ltdc.c @@ -0,0 +1,1191 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_ltdc.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief LTDC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the LTDC peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Errors functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Program the required configuration through the following parameters: + the LTDC timing, the horizontal and vertical polarity, + the pixel clock polarity, Data Enable polarity and the LTDC background color value + using HAL_LTDC_Init() function + + (#) Program the required configuration through the following parameters: + the pixel format, the blending factors, input alpha value, the window size + and the image size using HAL_LTDC_ConfigLayer() function for foreground + or/and background layer. + + (#) Optionally, configure and enable the CLUT using HAL_LTDC_ConfigCLUT() and + HAL_LTDC_EnableCLUT functions. + + (#) Optionally, enable the Dither using HAL_LTDC_EnableDither(). + + (#) Optionally, configure and enable the Color keying using HAL_LTDC_ConfigColorKeying() + and HAL_LTDC_EnableColorKeying functions. + + (#) Optionally, configure LineInterrupt using HAL_LTDC_ProgramLineEvent() + function + + (#) If needed, reconfigure and change the pixel format value, the alpha value + value, the window size, the window position and the layer start address + for foreground or/and background layer using respectively the following + functions: HAL_LTDC_SetPixelFormat(), HAL_LTDC_SetAlpha(), HAL_LTDC_SetWindowSize(), + HAL_LTDC_SetWindowPosition(), HAL_LTDC_SetAddress. + + (#) To control LTDC state you can use the following function: HAL_LTDC_GetState() + + *** LTDC HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in LTDC HAL driver. + + (+) __HAL_LTDC_ENABLE: Enable the LTDC. + (+) __HAL_LTDC_DISABLE: Disable the LTDC. + (+) __HAL_LTDC_LAYER_ENABLE: Enable the LTDC Layer. + (+) __HAL_LTDC_LAYER_DISABLE: Disable the LTDC Layer. + (+) __HAL_LTDC_RELOAD_CONFIG: Reload Layer Configuration. + (+) __HAL_LTDC_GET_FLAG: Get the LTDC pending flags. + (+) __HAL_LTDC_CLEAR_FLAG: Clear the LTDC pending flags. + (+) __HAL_LTDC_ENABLE_IT: Enable the specified LTDC interrupts. + (+) __HAL_LTDC_DISABLE_IT: Disable the specified LTDC interrupts. + (+) __HAL_LTDC_GET_IT_SOURCE: Check whether the specified LTDC interrupt has occurred or not. + + [..] + (@) You can refer to the LTDC HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 LTDC LTDC + * @brief LTDC HAL module driver + * @{ + */ + +#ifdef HAL_LTDC_MODULE_ENABLED + +#if defined(STM32F429xx) || defined(STM32F439xx) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static void LTDC_SetConfig(LTDC_HandleTypeDef *hltdc, LTDC_LayerCfgTypeDef *pLayerCfg, uint32_t LayerIdx); +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup LTDC_Exported_Functions LTDC Exported Functions + * @{ + */ + +/** @defgroup LTDC_Exported_Functions_Group1 Initialization and Configuration functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initialize and configure the LTDC + (+) De-initialize the LTDC + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the LTDC according to the specified + * parameters in the LTDC_InitTypeDef and create the associated handle. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_Init(LTDC_HandleTypeDef *hltdc) +{ + uint32_t tmp = 0, tmp1 = 0; + + /* Check the LTDC peripheral state */ + if(hltdc == NULL) + { + return HAL_ERROR; + } + + /* Check function parameters */ + assert_param(IS_LTDC_ALL_INSTANCE(hltdc->Instance)); + assert_param(IS_LTDC_HSYNC(hltdc->Init.HorizontalSync)); + assert_param(IS_LTDC_VSYNC(hltdc->Init.VerticalSync)); + assert_param(IS_LTDC_AHBP(hltdc->Init.AccumulatedHBP)); + assert_param(IS_LTDC_AVBP(hltdc->Init.AccumulatedVBP)); + assert_param(IS_LTDC_AAH(hltdc->Init.AccumulatedActiveH)); + assert_param(IS_LTDC_AAW(hltdc->Init.AccumulatedActiveW)); + assert_param(IS_LTDC_TOTALH(hltdc->Init.TotalHeigh)); + assert_param(IS_LTDC_TOTALW(hltdc->Init.TotalWidth)); + assert_param(IS_LTDC_HSPOL(hltdc->Init.HSPolarity)); + assert_param(IS_LTDC_VSPOL(hltdc->Init.VSPolarity)); + assert_param(IS_LTDC_DEPOL(hltdc->Init.DEPolarity)); + assert_param(IS_LTDC_PCPOL(hltdc->Init.PCPolarity)); + + if(hltdc->State == HAL_LTDC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hltdc->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_LTDC_MspInit(hltdc); + } + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Configures the HS, VS, DE and PC polarity */ + hltdc->Instance->GCR &= ~(LTDC_GCR_HSPOL | LTDC_GCR_VSPOL | LTDC_GCR_DEPOL | LTDC_GCR_PCPOL); + hltdc->Instance->GCR |= (uint32_t)(hltdc->Init.HSPolarity | hltdc->Init.VSPolarity | \ + hltdc->Init.DEPolarity | hltdc->Init.PCPolarity); + + /* Sets Synchronization size */ + hltdc->Instance->SSCR &= ~(LTDC_SSCR_VSH | LTDC_SSCR_HSW); + tmp = (hltdc->Init.HorizontalSync << 16); + hltdc->Instance->SSCR |= (tmp | hltdc->Init.VerticalSync); + + /* Sets Accumulated Back porch */ + hltdc->Instance->BPCR &= ~(LTDC_BPCR_AVBP | LTDC_BPCR_AHBP); + tmp = (hltdc->Init.AccumulatedHBP << 16); + hltdc->Instance->BPCR |= (tmp | hltdc->Init.AccumulatedVBP); + + /* Sets Accumulated Active Width */ + hltdc->Instance->AWCR &= ~(LTDC_AWCR_AAH | LTDC_AWCR_AAW); + tmp = (hltdc->Init.AccumulatedActiveW << 16); + hltdc->Instance->AWCR |= (tmp | hltdc->Init.AccumulatedActiveH); + + /* Sets Total Width */ + hltdc->Instance->TWCR &= ~(LTDC_TWCR_TOTALH | LTDC_TWCR_TOTALW); + tmp = (hltdc->Init.TotalWidth << 16); + hltdc->Instance->TWCR |= (tmp | hltdc->Init.TotalHeigh); + + /* Sets the background color value */ + tmp = ((uint32_t)(hltdc->Init.Backcolor.Green) << 8); + tmp1 = ((uint32_t)(hltdc->Init.Backcolor.Red) << 16); + hltdc->Instance->BCCR &= ~(LTDC_BCCR_BCBLUE | LTDC_BCCR_BCGREEN | LTDC_BCCR_BCRED); + hltdc->Instance->BCCR |= (tmp1 | tmp | hltdc->Init.Backcolor.Blue); + + /* Enable the transfer Error interrupt */ + __HAL_LTDC_ENABLE_IT(hltdc, LTDC_IT_TE); + + /* Enable the FIFO underrun interrupt */ + __HAL_LTDC_ENABLE_IT(hltdc, LTDC_IT_FU); + + /* Enable LTDC by setting LTDCEN bit */ + __HAL_LTDC_ENABLE(hltdc); + + /* Initialize the error code */ + hltdc->ErrorCode = HAL_LTDC_ERROR_NONE; + + /* Initialize the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Deinitializes the LTDC peripheral registers to their default reset + * values. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval None + */ + +HAL_StatusTypeDef HAL_LTDC_DeInit(LTDC_HandleTypeDef *hltdc) +{ + /* DeInit the low level hardware */ + HAL_LTDC_MspDeInit(hltdc); + + /* Initialize the error code */ + hltdc->ErrorCode = HAL_LTDC_ERROR_NONE; + + /* Initialize the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Initializes the LTDC MSP. + * @param hltdc : pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval None + */ +__weak void HAL_LTDC_MspInit(LTDC_HandleTypeDef* hltdc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_LTDC_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes the LTDC MSP. + * @param hltdc : pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval None + */ +__weak void HAL_LTDC_MspDeInit(LTDC_HandleTypeDef* hltdc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_LTDC_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup LTDC_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides function allowing to: + (+) Handle LTDC interrupt request + +@endverbatim + * @{ + */ +/** + * @brief Handles LTDC interrupt request. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval HAL status + */ +void HAL_LTDC_IRQHandler(LTDC_HandleTypeDef *hltdc) +{ + /* Transfer Error Interrupt management ***************************************/ + if(__HAL_LTDC_GET_FLAG(hltdc, LTDC_FLAG_TE) != RESET) + { + if(__HAL_LTDC_GET_IT_SOURCE(hltdc, LTDC_IT_TE) != RESET) + { + /* Disable the transfer Error interrupt */ + __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_TE); + + /* Clear the transfer error flag */ + __HAL_LTDC_CLEAR_FLAG(hltdc, LTDC_FLAG_TE); + + /* Update error code */ + hltdc->ErrorCode |= HAL_LTDC_ERROR_TE; + + /* Change LTDC state */ + hltdc->State = HAL_LTDC_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + /* Transfer error Callback */ + HAL_LTDC_ErrorCallback(hltdc); + } + } + /* FIFO underrun Interrupt management ***************************************/ + if(__HAL_LTDC_GET_FLAG(hltdc, LTDC_FLAG_FU) != RESET) + { + if(__HAL_LTDC_GET_IT_SOURCE(hltdc, LTDC_IT_FU) != RESET) + { + /* Disable the FIFO underrun interrupt */ + __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_FU); + + /* Clear the FIFO underrun flag */ + __HAL_LTDC_CLEAR_FLAG(hltdc, LTDC_FLAG_FU); + + /* Update error code */ + hltdc->ErrorCode |= HAL_LTDC_ERROR_FU; + + /* Change LTDC state */ + hltdc->State = HAL_LTDC_STATE_ERROR; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + /* Transfer error Callback */ + HAL_LTDC_ErrorCallback(hltdc); + } + } + /* Line Interrupt management ************************************************/ + if(__HAL_LTDC_GET_FLAG(hltdc, LTDC_FLAG_LI) != RESET) + { + if(__HAL_LTDC_GET_IT_SOURCE(hltdc, LTDC_IT_LI) != RESET) + { + /* Disable the Line interrupt */ + __HAL_LTDC_DISABLE_IT(hltdc, LTDC_IT_LI); + + /* Clear the Line interrupt flag */ + __HAL_LTDC_CLEAR_FLAG(hltdc, LTDC_FLAG_LI); + + /* Change LTDC state */ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + /* Line interrupt Callback */ + HAL_LTDC_LineEvenCallback(hltdc); + } + } +} + +/** + * @brief Error LTDC callback. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval None + */ +__weak void HAL_LTDC_ErrorCallback(LTDC_HandleTypeDef *hltdc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_LTDC_ErrorCallback could be implemented in the user file + */ +} + +/** + * @brief Line Event callback. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval None + */ +__weak void HAL_LTDC_LineEvenCallback(LTDC_HandleTypeDef *hltdc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_LTDC_LineEvenCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup LTDC_Exported_Functions_Group3 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure the LTDC foreground or/and background parameters. + (+) Set the active layer. + (+) Configure the color keying. + (+) Configure the C-LUT. + (+) Enable / Disable the color keying. + (+) Enable / Disable the C-LUT. + (+) Update the layer position. + (+) Update the layer size. + (+) Update pixel format on the fly. + (+) Update transparency on the fly. + (+) Update address on the fly. + +@endverbatim + * @{ + */ + +/** + * @brief Configure the LTDC Layer according to the specified + * parameters in the LTDC_InitTypeDef and create the associated handle. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param pLayerCfg: pointer to a LTDC_LayerCfgTypeDef structure that contains + * the configuration information for the Layer. + * @param LayerIdx: LTDC Layer index. + * This parameter can be one of the following values: + * 0 or 1 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_ConfigLayer(LTDC_HandleTypeDef *hltdc, LTDC_LayerCfgTypeDef *pLayerCfg, uint32_t LayerIdx) +{ + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + assert_param(IS_LTDC_PIXEL_FORMAT(pLayerCfg->PixelFormat)); + assert_param(IS_LTDC_BLENDING_FACTOR1(pLayerCfg->BlendingFactor1)); + assert_param(IS_LTDC_BLENDING_FACTOR2(pLayerCfg->BlendingFactor2)); + assert_param(IS_LTDC_HCONFIGST(pLayerCfg->WindowX0)); + assert_param(IS_LTDC_HCONFIGSP(pLayerCfg->WindowX1)); + assert_param(IS_LTDC_VCONFIGST(pLayerCfg->WindowY0)); + assert_param(IS_LTDC_VCONFIGSP(pLayerCfg->WindowY1)); + assert_param(IS_LTDC_ALPHA(pLayerCfg->Alpha0)); + assert_param(IS_LTDC_CFBLL(pLayerCfg->ImageWidth)); + assert_param(IS_LTDC_CFBLNBR(pLayerCfg->ImageHeight)); + + /* Copy new layer configuration into handle structure */ + hltdc->LayerCfg[LayerIdx] = *pLayerCfg; + + /* Configure the LTDC Layer */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Sets the Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Initialize the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Configure the color keying. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param RGBValue: the color key value + * @param LayerIdx: LTDC Layer index. + * This parameter can be one of the following values: + * 0 or 1 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_ConfigColorKeying(LTDC_HandleTypeDef *hltdc, uint32_t RGBValue, uint32_t LayerIdx) +{ + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Configures the default color values */ + LTDC_LAYER(hltdc, LayerIdx)->CKCR &= ~(LTDC_LxCKCR_CKBLUE | LTDC_LxCKCR_CKGREEN | LTDC_LxCKCR_CKRED); + LTDC_LAYER(hltdc, LayerIdx)->CKCR = RGBValue; + + /* Sets the Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Load the color lookup table. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param pCLUT: pointer to the color lookup table address. + * @param CLUTSize: the color lookup table size. + * @param LayerIdx: LTDC Layer index. + * This parameter can be one of the following values: + * 0 or 1 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_ConfigCLUT(LTDC_HandleTypeDef *hltdc, uint32_t *pCLUT, uint32_t CLUTSize, uint32_t LayerIdx) +{ + uint32_t tmp = 0; + uint32_t counter = 0; + uint32_t pcounter = 0; + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + for(counter = 0; (counter < CLUTSize); counter++) + { + if(hltdc->LayerCfg[LayerIdx].PixelFormat == LTDC_PIXEL_FORMAT_AL44) + { + tmp = (((counter + 16*counter) << 24) | ((uint32_t)(*pCLUT) & 0xFF) | ((uint32_t)(*pCLUT) & 0xFF00) | ((uint32_t)(*pCLUT) & 0xFF0000)); + } + else + { + tmp = ((counter << 24) | ((uint32_t)(*pCLUT) & 0xFF) | ((uint32_t)(*pCLUT) & 0xFF00) | ((uint32_t)(*pCLUT) & 0xFF0000)); + } + pcounter = (uint32_t)pCLUT + sizeof(*pCLUT); + pCLUT = (uint32_t *)pcounter; + + /* Specifies the C-LUT address and RGB value */ + LTDC_LAYER(hltdc, LayerIdx)->CLUTWR = tmp; + } + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Enable the color keying. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param LayerIdx: LTDC Layer index. + * This parameter can be one of the following values: + * 0 or 1 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_EnableColorKeying(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx) +{ + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Enable LTDC color keying by setting COLKEN bit */ + LTDC_LAYER(hltdc, LayerIdx)->CR |= (uint32_t)LTDC_LxCR_COLKEN; + + /* Sets the Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Disable the color keying. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param LayerIdx: LTDC Layer index. + * This parameter can be one of the following values: + * 0 or 1 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_DisableColorKeying(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx) +{ + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Disable LTDC color keying by setting COLKEN bit */ + LTDC_LAYER(hltdc, LayerIdx)->CR &= ~(uint32_t)LTDC_LxCR_COLKEN; + + /* Sets the Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Enable the color lookup table. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param LayerIdx: LTDC Layer index. + * This parameter can be one of the following values: + * 0 or 1 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_EnableCLUT(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx) +{ + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Disable LTDC color lookup table by setting CLUTEN bit */ + LTDC_LAYER(hltdc, LayerIdx)->CR |= (uint32_t)LTDC_LxCR_CLUTEN; + + /* Sets the Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Disable the color lookup table. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param LayerIdx: LTDC Layer index. + * This parameter can be one of the following values: + * 0 or 1 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_DisableCLUT(LTDC_HandleTypeDef *hltdc, uint32_t LayerIdx) +{ + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Disable LTDC color lookup table by setting CLUTEN bit */ + LTDC_LAYER(hltdc, LayerIdx)->CR &= ~(uint32_t)LTDC_LxCR_CLUTEN; + + /* Sets the Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Enables Dither. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_LTDC_EnableDither(LTDC_HandleTypeDef *hltdc) +{ + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Enable Dither by setting DTEN bit */ + LTDC->GCR |= (uint32_t)LTDC_GCR_DTEN; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Disables Dither. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_LTDC_DisableDither(LTDC_HandleTypeDef *hltdc) +{ + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Disable Dither by setting DTEN bit */ + LTDC->GCR &= ~(uint32_t)LTDC_GCR_DTEN; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Set the LTDC window size. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param XSize: LTDC Pixel per line + * @param YSize: LTDC Line number + * @param LayerIdx: LTDC Layer index. + * This parameter can be one of the following values: + * 0 or 1 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetWindowSize(LTDC_HandleTypeDef *hltdc, uint32_t XSize, uint32_t YSize, uint32_t LayerIdx) +{ + LTDC_LayerCfgTypeDef *pLayerCfg; + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Get layer configuration from handle structure */ + pLayerCfg = &hltdc->LayerCfg[LayerIdx]; + + /* Check the parameters (Layers parameters)*/ + assert_param(IS_LTDC_LAYER(LayerIdx)); + assert_param(IS_LTDC_HCONFIGST(pLayerCfg->WindowX0)); + assert_param(IS_LTDC_HCONFIGSP(pLayerCfg->WindowX1)); + assert_param(IS_LTDC_VCONFIGST(pLayerCfg->WindowY0)); + assert_param(IS_LTDC_VCONFIGSP(pLayerCfg->WindowY1)); + assert_param(IS_LTDC_CFBLL(XSize)); + assert_param(IS_LTDC_CFBLNBR(YSize)); + + /* update horizontal start/stop */ + pLayerCfg->WindowX0 = 0; + pLayerCfg->WindowX1 = XSize + pLayerCfg->WindowX0; + + /* update vertical start/stop */ + pLayerCfg->WindowY0 = 0; + pLayerCfg->WindowY1 = YSize + pLayerCfg->WindowY0; + + /* Reconfigures the color frame buffer pitch in byte */ + pLayerCfg->ImageWidth = XSize; + + /* Reconfigures the frame buffer line number */ + pLayerCfg->ImageHeight = YSize; + + /* Set LTDC parameters */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Sets the Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Set the LTDC window position. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param X0: LTDC window X offset + * @param Y0: LTDC window Y offset + * @param LayerIdx: LTDC Layer index. + * This parameter can be one of the following values: + * 0 or 1 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetWindowPosition(LTDC_HandleTypeDef *hltdc, uint32_t X0, uint32_t Y0, uint32_t LayerIdx) +{ + LTDC_LayerCfgTypeDef *pLayerCfg; + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Get layer configuration from handle structure */ + pLayerCfg = &hltdc->LayerCfg[LayerIdx]; + + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + assert_param(IS_LTDC_HCONFIGST(pLayerCfg->WindowX0)); + assert_param(IS_LTDC_HCONFIGSP(pLayerCfg->WindowX1)); + assert_param(IS_LTDC_VCONFIGST(pLayerCfg->WindowY0)); + assert_param(IS_LTDC_VCONFIGSP(pLayerCfg->WindowY1)); + + /* update horizontal start/stop */ + pLayerCfg->WindowX0 = X0; + pLayerCfg->WindowX1 = X0 + pLayerCfg->ImageWidth; + + /* update vertical start/stop */ + pLayerCfg->WindowY0 = Y0; + pLayerCfg->WindowY1 = Y0 + pLayerCfg->ImageHeight; + + /* Set LTDC parameters */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Sets the Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Reconfigure the pixel format. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param Pixelformat: new pixel format value. + * @param LayerIdx: LTDC Layer index. + * This parameter can be one of the following values: + * 0 or 1. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetPixelFormat(LTDC_HandleTypeDef *hltdc, uint32_t Pixelformat, uint32_t LayerIdx) +{ + LTDC_LayerCfgTypeDef *pLayerCfg; + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + assert_param(IS_LTDC_PIXEL_FORMAT(Pixelformat)); + + /* Get layer configuration from handle structure */ + pLayerCfg = &hltdc->LayerCfg[LayerIdx]; + + /* Reconfigure the pixel format */ + pLayerCfg->PixelFormat = Pixelformat; + + /* Set LTDC parameters */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Sets the Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Reconfigure the layer alpha value. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param Alpha: new alpha value. + * @param LayerIdx: LTDC Layer index. + * This parameter can be one of the following values: + * 0 or 1 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetAlpha(LTDC_HandleTypeDef *hltdc, uint32_t Alpha, uint32_t LayerIdx) +{ + LTDC_LayerCfgTypeDef *pLayerCfg; + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_LTDC_ALPHA(Alpha)); + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Get layer configuration from handle structure */ + pLayerCfg = &hltdc->LayerCfg[LayerIdx]; + + /* Reconfigure the Alpha value */ + pLayerCfg->Alpha = Alpha; + + /* Set LTDC parameters */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Sets the Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} +/** + * @brief Reconfigure the frame buffer Address. + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param Address: new address value. + * @param LayerIdx: LTDC Layer index. + * This parameter can be one of the following values: + * 0 or 1. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_SetAddress(LTDC_HandleTypeDef *hltdc, uint32_t Address, uint32_t LayerIdx) +{ + LTDC_LayerCfgTypeDef *pLayerCfg; + + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_LTDC_LAYER(LayerIdx)); + + /* Get layer configuration from handle structure */ + pLayerCfg = &hltdc->LayerCfg[LayerIdx]; + + /* Reconfigure the Address */ + pLayerCfg->FBStartAdress = Address; + + /* Set LTDC parameters */ + LTDC_SetConfig(hltdc, pLayerCfg, LayerIdx); + + /* Sets the Reload type */ + hltdc->Instance->SRCR = LTDC_SRCR_IMR; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @brief Define the position of the line interrupt . + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param Line: Line Interrupt Position. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LTDC_ProgramLineEvent(LTDC_HandleTypeDef *hltdc, uint32_t Line) +{ + /* Process locked */ + __HAL_LOCK(hltdc); + + /* Change LTDC peripheral state */ + hltdc->State = HAL_LTDC_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_LTDC_LIPOS(Line)); + + /* Enable the Line interrupt */ + __HAL_LTDC_ENABLE_IT(hltdc, LTDC_IT_LI); + + /* Sets the Line Interrupt position */ + LTDC->LIPCR = (uint32_t)Line; + + /* Change the LTDC state*/ + hltdc->State = HAL_LTDC_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hltdc); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup LTDC_Exported_Functions_Group4 Peripheral State and Errors functions + * @brief Peripheral State and Errors functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to + (+) Check the LTDC state. + (+) Get error code. + +@endverbatim + * @{ + */ + +/** + * @brief Return the LTDC state + * @param hltdc: pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @retval HAL state + */ +HAL_LTDC_StateTypeDef HAL_LTDC_GetState(LTDC_HandleTypeDef *hltdc) +{ + return hltdc->State; +} + +/** +* @brief Return the LTDC error code +* @param hltdc : pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. +* @retval LTDC Error Code +*/ +uint32_t HAL_LTDC_GetError(LTDC_HandleTypeDef *hltdc) +{ + return hltdc->ErrorCode; +} + +/** + * @} + */ + +/** + * @brief Configures the LTDC peripheral + * @param hltdc : Pointer to a LTDC_HandleTypeDef structure that contains + * the configuration information for the LTDC. + * @param pLayerCfg: Pointer LTDC Layer Configuration structure + * @param LayerIdx: LTDC Layer index. + * This parameter can be one of the following values: 0 or 1 + * @retval None + */ +static void LTDC_SetConfig(LTDC_HandleTypeDef *hltdc, LTDC_LayerCfgTypeDef *pLayerCfg, uint32_t LayerIdx) +{ + uint32_t tmp = 0; + uint32_t tmp1 = 0; + uint32_t tmp2 = 0; + + /* Configures the horizontal start and stop position */ + tmp = ((pLayerCfg->WindowX1 + ((hltdc->Instance->BPCR & LTDC_BPCR_AHBP) >> 16)) << 16); + LTDC_LAYER(hltdc, LayerIdx)->WHPCR &= ~(LTDC_LxWHPCR_WHSTPOS | LTDC_LxWHPCR_WHSPPOS); + LTDC_LAYER(hltdc, LayerIdx)->WHPCR = ((pLayerCfg->WindowX0 + ((hltdc->Instance->BPCR & LTDC_BPCR_AHBP) >> 16) + 1) | tmp); + + /* Configures the vertical start and stop position */ + tmp = ((pLayerCfg->WindowY1 + (hltdc->Instance->BPCR & LTDC_BPCR_AVBP)) << 16); + LTDC_LAYER(hltdc, LayerIdx)->WVPCR &= ~(LTDC_LxWVPCR_WVSTPOS | LTDC_LxWVPCR_WVSPPOS); + LTDC_LAYER(hltdc, LayerIdx)->WVPCR = ((pLayerCfg->WindowY0 + (hltdc->Instance->BPCR & LTDC_BPCR_AVBP) + 1) | tmp); + + /* Specifies the pixel format */ + LTDC_LAYER(hltdc, LayerIdx)->PFCR &= ~(LTDC_LxPFCR_PF); + LTDC_LAYER(hltdc, LayerIdx)->PFCR = (pLayerCfg->PixelFormat); + + /* Configures the default color values */ + tmp = ((uint32_t)(pLayerCfg->Backcolor.Green) << 8); + tmp1 = ((uint32_t)(pLayerCfg->Backcolor.Red) << 16); + tmp2 = (pLayerCfg->Alpha0 << 24); + LTDC_LAYER(hltdc, LayerIdx)->DCCR &= ~(LTDC_LxDCCR_DCBLUE | LTDC_LxDCCR_DCGREEN | LTDC_LxDCCR_DCRED | LTDC_LxDCCR_DCALPHA); + LTDC_LAYER(hltdc, LayerIdx)->DCCR = (pLayerCfg->Backcolor.Blue | tmp | tmp1 | tmp2); + + /* Specifies the constant alpha value */ + LTDC_LAYER(hltdc, LayerIdx)->CACR &= ~(LTDC_LxCACR_CONSTA); + LTDC_LAYER(hltdc, LayerIdx)->CACR = (pLayerCfg->Alpha); + + /* Specifies the blending factors */ + LTDC_LAYER(hltdc, LayerIdx)->BFCR &= ~(LTDC_LxBFCR_BF2 | LTDC_LxBFCR_BF1); + LTDC_LAYER(hltdc, LayerIdx)->BFCR = (pLayerCfg->BlendingFactor1 | pLayerCfg->BlendingFactor2); + + /* Configures the color frame buffer start address */ + LTDC_LAYER(hltdc, LayerIdx)->CFBAR &= ~(LTDC_LxCFBAR_CFBADD); + LTDC_LAYER(hltdc, LayerIdx)->CFBAR = (pLayerCfg->FBStartAdress); + + if(pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_ARGB8888) + { + tmp = 4; + } + else if (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_RGB888) + { + tmp = 3; + } + else if((pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_ARGB4444) || \ + (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_RGB565) || \ + (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_ARGB1555) || \ + (pLayerCfg->PixelFormat == LTDC_PIXEL_FORMAT_AL88)) + { + tmp = 2; + } + else + { + tmp = 1; + } + + /* Configures the color frame buffer pitch in byte */ + LTDC_LAYER(hltdc, LayerIdx)->CFBLR &= ~(LTDC_LxCFBLR_CFBLL | LTDC_LxCFBLR_CFBP); + LTDC_LAYER(hltdc, LayerIdx)->CFBLR = (((pLayerCfg->ImageWidth * tmp) << 16) | (((pLayerCfg->WindowX1 - pLayerCfg->WindowX0) * tmp) + 3)); + + /* Configures the frame buffer line number */ + LTDC_LAYER(hltdc, LayerIdx)->CFBLNR &= ~(LTDC_LxCFBLNR_CFBLNBR); + LTDC_LAYER(hltdc, LayerIdx)->CFBLNR = (pLayerCfg->ImageHeight); + + /* Enable LTDC_Layer by setting LEN bit */ + LTDC_LAYER(hltdc, LayerIdx)->CR |= (uint32_t)LTDC_LxCR_LEN; +} + +/** + * @} + */ +#endif /* STM32F429xx || STM32F439xx */ +#endif /* HAL_LTDC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_msp_template.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_msp_template.c new file mode 100644 index 0000000..fa3cfbc --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_msp_template.c @@ -0,0 +1,119 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_msp_template.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief This file contains the HAL System and Peripheral (PPP) MSP initialization + * and de-initialization functions. + * It should be copied to the application folder and renamed into 'stm32f4xx_hal_msp.c'. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 HAL_MSP HAL MSP + * @brief HAL MSP module. + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup HAL_MSP_Private_Functions HAL MSP Private Functions + * @{ + */ + +/** + * @brief Initializes the Global MSP. + * @note This function is called from HAL_Init() function to perform system + * level initialization (GPIOs, clock, DMA, interrupt). + * @retval None + */ +void HAL_MspInit(void) +{ + +} + +/** + * @brief DeInitializes the Global MSP. + * @note This functiona is called from HAL_DeInit() function to perform system + * level de-initialization (GPIOs, clock, DMA, interrupt). + * @retval None + */ +void HAL_MspDeInit(void) +{ + +} + +/** + * @brief Initializes the PPP MSP. + * @note This functiona is called from HAL_PPP_Init() function to perform + * peripheral(PPP) system level initialization (GPIOs, clock, DMA, interrupt) + * @retval None + */ +void HAL_PPP_MspInit(void) +{ + +} + +/** + * @brief DeInitializes the PPP MSP. + * @note This functiona is called from HAL_PPP_DeInit() function to perform + * peripheral(PPP) system level de-initialization (GPIOs, clock, DMA, interrupt) + * @retval None + */ +void HAL_PPP_MspDeInit(void) +{ + +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c new file mode 100644 index 0000000..0a78d6a --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c @@ -0,0 +1,1125 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_nand.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief NAND HAL module driver. + * This file provides a generic firmware to drive NAND memories mounted + * as external device. + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + This driver is a generic layered driver which contains a set of APIs used to + control NAND flash memories. It uses the FMC/FSMC layer functions to interface + with NAND devices. This driver is used as follows: + + (+) NAND flash memory configuration sequence using the function HAL_NAND_Init() + with control and timing parameters for both common and attribute spaces. + + (+) Read NAND flash memory maker and device IDs using the function + HAL_NAND_Read_ID(). The read information is stored in the NAND_ID_TypeDef + structure declared by the function caller. + + (+) Access NAND flash memory by read/write operations using the functions + HAL_NAND_Read_Page()/HAL_NAND_Read_SpareArea(), HAL_NAND_Write_Page()/HAL_NAND_Write_SpareArea() + to read/write page(s)/spare area(s). These functions use specific device + information (Block, page size..) predefined by the user in the HAL_NAND_Info_TypeDef + structure. The read/write address information is contained by the Nand_Address_Typedef + structure passed as parameter. + + (+) Perform NAND flash Reset chip operation using the function HAL_NAND_Reset(). + + (+) Perform NAND flash erase block operation using the function HAL_NAND_Erase_Block(). + The erase block address information is contained in the Nand_Address_Typedef + structure passed as parameter. + + (+) Read the NAND flash status operation using the function HAL_NAND_Read_Status(). + + (+) You can also control the NAND device by calling the control APIs HAL_NAND_ECC_Enable()/ + HAL_NAND_ECC_Disable() to respectively enable/disable the ECC code correction + feature or the function HAL_NAND_GetECC() to get the ECC correction code. + + (+) You can monitor the NAND device HAL state by calling the function + HAL_NAND_GetState() + + [..] + (@) This driver is a set of generic APIs which handle standard NAND flash operations. + If a NAND flash device contains different operations and/or implementations, + it should be implemented separately. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 + * @{ + */ + + +#ifdef HAL_NAND_MODULE_ENABLED + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F446xx) + +/** @defgroup NAND NAND + * @brief NAND HAL module driver + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup NAND_Private_Constants NAND Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup NAND_Private_Macros NAND Private Macros + * @{ + */ + +/** + * @} + */ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup NAND_Exported_Functions NAND Exported Functions + * @{ + */ + +/** @defgroup NAND_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * + @verbatim + ============================================================================== + ##### NAND Initialization and de-initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to initialize/de-initialize + the NAND memory + +@endverbatim + * @{ + */ + +/** + * @brief Perform NAND memory Initialization sequence + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param ComSpace_Timing: pointer to Common space timing structure + * @param AttSpace_Timing: pointer to Attribute space timing structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing) +{ + /* Check the NAND handle state */ + if(hnand == NULL) + { + return HAL_ERROR; + } + + if(hnand->State == HAL_NAND_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hnand->Lock = HAL_UNLOCKED; + /* Initialize the low level hardware (MSP) */ + HAL_NAND_MspInit(hnand); + } + + /* Initialize NAND control Interface */ + FMC_NAND_Init(hnand->Instance, &(hnand->Init)); + + /* Initialize NAND common space timing Interface */ + FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank); + + /* Initialize NAND attribute space timing Interface */ + FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank); + + /* Enable the NAND device */ + __FMC_NAND_ENABLE(hnand->Instance, hnand->Init.NandBank); + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Perform NAND memory De-Initialization sequence + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand) +{ + /* Initialize the low level hardware (MSP) */ + HAL_NAND_MspDeInit(hnand); + + /* Configure the NAND registers with their reset values */ + FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank); + + /* Reset the NAND controller state */ + hnand->State = HAL_NAND_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hnand); + + return HAL_OK; +} + +/** + * @brief NAND MSP Init + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval None + */ +__weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_NAND_MspInit could be implemented in the user file + */ +} + +/** + * @brief NAND MSP DeInit + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval None + */ +__weak void HAL_NAND_MspDeInit(NAND_HandleTypeDef *hnand) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_NAND_MspDeInit could be implemented in the user file + */ +} + + +/** + * @brief This function handles NAND device interrupt request. + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval HAL status +*/ +void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand) +{ + /* Check NAND interrupt Rising edge flag */ + if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE)) + { + /* NAND interrupt callback*/ + HAL_NAND_ITCallback(hnand); + + /* Clear NAND interrupt Rising edge pending bit */ + __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE); + } + + /* Check NAND interrupt Level flag */ + if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL)) + { + /* NAND interrupt callback*/ + HAL_NAND_ITCallback(hnand); + + /* Clear NAND interrupt Level pending bit */ + __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL); + } + + /* Check NAND interrupt Falling edge flag */ + if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE)) + { + /* NAND interrupt callback*/ + HAL_NAND_ITCallback(hnand); + + /* Clear NAND interrupt Falling edge pending bit */ + __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE); + } + + /* Check NAND interrupt FIFO empty flag */ + if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT)) + { + /* NAND interrupt callback*/ + HAL_NAND_ITCallback(hnand); + + /* Clear NAND interrupt FIFO empty pending bit */ + __FMC_NAND_CLEAR_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT); + } + +} + +/** + * @brief NAND interrupt feature callback + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval None + */ +__weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_NAND_ITCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup NAND_Exported_Functions_Group2 Input and Output functions + * @brief Input Output and memory control functions + * + @verbatim + ============================================================================== + ##### NAND Input and Output functions ##### + ============================================================================== + [..] + This section provides functions allowing to use and control the NAND + memory + +@endverbatim + * @{ + */ + +/** + * @brief Read the NAND memory electronic signature + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pNAND_ID: NAND ID structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID) +{ + __IO uint32_t data = 0; + uint32_t deviceaddress = 0; + + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Check the NAND controller state */ + if(hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Identify the device address */ + if(hnand->Init.NandBank == FMC_NAND_BANK2) + { + deviceaddress = NAND_DEVICE1; + } + else + { + deviceaddress = NAND_DEVICE2; + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Send Read ID command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_READID; + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00; + + /* Read the electronic signature from NAND flash */ + data = *(__IO uint32_t *)deviceaddress; + + /* Return the data read */ + pNAND_ID->Maker_Id = ADDR_1ST_CYCLE(data); + pNAND_ID->Device_Id = ADDR_2ND_CYCLE(data); + pNAND_ID->Third_Id = ADDR_3RD_CYCLE(data); + pNAND_ID->Fourth_Id = ADDR_4TH_CYCLE(data); + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + + return HAL_OK; +} + +/** + * @brief NAND memory reset + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand) +{ + uint32_t deviceaddress = 0; + + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Check the NAND controller state */ + if(hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Identify the device address */ + if(hnand->Init.NandBank == FMC_NAND_BANK2) + { + deviceaddress = NAND_DEVICE1; + } + else + { + deviceaddress = NAND_DEVICE2; + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Send NAND reset command */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = 0xFF; + + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + + return HAL_OK; + +} + +/** + * @brief Read Page(s) from NAND memory block + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pAddress : pointer to NAND address structure + * @param pBuffer : pointer to destination read buffer + * @param NumPageToRead : number of pages to read from block + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Read_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead) +{ + __IO uint32_t index = 0; + uint32_t deviceaddress = 0, size = 0, numpagesread = 0, addressstatus = NAND_VALID_ADDRESS; + NAND_AddressTypeDef nandaddress; + uint32_t addressoffset = 0; + + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Check the NAND controller state */ + if(hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Identify the device address */ + if(hnand->Init.NandBank == FMC_NAND_BANK2) + { + deviceaddress = NAND_DEVICE1; + } + else + { + deviceaddress = NAND_DEVICE2; + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Save the content of pAddress as it will be modified */ + nandaddress.Block = pAddress->Block; + nandaddress.Page = pAddress->Page; + nandaddress.Zone = pAddress->Zone; + + /* Page(s) read loop */ + while((NumPageToRead != 0) && (addressstatus == NAND_VALID_ADDRESS)) + { + /* update the buffer size */ + size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpagesread); + + /* Get the address offset */ + addressoffset = ARRAY_ADDRESS(&nandaddress, hnand); + + /* Send read page command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; + + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00; + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset); + + /* for 512 and 1 GB devices, 4th cycle is required */ + if(hnand->Info.BlockNbr >= 1024) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset); + } + + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1; + + /* Get Data into Buffer */ + for(index = size; index != 0; index--) + { + *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress; + } + + /* Increment read pages number */ + numpagesread++; + + /* Decrement pages to read */ + NumPageToRead--; + + /* Increment the NAND address */ + addressstatus = HAL_NAND_Address_Inc(hnand, &nandaddress); + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + + return HAL_OK; + +} + +/** + * @brief Write Page(s) to NAND memory block + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pAddress : pointer to NAND address structure + * @param pBuffer : pointer to source buffer to write + * @param NumPageToWrite : number of pages to write to block + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Write_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite) +{ + __IO uint32_t index = 0; + uint32_t tickstart = 0; + uint32_t deviceaddress = 0 , size = 0, numpageswritten = 0, addressstatus = NAND_VALID_ADDRESS; + NAND_AddressTypeDef nandaddress; + uint32_t addressoffset = 0; + + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Check the NAND controller state */ + if(hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Identify the device address */ + if(hnand->Init.NandBank == FMC_NAND_BANK2) + { + deviceaddress = NAND_DEVICE1; + } + else + { + deviceaddress = NAND_DEVICE2; + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Save the content of pAddress as it will be modified */ + nandaddress.Block = pAddress->Block; + nandaddress.Page = pAddress->Page; + nandaddress.Zone = pAddress->Zone; + + /* Page(s) write loop */ + while((NumPageToWrite != 0) && (addressstatus == NAND_VALID_ADDRESS)) + { + /* update the buffer size */ + size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpageswritten); + + /* Get the address offset */ + addressoffset = ARRAY_ADDRESS(&nandaddress, hnand); + + /* Send write page command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0; + + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00; + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset); + + /* for 512 and 1 GB devices, 4th cycle is required */ + if(hnand->Info.BlockNbr >= 1024) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset); + } + + /* Write data to memory */ + for(index = size; index != 0; index--) + { + *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++; + } + + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Read status until NAND is ready */ + while(HAL_NAND_Read_Status(hnand) != NAND_READY) + { + if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT) + { + return HAL_TIMEOUT; + } + } + + /* Increment written pages number */ + numpageswritten++; + + /* Decrement pages to write */ + NumPageToWrite--; + + /* Increment the NAND address */ + addressstatus = HAL_NAND_Address_Inc(hnand, &nandaddress); + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + + return HAL_OK; +} + +/** + * @brief Read Spare area(s) from NAND memory + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pAddress : pointer to NAND address structure + * @param pBuffer: pointer to source buffer to write + * @param NumSpareAreaToRead: Number of spare area to read + * @retval HAL status +*/ +HAL_StatusTypeDef HAL_NAND_Read_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaToRead) +{ + __IO uint32_t index = 0; + uint32_t deviceaddress = 0, size = 0, num_spare_area_read = 0, addressstatus = NAND_VALID_ADDRESS; + NAND_AddressTypeDef nandaddress; + uint32_t addressoffset = 0; + + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Check the NAND controller state */ + if(hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Identify the device address */ + if(hnand->Init.NandBank == FMC_NAND_BANK2) + { + deviceaddress = NAND_DEVICE1; + } + else + { + deviceaddress = NAND_DEVICE2; + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Save the content of pAddress as it will be modified */ + nandaddress.Block = pAddress->Block; + nandaddress.Page = pAddress->Page; + nandaddress.Zone = pAddress->Zone; + + /* Spare area(s) read loop */ + while((NumSpareAreaToRead != 0) && (addressstatus == NAND_VALID_ADDRESS)) + { + /* update the buffer size */ + size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * num_spare_area_read); + + /* Get the address offset */ + addressoffset = ARRAY_ADDRESS(&nandaddress, hnand); + + /* Send read spare area command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C; + + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00; + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset); + + /* for 512 and 1 GB devices, 4th cycle is required */ + if(hnand->Info.BlockNbr >= 1024) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset); + } + + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1; + + /* Get Data into Buffer */ + for (index = size ;index != 0; index--) + { + *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress; + } + + /* Increment read spare areas number */ + num_spare_area_read++; + + /* Decrement spare areas to read */ + NumSpareAreaToRead--; + + /* Increment the NAND address */ + addressstatus = HAL_NAND_Address_Inc(hnand, &nandaddress); + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + + return HAL_OK; +} + +/** + * @brief Write Spare area(s) to NAND memory + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pAddress : pointer to NAND address structure + * @param pBuffer : pointer to source buffer to write + * @param NumSpareAreaTowrite : number of spare areas to write to block + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Write_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite) +{ + __IO uint32_t index = 0; + uint32_t tickstart = 0; + uint32_t deviceaddress = 0, size = 0, num_spare_area_written = 0, addressstatus = NAND_VALID_ADDRESS; + NAND_AddressTypeDef nandaddress; + uint32_t addressoffset = 0; + + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Check the NAND controller state */ + if(hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Identify the device address */ + if(hnand->Init.NandBank == FMC_NAND_BANK2) + { + deviceaddress = NAND_DEVICE1; + } + else + { + deviceaddress = NAND_DEVICE2; + } + + /* Update the FMC_NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Save the content of pAddress as it will be modified */ + nandaddress.Block = pAddress->Block; + nandaddress.Page = pAddress->Page; + nandaddress.Zone = pAddress->Zone; + + /* Spare area(s) write loop */ + while((NumSpareAreaTowrite != 0) && (addressstatus == NAND_VALID_ADDRESS)) + { + /* update the buffer size */ + size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * num_spare_area_written); + + /* Get the address offset */ + addressoffset = ARRAY_ADDRESS(&nandaddress, hnand); + + /* Send write Spare area command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C; + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0; + + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00; + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset); + + /* for 512 and 1 GB devices, 4th cycle is required */ + if(hnand->Info.BlockNbr >= 1024) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset); + } + + /* Write data to memory */ + for(; index < size; index++) + { + *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++; + } + + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Read status until NAND is ready */ + while(HAL_NAND_Read_Status(hnand) != NAND_READY) + { + if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT) + { + return HAL_TIMEOUT; + } + } + + /* Increment written spare areas number */ + num_spare_area_written++; + + /* Decrement spare areas to write */ + NumSpareAreaTowrite--; + + /* Increment the NAND address */ + addressstatus = HAL_NAND_Address_Inc(hnand, &nandaddress); + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + + return HAL_OK; +} + +/** + * @brief NAND memory Block erase + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pAddress : pointer to NAND address structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress) +{ + uint32_t deviceaddress = 0; + uint32_t tickstart = 0; + + /* Process Locked */ + __HAL_LOCK(hnand); + + /* Check the NAND controller state */ + if(hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Identify the device address */ + if(hnand->Init.NandBank == FMC_NAND_BANK2) + { + deviceaddress = NAND_DEVICE1; + } + else + { + deviceaddress = NAND_DEVICE2; + } + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Send Erase block command sequence */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0; + + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); + + /* for 512 and 1 GB devices, 4th cycle is required */ + if(hnand->Info.BlockNbr >= 1024) + { + *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); + } + + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1; + + /* Update the NAND controller state */ + hnand->State = HAL_NAND_STATE_READY; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Read status until NAND is ready */ + while(HAL_NAND_Read_Status(hnand) != NAND_READY) + { + if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT) + { + /* Process unlocked */ + __HAL_UNLOCK(hnand); + + return HAL_TIMEOUT; + } + } + + /* Process unlocked */ + __HAL_UNLOCK(hnand); + + return HAL_OK; +} + +/** + * @brief NAND memory read status + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval NAND status + */ +uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand) +{ + uint32_t data = 0; + uint32_t deviceaddress = 0; + + /* Identify the device address */ + if(hnand->Init.NandBank == FMC_NAND_BANK2) + { + deviceaddress = NAND_DEVICE1; + } + else + { + deviceaddress = NAND_DEVICE2; + } + + /* Send Read status operation command */ + *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_STATUS; + + /* Read status register data */ + data = *(__IO uint8_t *)deviceaddress; + + /* Return the status */ + if((data & NAND_ERROR) == NAND_ERROR) + { + return NAND_ERROR; + } + else if((data & NAND_READY) == NAND_READY) + { + return NAND_READY; + } + + return NAND_BUSY; +} + +/** + * @brief Increment the NAND memory address + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param pAddress: pointer to NAND address structure + * @retval The new status of the increment address operation. It can be: + * - NAND_VALID_ADDRESS: When the new address is valid address + * - NAND_INVALID_ADDRESS: When the new address is invalid address + */ +uint32_t HAL_NAND_Address_Inc(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress) +{ + uint32_t status = NAND_VALID_ADDRESS; + + /* Increment page address */ + pAddress->Page++; + + /* Check NAND address is valid */ + if(pAddress->Page == hnand->Info.BlockSize) + { + pAddress->Page = 0; + pAddress->Block++; + + if(pAddress->Block == hnand->Info.ZoneSize) + { + pAddress->Block = 0; + pAddress->Zone++; + + if(pAddress->Zone == (hnand->Info.ZoneSize/ hnand->Info.BlockNbr)) + { + status = NAND_INVALID_ADDRESS; + } + } + } + + return (status); +} +/** + * @} + */ + +/** @defgroup NAND_Exported_Functions_Group3 Peripheral Control functions + * @brief management functions + * +@verbatim + ============================================================================== + ##### NAND Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the NAND interface. + +@endverbatim + * @{ + */ + + +/** + * @brief Enables dynamically NAND ECC feature. + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_ECC_Enable(NAND_HandleTypeDef *hnand) +{ + /* Check the NAND controller state */ + if(hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Update the NAND state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Enable ECC feature */ + FMC_NAND_ECC_Enable(hnand->Instance, hnand->Init.NandBank); + + /* Update the NAND state */ + hnand->State = HAL_NAND_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Disables dynamically FMC_NAND ECC feature. + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_ECC_Disable(NAND_HandleTypeDef *hnand) +{ + /* Check the NAND controller state */ + if(hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Update the NAND state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Disable ECC feature */ + FMC_NAND_ECC_Disable(hnand->Instance, hnand->Init.NandBank); + + /* Update the NAND state */ + hnand->State = HAL_NAND_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Disables dynamically NAND ECC feature. + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @param ECCval: pointer to ECC value + * @param Timeout: maximum timeout to wait + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NAND_GetECC(NAND_HandleTypeDef *hnand, uint32_t *ECCval, uint32_t Timeout) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the NAND controller state */ + if(hnand->State == HAL_NAND_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Update the NAND state */ + hnand->State = HAL_NAND_STATE_BUSY; + + /* Get NAND ECC value */ + status = FMC_NAND_GetECC(hnand->Instance, ECCval, hnand->Init.NandBank, Timeout); + + /* Update the NAND state */ + hnand->State = HAL_NAND_STATE_READY; + + return status; +} + +/** + * @} + */ + + +/** @defgroup NAND_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + ============================================================================== + ##### NAND State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the NAND controller + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief return the NAND state + * @param hnand: pointer to a NAND_HandleTypeDef structure that contains + * the configuration information for NAND module. + * @retval HAL state + */ +HAL_NAND_StateTypeDef HAL_NAND_GetState(NAND_HandleTypeDef *hnand) +{ + return hnand->State; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx ||\ + STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||\ + STM32F446xx */ + +#endif /* HAL_NAND_MODULE_ENABLED */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nor.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nor.c new file mode 100644 index 0000000..754aafb --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nor.c @@ -0,0 +1,1007 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_nor.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief NOR HAL module driver. + * This file provides a generic firmware to drive NOR memories mounted + * as external device. + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + This driver is a generic layered driver which contains a set of APIs used to + control NOR flash memories. It uses the FMC/FSMC layer functions to interface + with NOR devices. This driver is used as follows: + + (+) NOR flash memory configuration sequence using the function HAL_NOR_Init() + with control and timing parameters for both normal and extended mode. + + (+) Read NOR flash memory manufacturer code and device IDs using the function + HAL_NOR_Read_ID(). The read information is stored in the NOR_ID_TypeDef + structure declared by the function caller. + + (+) Access NOR flash memory by read/write data unit operations using the functions + HAL_NOR_Read(), HAL_NOR_Program(). + + (+) Perform NOR flash erase block/chip operations using the functions + HAL_NOR_Erase_Block() and HAL_NOR_Erase_Chip(). + + (+) Read the NOR flash CFI (common flash interface) IDs using the function + HAL_NOR_Read_CFI(). The read information is stored in the NOR_CFI_TypeDef + structure declared by the function caller. + + (+) You can also control the NOR device by calling the control APIs HAL_NOR_WriteOperation_Enable()/ + HAL_NOR_WriteOperation_Disable() to respectively enable/disable the NOR write operation + + (+) You can monitor the NOR device HAL state by calling the function + HAL_NOR_GetState() + [..] + (@) This driver is a set of generic APIs which handle standard NOR flash operations. + If a NOR flash device contains different operations and/or implementations, + it should be implemented separately. + + *** NOR HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in NOR HAL driver. + + (+) NOR_WRITE : NOR memory write data to specified address + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 NOR NOR + * @brief NOR driver modules + * @{ + */ +#ifdef HAL_NOR_MODULE_ENABLED +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F446xx) +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/** @defgroup NOR_Private_Defines NOR Private Defines + * @{ + */ + +/* Constants to define address to set to write a command */ +#define NOR_CMD_ADDRESS_FIRST (uint16_t)0x0555 +#define NOR_CMD_ADDRESS_FIRST_CFI (uint16_t)0x0055 +#define NOR_CMD_ADDRESS_SECOND (uint16_t)0x02AA +#define NOR_CMD_ADDRESS_THIRD (uint16_t)0x0555 +#define NOR_CMD_ADDRESS_FOURTH (uint16_t)0x0555 +#define NOR_CMD_ADDRESS_FIFTH (uint16_t)0x02AA +#define NOR_CMD_ADDRESS_SIXTH (uint16_t)0x0555 + +/* Constants to define data to program a command */ +#define NOR_CMD_DATA_READ_RESET (uint16_t)0x00F0 +#define NOR_CMD_DATA_FIRST (uint16_t)0x00AA +#define NOR_CMD_DATA_SECOND (uint16_t)0x0055 +#define NOR_CMD_DATA_AUTO_SELECT (uint16_t)0x0090 +#define NOR_CMD_DATA_PROGRAM (uint16_t)0x00A0 +#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD (uint16_t)0x0080 +#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH (uint16_t)0x00AA +#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH (uint16_t)0x0055 +#define NOR_CMD_DATA_CHIP_ERASE (uint16_t)0x0010 +#define NOR_CMD_DATA_CFI (uint16_t)0x0098 + +#define NOR_CMD_DATA_BUFFER_AND_PROG (uint8_t)0x25 +#define NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM (uint8_t)0x29 +#define NOR_CMD_DATA_BLOCK_ERASE (uint8_t)0x30 + +/* Mask on NOR STATUS REGISTER */ +#define NOR_MASK_STATUS_DQ5 (uint16_t)0x0020 +#define NOR_MASK_STATUS_DQ6 (uint16_t)0x0040 + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup NOR_Exported_Functions NOR Exported Functions + * @{ + */ + +/** @defgroup NOR_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * + @verbatim + ============================================================================== + ##### NOR Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to initialize/de-initialize + the NOR memory + +@endverbatim + * @{ + */ + +/** + * @brief Perform the NOR memory Initialization sequence + * @param hnor: pointer to the NOR handle + * @param Timing: pointer to NOR control timing structure + * @param ExtTiming: pointer to NOR extended mode timing structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_Init(NOR_HandleTypeDef *hnor, FMC_NORSRAM_TimingTypeDef *Timing, FMC_NORSRAM_TimingTypeDef *ExtTiming) +{ + /* Check the NOR handle parameter */ + if(hnor == NULL) + { + return HAL_ERROR; + } + + if(hnor->State == HAL_NOR_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hnor->Lock = HAL_UNLOCKED; + /* Initialize the low level hardware (MSP) */ + HAL_NOR_MspInit(hnor); + } + + /* Initialize NOR control Interface */ + FMC_NORSRAM_Init(hnor->Instance, &(hnor->Init)); + + /* Initialize NOR timing Interface */ + FMC_NORSRAM_Timing_Init(hnor->Instance, Timing, hnor->Init.NSBank); + + /* Initialize NOR extended mode timing Interface */ + FMC_NORSRAM_Extended_Timing_Init(hnor->Extended, ExtTiming, hnor->Init.NSBank, hnor->Init.ExtendedMode); + + /* Enable the NORSRAM device */ + __FMC_NORSRAM_ENABLE(hnor->Instance, hnor->Init.NSBank); + + /* Check the NOR controller state */ + hnor->State = HAL_NOR_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Perform NOR memory De-Initialization sequence + * @param hnor: pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_DeInit(NOR_HandleTypeDef *hnor) +{ + /* De-Initialize the low level hardware (MSP) */ + HAL_NOR_MspDeInit(hnor); + + /* Configure the NOR registers with their reset values */ + FMC_NORSRAM_DeInit(hnor->Instance, hnor->Extended, hnor->Init.NSBank); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hnor); + + return HAL_OK; +} + +/** + * @brief NOR MSP Init + * @param hnor: pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @retval None + */ +__weak void HAL_NOR_MspInit(NOR_HandleTypeDef *hnor) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_NOR_MspInit could be implemented in the user file + */ +} + +/** + * @brief NOR MSP DeInit + * @param hnor: pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @retval None + */ +__weak void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_NOR_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief NOR BSP Wait for Ready/Busy signal + * @param hnor: pointer to a NOR_HandleTypeDef structure that contains + * the configuration information for NOR module. + * @param Timeout: Maximum timeout value + * @retval None + */ +__weak void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_NOR_BspWait could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup NOR_Exported_Functions_Group2 Input and Output functions + * @brief Input Output and memory control functions + * + @verbatim + ============================================================================== + ##### NOR Input and Output functions ##### + ============================================================================== + [..] + This section provides functions allowing to use and control the NOR memory + +@endverbatim + * @{ + */ + +/** + * @brief Read NOR flash IDs + * @param hnor: pointer to the NOR handle + * @param pNOR_ID : pointer to NOR ID structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID) +{ + uint32_t deviceaddress = 0; + + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Check the NOR controller state */ + if(hnor->State == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Send read ID command */ + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_AUTO_SELECT); + + /* Read the NOR IDs */ + pNOR_ID->Manufacturer_Code = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, MC_ADDRESS); + pNOR_ID->Device_Code1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, DEVICE_CODE1_ADDR); + pNOR_ID->Device_Code2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, DEVICE_CODE2_ADDR); + pNOR_ID->Device_Code3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, DEVICE_CODE3_ADDR); + + /* Check the NOR controller state */ + hnor->State = HAL_NOR_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + + return HAL_OK; +} + +/** + * @brief Returns the NOR memory to Read mode. + * @param hnor: pointer to the NOR handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor) +{ + uint32_t deviceaddress = 0; + + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Check the NOR controller state */ + if(hnor->State == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + NOR_WRITE(deviceaddress, NOR_CMD_DATA_READ_RESET); + + /* Check the NOR controller state */ + hnor->State = HAL_NOR_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + + return HAL_OK; +} + +/** + * @brief Read data from NOR memory + * @param hnor: pointer to the NOR handle + * @param pAddress: pointer to Device address + * @param pData : pointer to read data + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData) +{ + uint32_t deviceaddress = 0; + + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Check the NOR controller state */ + if(hnor->State == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Send read data command */ + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); + NOR_WRITE((uint32_t)pAddress, NOR_CMD_DATA_READ_RESET); + + /* Read the data */ + *pData = *(__IO uint32_t *)(uint32_t)pAddress; + + /* Check the NOR controller state */ + hnor->State = HAL_NOR_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + + return HAL_OK; +} + +/** + * @brief Program data to NOR memory + * @param hnor: pointer to the NOR handle + * @param pAddress: Device address + * @param pData : pointer to the data to write + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData) +{ + uint32_t deviceaddress = 0; + + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Check the NOR controller state */ + if(hnor->State == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Send program data command */ + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_PROGRAM); + + /* Write the data */ + NOR_WRITE(pAddress, *pData); + + /* Check the NOR controller state */ + hnor->State = HAL_NOR_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + + return HAL_OK; +} + +/** + * @brief Reads a half-word buffer from the NOR memory. + * @param hnor: pointer to the NOR handle + * @param uwAddress: NOR memory internal address to read from. + * @param pData: pointer to the buffer that receives the data read from the + * NOR memory. + * @param uwBufferSize : number of Half word to read. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize) +{ + uint32_t deviceaddress = 0; + + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Check the NOR controller state */ + if(hnor->State == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Send read data command */ + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); + NOR_WRITE(uwAddress, 0x00F0); + + /* Read buffer */ + while( uwBufferSize > 0) + { + *pData++ = *(__IO uint16_t *)uwAddress; + uwAddress += 2; + uwBufferSize--; + } + + /* Check the NOR controller state */ + hnor->State = HAL_NOR_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + + return HAL_OK; +} + +/** + * @brief Writes a half-word buffer to the NOR memory. This function must be used + only with S29GL128P NOR memory. + * @param hnor: pointer to the NOR handle + * @param uwAddress: NOR memory internal start write address + * @param pData: pointer to source data buffer. + * @param uwBufferSize: Size of the buffer to write + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize) +{ + uint16_t * p_currentaddress = (uint16_t *)NULL; + uint16_t * p_endaddress = (uint16_t *)NULL; + uint32_t lastloadedaddress = 0, deviceaddress = 0; + + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Check the NOR controller state */ + if(hnor->State == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Initialize variables */ + p_currentaddress = (uint16_t*)((uint32_t)(uwAddress)); + p_endaddress = p_currentaddress + (uwBufferSize-1); + lastloadedaddress = (uint32_t)(uwAddress); + + /* Issue unlock command sequence */ + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); + + /* Write Buffer Load Command */ + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, uwAddress), NOR_CMD_DATA_BUFFER_AND_PROG); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, uwAddress), (uwBufferSize - 1)); + + /* Load Data into NOR Buffer */ + while(p_currentaddress <= p_endaddress) + { + /* Store last loaded address & data value (for polling) */ + lastloadedaddress = (uint32_t)p_currentaddress; + + NOR_WRITE(p_currentaddress, *pData++); + + p_currentaddress ++; + } + + NOR_WRITE((uint32_t)(lastloadedaddress), NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM); + + /* Check the NOR controller state */ + hnor->State = HAL_NOR_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + + return HAL_OK; + +} + +/** + * @brief Erase the specified block of the NOR memory + * @param hnor: pointer to the NOR handle + * @param BlockAddress : Block to erase address + * @param Address: Device address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address) +{ + uint32_t deviceaddress = 0; + + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Check the NOR controller state */ + if(hnor->State == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Send block erase command sequence */ + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH); + NOR_WRITE((uint32_t)(BlockAddress + Address), NOR_CMD_DATA_BLOCK_ERASE); + + /* Check the NOR memory status and update the controller state */ + hnor->State = HAL_NOR_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + + return HAL_OK; + +} + +/** + * @brief Erase the entire NOR chip. + * @param hnor: pointer to the NOR handle + * @param Address : Device address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address) +{ + uint32_t deviceaddress = 0; + + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Check the NOR controller state */ + if(hnor->State == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Send NOR chip erase command sequence */ + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH); + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_SIXTH), NOR_CMD_DATA_CHIP_ERASE); + + /* Check the NOR memory status and update the controller state */ + hnor->State = HAL_NOR_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + + return HAL_OK; +} + +/** + * @brief Read NOR flash CFI IDs + * @param hnor: pointer to the NOR handle + * @param pNOR_CFI : pointer to NOR CFI IDs structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI) +{ + uint32_t deviceaddress = 0; + + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Check the NOR controller state */ + if(hnor->State == HAL_NOR_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Select the NOR device address */ + if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) + { + deviceaddress = NOR_MEMORY_ADRESS1; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) + { + deviceaddress = NOR_MEMORY_ADRESS2; + } + else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) + { + deviceaddress = NOR_MEMORY_ADRESS3; + } + else /* FMC_NORSRAM_BANK4 */ + { + deviceaddress = NOR_MEMORY_ADRESS4; + } + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Send read CFI query command */ + NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI); + + /* read the NOR CFI information */ + pNOR_CFI->CFI_1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, CFI1_ADDRESS); + pNOR_CFI->CFI_2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, CFI2_ADDRESS); + pNOR_CFI->CFI_3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, CFI3_ADDRESS); + pNOR_CFI->CFI_4 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, CFI4_ADDRESS); + + /* Check the NOR controller state */ + hnor->State = HAL_NOR_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup NOR_Exported_Functions_Group3 Control functions + * @brief management functions + * +@verbatim + ============================================================================== + ##### NOR Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the NOR interface. + +@endverbatim + * @{ + */ + +/** + * @brief Enables dynamically NOR write operation. + * @param hnor: pointer to the NOR handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor) +{ + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Enable write operation */ + FMC_NORSRAM_WriteOperation_Enable(hnor->Instance, hnor->Init.NSBank); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + + return HAL_OK; +} + +/** + * @brief Disables dynamically NOR write operation. + * @param hnor: pointer to the NOR handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor) +{ + /* Process Locked */ + __HAL_LOCK(hnor); + + /* Update the SRAM controller state */ + hnor->State = HAL_NOR_STATE_BUSY; + + /* Disable write operation */ + FMC_NORSRAM_WriteOperation_Disable(hnor->Instance, hnor->Init.NSBank); + + /* Update the NOR controller state */ + hnor->State = HAL_NOR_STATE_PROTECTED; + + /* Process unlocked */ + __HAL_UNLOCK(hnor); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup NOR_Exported_Functions_Group4 State functions + * @brief Peripheral State functions + * +@verbatim + ============================================================================== + ##### NOR State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the NOR controller + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief return the NOR controller state + * @param hnor: pointer to the NOR handle + * @retval NOR controller state + */ +HAL_NOR_StateTypeDef HAL_NOR_GetState(NOR_HandleTypeDef *hnor) +{ + return hnor->State; +} + +/** + * @brief Returns the NOR operation status. + * @param hnor: pointer to the NOR handle + * @param Address: Device address + * @param Timeout: NOR programming Timeout + * @retval NOR_Status: The returned value can be: HAL_NOR_STATUS_SUCCESS, HAL_NOR_STATUS_ERROR + * or HAL_NOR_STATUS_TIMEOUT + */ +HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout) +{ + HAL_NOR_StatusTypeDef status = HAL_NOR_STATUS_ONGOING; + uint16_t tmpSR1 = 0, tmpSR2 = 0; + uint32_t tickstart = 0; + + /* Poll on NOR memory Ready/Busy signal ------------------------------------*/ + HAL_NOR_MspWait(hnor, Timeout); + + /* Get the NOR memory operation status -------------------------------------*/ + + /* Get tick */ + tickstart = HAL_GetTick(); + while((status != HAL_NOR_STATUS_SUCCESS ) && (status != HAL_NOR_STATUS_TIMEOUT)) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + status = HAL_NOR_STATUS_TIMEOUT; + } + } + + /* Read NOR status register (DQ6 and DQ5) */ + tmpSR1 = *(__IO uint16_t *)Address; + tmpSR2 = *(__IO uint16_t *)Address; + + /* If DQ6 did not toggle between the two reads then return HAL_NOR_STATUS_SUCCESS */ + if((tmpSR1 & NOR_MASK_STATUS_DQ6) == (tmpSR2 & NOR_MASK_STATUS_DQ6)) + { + return HAL_NOR_STATUS_SUCCESS ; + } + + if((tmpSR1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5) + { + status = HAL_NOR_STATUS_ONGOING; + } + + tmpSR1 = *(__IO uint16_t *)Address; + tmpSR2 = *(__IO uint16_t *)Address; + + /* If DQ6 did not toggle between the two reads then return HAL_NOR_STATUS_SUCCESS */ + if((tmpSR1 & NOR_MASK_STATUS_DQ6) == (tmpSR2 & NOR_MASK_STATUS_DQ6)) + { + return HAL_NOR_STATUS_SUCCESS; + } + if((tmpSR1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5) + { + return HAL_NOR_STATUS_ERROR; + } + } + + /* Return the operation status */ + return status; +} + +/** + * @} + */ + + +/** + * @} + */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx ||\ + STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ +#endif /* HAL_NOR_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pccard.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pccard.c new file mode 100644 index 0000000..c8e54e3 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pccard.c @@ -0,0 +1,742 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_pccard.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief PCCARD HAL module driver. + * This file provides a generic firmware to drive PCCARD memories mounted + * as external device. + * + @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + This driver is a generic layered driver which contains a set of APIs used to + control PCCARD/compact flash memories. It uses the FMC/FSMC layer functions + to interface with PCCARD devices. This driver is used for: + + (+) PCCARD/Compact Flash memory configuration sequence using the function + HAL_PCCARD_Init()/HAL_CF_Init() with control and timing parameters for + both common and attribute spaces. + + (+) Read PCCARD/Compact Flash memory maker and device IDs using the function + HAL_PCCARD_Read_ID()/HAL_CF_Read_ID(). The read information is stored in + the CompactFlash_ID structure declared by the function caller. + + (+) Access PCCARD/Compact Flash memory by read/write operations using the functions + HAL_PCCARD_Read_Sector()/ HAL_PCCARD_Write_Sector() - + HAL_CF_Read_Sector()/HAL_CF_Write_Sector(), to read/write sector. + + (+) Perform PCCARD/Compact Flash Reset chip operation using the function + HAL_PCCARD_Reset()/HAL_CF_Reset. + + (+) Perform PCCARD/Compact Flash erase sector operation using the function + HAL_PCCARD_Erase_Sector()/HAL_CF_Erase_Sector. + + (+) Read the PCCARD/Compact Flash status operation using the function + HAL_PCCARD_ReadStatus()/HAL_CF_ReadStatus(). + + (+) You can monitor the PCCARD/Compact Flash device HAL state by calling + the function HAL_PCCARD_GetState()/HAL_CF_GetState() + + [..] + (@) This driver is a set of generic APIs which handle standard PCCARD/compact flash + operations. If a PCCARD/Compact Flash device contains different operations + and/or implementations, it should be implemented separately. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 + * @{ + */ + +#ifdef HAL_PCCARD_MODULE_ENABLED +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) +/** @defgroup PCCARD PCCARD + * @brief PCCARD HAL module driver + * @{ + */ +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ + +/** @defgroup PCCARD_Private_Defines PCCARD Private Defines + * @{ + */ +#define PCCARD_TIMEOUT_READ_ID (uint32_t)0x0000FFFF +#define PCCARD_TIMEOUT_READ_WRITE_SECTOR (uint32_t)0x0000FFFF +#define PCCARD_TIMEOUT_ERASE_SECTOR (uint32_t)0x00000400 +#define PCCARD_TIMEOUT_STATUS (uint32_t)0x01000000 + +#define PCCARD_STATUS_OK (uint8_t)0x58 +#define PCCARD_STATUS_WRITE_OK (uint8_t)0x50 +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function ----------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup PCCARD_Exported_Functions PCCARD Exported Functions + * @{ + */ + +/** @defgroup PCCARD_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * + @verbatim + ============================================================================== + ##### PCCARD Initialization and de-initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to initialize/de-initialize + the PCCARD memory + +@endverbatim + * @{ + */ + +/** + * @brief Perform the PCCARD memory Initialization sequence + * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains + * the configuration information for PCCARD module. + * @param ComSpaceTiming: Common space timing structure + * @param AttSpaceTiming: Attribute space timing structure + * @param IOSpaceTiming: IO space timing structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCCARD_Init(PCCARD_HandleTypeDef *hpccard, FMC_NAND_PCC_TimingTypeDef *ComSpaceTiming, FMC_NAND_PCC_TimingTypeDef *AttSpaceTiming, FMC_NAND_PCC_TimingTypeDef *IOSpaceTiming) +{ + /* Check the PCCARD controller state */ + if(hpccard == NULL) + { + return HAL_ERROR; + } + + if(hpccard->State == HAL_PCCARD_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hpccard->Lock = HAL_UNLOCKED; + /* Initialize the low level hardware (MSP) */ + HAL_PCCARD_MspInit(hpccard); + } + + /* Initialize the PCCARD state */ + hpccard->State = HAL_PCCARD_STATE_BUSY; + + /* Initialize PCCARD control Interface */ + FMC_PCCARD_Init(hpccard->Instance, &(hpccard->Init)); + + /* Init PCCARD common space timing Interface */ + FMC_PCCARD_CommonSpace_Timing_Init(hpccard->Instance, ComSpaceTiming); + + /* Init PCCARD attribute space timing Interface */ + FMC_PCCARD_AttributeSpace_Timing_Init(hpccard->Instance, AttSpaceTiming); + + /* Init PCCARD IO space timing Interface */ + FMC_PCCARD_IOSpace_Timing_Init(hpccard->Instance, IOSpaceTiming); + + /* Enable the PCCARD device */ + __FMC_PCCARD_ENABLE(hpccard->Instance); + + /* Update the PCCARD state */ + hpccard->State = HAL_PCCARD_STATE_READY; + + return HAL_OK; + +} + +/** + * @brief Perform the PCCARD memory De-initialization sequence + * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains + * the configuration information for PCCARD module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCCARD_DeInit(PCCARD_HandleTypeDef *hpccard) +{ + /* De-Initialize the low level hardware (MSP) */ + HAL_PCCARD_MspDeInit(hpccard); + + /* Configure the PCCARD registers with their reset values */ + FMC_PCCARD_DeInit(hpccard->Instance); + + /* Update the PCCARD controller state */ + hpccard->State = HAL_PCCARD_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hpccard); + + return HAL_OK; +} + +/** + * @brief PCCARD MSP Init + * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains + * the configuration information for PCCARD module. + * @retval None + */ +__weak void HAL_PCCARD_MspInit(PCCARD_HandleTypeDef *hpccard) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCCARD_MspInit could be implemented in the user file + */ +} + +/** + * @brief PCCARD MSP DeInit + * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains + * the configuration information for PCCARD module. + * @retval None + */ +__weak void HAL_PCCARD_MspDeInit(PCCARD_HandleTypeDef *hpccard) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCCARD_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup PCCARD_Exported_Functions_Group2 Input and Output functions + * @brief Input Output and memory control functions + * + @verbatim + ============================================================================== + ##### PCCARD Input and Output functions ##### + ============================================================================== + [..] + This section provides functions allowing to use and control the PCCARD memory + +@endverbatim + * @{ + */ + +/** + * @brief Read Compact Flash's ID. + * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains + * the configuration information for PCCARD module. + * @param CompactFlash_ID: Compact flash ID structure. + * @param pStatus: pointer to compact flash status + * @retval HAL status + * + */ +HAL_StatusTypeDef HAL_PCCARD_Read_ID(PCCARD_HandleTypeDef *hpccard, uint8_t CompactFlash_ID[], uint8_t *pStatus) +{ + uint32_t timeout = PCCARD_TIMEOUT_READ_ID, index = 0; + uint8_t status = 0; + + /* Process Locked */ + __HAL_LOCK(hpccard); + + /* Check the PCCARD controller state */ + if(hpccard->State == HAL_PCCARD_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Update the PCCARD controller state */ + hpccard->State = HAL_PCCARD_STATE_BUSY; + + /* Initialize the PCCARD status */ + *pStatus = PCCARD_READY; + + /* Send the Identify Command */ + *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD) = 0xECEC; + + /* Read PCCARD IDs and timeout treatment */ + do + { + /* Read the PCCARD status */ + status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE); + + timeout--; + }while((status != PCCARD_STATUS_OK) && timeout); + + if(timeout == 0) + { + *pStatus = PCCARD_TIMEOUT_ERROR; + } + else + { + /* Read PCCARD ID bytes */ + for(index = 0; index < 16; index++) + { + CompactFlash_ID[index] = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_DATA); + } + } + + /* Update the PCCARD controller state */ + hpccard->State = HAL_PCCARD_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hpccard); + + return HAL_OK; +} + +/** + * @brief Read sector from PCCARD memory + * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains + * the configuration information for PCCARD module. + * @param pBuffer: pointer to destination read buffer + * @param SectorAddress: Sector address to read + * @param pStatus: pointer to PCCARD status + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCCARD_Read_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress, uint8_t *pStatus) +{ + uint32_t timeout = PCCARD_TIMEOUT_READ_WRITE_SECTOR, index = 0; + uint8_t status = 0; + + /* Process Locked */ + __HAL_LOCK(hpccard); + + /* Check the PCCARD controller state */ + if(hpccard->State == HAL_PCCARD_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Update the PCCARD controller state */ + hpccard->State = HAL_PCCARD_STATE_BUSY; + + /* Initialize PCCARD status */ + *pStatus = PCCARD_READY; + + /* Set the parameters to write a sector */ + *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = (uint16_t)0x00; + *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT) = ((uint16_t)0x0100 ) | ((uint16_t)SectorAddress); + *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD) = (uint16_t)0xE4A0; + + do + { + /* wait till the Status = 0x80 */ + status = *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE); + timeout--; + }while((status == 0x80) && timeout); + + if(timeout == 0) + { + *pStatus = PCCARD_TIMEOUT_ERROR; + } + + timeout = PCCARD_TIMEOUT_READ_WRITE_SECTOR; + + do + { + /* wait till the Status = PCCARD_STATUS_OK */ + status = *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE); + timeout--; + }while((status != PCCARD_STATUS_OK) && timeout); + + if(timeout == 0) + { + *pStatus = PCCARD_TIMEOUT_ERROR; + } + + /* Read bytes */ + for(; index < PCCARD_SECTOR_SIZE; index++) + { + *(uint16_t *)pBuffer++ = *(uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR); + } + + /* Update the PCCARD controller state */ + hpccard->State = HAL_PCCARD_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hpccard); + + return HAL_OK; +} + + +/** + * @brief Write sector to PCCARD memory + * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains + * the configuration information for PCCARD module. + * @param pBuffer: pointer to source write buffer + * @param SectorAddress: Sector address to write + * @param pStatus: pointer to PCCARD status + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCCARD_Write_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t *pBuffer, uint16_t SectorAddress, uint8_t *pStatus) +{ + uint32_t timeout = PCCARD_TIMEOUT_READ_WRITE_SECTOR, index = 0; + uint8_t status = 0; + + /* Process Locked */ + __HAL_LOCK(hpccard); + + /* Check the PCCARD controller state */ + if(hpccard->State == HAL_PCCARD_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Update the PCCARD controller state */ + hpccard->State = HAL_PCCARD_STATE_BUSY; + + /* Initialize PCCARD status */ + *pStatus = PCCARD_READY; + + /* Set the parameters to write a sector */ + *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = (uint16_t)0x00; + *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT) = ((uint16_t)0x0100 ) | ((uint16_t)SectorAddress); + *(__IO uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD) = (uint16_t)0x30A0; + + do + { + /* Wait till the Status = PCCARD_STATUS_OK */ + status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE); + timeout--; + }while((status != PCCARD_STATUS_OK) && timeout); + + if(timeout == 0) + { + *pStatus = PCCARD_TIMEOUT_ERROR; + } + + /* Write bytes */ + for(; index < PCCARD_SECTOR_SIZE; index++) + { + *(uint16_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR) = *(uint16_t *)pBuffer++; + } + + do + { + /* Wait till the Status = PCCARD_STATUS_WRITE_OK */ + status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE); + timeout--; + }while((status != PCCARD_STATUS_WRITE_OK) && timeout); + + if(timeout == 0) + { + *pStatus = PCCARD_TIMEOUT_ERROR; + } + + /* Update the PCCARD controller state */ + hpccard->State = HAL_PCCARD_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hpccard); + + return HAL_OK; +} + + +/** + * @brief Erase sector from PCCARD memory + * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains + * the configuration information for PCCARD module. + * @param SectorAddress: Sector address to erase + * @param pStatus: pointer to PCCARD status + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCCARD_Erase_Sector(PCCARD_HandleTypeDef *hpccard, uint16_t SectorAddress, uint8_t *pStatus) +{ + uint32_t timeout = PCCARD_TIMEOUT_ERASE_SECTOR; + uint8_t status = 0; + + /* Process Locked */ + __HAL_LOCK(hpccard); + + /* Check the PCCARD controller state */ + if(hpccard->State == HAL_PCCARD_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Update the PCCARD controller state */ + hpccard->State = HAL_PCCARD_STATE_BUSY; + + /* Initialize PCCARD status */ + *pStatus = PCCARD_READY; + + /* Set the parameters to write a sector */ + *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_LOW) = 0x00; + *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CYLINDER_HIGH) = 0x00; + *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_NUMBER) = SectorAddress; + *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_SECTOR_COUNT) = 0x01; + *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_CARD_HEAD) = 0xA0; + *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD) = ATA_ERASE_SECTOR_CMD; + + /* wait till the PCCARD is ready */ + status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE); + + while((status != PCCARD_STATUS_WRITE_OK) && timeout) + { + status = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE); + timeout--; + } + + if(timeout == 0) + { + *pStatus = PCCARD_TIMEOUT_ERROR; + } + + /* Check the PCCARD controller state */ + hpccard->State = HAL_PCCARD_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hpccard); + + return HAL_OK; +} + +/** + * @brief Reset the PCCARD memory + * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains + * the configuration information for PCCARD module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCCARD_Reset(PCCARD_HandleTypeDef *hpccard) +{ + /* Process Locked */ + __HAL_LOCK(hpccard); + + /* Check the PCCARD controller state */ + if(hpccard->State == HAL_PCCARD_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Provide a SW reset and Read and verify the: + - PCCard Configuration Option Register at address 0x98000200 --> 0x80 + - Card Configuration and Status Register at address 0x98000202 --> 0x00 + - Pin Replacement Register at address 0x98000204 --> 0x0C + - Socket and Copy Register at address 0x98000206 --> 0x00 + */ + + /* Check the PCCARD controller state */ + hpccard->State = HAL_PCCARD_STATE_BUSY; + + *(__IO uint8_t *)(PCCARD_ATTRIBUTE_SPACE_ADDRESS | ATA_CARD_CONFIGURATION ) = 0x01; + + /* Check the PCCARD controller state */ + hpccard->State = HAL_PCCARD_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hpccard); + + return HAL_OK; +} + +/** + * @brief This function handles PCCARD device interrupt request. + * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains + * the configuration information for PCCARD module. + * @retval HAL status +*/ +void HAL_PCCARD_IRQHandler(PCCARD_HandleTypeDef *hpccard) +{ + /* Check PCCARD interrupt Rising edge flag */ + if(__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_RISING_EDGE)) + { + /* PCCARD interrupt callback*/ + HAL_PCCARD_ITCallback(hpccard); + + /* Clear PCCARD interrupt Rising edge pending bit */ + __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_RISING_EDGE); + } + + /* Check PCCARD interrupt Level flag */ + if(__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_LEVEL)) + { + /* PCCARD interrupt callback*/ + HAL_PCCARD_ITCallback(hpccard); + + /* Clear PCCARD interrupt Level pending bit */ + __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_LEVEL); + } + + /* Check PCCARD interrupt Falling edge flag */ + if(__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_FALLING_EDGE)) + { + /* PCCARD interrupt callback*/ + HAL_PCCARD_ITCallback(hpccard); + + /* Clear PCCARD interrupt Falling edge pending bit */ + __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_FALLING_EDGE); + } + + /* Check PCCARD interrupt FIFO empty flag */ + if(__FMC_PCCARD_GET_FLAG(hpccard->Instance, FMC_FLAG_FEMPT)) + { + /* PCCARD interrupt callback*/ + HAL_PCCARD_ITCallback(hpccard); + + /* Clear PCCARD interrupt FIFO empty pending bit */ + __FMC_PCCARD_CLEAR_FLAG(hpccard->Instance, FMC_FLAG_FEMPT); + } +} + +/** + * @brief PCCARD interrupt feature callback + * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains + * the configuration information for PCCARD module. + * @retval None + */ +__weak void HAL_PCCARD_ITCallback(PCCARD_HandleTypeDef *hpccard) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCCARD_ITCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup PCCARD_Exported_Functions_Group3 State functions + * @brief Peripheral State functions + * +@verbatim + ============================================================================== + ##### PCCARD State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the PCCARD controller + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief return the PCCARD controller state + * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains + * the configuration information for PCCARD module. + * @retval HAL state + */ +HAL_PCCARD_StateTypeDef HAL_PCCARD_GetState(PCCARD_HandleTypeDef *hpccard) +{ + return hpccard->State; +} + +/** + * @brief Get the compact flash memory status + * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains + * the configuration information for PCCARD module. + * @retval New status of the PCCARD operation. This parameter can be: + * - CompactFlash_TIMEOUT_ERROR: when the previous operation generate + * a Timeout error + * - CompactFlash_READY: when memory is ready for the next operation + */ +HAL_PCCARD_StatusTypeDef HAL_PCCARD_GetStatus(PCCARD_HandleTypeDef *hpccard) +{ + uint32_t timeout = PCCARD_TIMEOUT_STATUS, status_pccard = 0; + + /* Check the PCCARD controller state */ + if(hpccard->State == HAL_PCCARD_STATE_BUSY) + { + return HAL_PCCARD_STATUS_ONGOING; + } + + status_pccard = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE); + + while((status_pccard == PCCARD_BUSY) && timeout) + { + status_pccard = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE); + timeout--; + } + + if(timeout == 0) + { + status_pccard = PCCARD_TIMEOUT_ERROR; + } + + /* Return the operation status */ + return (HAL_PCCARD_StatusTypeDef) status_pccard; +} + +/** + * @brief Reads the Compact Flash memory status using the Read status command + * @param hpccard: pointer to a PCCARD_HandleTypeDef structure that contains + * the configuration information for PCCARD module. + * @retval The status of the Compact Flash memory. This parameter can be: + * - CompactFlash_BUSY: when memory is busy + * - CompactFlash_READY: when memory is ready for the next operation + * - CompactFlash_ERROR: when the previous operation generates error + */ +HAL_PCCARD_StatusTypeDef HAL_PCCARD_ReadStatus(PCCARD_HandleTypeDef *hpccard) +{ + uint8_t data = 0, status_pccard = PCCARD_BUSY; + + /* Check the PCCARD controller state */ + if(hpccard->State == HAL_PCCARD_STATE_BUSY) + { + return HAL_PCCARD_STATUS_ONGOING; + } + + /* Read status operation */ + data = *(__IO uint8_t *)(PCCARD_IO_SPACE_PRIMARY_ADDR | ATA_STATUS_CMD_ALTERNATE); + + if((data & PCCARD_TIMEOUT_ERROR) == PCCARD_TIMEOUT_ERROR) + { + status_pccard = PCCARD_TIMEOUT_ERROR; + } + else if((data & PCCARD_READY) == PCCARD_READY) + { + status_pccard = PCCARD_READY; + } + + return (HAL_PCCARD_StatusTypeDef) status_pccard; +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx ||\ + STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c new file mode 100644 index 0000000..bbf1d13 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c @@ -0,0 +1,1208 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_pcd.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief PCD HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The PCD HAL driver can be used as follows: + + (#) Declare a PCD_HandleTypeDef handle structure, for example: + PCD_HandleTypeDef hpcd; + + (#) Fill parameters of Init structure in HCD handle + + (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...) + + (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API: + (##) Enable the PCD/USB Low Level interface clock using + (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode) + + (##) Initialize the related GPIO clocks + (##) Configure PCD pin-out + (##) Configure PCD NVIC interrupt + + (#)Associate the Upper USB device stack to the HAL PCD Driver: + (##) hpcd.pData = pdev; + + (#)Enable PCD transmission and reception: + (##) HAL_PCD_Start(); + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 PCD PCD + * @brief PCD HAL module driver + * @{ + */ + +#ifdef HAL_PCD_MODULE_ENABLED + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PCD_Private_Macros PCD Private Macros + * @{ + */ +#define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b)) +/** + * @} + */ + +/* Private functions prototypes ----------------------------------------------*/ +/** @defgroup PCD_Private_Functions PCD Private Functions + * @{ + */ +static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup PCD_Exported_Functions PCD Exported Functions + * @{ + */ + +/** @defgroup PCD_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: + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the PCD according to the specified + * parameters in the PCD_InitTypeDef and initialize the associated handle. + * @param hpcd: PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd) +{ + uint32_t i = 0; + + /* Check the PCD handle allocation */ + if(hpcd == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance)); + + hpcd->State = HAL_PCD_STATE_BUSY; + + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + HAL_PCD_MspInit(hpcd); + + /* Disable the Interrupts */ + __HAL_PCD_DISABLE(hpcd); + + /*Init the Core (common init.) */ + USB_CoreInit(hpcd->Instance, hpcd->Init); + + /* Force Device Mode*/ + USB_SetCurrentMode(hpcd->Instance , USB_OTG_DEVICE_MODE); + + /* Init endpoints structures */ + for (i = 0; i < 15 ; i++) + { + /* Init ep structure */ + hpcd->IN_ep[i].is_in = 1; + hpcd->IN_ep[i].num = i; + hpcd->IN_ep[i].tx_fifo_num = i; + /* Control until ep is activated */ + hpcd->IN_ep[i].type = EP_TYPE_CTRL; + hpcd->IN_ep[i].maxpacket = 0; + hpcd->IN_ep[i].xfer_buff = 0; + hpcd->IN_ep[i].xfer_len = 0; + } + + for (i = 0; i < 15 ; i++) + { + hpcd->OUT_ep[i].is_in = 0; + hpcd->OUT_ep[i].num = i; + hpcd->IN_ep[i].tx_fifo_num = i; + /* Control until ep is activated */ + hpcd->OUT_ep[i].type = EP_TYPE_CTRL; + hpcd->OUT_ep[i].maxpacket = 0; + hpcd->OUT_ep[i].xfer_buff = 0; + hpcd->OUT_ep[i].xfer_len = 0; + + hpcd->Instance->DIEPTXF[i] = 0; + } + + /* Init Device */ + USB_DevInit(hpcd->Instance, hpcd->Init); + + hpcd->State= HAL_PCD_STATE_READY; + +#ifdef USB_OTG_GLPMCFG_LPMEN + /* Activate LPM */ + if (hpcd->Init.lpm_enable == 1) + { + HAL_PCDEx_ActivateLPM(hpcd); + } +#endif /* USB_OTG_GLPMCFG_LPMEN */ + + USB_DevDisconnect (hpcd->Instance); + return HAL_OK; +} + +/** + * @brief DeInitializes the PCD peripheral. + * @param hpcd: PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd) +{ + /* Check the PCD handle allocation */ + if(hpcd == NULL) + { + return HAL_ERROR; + } + + hpcd->State = HAL_PCD_STATE_BUSY; + + /* Stop Device */ + HAL_PCD_Stop(hpcd); + + /* DeInit the low level hardware */ + HAL_PCD_MspDeInit(hpcd); + + hpcd->State = HAL_PCD_STATE_RESET; + + return HAL_OK; +} + +/** + * @brief Initializes the PCD MSP. + * @param hpcd: PCD handle + * @retval None + */ +__weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCD_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes PCD MSP. + * @param hpcd: PCD handle + * @retval None + */ +__weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCD_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the PCD data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Start The USB OTG Device. + * @param hpcd: PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd) +{ + __HAL_LOCK(hpcd); + USB_DevConnect (hpcd->Instance); + __HAL_PCD_ENABLE(hpcd); + __HAL_UNLOCK(hpcd); + return HAL_OK; +} + +/** + * @brief Stop The USB OTG Device. + * @param hpcd: PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd) +{ + __HAL_LOCK(hpcd); + __HAL_PCD_DISABLE(hpcd); + USB_StopDevice(hpcd->Instance); + USB_DevDisconnect(hpcd->Instance); + __HAL_UNLOCK(hpcd); + return HAL_OK; +} + +/** + * @brief Handles PCD interrupt request. + * @param hpcd: PCD handle + * @retval HAL status + */ +void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + uint32_t i = 0, ep_intr = 0, epint = 0, epnum = 0; + uint32_t fifoemptymsk = 0, temp = 0; + USB_OTG_EPTypeDef *ep; + + /* ensure that we are in device mode */ + if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE) + { + /* avoid spurious interrupt */ + if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd)) + { + return; + } + + if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS)) + { + /* incorrect mode, acknowledge the interrupt */ + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS); + } + + if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT)) + { + epnum = 0; + + /* Read in the device interrupt bits */ + ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance); + + while ( ep_intr ) + { + if (ep_intr & 0x1) + { + epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum); + + if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) + { + CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC); + + if(hpcd->Init.dma_enable == 1) + { + hpcd->OUT_ep[epnum].xfer_count = hpcd->OUT_ep[epnum].maxpacket- (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ); + hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket; + } + + HAL_PCD_DataOutStageCallback(hpcd, epnum); + if(hpcd->Init.dma_enable == 1) + { + if((epnum == 0) && (hpcd->OUT_ep[epnum].xfer_len == 0)) + { + /* this is ZLP, so prepare EP0 for next setup */ + USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup); + } + } + } + + if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) + { + /* Inform the upper layer that a setup packet is available */ + HAL_PCD_SetupStageCallback(hpcd); + CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP); + } + + if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS) + { + CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS); + } + } + epnum++; + ep_intr >>= 1; + } + } + + if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT)) + { + /* Read in the device interrupt bits */ + ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance); + + epnum = 0; + + while ( ep_intr ) + { + if (ep_intr & 0x1) /* In ITR */ + { + epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum); + + if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC) + { + fifoemptymsk = 0x1 << epnum; + USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; + + CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC); + + if (hpcd->Init.dma_enable == 1) + { + hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket; + } + + HAL_PCD_DataInStageCallback(hpcd, epnum); + + if (hpcd->Init.dma_enable == 1) + { + /* this is ZLP, so prepare EP0 for next setup */ + if((epnum == 0) && (hpcd->IN_ep[epnum].xfer_len == 0)) + { + /* prepare to rx more setup packets */ + USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup); + } + } + } + if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC) + { + CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC); + } + if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE) + { + CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE); + } + if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE) + { + CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE); + } + if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD) + { + CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD); + } + if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) + { + PCD_WriteEmptyTxFifo(hpcd , epnum); + } + } + epnum++; + ep_intr >>= 1; + } + } + + /* Handle Resume Interrupt */ + if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT)) + { + /* Clear the Remote Wake-up Signaling */ + USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; + +#ifdef USB_OTG_GLPMCFG_LPMEN + if(hpcd->LPM_State == LPM_L1) + { + hpcd->LPM_State = LPM_L0; + HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE); + } + else +#endif /* USB_OTG_GLPMCFG_LPMEN */ + { + HAL_PCD_ResumeCallback(hpcd); + } + + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT); + } + + /* Handle Suspend Interrupt */ + if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP)) + { + if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS) + { + + HAL_PCD_SuspendCallback(hpcd); + } + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP); + } + +#ifdef USB_OTG_GLPMCFG_LPMEN + /* Handle LPM Interrupt */ + if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT)) + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT); + if( hpcd->LPM_State == LPM_L0) + { + hpcd->LPM_State = LPM_L1; + hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >>2 ; + HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); + } + else + { + HAL_PCD_SuspendCallback(hpcd); + } + } +#endif /* USB_OTG_GLPMCFG_LPMEN */ + + /* Handle Reset Interrupt */ + if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST)) + { + USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; + USB_FlushTxFifo(hpcd->Instance , 0 ); + + for (i = 0; i < hpcd->Init.dev_endpoints ; i++) + { + USBx_INEP(i)->DIEPINT = 0xFF; + USBx_OUTEP(i)->DOEPINT = 0xFF; + } + USBx_DEVICE->DAINT = 0xFFFFFFFF; + USBx_DEVICE->DAINTMSK |= 0x10001; + + if(hpcd->Init.use_dedicated_ep1) + { + USBx_DEVICE->DOUTEP1MSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM); + USBx_DEVICE->DINEP1MSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM); + } + else + { + USBx_DEVICE->DOEPMSK |= (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM); + USBx_DEVICE->DIEPMSK |= (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM); + } + + /* Set Default Address to 0 */ + USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD; + + /* setup EP0 to receive SETUP packets */ + USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup); + + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST); + } + + /* Handle Enumeration done Interrupt */ + if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE)) + { + USB_ActivateSetup(hpcd->Instance); + hpcd->Instance->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; + + if ( USB_GetDevSpeed(hpcd->Instance) == USB_OTG_SPEED_HIGH) + { + hpcd->Init.speed = USB_OTG_SPEED_HIGH; + hpcd->Init.ep0_mps = USB_OTG_HS_MAX_PACKET_SIZE ; + hpcd->Instance->GUSBCFG |= (uint32_t)((USBD_HS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT); + } + else + { + hpcd->Init.speed = USB_OTG_SPEED_FULL; + hpcd->Init.ep0_mps = USB_OTG_FS_MAX_PACKET_SIZE ; + hpcd->Instance->GUSBCFG |= (uint32_t)((USBD_FS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT); + } + + HAL_PCD_ResetCallback(hpcd); + + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE); + } + + /* Handle RxQLevel Interrupt */ + if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL)) + { + USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL); + + temp = USBx->GRXSTSP; + + ep = &hpcd->OUT_ep[temp & USB_OTG_GRXSTSP_EPNUM]; + + if(((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT) + { + if((temp & USB_OTG_GRXSTSP_BCNT) != 0) + { + USB_ReadPacket(USBx, ep->xfer_buff, (temp & USB_OTG_GRXSTSP_BCNT) >> 4); + ep->xfer_buff += (temp & USB_OTG_GRXSTSP_BCNT) >> 4; + ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4; + } + } + else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT) + { + USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8); + ep->xfer_count += (temp & USB_OTG_GRXSTSP_BCNT) >> 4; + } + USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL); + } + + /* Handle SOF Interrupt */ + if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF)) + { + HAL_PCD_SOFCallback(hpcd); + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF); + } + + /* Handle Incomplete ISO IN Interrupt */ + if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR)) + { + HAL_PCD_ISOINIncompleteCallback(hpcd, epnum); + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR); + } + + /* Handle Incomplete ISO OUT Interrupt */ + if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT)) + { + HAL_PCD_ISOOUTIncompleteCallback(hpcd, epnum); + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT); + } + + /* Handle Connection event Interrupt */ + if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT)) + { + HAL_PCD_ConnectCallback(hpcd); + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT); + } + + /* Handle Disconnection event Interrupt */ + if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT)) + { + temp = hpcd->Instance->GOTGINT; + + if((temp & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET) + { + HAL_PCD_DisconnectCallback(hpcd); + } + hpcd->Instance->GOTGINT |= temp; + } + } +} + +/** + * @brief Data OUT stage callback. + * @param hpcd: PCD handle + * @param epnum: endpoint number + * @retval None + */ + __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCD_DataOutStageCallback could be implemented in the user file + */ +} + +/** + * @brief Data IN stage callback. + * @param hpcd: PCD handle + * @param epnum: endpoint number + * @retval None + */ + __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCD_DataInStageCallback could be implemented in the user file + */ +} +/** + * @brief Setup stage callback. + * @param hpcd: PCD handle + * @retval None + */ + __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCD_SetupStageCallback could be implemented in the user file + */ +} + +/** + * @brief USB Start Of Frame callback. + * @param hpcd: PCD handle + * @retval None + */ + __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCD_SOFCallback could be implemented in the user file + */ +} + +/** + * @brief USB Reset callback. + * @param hpcd: PCD handle + * @retval None + */ + __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCD_ResetCallback could be implemented in the user file + */ +} + +/** + * @brief Suspend event callback. + * @param hpcd: PCD handle + * @retval None + */ + __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCD_SuspendCallback could be implemented in the user file + */ +} + +/** + * @brief Resume event callback. + * @param hpcd: PCD handle + * @retval None + */ + __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCD_ResumeCallback could be implemented in the user file + */ +} + +/** + * @brief Incomplete ISO OUT callback. + * @param hpcd: PCD handle + * @param epnum: endpoint number + * @retval None + */ + __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file + */ +} + +/** + * @brief Incomplete ISO IN callback. + * @param hpcd: PCD handle + * @param epnum: endpoint number + * @retval None + */ + __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file + */ +} + +/** + * @brief Connection event callback. + * @param hpcd: PCD handle + * @retval None + */ + __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCD_ConnectCallback could be implemented in the user file + */ +} + +/** + * @brief Disconnection event callback. + * @param hpcd: PCD handle + * @retval None + */ + __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PCD_DisconnectCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions + * @brief management functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the PCD data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Connect the USB device. + * @param hpcd: PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd) +{ + __HAL_LOCK(hpcd); + USB_DevConnect(hpcd->Instance); + __HAL_UNLOCK(hpcd); + return HAL_OK; +} + +/** + * @brief Disconnect the USB device. + * @param hpcd: PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd) +{ + __HAL_LOCK(hpcd); + USB_DevDisconnect(hpcd->Instance); + __HAL_UNLOCK(hpcd); + return HAL_OK; +} + +/** + * @brief Set the USB Device address. + * @param hpcd: PCD handle + * @param address: new device address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address) +{ + __HAL_LOCK(hpcd); + USB_SetDevAddress(hpcd->Instance, address); + __HAL_UNLOCK(hpcd); + return HAL_OK; +} +/** + * @brief Open and configure an endpoint. + * @param hpcd: PCD handle + * @param ep_addr: endpoint address + * @param ep_mps: endpoint max packet size + * @param ep_type: endpoint type + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type) +{ + HAL_StatusTypeDef ret = HAL_OK; + USB_OTG_EPTypeDef *ep; + + if ((ep_addr & 0x80) == 0x80) + { + ep = &hpcd->IN_ep[ep_addr & 0x7F]; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & 0x7F]; + } + ep->num = ep_addr & 0x7F; + + ep->is_in = (0x80 & ep_addr) != 0; + ep->maxpacket = ep_mps; + ep->type = ep_type; + if (ep->is_in) + { + /* Assign a Tx FIFO */ + ep->tx_fifo_num = ep->num; + } + /* Set initial data PID. */ + if (ep_type == EP_TYPE_BULK ) + { + ep->data_pid_start = 0; + } + + __HAL_LOCK(hpcd); + USB_ActivateEndpoint(hpcd->Instance , ep); + __HAL_UNLOCK(hpcd); + return ret; +} + + +/** + * @brief Deactivate an endpoint. + * @param hpcd: PCD handle + * @param ep_addr: endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + USB_OTG_EPTypeDef *ep; + + if ((ep_addr & 0x80) == 0x80) + { + ep = &hpcd->IN_ep[ep_addr & 0x7F]; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & 0x7F]; + } + ep->num = ep_addr & 0x7F; + + ep->is_in = (0x80 & ep_addr) != 0; + + __HAL_LOCK(hpcd); + USB_DeactivateEndpoint(hpcd->Instance , ep); + __HAL_UNLOCK(hpcd); + return HAL_OK; +} + + +/** + * @brief Receive an amount of data. + * @param hpcd: PCD handle + * @param ep_addr: endpoint address + * @param pBuf: pointer to the reception buffer + * @param len: amount of data to be received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) +{ + USB_OTG_EPTypeDef *ep; + + ep = &hpcd->OUT_ep[ep_addr & 0x7F]; + + /*setup and start the Xfer */ + ep->xfer_buff = pBuf; + ep->xfer_len = len; + ep->xfer_count = 0; + ep->is_in = 0; + ep->num = ep_addr & 0x7F; + + if (hpcd->Init.dma_enable == 1) + { + ep->dma_addr = (uint32_t)pBuf; + } + + __HAL_LOCK(hpcd); + + if ((ep_addr & 0x7F) == 0 ) + { + USB_EP0StartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable); + } + else + { + USB_EPStartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable); + } + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Get Received Data Size. + * @param hpcd: PCD handle + * @param ep_addr: endpoint address + * @retval Data Size + */ +uint16_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + return hpcd->OUT_ep[ep_addr & 0x7F].xfer_count; +} +/** + * @brief Send an amount of data. + * @param hpcd: PCD handle + * @param ep_addr: endpoint address + * @param pBuf: pointer to the transmission buffer + * @param len: amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) +{ + USB_OTG_EPTypeDef *ep; + + ep = &hpcd->IN_ep[ep_addr & 0x7F]; + + /*setup and start the Xfer */ + ep->xfer_buff = pBuf; + ep->xfer_len = len; + ep->xfer_count = 0; + ep->is_in = 1; + ep->num = ep_addr & 0x7F; + + if (hpcd->Init.dma_enable == 1) + { + ep->dma_addr = (uint32_t)pBuf; + } + + __HAL_LOCK(hpcd); + + if ((ep_addr & 0x7F) == 0 ) + { + USB_EP0StartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable); + } + else + { + USB_EPStartXfer(hpcd->Instance , ep, hpcd->Init.dma_enable); + } + + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Set a STALL condition over an endpoint. + * @param hpcd: PCD handle + * @param ep_addr: endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + USB_OTG_EPTypeDef *ep; + + if ((0x80 & ep_addr) == 0x80) + { + ep = &hpcd->IN_ep[ep_addr & 0x7F]; + } + else + { + ep = &hpcd->OUT_ep[ep_addr]; + } + + ep->is_stall = 1; + ep->num = ep_addr & 0x7F; + ep->is_in = ((ep_addr & 0x80) == 0x80); + + + __HAL_LOCK(hpcd); + USB_EPSetStall(hpcd->Instance , ep); + if((ep_addr & 0x7F) == 0) + { + USB_EP0_OutStart(hpcd->Instance, hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup); + } + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Clear a STALL condition over in an endpoint. + * @param hpcd: PCD handle + * @param ep_addr: endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + USB_OTG_EPTypeDef *ep; + + if ((0x80 & ep_addr) == 0x80) + { + ep = &hpcd->IN_ep[ep_addr & 0x7F]; + } + else + { + ep = &hpcd->OUT_ep[ep_addr]; + } + + ep->is_stall = 0; + ep->num = ep_addr & 0x7F; + ep->is_in = ((ep_addr & 0x80) == 0x80); + + __HAL_LOCK(hpcd); + USB_EPClearStall(hpcd->Instance , ep); + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Flush an endpoint. + * @param hpcd: PCD handle + * @param ep_addr: endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + __HAL_LOCK(hpcd); + + if ((ep_addr & 0x80) == 0x80) + { + USB_FlushTxFifo(hpcd->Instance, ep_addr & 0x7F); + } + else + { + USB_FlushRxFifo(hpcd->Instance); + } + + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Activate remote wakeup signalling. + * @param hpcd: PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + + if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS) + { + /* Activate Remote wakeup signaling */ + USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG; + } + return HAL_OK; +} + +/** + * @brief De-activate remote wakeup signalling. + * @param hpcd: PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + + /* De-activate Remote wakeup signaling */ + USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG); + return HAL_OK; +} +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the PCD handle state. + * @param hpcd: PCD handle + * @retval HAL state + */ +PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd) +{ + return hpcd->State; +} +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup PCD_Private_Functions + * @{ + */ + +/** + * @brief Check FIFO for the next packet to be loaded. + * @param hpcd: PCD handle + * @param epnum : endpoint number + * @retval HAL status + */ +static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + USB_OTG_EPTypeDef *ep; + int32_t len = 0; + uint32_t len32b; + uint32_t fifoemptymsk = 0; + + ep = &hpcd->IN_ep[epnum]; + len = ep->xfer_len - ep->xfer_count; + + if (len > ep->maxpacket) + { + len = ep->maxpacket; + } + + + len32b = (len + 3) / 4; + + while ( (USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) > len32b && + ep->xfer_count < ep->xfer_len && + ep->xfer_len != 0) + { + /* Write the FIFO */ + len = ep->xfer_len - ep->xfer_count; + + if (len > ep->maxpacket) + { + len = ep->maxpacket; + } + len32b = (len + 3) / 4; + + USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable); + + ep->xfer_buff += len; + ep->xfer_count += len; + } + + if(len <= 0) + { + fifoemptymsk = 0x1 << epnum; + USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; + + } + + return HAL_OK; +} + +/** + * @} + */ + +#endif /* HAL_PCD_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c new file mode 100644 index 0000000..2d14dd4 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c @@ -0,0 +1,198 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_pcd_ex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief PCD HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Extended features functions + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 PCDEx PCDEx + * @brief PCD Extended HAL module driver + * @{ + */ +#ifdef HAL_PCD_MODULE_ENABLED + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup PCDEx_Exported_Functions PCD Extended Exported Functions + * @{ + */ + +/** @defgroup PCDEx_Exported_Functions_Group1 Peripheral Control functions + * @brief PCDEx control functions + * +@verbatim + =============================================================================== + ##### Extended features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Update FIFO configuration + +@endverbatim + * @{ + */ + +/** + * @brief Set Tx FIFO + * @param hpcd: PCD handle + * @param fifo: The number of Tx fifo + * @param size: Fifo size + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size) +{ + uint8_t i = 0; + uint32_t Tx_Offset = 0; + + /* TXn min size = 16 words. (n : Transmit FIFO index) + When a TxFIFO is not used, the Configuration should be as follows: + case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes) + --> Txm can use the space allocated for Txn. + case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes) + --> Txn should be configured with the minimum space of 16 words + The FIFO is used optimally when used TxFIFOs are allocated in the top + of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones. + When DMA is used 3n * FIFO locations should be reserved for internal DMA registers */ + + Tx_Offset = hpcd->Instance->GRXFSIZ; + + if(fifo == 0) + { + hpcd->Instance->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((uint32_t)size << 16) | Tx_Offset); + } + else + { + Tx_Offset += (hpcd->Instance->DIEPTXF0_HNPTXFSIZ) >> 16; + for (i = 0; i < (fifo - 1); i++) + { + Tx_Offset += (hpcd->Instance->DIEPTXF[i] >> 16); + } + + /* Multiply Tx_Size by 2 to get higher performance */ + hpcd->Instance->DIEPTXF[fifo - 1] = (uint32_t)(((uint32_t)size << 16) | Tx_Offset); + } + + return HAL_OK; +} + +/** + * @brief Set Rx FIFO + * @param hpcd: PCD handle + * @param size: Size of Rx fifo + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size) +{ + hpcd->Instance->GRXFSIZ = size; + + return HAL_OK; +} + +#if defined(STM32F446xx) +/** + * @brief Activate LPM feature + * @param hpcd: PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + + hpcd->lpm_active = ENABLE; + hpcd->LPM_State = LPM_L0; + USBx->GINTMSK |= USB_OTG_GINTMSK_LPMINTM; + USBx->GLPMCFG |= (USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL); + + return HAL_OK; +} + +/** + * @brief Deactivate LPM feature. + * @param hpcd: PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + + hpcd->lpm_active = DISABLE; + USBx->GINTMSK &= ~USB_OTG_GINTMSK_LPMINTM; + USBx->GLPMCFG &= ~(USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL); + + return HAL_OK; +} + +/** + * @brief Send LPM message to user layer callback. + * @param hpcd: PCD handle + * @param msg: LPM message + * @retval HAL status + */ +__weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg) +{ +} +#endif /* STM32F446xx */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_PCD_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c new file mode 100644 index 0000000..5834418 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c @@ -0,0 +1,574 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_pwr.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief PWR HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Power Controller (PWR) peripheral: + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 PWR PWR + * @brief PWR HAL module driver + * @{ + */ + +#ifdef HAL_PWR_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup PWR_Private_Constants + * @{ + */ + +/** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask + * @{ + */ +#define PVD_MODE_IT ((uint32_t)0x00010000) +#define PVD_MODE_EVT ((uint32_t)0x00020000) +#define PVD_RISING_EDGE ((uint32_t)0x00000001) +#define PVD_FALLING_EDGE ((uint32_t)0x00000002) +/** + * @} + */ + +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup PWR_Exported_Functions PWR Exported Functions + * @{ + */ + +/** @defgroup PWR_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] + After reset, the backup domain (RTC registers, RTC backup data + registers and backup SRAM) is protected against possible unwanted + write accesses. + To enable access to the RTC Domain and RTC registers, proceed as follows: + (+) Enable the Power Controller (PWR) APB1 interface clock using the + __HAL_RCC_PWR_CLK_ENABLE() macro. + (+) Enable access to RTC domain using the HAL_PWR_EnableBkUpAccess() function. + +@endverbatim + * @{ + */ + +/** + * @brief Deinitializes the HAL PWR peripheral registers to their default reset values. + * @retval None + */ +void HAL_PWR_DeInit(void) +{ + __HAL_RCC_PWR_FORCE_RESET(); + __HAL_RCC_PWR_RELEASE_RESET(); +} + +/** + * @brief Enables access to the backup domain (RTC registers, RTC + * backup data registers and backup SRAM). + * @note If the HSE divided by 2, 3, ..31 is used as the RTC clock, the + * Backup Domain Access should be kept enabled. + * @retval None + */ +void HAL_PWR_EnableBkUpAccess(void) +{ + *(__IO uint32_t *) CR_DBP_BB = (uint32_t)ENABLE; +} + +/** + * @brief Disables access to the backup domain (RTC registers, RTC + * backup data registers and backup SRAM). + * @note If the HSE divided by 2, 3, ..31 is used as the RTC clock, the + * Backup Domain Access should be kept enabled. + * @retval None + */ +void HAL_PWR_DisableBkUpAccess(void) +{ + *(__IO uint32_t *) CR_DBP_BB = (uint32_t)DISABLE; +} + +/** + * @} + */ + +/** @defgroup PWR_Exported_Functions_Group2 Peripheral Control functions + * @brief Low Power modes configuration functions + * +@verbatim + + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + + *** PVD configuration *** + ========================= + [..] + (+) The PVD is used to monitor the VDD power supply by comparing it to a + threshold selected by the PVD Level (PLS[2:0] bits in the PWR_CR). + (+) A PVDO flag is available to indicate if VDD/VDDA is higher or lower + than the PVD threshold. This event is internally connected to the EXTI + line16 and can generate an interrupt if enabled. This is done through + __HAL_PWR_PVD_EXTI_ENABLE_IT() macro. + (+) The PVD is stopped in Standby mode. + + *** Wake-up pin configuration *** + ================================ + [..] + (+) Wake-up pin is used to wake up the system from Standby mode. This pin is + forced in input pull-down configuration and is active on rising edges. + (+) There is one Wake-up pin: Wake-up Pin 1 on PA.00. + Only for STM32F446xx there are two Wake-Up pins: Pin1 on PA.00 and Pin 2 on PC.13 + + *** Low Power modes configuration *** + ===================================== + [..] + The devices feature 3 low-power modes: + (+) Sleep mode: Cortex-M4 core stopped, peripherals kept running. + (+) Stop mode: all clocks are stopped, regulator running, regulator + in low power mode + (+) Standby mode: 1.2V domain powered off. + + *** Sleep mode *** + ================== + [..] + (+) Entry: + The Sleep mode is entered by using the HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI) + functions with + (++) PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction + (++) PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction + + -@@- The Regulator parameter is not used for the STM32F4 family + and is kept as parameter just to maintain compatibility with the + lower power families (STM32L). + (+) Exit: + Any peripheral interrupt acknowledged by the nested vectored interrupt + controller (NVIC) can wake up the device from Sleep mode. + + *** Stop mode *** + ================= + [..] + In Stop mode, all clocks in the 1.2V domain are stopped, the PLL, the HSI, + and the HSE RC oscillators are disabled. Internal SRAM and register contents + are preserved. + The voltage regulator can be configured either in normal or low-power mode. + To minimize the consumption In Stop mode, FLASH can be powered off before + entering the Stop mode using the HAL_PWREx_EnableFlashPowerDown() function. + It can be switched on again by software after exiting the Stop mode using + the HAL_PWREx_DisableFlashPowerDown() function. + + (+) Entry: + The Stop mode is entered using the HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON) + function with: + (++) Main regulator ON. + (++) Low Power regulator ON. + (+) Exit: + Any EXTI Line (Internal or External) configured in Interrupt/Event mode. + + *** Standby mode *** + ==================== + [..] + (+) + The Standby mode allows to achieve the lowest power consumption. It is based + on the Cortex-M4 deep sleep mode, with the voltage regulator disabled. + The 1.2V domain is consequently powered off. The PLL, the HSI oscillator and + the HSE oscillator are also switched off. SRAM and register contents are lost + except for the RTC registers, RTC backup registers, backup SRAM and Standby + circuitry. + + The voltage regulator is OFF. + + (++) Entry: + (+++) The Standby mode is entered using the HAL_PWR_EnterSTANDBYMode() function. + (++) Exit: + (+++) WKUP pin rising edge, RTC alarm (Alarm A and Alarm B), RTC wake-up, + tamper event, time-stamp event, external reset in NRST pin, IWDG reset. + + *** Auto-wake-up (AWU) from low-power mode *** + ============================================= + [..] + + (+) The MCU can be woken up from low-power mode by an RTC Alarm event, an RTC + Wake-up event, a tamper event or a time-stamp event, without depending on + an external interrupt (Auto-wake-up mode). + + (+) RTC auto-wake-up (AWU) from the Stop and Standby modes + + (++) To wake up from the Stop mode with an RTC alarm event, it is necessary to + configure the RTC to generate the RTC alarm using the HAL_RTC_SetAlarm_IT() function. + + (++) To wake up from the Stop mode with an RTC Tamper or time stamp event, it + is necessary to configure the RTC to detect the tamper or time stamp event using the + HAL_RTCEx_SetTimeStamp_IT() or HAL_RTCEx_SetTamper_IT() functions. + + (++) To wake up from the Stop mode with an RTC Wake-up event, it is necessary to + configure the RTC to generate the RTC Wake-up event using the HAL_RTCEx_SetWakeUpTimer_IT() function. + +@endverbatim + * @{ + */ + +/** + * @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD). + * @param sConfigPVD: pointer to an PWR_PVDTypeDef structure that contains the configuration + * information for the PVD. + * @note Refer to the electrical characteristics of your device datasheet for + * more details about the voltage threshold corresponding to each + * detection level. + * @retval None + */ +void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD) +{ + /* Check the parameters */ + assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel)); + assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode)); + + /* Set PLS[7:5] bits according to PVDLevel value */ + MODIFY_REG(PWR->CR, PWR_CR_PLS, sConfigPVD->PVDLevel); + + /* Clear any previous config. Keep it clear if no event or IT mode is selected */ + __HAL_PWR_PVD_EXTI_DISABLE_EVENT(); + __HAL_PWR_PVD_EXTI_DISABLE_IT(); + __HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE(); + __HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE(); + + /* Configure interrupt mode */ + if((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT) + { + __HAL_PWR_PVD_EXTI_ENABLE_IT(); + } + + /* Configure event mode */ + if((sConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT) + { + __HAL_PWR_PVD_EXTI_ENABLE_EVENT(); + } + + /* Configure the edge */ + if((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE) + { + __HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE(); + } + + if((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE) + { + __HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE(); + } +} + +/** + * @brief Enables the Power Voltage Detector(PVD). + * @retval None + */ +void HAL_PWR_EnablePVD(void) +{ + *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)ENABLE; +} + +/** + * @brief Disables the Power Voltage Detector(PVD). + * @retval None + */ +void HAL_PWR_DisablePVD(void) +{ + *(__IO uint32_t *) CR_PVDE_BB = (uint32_t)DISABLE; +} + +/** + * @brief Enables the Wake-up PINx functionality. + * @param WakeUpPinx: Specifies the Power Wake-Up pin to enable. + * This parameter can be one of the following values: + * @arg PWR_WAKEUP_PIN1 + * @arg PWR_WAKEUP_PIN2 only available in case of STM32F446xx devices + * @retval None + */ +void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx) +{ + /* Check the parameter */ + assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx)); + + /* Enable the wake up pin */ + SET_BIT(PWR->CSR, WakeUpPinx); +} + +/** + * @brief Disables the Wake-up PINx functionality. + * @param WakeUpPinx: Specifies the Power Wake-Up pin to disable. + * This parameter can be one of the following values: + * @arg PWR_WAKEUP_PIN1 + * @arg PWR_WAKEUP_PIN2 only available in case of STM32F446xx devices + * @retval None + */ +void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx) +{ + /* Check the parameter */ + assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx)); + + /* Disable the wake up pin */ + CLEAR_BIT(PWR->CSR, WakeUpPinx); +} + +/** + * @brief Enters Sleep mode. + * + * @note In Sleep mode, all I/O pins keep the same state as in Run mode. + * + * @note In Sleep mode, the systick is stopped to avoid exit from this mode with + * systick interrupt when used as time base for Timeout + * + * @param Regulator: Specifies the regulator state in SLEEP mode. + * This parameter can be one of the following values: + * @arg PWR_MAINREGULATOR_ON: SLEEP mode with regulator ON + * @arg PWR_LOWPOWERREGULATOR_ON: SLEEP mode with low power regulator ON + * @note This parameter is not used for the STM32F4 family and is kept as parameter + * just to maintain compatibility with the lower power families. + * @param SLEEPEntry: Specifies if SLEEP mode in entered with WFI or WFE instruction. + * This parameter can be one of the following values: + * @arg PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction + * @arg PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction + * @retval None + */ +void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry) +{ + /* Check the parameters */ + assert_param(IS_PWR_REGULATOR(Regulator)); + assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry)); + + /* Clear SLEEPDEEP bit of Cortex System Control Register */ + CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); + + /* Select SLEEP mode entry -------------------------------------------------*/ + if(SLEEPEntry == PWR_SLEEPENTRY_WFI) + { + /* Request Wait For Interrupt */ + __WFI(); + } + else + { + /* Request Wait For Event */ + __SEV(); + __WFE(); + __WFE(); + } +} + +/** + * @brief Enters Stop mode. + * @note In Stop mode, all I/O pins keep the same state as in Run mode. + * @note When exiting Stop mode by issuing an interrupt or a wake-up event, + * the HSI RC oscillator is selected as system clock. + * @note When the voltage regulator operates in low power mode, an additional + * startup delay is incurred when waking up from Stop mode. + * By keeping the internal regulator ON during Stop mode, the consumption + * is higher although the startup time is reduced. + * @param Regulator: Specifies the regulator state in Stop mode. + * This parameter can be one of the following values: + * @arg PWR_MAINREGULATOR_ON: Stop mode with regulator ON + * @arg PWR_LOWPOWERREGULATOR_ON: Stop mode with low power regulator ON + * @param STOPEntry: Specifies if Stop mode in entered with WFI or WFE instruction. + * This parameter can be one of the following values: + * @arg PWR_STOPENTRY_WFI: Enter Stop mode with WFI instruction + * @arg PWR_STOPENTRY_WFE: Enter Stop mode with WFE instruction + * @retval None + */ +void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry) +{ + /* Check the parameters */ + assert_param(IS_PWR_REGULATOR(Regulator)); + assert_param(IS_PWR_STOP_ENTRY(STOPEntry)); + + /* Select the regulator state in Stop mode: Set PDDS and LPDS bits according to PWR_Regulator value */ + MODIFY_REG(PWR->CR, (PWR_CR_PDDS | PWR_CR_LPDS), Regulator); + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); + + /* Select Stop mode entry --------------------------------------------------*/ + if(STOPEntry == PWR_STOPENTRY_WFI) + { + /* Request Wait For Interrupt */ + __WFI(); + } + else + { + /* Request Wait For Event */ + __SEV(); + __WFE(); + __WFE(); + } + /* Reset SLEEPDEEP bit of Cortex System Control Register */ + CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); +} + +/** + * @brief Enters Standby mode. + * @note In Standby mode, all I/O pins are high impedance except for: + * - Reset pad (still available) + * - RTC_AF1 pin (PC13) if configured for tamper, time-stamp, RTC + * Alarm out, or RTC clock calibration out. + * - RTC_AF2 pin (PI8) if configured for tamper or time-stamp. + * - WKUP pin 1 (PA0) if enabled. + * @retval None + */ +void HAL_PWR_EnterSTANDBYMode(void) +{ + /* Select Standby mode */ + SET_BIT(PWR->CR, PWR_CR_PDDS); + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); + + /* This option is used to ensure that store operations are completed */ +#if defined ( __CC_ARM) + __force_stores(); +#endif + /* Request Wait For Interrupt */ + __WFI(); +} + +/** + * @brief This function handles the PWR PVD interrupt request. + * @note This API should be called under the PVD_IRQHandler(). + * @retval None + */ +void HAL_PWR_PVD_IRQHandler(void) +{ + /* Check PWR Exti flag */ + if(__HAL_PWR_PVD_EXTI_GET_FLAG() != RESET) + { + /* PWR PVD interrupt user callback */ + HAL_PWR_PVDCallback(); + + /* Clear PWR Exti pending bit */ + __HAL_PWR_PVD_EXTI_CLEAR_FLAG(); + } +} + +/** + * @brief PWR PVD interrupt callback + * @retval None + */ +__weak void HAL_PWR_PVDCallback(void) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_PWR_PVDCallback could be implemented in the user file + */ +} + +/** + * @brief Indicates Sleep-On-Exit when returning from Handler mode to Thread mode. + * @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the processor + * re-enters SLEEP mode when an interruption handling is over. + * Setting this bit is useful when the processor is expected to run only on + * interruptions handling. + * @retval None + */ +void HAL_PWR_EnableSleepOnExit(void) +{ + /* Set SLEEPONEXIT bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk)); +} + +/** + * @brief Disables Sleep-On-Exit feature when returning from Handler mode to Thread mode. + * @note Clears SLEEPONEXIT bit of SCR register. When this bit is set, the processor + * re-enters SLEEP mode when an interruption handling is over. + * @retval None + */ +void HAL_PWR_DisableSleepOnExit(void) +{ + /* Clear SLEEPONEXIT bit of Cortex System Control Register */ + CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk)); +} + +/** + * @brief Enables CORTEX M4 SEVONPEND bit. + * @note Sets SEVONPEND bit of SCR register. When this bit is set, this causes + * WFE to wake up when an interrupt moves from inactive to pended. + * @retval None + */ +void HAL_PWR_EnableSEVOnPend(void) +{ + /* Set SEVONPEND bit of Cortex System Control Register */ + SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk)); +} + +/** + * @brief Disables CORTEX M4 SEVONPEND bit. + * @note Clears SEVONPEND bit of SCR register. When this bit is set, this causes + * WFE to wake up when an interrupt moves from inactive to pended. + * @retval None + */ +void HAL_PWR_DisableSEVOnPend(void) +{ + /* Clear SEVONPEND bit of Cortex System Control Register */ + CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk)); +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_PWR_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c new file mode 100644 index 0000000..a1e4691 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c @@ -0,0 +1,624 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_pwr_ex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Extended PWR HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of PWR extension peripheral: + * + Peripheral Extended features functions + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 PWREx PWREx + * @brief PWR HAL module driver + * @{ + */ + +#ifdef HAL_PWR_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup PWREx_Private_Constants + * @{ + */ +#define PWR_OVERDRIVE_TIMEOUT_VALUE 1000 +#define PWR_UDERDRIVE_TIMEOUT_VALUE 1000 +#define PWR_BKPREG_TIMEOUT_VALUE 1000 +#define PWR_VOSRDY_TIMEOUT_VALUE 1000 +/** + * @} + */ + + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** @defgroup PWREx_Exported_Functions PWREx Exported Functions + * @{ + */ + +/** @defgroup PWREx_Exported_Functions_Group1 Peripheral Extended features functions + * @brief Peripheral Extended features functions + * +@verbatim + + =============================================================================== + ##### Peripheral extended features functions ##### + =============================================================================== + + *** Main and Backup Regulators configuration *** + ================================================ + [..] + (+) The backup domain includes 4 Kbytes of backup SRAM accessible only from + the CPU, and address in 32-bit, 16-bit or 8-bit mode. Its content is + retained even in Standby or VBAT mode when the low power backup regulator + is enabled. It can be considered as an internal EEPROM when VBAT is + always present. You can use the HAL_PWREx_EnableBkUpReg() function to + enable the low power backup regulator. + + (+) When the backup domain is supplied by VDD (analog switch connected to VDD) + the backup SRAM is powered from VDD which replaces the VBAT power supply to + save battery life. + + (+) The backup SRAM is not mass erased by a tamper event. It is read + protected to prevent confidential data, such as cryptographic private + key, from being accessed. The backup SRAM can be erased only through + the Flash interface when a protection level change from level 1 to + level 0 is requested. + -@- Refer to the description of Read protection (RDP) in the Flash + programming manual. + + (+) The main internal regulator can be configured to have a tradeoff between + performance and power consumption when the device does not operate at + the maximum frequency. This is done through __HAL_PWR_MAINREGULATORMODE_CONFIG() + macro which configure VOS bit in PWR_CR register + + Refer to the product datasheets for more details. + + *** FLASH Power Down configuration **** + ======================================= + [..] + (+) By setting the FPDS bit in the PWR_CR register by using the + HAL_PWREx_EnableFlashPowerDown() function, the Flash memory also enters power + down mode when the device enters Stop mode. When the Flash memory + is in power down mode, an additional startup delay is incurred when + waking up from Stop mode. + + (+) For STM32F42xxx/43xxx Devices, the scale can be modified only when the PLL + is OFF and the HSI or HSE clock source is selected as system clock. + The new value programmed is active only when the PLL is ON. + When the PLL is OFF, the voltage scale 3 is automatically selected. + Refer to the datasheets for more details. + + *** Over-Drive and Under-Drive configuration **** + ================================================= + [..] + (+) For STM32F42xxx/43xxx Devices, in Run mode: the main regulator has + 2 operating modes available: + (++) Normal mode: The CPU and core logic operate at maximum frequency at a given + voltage scaling (scale 1, scale 2 or scale 3) + (++) Over-drive mode: This mode allows the CPU and the core logic to operate at a + higher frequency than the normal mode for a given voltage scaling (scale 1, + scale 2 or scale 3). This mode is enabled through HAL_PWREx_EnableOverDrive() function and + disabled by HAL_PWREx_DisableOverDrive() function, to enter or exit from Over-drive mode please follow + the sequence described in Reference manual. + + (+) For STM32F42xxx/43xxx Devices, in Stop mode: the main regulator or low power regulator + supplies a low power voltage to the 1.2V domain, thus preserving the content of registers + and internal SRAM. 2 operating modes are available: + (++) Normal mode: the 1.2V domain is preserved in nominal leakage mode. This mode is only + available when the main regulator or the low power regulator is used in Scale 3 or + low voltage mode. + (++) Under-drive mode: the 1.2V domain is preserved in reduced leakage mode. This mode is only + available when the main regulator or the low power regulator is in low voltage mode. + +@endverbatim + * @{ + */ + +/** + * @brief Enables the Backup Regulator. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PWREx_EnableBkUpReg(void) +{ + uint32_t tickstart = 0; + + *(__IO uint32_t *) CSR_BRE_BB = (uint32_t)ENABLE; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till Backup regulator ready flag is set */ + while(__HAL_PWR_GET_FLAG(PWR_FLAG_BRR) == RESET) + { + if((HAL_GetTick() - tickstart ) > PWR_BKPREG_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + return HAL_OK; +} + +/** + * @brief Disables the Backup Regulator. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PWREx_DisableBkUpReg(void) +{ + uint32_t tickstart = 0; + + *(__IO uint32_t *) CSR_BRE_BB = (uint32_t)DISABLE; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till Backup regulator ready flag is set */ + while(__HAL_PWR_GET_FLAG(PWR_FLAG_BRR) != RESET) + { + if((HAL_GetTick() - tickstart ) > PWR_BKPREG_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + return HAL_OK; +} + +/** + * @brief Enables the Flash Power Down in Stop mode. + * @retval None + */ +void HAL_PWREx_EnableFlashPowerDown(void) +{ + *(__IO uint32_t *) CR_FPDS_BB = (uint32_t)ENABLE; +} + +/** + * @brief Disables the Flash Power Down in Stop mode. + * @retval None + */ +void HAL_PWREx_DisableFlashPowerDown(void) +{ + *(__IO uint32_t *) CR_FPDS_BB = (uint32_t)DISABLE; +} + +/** + * @brief Return Voltage Scaling Range. + * @retval The configured scale for the regulator voltage(VOS bit field). + * The returned value can be one of the following: + * - @arg PWR_REGULATOR_VOLTAGE_SCALE1: Regulator voltage output Scale 1 mode + * - @arg PWR_REGULATOR_VOLTAGE_SCALE2: Regulator voltage output Scale 2 mode + * - @arg PWR_REGULATOR_VOLTAGE_SCALE3: Regulator voltage output Scale 3 mode + */ +uint32_t HAL_PWREx_GetVoltageRange(void) +{ + return (PWR->CR & PWR_CR_VOS); +} + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) +/** + * @brief Configures the main internal regulator output voltage. + * @param VoltageScaling: specifies the regulator output voltage to achieve + * a tradeoff between performance and power consumption. + * This parameter can be one of the following values: + * @arg PWR_REGULATOR_VOLTAGE_SCALE1: Regulator voltage output range 1 mode, + * the maximum value of fHCLK = 168 MHz. + * @arg PWR_REGULATOR_VOLTAGE_SCALE2: Regulator voltage output range 2 mode, + * the maximum value of fHCLK = 144 MHz. + * @note When moving from Range 1 to Range 2, the system frequency must be decreased to + * a value below 144 MHz before calling HAL_PWREx_ConfigVoltageScaling() API. + * When moving from Range 2 to Range 1, the system frequency can be increased to + * a value up to 168 MHz after calling HAL_PWREx_ConfigVoltageScaling() API. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling) +{ + uint32_t tickstart = 0; + + assert_param(IS_PWR_VOLTAGE_SCALING_RANGE(VoltageScaling)); + + /* Enable PWR RCC Clock Peripheral */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* Set Range */ + __HAL_PWR_VOLTAGESCALING_CONFIG(VoltageScaling); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + while((__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY) == RESET)) + { + if((HAL_GetTick() - tickstart ) > PWR_VOSRDY_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +#elif defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) +/** + * @brief Configures the main internal regulator output voltage. + * @param VoltageScaling: specifies the regulator output voltage to achieve + * a tradeoff between performance and power consumption. + * This parameter can be one of the following values: + * @arg PWR_REGULATOR_VOLTAGE_SCALE1: Regulator voltage output range 1 mode, + * the maximum value of fHCLK is 168 MHz. It can be extended to + * 180 MHz by activating the over-drive mode. + * @arg PWR_REGULATOR_VOLTAGE_SCALE2: Regulator voltage output range 2 mode, + * the maximum value of fHCLK is 144 MHz. It can be extended to, + * 168 MHz by activating the over-drive mode. + * @arg PWR_REGULATOR_VOLTAGE_SCALE3: Regulator voltage output range 3 mode, + * the maximum value of fHCLK is 120 MHz. + * @note To update the system clock frequency(SYSCLK): + * - Set the HSI or HSE as system clock frequency using the HAL_RCC_ClockConfig(). + * - Call the HAL_RCC_OscConfig() to configure the PLL. + * - Call HAL_PWREx_ConfigVoltageScaling() API to adjust the voltage scale. + * - Set the new system clock frequency using the HAL_RCC_ClockConfig(). + * @note The scale can be modified only when the HSI or HSE clock source is selected + * as system clock source, otherwise the API returns HAL_ERROR. + * @note When the PLL is OFF, the voltage scale 3 is automatically selected and the VOS bits + * value in the PWR_CR1 register are not taken in account. + * @note This API forces the PLL state ON to allow the possibility to configure the voltage scale 1 or 2. + * @note The new voltage scale is active only when the PLL is ON. + * @retval HAL Status + */ +HAL_StatusTypeDef HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling) +{ + uint32_t tickstart = 0; + + assert_param(IS_PWR_VOLTAGE_SCALING_RANGE(VoltageScaling)); + + /* Enable PWR RCC Clock Peripheral */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* Check if the PLL is used as system clock or not */ + if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL) + { + /* Disable the main PLL */ + __HAL_RCC_PLL_DISABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + /* Wait till PLL is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Set Range */ + __HAL_PWR_VOLTAGESCALING_CONFIG(VoltageScaling); + + /* Enable the main PLL */ + __HAL_RCC_PLL_ENABLE(); + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + /* Wait till PLL is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Get Start Tick */ + tickstart = HAL_GetTick(); + while((__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY) == RESET)) + { + if((HAL_GetTick() - tickstart ) > PWR_VOSRDY_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */ + +#if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) +/** + * @brief Enables Main Regulator low voltage mode. + * @note This mode is only available for STM32F401xx/STM32F411xx devices. + * @retval None + */ +void HAL_PWREx_EnableMainRegulatorLowVoltage(void) +{ + *(__IO uint32_t *) CR_MRLVDS_BB = (uint32_t)ENABLE; +} + +/** + * @brief Disables Main Regulator low voltage mode. + * @note This mode is only available for STM32F401xx/STM32F411xx devices. + * @retval None + */ +void HAL_PWREx_DisableMainRegulatorLowVoltage(void) +{ + *(__IO uint32_t *) CR_MRLVDS_BB = (uint32_t)DISABLE; +} + +/** + * @brief Enables Low Power Regulator low voltage mode. + * @note This mode is only available for STM32F401xx/STM32F411xx devices. + * @retval None + */ +void HAL_PWREx_EnableLowRegulatorLowVoltage(void) +{ + *(__IO uint32_t *) CR_LPLVDS_BB = (uint32_t)ENABLE; +} + +/** + * @brief Disables Low Power Regulator low voltage mode. + * @note This mode is only available for STM32F401xx/STM32F411xx devices. + * @retval None + */ +void HAL_PWREx_DisableLowRegulatorLowVoltage(void) +{ + *(__IO uint32_t *) CR_LPLVDS_BB = (uint32_t)DISABLE; +} + +#endif /* STM32F401xC || STM32F401xE || STM32F411xE */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) +/** + * @brief Activates the Over-Drive mode. + * @note This function can be used only for STM32F42xx/STM32F43xx devices. + * This mode allows the CPU and the core logic to operate at a higher frequency + * than the normal mode for a given voltage scaling (scale 1, scale 2 or scale 3). + * @note It is recommended to enter or exit Over-drive mode when the application is not running + * critical tasks and when the system clock source is either HSI or HSE. + * During the Over-drive switch activation, no peripheral clocks should be enabled. + * The peripheral clocks must be enabled once the Over-drive mode is activated. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PWREx_EnableOverDrive(void) +{ + uint32_t tickstart = 0; + + __HAL_RCC_PWR_CLK_ENABLE(); + + /* Enable the Over-drive to extend the clock frequency to 180 Mhz */ + __HAL_PWR_OVERDRIVE_ENABLE(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(!__HAL_PWR_GET_FLAG(PWR_FLAG_ODRDY)) + { + if((HAL_GetTick() - tickstart ) > PWR_OVERDRIVE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Enable the Over-drive switch */ + __HAL_PWR_OVERDRIVESWITCHING_ENABLE(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(!__HAL_PWR_GET_FLAG(PWR_FLAG_ODSWRDY)) + { + if((HAL_GetTick() - tickstart ) > PWR_OVERDRIVE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + return HAL_OK; +} + +/** + * @brief Deactivates the Over-Drive mode. + * @note This function can be used only for STM32F42xx/STM32F43xx devices. + * This mode allows the CPU and the core logic to operate at a higher frequency + * than the normal mode for a given voltage scaling (scale 1, scale 2 or scale 3). + * @note It is recommended to enter or exit Over-drive mode when the application is not running + * critical tasks and when the system clock source is either HSI or HSE. + * During the Over-drive switch activation, no peripheral clocks should be enabled. + * The peripheral clocks must be enabled once the Over-drive mode is activated. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PWREx_DisableOverDrive(void) +{ + uint32_t tickstart = 0; + + __HAL_RCC_PWR_CLK_ENABLE(); + + /* Disable the Over-drive switch */ + __HAL_PWR_OVERDRIVESWITCHING_DISABLE(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(__HAL_PWR_GET_FLAG(PWR_FLAG_ODSWRDY)) + { + if((HAL_GetTick() - tickstart ) > PWR_OVERDRIVE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Disable the Over-drive */ + __HAL_PWR_OVERDRIVE_DISABLE(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(__HAL_PWR_GET_FLAG(PWR_FLAG_ODRDY)) + { + if((HAL_GetTick() - tickstart ) > PWR_OVERDRIVE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +/** + * @brief Enters in Under-Drive STOP mode. + * + * @note This mode is only available for STM32F42xxx/STM324F3xxx devices. + * + * @note This mode can be selected only when the Under-Drive is already active + * + * @note This mode is enabled only with STOP low power mode. + * In this mode, the 1.2V domain is preserved in reduced leakage mode. This + * mode is only available when the main regulator or the low power regulator + * is in low voltage mode + * + * @note If the Under-drive mode was enabled, it is automatically disabled after + * exiting Stop mode. + * When the voltage regulator operates in Under-drive mode, an additional + * startup delay is induced when waking up from Stop mode. + * + * @note In Stop mode, all I/O pins keep the same state as in Run mode. + * + * @note When exiting Stop mode by issuing an interrupt or a wake-up event, + * the HSI RC oscillator is selected as system clock. + * + * @note When the voltage regulator operates in low power mode, an additional + * startup delay is incurred when waking up from Stop mode. + * By keeping the internal regulator ON during Stop mode, the consumption + * is higher although the startup time is reduced. + * + * @param Regulator: specifies the regulator state in STOP mode. + * This parameter can be one of the following values: + * @arg PWR_MAINREGULATOR_UNDERDRIVE_ON: Main Regulator in under-drive mode + * and Flash memory in power-down when the device is in Stop under-drive mode + * @arg PWR_LOWPOWERREGULATOR_UNDERDRIVE_ON: Low Power Regulator in under-drive mode + * and Flash memory in power-down when the device is in Stop under-drive mode + * @param STOPEntry: specifies if STOP mode in entered with WFI or WFE instruction. + * This parameter can be one of the following values: + * @arg PWR_SLEEPENTRY_WFI: enter STOP mode with WFI instruction + * @arg PWR_SLEEPENTRY_WFE: enter STOP mode with WFE instruction + * @retval None + */ +HAL_StatusTypeDef HAL_PWREx_EnterUnderDriveSTOPMode(uint32_t Regulator, uint8_t STOPEntry) +{ + uint32_t tmpreg1 = 0; + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_PWR_REGULATOR_UNDERDRIVE(Regulator)); + assert_param(IS_PWR_STOP_ENTRY(STOPEntry)); + + /* Enable Power ctrl clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + /* Enable the Under-drive Mode ---------------------------------------------*/ + /* Clear Under-drive flag */ + __HAL_PWR_CLEAR_ODRUDR_FLAG(); + + /* Enable the Under-drive */ + __HAL_PWR_UNDERDRIVE_ENABLE(); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait for UnderDrive mode is ready */ + while(__HAL_PWR_GET_FLAG(PWR_FLAG_UDRDY)) + { + if((HAL_GetTick() - tickstart ) > PWR_UDERDRIVE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Select the regulator state in STOP mode ---------------------------------*/ + tmpreg1 = PWR->CR; + /* Clear PDDS, LPDS, MRLUDS and LPLUDS bits */ + tmpreg1 &= (uint32_t)~(PWR_CR_PDDS | PWR_CR_LPDS | PWR_CR_LPUDS | PWR_CR_MRUDS); + + /* Set LPDS, MRLUDS and LPLUDS bits according to PWR_Regulator value */ + tmpreg1 |= Regulator; + + /* Store the new value */ + PWR->CR = tmpreg1; + + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* Select STOP mode entry --------------------------------------------------*/ + if(STOPEntry == PWR_SLEEPENTRY_WFI) + { + /* Request Wait For Interrupt */ + __WFI(); + } + else + { + /* Request Wait For Event */ + __WFE(); + } + /* Reset SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); + + return HAL_OK; +} + +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_PWR_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_qspi.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_qspi.c new file mode 100644 index 0000000..526a048 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_qspi.c @@ -0,0 +1,1942 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_qspi.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief QSPI HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the QuadSPI interface (QSPI). + * + Initialization and de-initialization functions + * + Indirect functional mode management + * + Memory-mapped functional mode management + * + Auto-polling functional mode management + * + Interrupts and flags management + * + DMA channel configuration for indirect functional mode + * + Errors management and abort functionality + * + @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + *** Initialization *** + ====================== + [..] + (#) As prerequisite, fill in the HAL_QSPI_MspInit() : + (+) Enable QuadSPI clock interface with __HAL_RCC_QSPI_CLK_ENABLE(). + (+) Reset QuadSPI IP with __HAL_RCC_QSPI_FORCE_RESET() and __HAL_RCC_QSPI_RELEASE_RESET(). + (+) Enable the clocks for the QuadSPI GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE(). + (+) Configure these QuadSPI pins in alternate mode using HAL_GPIO_Init(). + (+) If interrupt mode is used, enable and configure QuadSPI global + interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ(). + (+) If DMA mode is used, enable the clocks for the QuadSPI DMA channel + with __HAL_RCC_DMAx_CLK_ENABLE(), configure DMA with HAL_DMA_Init(), + link it with QuadSPI handle using __HAL_LINKDMA(), enable and configure + DMA channel global interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ(). + (#) Configure the flash size, the clock prescaler, the fifo threshold, the + clock mode, the sample shifting and the CS high time using the HAL_QSPI_Init() function. + + *** Indirect functional mode *** + ================================ + [..] + (#) Configure the command sequence using the HAL_QSPI_Command() or HAL_QSPI_Command_IT() + functions : + (+) Instruction phase : the mode used and if present the instruction opcode. + (+) Address phase : the mode used and if present the size and the address value. + (+) Alternate-bytes phase : the mode used and if present the size and the alternate + bytes values. + (+) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase). + (+) Data phase : the mode used and if present the number of bytes. + (+) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay + if activated. + (+) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode. + (#) If no data is required for the command, it is sent directly to the memory : + (+) In polling mode, the output of the function is done when the transfer is complete. + (+) In interrupt mode, HAL_QSPI_CmdCpltCallback() will be called when the transfer is complete. + (#) For the indirect write mode, use HAL_QSPI_Transmit(), HAL_QSPI_Transmit_DMA() or + HAL_QSPI_Transmit_IT() after the command configuration : + (+) In polling mode, the output of the function is done when the transfer is complete. + (+) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold + is reached and HAL_QSPI_TxCpltCallback() will be called when the transfer is complete. + (+) In DMA mode, HAL_QSPI_TxHalfCpltCallback() will be called at the half transfer and + HAL_QSPI_TxCpltCallback() will be called when the transfer is complete. + (#) For the indirect read mode, use HAL_QSPI_Receive(), HAL_QSPI_Receive_DMA() or + HAL_QSPI_Receive_IT() after the command configuration : + (+) In polling mode, the output of the function is done when the transfer is complete. + (+) In interrupt mode, HAL_QSPI_FifoThresholdCallback() will be called when the fifo threshold + is reached and HAL_QSPI_RxCpltCallback() will be called when the transfer is complete. + (+) In DMA mode, HAL_QSPI_RxHalfCpltCallback() will be called at the half transfer and + HAL_QSPI_RxCpltCallback() will be called when the transfer is complete. + + *** Auto-polling functional mode *** + ==================================== + [..] + (#) Configure the command sequence and the auto-polling functional mode using the + HAL_QSPI_AutoPolling() or HAL_QSPI_AutoPolling_IT() functions : + (+) Instruction phase : the mode used and if present the instruction opcode. + (+) Address phase : the mode used and if present the size and the address value. + (+) Alternate-bytes phase : the mode used and if present the size and the alternate + bytes values. + (+) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase). + (+) Data phase : the mode used. + (+) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay + if activated. + (+) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode. + (+) The size of the status bytes, the match value, the mask used, the match mode (OR/AND), + the polling interval and the automatic stop activation. + (#) After the configuration : + (+) In polling mode, the output of the function is done when the status match is reached. The + automatic stop is activated to avoid an infinite loop. + (+) In interrupt mode, HAL_QSPI_StatusMatchCallback() will be called each time the status match is reached. + + *** Memory-mapped functional mode *** + ===================================== + [..] + (#) Configure the command sequence and the memory-mapped functional mode using the + HAL_QSPI_MemoryMapped() functions : + (+) Instruction phase : the mode used and if present the instruction opcode. + (+) Address phase : the mode used and the size. + (+) Alternate-bytes phase : the mode used and if present the size and the alternate + bytes values. + (+) Dummy-cycles phase : the number of dummy cycles (mode used is same as data phase). + (+) Data phase : the mode used. + (+) Double Data Rate (DDR) mode : the activation (or not) of this mode and the delay + if activated. + (+) Sending Instruction Only Once (SIOO) mode : the activation (or not) of this mode. + (+) The timeout activation and the timeout period. + (#) After the configuration, the QuadSPI will be used as soon as an access on the AHB is done on + the address range. HAL_QSPI_TimeOutCallback() will be called when the timeout expires. + + *** Errors management and abort functionality *** + ================================================== + [..] + (#) HAL_QSPI_GetError() function gives the error rised during the last operation. + (#) HAL_QSPI_Abort() function aborts any on-going operation and flushes the fifo. + (#) HAL_QSPI_GetState() function gives the current state of the HAL QuadSPI driver. + + *** Workarounds linked to Silicon Limitation *** + ==================================================== + [..] + (#) Workarounds Implemented inside HAL Driver + (+) Extra data written in the FIFO at the end of a read transfer + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 QSPI QSPI + * @brief HAL QSPI module driver + * @{ + */ +#ifdef HAL_QSPI_MODULE_ENABLED + +#if defined(STM32F446xx) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup QSPI_Private_Constants + * @{ + */ +#define QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE ((uint32_t)0x00000000) /*!Instance)); + assert_param(IS_QSPI_CLOCK_PRESCALER(hqspi->Init.ClockPrescaler)); + assert_param(IS_QSPI_FIFO_THRESHOLD(hqspi->Init.FifoThreshold)); + assert_param(IS_QSPI_SSHIFT(hqspi->Init.SampleShifting)); + assert_param(IS_QSPI_FLASH_SIZE(hqspi->Init.FlashSize)); + assert_param(IS_QSPI_CS_HIGH_TIME(hqspi->Init.ChipSelectHighTime)); + assert_param(IS_QSPI_CLOCK_MODE(hqspi->Init.ClockMode)); + assert_param(IS_QSPI_DUAL_FLASH_MODE(hqspi->Init.DualFlash)); + + if (hqspi->Init.DualFlash != QSPI_DUALFLASH_ENABLE ) + { + assert_param(IS_QSPI_FLASH_ID(hqspi->Init.FlashID)); + } + + /* Process locked */ + __HAL_LOCK(hqspi); + + if(hqspi->State == HAL_QSPI_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hqspi->Lock = HAL_UNLOCKED; + + /* Init the low level hardware : GPIO, CLOCK */ + HAL_QSPI_MspInit(hqspi); + + /* Configure the default timeout for the QSPI memory access */ + HAL_QSPI_SetTimeout(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE); + } + + /* Configure QSPI FIFO Threshold */ + MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_FTHRES, ((hqspi->Init.FifoThreshold - 1) << 8)); + + /* Wait till BUSY flag reset */ + status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout); + + if(status == HAL_OK) + { + + /* Configure QSPI Clock Prescaler and Sample Shift */ + MODIFY_REG(hqspi->Instance->CR,(QUADSPI_CR_PRESCALER | QUADSPI_CR_SSHIFT | QUADSPI_CR_FSEL | QUADSPI_CR_DFM), ((hqspi->Init.ClockPrescaler << 24)| hqspi->Init.SampleShifting | hqspi->Init.FlashID| hqspi->Init.DualFlash )); + + /* Configure QSPI Flash Size, CS High Time and Clock Mode */ + MODIFY_REG(hqspi->Instance->DCR, (QUADSPI_DCR_FSIZE | QUADSPI_DCR_CSHT | QUADSPI_DCR_CKMODE), + ((hqspi->Init.FlashSize << 16) | hqspi->Init.ChipSelectHighTime | hqspi->Init.ClockMode)); + + /* Enable the QSPI peripheral */ + __HAL_QSPI_ENABLE(hqspi); + + /* Set QSPI error code to none */ + hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; + + /* Initialize the QSPI state */ + hqspi->State = HAL_QSPI_STATE_READY; + } + + /* Release Lock */ + __HAL_UNLOCK(hqspi); + + /* Return function status */ + return status; +} + +/** + * @brief DeInitializes the QSPI peripheral + * @param hqspi: qspi handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi) +{ + /* Check the QSPI handle allocation */ + if(hqspi == NULL) + { + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hqspi); + + /* Disable the QSPI Peripheral Clock */ + __HAL_QSPI_DISABLE(hqspi); + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ + HAL_QSPI_MspDeInit(hqspi); + + /* Set QSPI error code to none */ + hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; + + /* Initialize the QSPI state */ + hqspi->State = HAL_QSPI_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hqspi); + + return HAL_OK; +} + +/** + * @brief QSPI MSP Init + * @param hqspi: QSPI handle + * @retval None + */ + __weak void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_QSPI_MspInit can be implemented in the user file + */ +} + +/** + * @brief QSPI MSP DeInit + * @param hqspi: QSPI handle + * @retval None + */ + __weak void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi) +{ + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_QSPI_MspDeInit can be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup QSPI_Exported_Functions_Group2 IO operation functions + * @brief QSPI Transmit/Receive functions + * +@verbatim + =============================================================================== + ##### I/O operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to : + (+) Handle the interrupts. + (+) Handle the command sequence. + (+) Transmit data in blocking, interrupt or DMA mode. + (+) Receive data in blocking, interrupt or DMA mode. + (+) Manage the auto-polling functional mode. + (+) Manage the memory-mapped functional mode. + +@endverbatim + * @{ + */ + +/** + * @brief This function handles QSPI interrupt request. + * @param hqspi: QSPI handle + * @retval None. + */ +void HAL_QSPI_IRQHandler(QSPI_HandleTypeDef *hqspi) +{ + __IO uint32_t *data_reg; + uint32_t flag = 0, itsource = 0; + + /* QSPI FIFO Threshold interrupt occurred ----------------------------------*/ + flag = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT); + itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_FT); + + if((flag != RESET) && (itsource != RESET)) + { + data_reg = &hqspi->Instance->DR; + + if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX) + { + /* Transmission process */ + while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != 0) + { + if (hqspi->TxXferCount > 0) + { + /* Fill the FIFO until it is full */ + *(__IO uint8_t *)data_reg = *hqspi->pTxBuffPtr++; + hqspi->TxXferCount--; + } + else + { + /* No more data available for the transfer */ + break; + } + } + } + else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX) + { + /* Receiving Process */ + while(__HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_FT) != 0) + { + if (hqspi->RxXferCount > 0) + { + /* Read the FIFO until it is empty */ + *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg; + hqspi->RxXferCount--; + } + else + { + /* All data have been received for the transfer */ + break; + } + } + } + + /* FIFO Threshold callback */ + HAL_QSPI_FifoThresholdCallback(hqspi); + } + + /* QSPI Transfer Complete interrupt occurred -------------------------------*/ + flag = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_TC); + itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_TC); + + if((flag != RESET) && (itsource != RESET)) + { + /* Clear interrupt */ + __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC); + + /* Disable the QSPI FIFO Threshold, Transfer Error and Transfer complete Interrupts */ + __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT); + + /* Transfer complete callback */ + if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_TX) + { + /* Clear Busy bit */ + HAL_QSPI_Abort(hqspi); + + /* TX Complete callback */ + HAL_QSPI_TxCpltCallback(hqspi); + } + else if(hqspi->State == HAL_QSPI_STATE_BUSY_INDIRECT_RX) + { + data_reg = &hqspi->Instance->DR; + while(READ_BIT(hqspi->Instance->SR, QUADSPI_SR_FLEVEL) != 0) + { + if (hqspi->RxXferCount > 0) + { + /* Read the last data received in the FIFO until it is empty */ + *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg; + hqspi->RxXferCount--; + } + else + { + /* All data have been received for the transfer */ + break; + } + } + + /* Workaround - Extra data written in the FIFO at the end of a read transfer */ + HAL_QSPI_Abort(hqspi); + + /* RX Complete callback */ + HAL_QSPI_RxCpltCallback(hqspi); + } + else if(hqspi->State == HAL_QSPI_STATE_BUSY) + { + /* Command Complete callback */ + HAL_QSPI_CmdCpltCallback(hqspi); + } + + /* Change state of QSPI */ + hqspi->State = HAL_QSPI_STATE_READY; + } + + /* QSPI Status Match interrupt occurred ------------------------------------*/ + flag = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_SM); + itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_SM); + + if((flag != RESET) && (itsource != RESET)) + { + /* Clear interrupt */ + __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM); + + /* Check if the automatic poll mode stop is activated */ + if(READ_BIT(hqspi->Instance->CR, QUADSPI_CR_APMS) != 0) + { + /* Disable the QSPI FIFO Threshold, Transfer Error and Status Match Interrupts */ + __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_FT | QSPI_IT_TE); + + /* Change state of QSPI */ + hqspi->State = HAL_QSPI_STATE_READY; + } + + /* Status match callback */ + HAL_QSPI_StatusMatchCallback(hqspi); + } + + /* QSPI Transfer Error interrupt occurred ----------------------------------*/ + flag = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_TE); + itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_TE); + + if((flag != RESET) && (itsource != RESET)) + { + /* Clear interrupt */ + __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TE); + + /* Disable all the QSPI Interrupts */ + __HAL_QSPI_DISABLE_IT(hqspi, QSPI_IT_SM | QSPI_IT_TC | QSPI_IT_TE | QSPI_IT_FT); + + /* Set error code */ + hqspi->ErrorCode |= HAL_QSPI_ERROR_TRANSFER; + + /* Change state of QSPI */ + hqspi->State = HAL_QSPI_STATE_ERROR; + + /* Error callback */ + HAL_QSPI_ErrorCallback(hqspi); + } + + /* QSPI Time out interrupt occurred -----------------------------------------*/ + flag = __HAL_QSPI_GET_FLAG(hqspi, QSPI_FLAG_TO); + itsource = __HAL_QSPI_GET_IT_SOURCE(hqspi, QSPI_IT_TO); + + if((flag != RESET) && (itsource != RESET)) + { + /* Clear interrupt */ + __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TO); + + /* Time out callback */ + HAL_QSPI_TimeOutCallback(hqspi); + } +} + +/** + * @brief Sets the command configuration. + * @param hqspi: QSPI handle + * @param cmd : structure that contains the command configuration information + * @param Timeout : Time out duration + * @note This function is used only in Indirect Read or Write Modes + * @retval HAL status + */ +HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout) +{ + HAL_StatusTypeDef status = HAL_ERROR; + + /* Check the parameters */ + assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode)); + if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE) + { + assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction)); + } + + assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode)); + if (cmd->AddressMode != QSPI_ADDRESS_NONE) + { + assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize)); + } + + assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode)); + if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE) + { + assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize)); + } + + assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles)); + assert_param(IS_QSPI_DATA_MODE(cmd->DataMode)); + + assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode)); + assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle)); + assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode)); + + /* Process locked */ + __HAL_LOCK(hqspi); + + if(hqspi->State == HAL_QSPI_STATE_READY) + { + hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; + + /* Update QSPI state */ + hqspi->State = HAL_QSPI_STATE_BUSY; + + /* Wait till BUSY flag reset */ + status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, Timeout); + + if (status == HAL_OK) + { + /* Call the configuration function */ + QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE); + + if (cmd->DataMode == QSPI_DATA_NONE) + { + /* When there is no data phase, the transfer start as soon as the configuration is done + so wait until TC flag is set to go back in idle state */ + if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, Timeout) != HAL_OK) + { + status = HAL_TIMEOUT; + } + else + { + __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC); + + /* Update QSPI state */ + hqspi->State = HAL_QSPI_STATE_READY; + } + + } + else + { + /* Update QSPI state */ + hqspi->State = HAL_QSPI_STATE_READY; + } + } + } + else + { + status = HAL_BUSY; + } + + /* Process unlocked */ + __HAL_UNLOCK(hqspi); + + /* Return function status */ + return status; +} + +/** + * @brief Sets the command configuration in interrupt mode. + * @param hqspi: QSPI handle + * @param cmd : structure that contains the command configuration information + * @note This function is used only in Indirect Read or Write Modes + * @retval HAL status + */ +HAL_StatusTypeDef HAL_QSPI_Command_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd) +{ + HAL_StatusTypeDef status = HAL_ERROR; + + /* Check the parameters */ + assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode)); + if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE) + { + assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction)); + } + + assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode)); + if (cmd->AddressMode != QSPI_ADDRESS_NONE) + { + assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize)); + } + + assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode)); + if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE) + { + assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize)); + } + + assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles)); + assert_param(IS_QSPI_DATA_MODE(cmd->DataMode)); + + assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode)); + assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle)); + assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode)); + + /* Process locked */ + __HAL_LOCK(hqspi); + + if(hqspi->State == HAL_QSPI_STATE_READY) + { + hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; + + /* Update QSPI state */ + hqspi->State = HAL_QSPI_STATE_BUSY; + + /* Wait till BUSY flag reset */ + status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout); + + if (status == HAL_OK) + { + if (cmd->DataMode == QSPI_DATA_NONE) + { + /* When there is no data phase, the transfer start as soon as the configuration is done + so activate TC and TE interrupts */ + /* Enable the QSPI Transfer Error Interrupt */ + __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_TC); + } + + /* Call the configuration function */ + QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE); + + if (cmd->DataMode != QSPI_DATA_NONE) + { + /* Update QSPI state */ + hqspi->State = HAL_QSPI_STATE_READY; + } + } + } + else + { + status = HAL_BUSY; + } + + /* Process unlocked */ + __HAL_UNLOCK(hqspi); + + /* Return function status */ + return status; +} + +/** + * @brief Transmit an amount of data in blocking mode. + * @param hqspi: QSPI handle + * @param pData: pointer to data buffer + * @param Timeout : Time out duration + * @note This function is used only in Indirect Write Mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout) +{ + HAL_StatusTypeDef status = HAL_OK; + __IO uint32_t *data_reg = &hqspi->Instance->DR; + + /* Process locked */ + __HAL_LOCK(hqspi); + + if(hqspi->State == HAL_QSPI_STATE_READY) + { + if(pData != NULL ) + { + hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; + + /* Update state */ + hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX; + + /* Configure counters and size of the handle */ + hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1; + hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1; + hqspi->pTxBuffPtr = pData; + + /* Configure QSPI: CCR register with functional as indirect write */ + MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE); + + while(hqspi->TxXferCount > 0) + { + /* Wait until FT flag is set to send data */ + if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_FT, SET, Timeout) != HAL_OK) + { + status = HAL_TIMEOUT; + break; + } + + *(__IO uint8_t *)data_reg = *hqspi->pTxBuffPtr++; + hqspi->TxXferCount--; + } + + if (status == HAL_OK) + { + /* Wait until TC flag is set to go back in idle state */ + if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, Timeout) != HAL_OK) + { + status = HAL_TIMEOUT; + } + else + { + /* Clear Transfer Complete bit */ + __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC); + + /* Clear Busy bit */ + status = HAL_QSPI_Abort(hqspi); + } + } + + /* Update QSPI state */ + hqspi->State = HAL_QSPI_STATE_READY; + } + else + { + status = HAL_ERROR; + } + } + else + { + status = HAL_BUSY; + } + + /* Process unlocked */ + __HAL_UNLOCK(hqspi); + + return status; +} + + +/** + * @brief Receive an amount of data in blocking mode + * @param hqspi: QSPI handle + * @param pData: pointer to data buffer + * @param Timeout : Time out duration + * @note This function is used only in Indirect Read Mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t addr_reg = READ_REG(hqspi->Instance->AR); + __IO uint32_t *data_reg = &hqspi->Instance->DR; + + /* Process locked */ + __HAL_LOCK(hqspi); + + if(hqspi->State == HAL_QSPI_STATE_READY) + { + if(pData != NULL ) + { + hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; + + /* Update state */ + hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX; + + /* Configure counters and size of the handle */ + hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1; + hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1; + hqspi->pRxBuffPtr = pData; + + /* Configure QSPI: CCR register with functional as indirect read */ + MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ); + + /* Start the transfer by re-writing the address in AR register */ + WRITE_REG(hqspi->Instance->AR, addr_reg); + + while(hqspi->RxXferCount > 0) + { + /* Wait until FT or TC flag is set to read received data */ + if(QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, Timeout) != HAL_OK) + { + status = HAL_TIMEOUT; + break; + } + + *hqspi->pRxBuffPtr++ = *(__IO uint8_t *)data_reg; + hqspi->RxXferCount--; + } + + if (status == HAL_OK) + { + /* Wait until TC flag is set to go back in idle state */ + if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, Timeout) != HAL_OK) + { + status = HAL_TIMEOUT; + } + else + { + /* Clear Transfer Complete bit */ + __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC); + + /* Workaround - Extra data written in the FIFO at the end of a read transfer */ + status = HAL_QSPI_Abort(hqspi); + } + } + + /* Update QSPI state */ + hqspi->State = HAL_QSPI_STATE_READY; + } + else + { + status = HAL_ERROR; + } + } + else + { + status = HAL_BUSY; + } + + /* Process unlocked */ + __HAL_UNLOCK(hqspi); + + return status; +} + +/** + * @brief Send an amount of data in interrupt mode + * @param hqspi: QSPI handle + * @param pData: pointer to data buffer + * @note This function is used only in Indirect Write Mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_QSPI_Transmit_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hqspi); + + if(hqspi->State == HAL_QSPI_STATE_READY) + { + if(pData != NULL ) + { + hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; + + /* Update state */ + hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX; + + /* Configure counters and size of the handle */ + hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1; + hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1; + hqspi->pTxBuffPtr = pData; + + /* Configure QSPI: CCR register with functional as indirect write */ + MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE); + + /* Enable the QSPI transfer error, FIFO threshold and transfert complete Interrupts */ + __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC); + + } + else + { + status = HAL_ERROR; + } + } + else + { + status = HAL_BUSY; + } + + /* Process unlocked */ + __HAL_UNLOCK(hqspi); + + return status; +} + +/** + * @brief Receive an amount of data in no-blocking mode with Interrupt + * @param hqspi: QSPI handle + * @param pData: pointer to data buffer + * @note This function is used only in Indirect Read Mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_QSPI_Receive_IT(QSPI_HandleTypeDef *hqspi, uint8_t *pData) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t addr_reg = READ_REG(hqspi->Instance->AR); + + /* Process locked */ + __HAL_LOCK(hqspi); + + if(hqspi->State == HAL_QSPI_STATE_READY) + { + if(pData != NULL ) + { + hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; + + /* Update state */ + hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX; + + /* Configure counters and size of the handle */ + hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1; + hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1; + hqspi->pRxBuffPtr = pData; + + /* Configure QSPI: CCR register with functional as indirect read */ + MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ); + + /* Start the transfer by re-writing the address in AR register */ + WRITE_REG(hqspi->Instance->AR, addr_reg); + + /* Enable the QSPI transfer error, FIFO threshold and transfert complete Interrupts */ + __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TE | QSPI_IT_FT | QSPI_IT_TC); + } + else + { + status = HAL_ERROR; + } + } + else + { + status = HAL_BUSY; + } + + /* Process unlocked */ + __HAL_UNLOCK(hqspi); + + return status; +} + +/** + * @brief Sends an amount of data in non blocking mode with DMA. + * @param hqspi: QSPI handle + * @param pData: pointer to data buffer + * @note This function is used only in Indirect Write Mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_QSPI_Transmit_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t *tmp; + + /* Process locked */ + __HAL_LOCK(hqspi); + + if(hqspi->State == HAL_QSPI_STATE_READY) + { + if(pData != NULL ) + { + hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; + + /* Update state */ + hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_TX; + + /* Configure counters and size of the handle */ + hqspi->TxXferCount = READ_REG(hqspi->Instance->DLR) + 1; + hqspi->TxXferSize = READ_REG(hqspi->Instance->DLR) + 1; + hqspi->pTxBuffPtr = pData; + + /* Configure QSPI: CCR register with functional mode as indirect write */ + MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE); + + /* Set the QSPI DMA transfer complete callback */ + hqspi->hdma->XferCpltCallback = QSPI_DMATxCplt; + + /* Set the QSPI DMA Half transfer complete callback */ + hqspi->hdma->XferHalfCpltCallback = QSPI_DMATxHalfCplt; + + /* Set the DMA error callback */ + hqspi->hdma->XferErrorCallback = QSPI_DMAError; + + /* Configure the direction of the DMA */ + hqspi->hdma->Init.Direction = DMA_MEMORY_TO_PERIPH; + MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction); + + /* Enable the QSPI transmit DMA Channel */ + tmp = (uint32_t*)&pData; + HAL_DMA_Start_IT(hqspi->hdma, *(uint32_t*)tmp, (uint32_t)&hqspi->Instance->DR, hqspi->TxXferSize); + + /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */ + SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN); + } + else + { + status = HAL_OK; + } + } + else + { + status = HAL_BUSY; + } + + /* Process unlocked */ + __HAL_UNLOCK(hqspi); + + return status; +} + +/** + * @brief Receives an amount of data in non blocking mode with DMA. + * @param hqspi: QSPI handle + * @param pData: pointer to data buffer. + * @note This function is used only in Indirect Read Mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_QSPI_Receive_DMA(QSPI_HandleTypeDef *hqspi, uint8_t *pData) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t *tmp; + uint32_t addr_reg = READ_REG(hqspi->Instance->AR); + + /* Process locked */ + __HAL_LOCK(hqspi); + + if(hqspi->State == HAL_QSPI_STATE_READY) + { + if(pData != NULL ) + { + hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; + + /* Update state */ + hqspi->State = HAL_QSPI_STATE_BUSY_INDIRECT_RX; + + /* Configure counters and size of the handle */ + hqspi->RxXferCount = READ_REG(hqspi->Instance->DLR) + 1; + hqspi->RxXferSize = READ_REG(hqspi->Instance->DLR) + 1; + hqspi->pRxBuffPtr = pData; + + /* Set the QSPI DMA transfer complete callback */ + hqspi->hdma->XferCpltCallback = QSPI_DMARxCplt; + + /* Set the QSPI DMA Half transfer complete callback */ + hqspi->hdma->XferHalfCpltCallback = QSPI_DMARxHalfCplt; + + /* Set the DMA error callback */ + hqspi->hdma->XferErrorCallback = QSPI_DMAError; + + /* Configure the direction of the DMA */ + hqspi->hdma->Init.Direction = DMA_PERIPH_TO_MEMORY; + MODIFY_REG(hqspi->hdma->Instance->CR, DMA_SxCR_DIR, hqspi->hdma->Init.Direction); + + /* Enable the DMA Channel */ + tmp = (uint32_t*)&pData; + HAL_DMA_Start_IT(hqspi->hdma, (uint32_t)&hqspi->Instance->DR, *(uint32_t*)tmp, hqspi->RxXferSize); + + /* Configure QSPI: CCR register with functional as indirect read */ + MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ); + + /* Start the transfer by re-writing the address in AR register */ + WRITE_REG(hqspi->Instance->AR, addr_reg); + + /* Enable the DMA transfer by setting the DMAEN bit in the QSPI CR register */ + SET_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN); + } + else + { + status = HAL_ERROR; + } + } + else + { + status = HAL_BUSY; + } + + /* Process unlocked */ + __HAL_UNLOCK(hqspi); + + return status; +} + +/** + * @brief Configure the QSPI Automatic Polling Mode in blocking mode. + * @param hqspi: QSPI handle + * @param cmd: structure that contains the command configuration information. + * @param cfg: structure that contains the polling configuration information. + * @param Timeout : Time out duration + * @note This function is used only in Automatic Polling Mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout) +{ + HAL_StatusTypeDef status = HAL_ERROR; + + /* Check the parameters */ + assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode)); + if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE) + { + assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction)); + } + + assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode)); + if (cmd->AddressMode != QSPI_ADDRESS_NONE) + { + assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize)); + } + + assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode)); + if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE) + { + assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize)); + } + + assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles)); + assert_param(IS_QSPI_DATA_MODE(cmd->DataMode)); + + assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode)); + assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle)); + assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode)); + + assert_param(IS_QSPI_INTERVAL(cfg->Interval)); + assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize)); + assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode)); + + /* Process locked */ + __HAL_LOCK(hqspi); + + if(hqspi->State == HAL_QSPI_STATE_READY) + { + + hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; + + /* Update state */ + hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING; + + /* Wait till BUSY flag reset */ + status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, Timeout); + + if (status == HAL_OK) + { + /* Configure QSPI: PSMAR register with the status match value */ + WRITE_REG(hqspi->Instance->PSMAR, cfg->Match); + + /* Configure QSPI: PSMKR register with the status mask value */ + WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask); + + /* Configure QSPI: PIR register with the interval value */ + WRITE_REG(hqspi->Instance->PIR, cfg->Interval); + + /* Configure QSPI: CR register with Match mode and Automatic stop enabled + (otherwise there will be an infinite loop in blocking mode) */ + MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS), + (cfg->MatchMode | QSPI_AUTOMATIC_STOP_ENABLE)); + + /* Call the configuration function */ + cmd->NbData = cfg->StatusBytesSize; + QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING); + + /* Wait until SM flag is set to go back in idle state */ + if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_SM, SET, Timeout) != HAL_OK) + { + status = HAL_TIMEOUT; + } + else + { + __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_SM); + + /* Update state */ + hqspi->State = HAL_QSPI_STATE_READY; + } + } + } + else + { + status = HAL_BUSY; + } + /* Process unlocked */ + __HAL_UNLOCK(hqspi); + + /* Return function status */ + return status; +} + +/** + * @brief Configure the QSPI Automatic Polling Mode in non-blocking mode. + * @param hqspi: QSPI handle + * @param cmd: structure that contains the command configuration information. + * @param cfg: structure that contains the polling configuration information. + * @note This function is used only in Automatic Polling Mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_QSPI_AutoPolling_IT(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg) +{ + HAL_StatusTypeDef status = HAL_ERROR; + + /* Check the parameters */ + assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode)); + if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE) + { + assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction)); + } + + assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode)); + if (cmd->AddressMode != QSPI_ADDRESS_NONE) + { + assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize)); + } + + assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode)); + if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE) + { + assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize)); + } + + assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles)); + assert_param(IS_QSPI_DATA_MODE(cmd->DataMode)); + + assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode)); + assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle)); + assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode)); + + assert_param(IS_QSPI_INTERVAL(cfg->Interval)); + assert_param(IS_QSPI_STATUS_BYTES_SIZE(cfg->StatusBytesSize)); + assert_param(IS_QSPI_MATCH_MODE(cfg->MatchMode)); + assert_param(IS_QSPI_AUTOMATIC_STOP(cfg->AutomaticStop)); + + /* Process locked */ + __HAL_LOCK(hqspi); + +if(hqspi->State == HAL_QSPI_STATE_READY) + { + hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; + + /* Update state */ + hqspi->State = HAL_QSPI_STATE_BUSY_AUTO_POLLING; + + /* Wait till BUSY flag reset */ + status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout); + + if (status == HAL_OK) + { + /* Configure QSPI: PSMAR register with the status match value */ + WRITE_REG(hqspi->Instance->PSMAR, cfg->Match); + + /* Configure QSPI: PSMKR register with the status mask value */ + WRITE_REG(hqspi->Instance->PSMKR, cfg->Mask); + + /* Configure QSPI: PIR register with the interval value */ + WRITE_REG(hqspi->Instance->PIR, cfg->Interval); + + /* Configure QSPI: CR register with Match mode and Automatic stop mode */ + MODIFY_REG(hqspi->Instance->CR, (QUADSPI_CR_PMM | QUADSPI_CR_APMS), + (cfg->MatchMode | cfg->AutomaticStop)); + + /* Call the configuration function */ + cmd->NbData = cfg->StatusBytesSize; + QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_AUTO_POLLING); + + /* Enable the QSPI Transfer Error, FIFO threshold and status match Interrupt */ + __HAL_QSPI_ENABLE_IT(hqspi, (QSPI_IT_FT | QSPI_IT_SM | QSPI_IT_TE)); + } + } + else + { + status = HAL_BUSY; + } + + /* Process unlocked */ + __HAL_UNLOCK(hqspi); + + /* Return function status */ + return status; +} + +/** + * @brief Configure the Memory Mapped mode. + * @param hqspi: QSPI handle + * @param cmd: structure that contains the command configuration information. + * @param cfg: structure that contains the memory mapped configuration information. + * @note This function is used only in Memory mapped Mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg) +{ + HAL_StatusTypeDef status = HAL_ERROR; + + /* Check the parameters */ + assert_param(IS_QSPI_INSTRUCTION_MODE(cmd->InstructionMode)); + if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE) + { + assert_param(IS_QSPI_INSTRUCTION(cmd->Instruction)); + } + + assert_param(IS_QSPI_ADDRESS_MODE(cmd->AddressMode)); + if (cmd->AddressMode != QSPI_ADDRESS_NONE) + { + assert_param(IS_QSPI_ADDRESS_SIZE(cmd->AddressSize)); + } + + assert_param(IS_QSPI_ALTERNATE_BYTES_MODE(cmd->AlternateByteMode)); + if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE) + { + assert_param(IS_QSPI_ALTERNATE_BYTES_SIZE(cmd->AlternateBytesSize)); + } + + assert_param(IS_QSPI_DUMMY_CYCLES(cmd->DummyCycles)); + assert_param(IS_QSPI_DATA_MODE(cmd->DataMode)); + + assert_param(IS_QSPI_DDR_MODE(cmd->DdrMode)); + assert_param(IS_QSPI_DDR_HHC(cmd->DdrHoldHalfCycle)); + assert_param(IS_QSPI_SIOO_MODE(cmd->SIOOMode)); + + assert_param(IS_QSPI_TIMEOUT_ACTIVATION(cfg->TimeOutActivation)); + + /* Process locked */ + __HAL_LOCK(hqspi); + + if(hqspi->State == HAL_QSPI_STATE_READY) + { + hqspi->ErrorCode = HAL_QSPI_ERROR_NONE; + + /* Update state */ + hqspi->State = HAL_QSPI_STATE_BUSY_MEM_MAPPED; + + /* Wait till BUSY flag reset */ + status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout); + + if (status == HAL_OK) + { + /* Configure QSPI: CR register with time out counter enable */ + MODIFY_REG(hqspi->Instance->CR, QUADSPI_CR_TCEN, cfg->TimeOutActivation); + + if (cfg->TimeOutActivation == QSPI_TIMEOUT_COUNTER_ENABLE) + { + assert_param(IS_QSPI_TIMEOUT_PERIOD(cfg->TimeOutPeriod)); + + /* Configure QSPI: LPTR register with the low-power time out value */ + WRITE_REG(hqspi->Instance->LPTR, cfg->TimeOutPeriod); + + /* Enable the QSPI TimeOut Interrupt */ + __HAL_QSPI_ENABLE_IT(hqspi, QSPI_IT_TO); + } + + /* Call the configuration function */ + QSPI_Config(hqspi, cmd, QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED); + + } + } + else + { + status = HAL_BUSY; + + } + + /* Process unlocked */ + __HAL_UNLOCK(hqspi); + + /* Return function status */ + return status; +} + +/** + * @brief Transfer Error callbacks + * @param hqspi: QSPI handle + * @retval None + */ +__weak void HAL_QSPI_ErrorCallback(QSPI_HandleTypeDef *hqspi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_QSPI_ErrorCallback could be implemented in the user file + */ +} + +/** + * @brief Command completed callbacks. + * @param hqspi: QSPI handle + * @retval None + */ +__weak void HAL_QSPI_CmdCpltCallback(QSPI_HandleTypeDef *hqspi) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_QSPI_CmdCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callbacks. + * @param hqspi: QSPI handle + * @retval None + */ +__weak void HAL_QSPI_RxCpltCallback(QSPI_HandleTypeDef *hqspi) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_QSPI_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Tx Transfer completed callbacks. + * @param hqspi: QSPI handle + * @retval None + */ + __weak void HAL_QSPI_TxCpltCallback(QSPI_HandleTypeDef *hqspi) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_QSPI_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Half Transfer completed callbacks. + * @param hqspi: QSPI handle + * @retval None + */ +__weak void HAL_QSPI_RxHalfCpltCallback(QSPI_HandleTypeDef *hqspi) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_QSPI_RxHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Tx Half Transfer completed callbacks. + * @param hqspi: QSPI handle + * @retval None + */ + __weak void HAL_QSPI_TxHalfCpltCallback(QSPI_HandleTypeDef *hqspi) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_QSPI_TxHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief FIFO Threshold callbacks + * @param hqspi: QSPI handle + * @retval None + */ +__weak void HAL_QSPI_FifoThresholdCallback(QSPI_HandleTypeDef *hqspi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_QSPI_FIFOThresholdCallback could be implemented in the user file + */ +} + +/** + * @brief Status Match callbacks + * @param hqspi: QSPI handle + * @retval None + */ +__weak void HAL_QSPI_StatusMatchCallback(QSPI_HandleTypeDef *hqspi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_QSPI_StatusMatchCallback could be implemented in the user file + */ +} + +/** + * @brief Timeout callbacks + * @param hqspi: QSPI handle + * @retval None + */ +__weak void HAL_QSPI_TimeOutCallback(QSPI_HandleTypeDef *hqspi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_QSPI_TimeOutCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup QSPI_Exported_Functions_Group3 Peripheral Control and State functions + * @brief QSPI control and State functions + * +@verbatim + =============================================================================== + ##### Peripheral Control and State functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to : + (+) Check in run-time the state of the driver. + (+) Check the error code set during last operation. + (+) Abort any operation. +..... +@endverbatim + * @{ + */ + +/** + * @brief Return the QSPI state. + * @param hqspi: QSPI handle + * @retval HAL state + */ +HAL_QSPI_StateTypeDef HAL_QSPI_GetState(QSPI_HandleTypeDef *hqspi) +{ + return hqspi->State; +} + +/** +* @brief Return the QSPI error code +* @param hqspi: QSPI handle +* @retval QSPI Error Code +*/ +uint32_t HAL_QSPI_GetError(QSPI_HandleTypeDef *hqspi) +{ + return hqspi->ErrorCode; +} + +/** +* @brief Abort the current transmission +* @param hqspi: QSPI handle +* @retval HAL status +*/ +HAL_StatusTypeDef HAL_QSPI_Abort(QSPI_HandleTypeDef *hqspi) +{ + HAL_StatusTypeDef status = HAL_ERROR; + + /* Configure QSPI: CR register with Abort request */ + SET_BIT(hqspi->Instance->CR, QUADSPI_CR_ABORT); + + /* Wait until TC flag is set to go back in idle state */ + if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, hqspi->Timeout) != HAL_OK) + { + status = HAL_TIMEOUT; + } + else + { + __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC); + + /* Wait until BUSY flag is reset */ + status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_BUSY, RESET, hqspi->Timeout); + + /* Update state */ + hqspi->State = HAL_QSPI_STATE_READY; + } + + return status; +} + +/** @brief Set QSPI timeout + * @param hqspi: QSPI handle. + * @param Timeout: Timeout for the QSPI memory access. + * @retval None + */ +void HAL_QSPI_SetTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Timeout) +{ + hqspi->Timeout = Timeout; +} + +/** +* @} +*/ + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief DMA QSPI receive process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void QSPI_DMARxCplt(DMA_HandleTypeDef *hdma) +{ + QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + hqspi->RxXferCount = 0; + + /* Wait for QSPI TC Flag */ + if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, hqspi->Timeout) != HAL_OK) + { + /* Time out Occurred */ + HAL_QSPI_ErrorCallback(hqspi); + } + else + { + /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */ + CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN); + + /* Disable the DMA channel */ + HAL_DMA_Abort(hdma); + + /* Clear Transfer Complete bit */ + __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC); + + /* Workaround - Extra data written in the FIFO at the end of a read transfer */ + HAL_QSPI_Abort(hqspi); + + /* Update state */ + hqspi->State = HAL_QSPI_STATE_READY; + + HAL_QSPI_RxCpltCallback(hqspi); + } +} + +/** + * @brief DMA QSPI transmit process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void QSPI_DMATxCplt(DMA_HandleTypeDef *hdma) +{ + QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + hqspi->TxXferCount = 0; + + /* Wait for QSPI TC Flag */ + if(QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, hqspi->Timeout) != HAL_OK) + { + /* Time out Occurred */ + HAL_QSPI_ErrorCallback(hqspi); + } + else + { + /* Disable the DMA transfer by clearing the DMAEN bit in the QSPI CR register */ + CLEAR_BIT(hqspi->Instance->CR, QUADSPI_CR_DMAEN); + + /* Disable the DMA channel */ + HAL_DMA_Abort(hdma); + + /* Clear Transfer Complete bit */ + __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC); + + /* Clear Busy bit */ + HAL_QSPI_Abort(hqspi); + + /* Update state */ + hqspi->State = HAL_QSPI_STATE_READY; + + HAL_QSPI_TxCpltCallback(hqspi); + } +} + +/** + * @brief DMA QSPI receive process half complete callback + * @param hdma : DMA handle + * @retval None + */ +static void QSPI_DMARxHalfCplt(DMA_HandleTypeDef *hdma) +{ + QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + HAL_QSPI_RxHalfCpltCallback(hqspi); +} + +/** + * @brief DMA QSPI transmit process half complete callback + * @param hdma : DMA handle + * @retval None + */ +static void QSPI_DMATxHalfCplt(DMA_HandleTypeDef *hdma) +{ + QSPI_HandleTypeDef* hqspi = (QSPI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + HAL_QSPI_TxHalfCpltCallback(hqspi); +} + +/** + * @brief DMA QSPI communication error callback. + * @param hdma: DMA handle + * @retval None + */ +static void QSPI_DMAError(DMA_HandleTypeDef *hdma) +{ + QSPI_HandleTypeDef* hqspi = ( QSPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + hqspi->RxXferCount = 0; + hqspi->TxXferCount = 0; + hqspi->State = HAL_QSPI_STATE_ERROR; + hqspi->ErrorCode |= HAL_QSPI_ERROR_DMA; + + HAL_QSPI_ErrorCallback(hqspi); +} + +/** + * @brief This function wait a flag state until time out. + * @param hqspi: QSPI handle + * @param Flag: Flag checked + * @param State: Value of the flag expected + * @param Timeout: Duration of the time out + * @retval HAL status + */ +static HAL_StatusTypeDef QSPI_WaitFlagStateUntilTimeout(QSPI_HandleTypeDef *hqspi, uint32_t Flag, + FlagStatus State, uint32_t Timeout) +{ + uint32_t tickstart = HAL_GetTick(); + + /* Wait until flag is in expected state */ + while((FlagStatus)(__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State) + { + /* Check for the Timeout */ + if (Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout)) + { + hqspi->State = HAL_QSPI_STATE_ERROR; + hqspi->ErrorCode |= HAL_QSPI_ERROR_TIMEOUT; + + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @brief This function configures the communication registers + * @param hqspi: QSPI handle + * @param cmd: structure that contains the command configuration information + * @param FunctionalMode: functional mode to configured + * This parameter can be one of the following values: + * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_WRITE: Indirect write mode + * @arg QSPI_FUNCTIONAL_MODE_INDIRECT_READ: Indirect read mode + * @arg QSPI_FUNCTIONAL_MODE_AUTO_POLLING: Automatic polling mode + * @arg QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED: Memory-mapped mode + * @retval None + */ +static void QSPI_Config(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t FunctionalMode) +{ + assert_param(IS_QSPI_FUNCTIONAL_MODE(FunctionalMode)); + + if ((cmd->DataMode != QSPI_DATA_NONE) && (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED)) + { + /* Configure QSPI: DLR register with the number of data to read or write */ + WRITE_REG(hqspi->Instance->DLR, (cmd->NbData - 1)); + } + + if (cmd->InstructionMode != QSPI_INSTRUCTION_NONE) + { + if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE) + { + /* Configure QSPI: ABR register with alternate bytes value */ + WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes); + + if (cmd->AddressMode != QSPI_ADDRESS_NONE) + { + /*---- Command with instruction, address and alternate bytes ----*/ + /* Configure QSPI: CCR register with all communications parameters */ + WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | + cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateBytesSize | + cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode | + cmd->InstructionMode | cmd->Instruction | FunctionalMode)); + + if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED) + { + /* Configure QSPI: AR register with address value */ + WRITE_REG(hqspi->Instance->AR, cmd->Address); + } + } + else + { + /*---- Command with instruction and alternate bytes ----*/ + /* Configure QSPI: CCR register with all communications parameters */ + WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | + cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateBytesSize | + cmd->AlternateByteMode | cmd->AddressMode | cmd->InstructionMode | + cmd->Instruction | FunctionalMode)); + } + } + else + { + if (cmd->AddressMode != QSPI_ADDRESS_NONE) + { + /*---- Command with instruction and address ----*/ + /* Configure QSPI: CCR register with all communications parameters */ + WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | + cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateByteMode | + cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode | + cmd->Instruction | FunctionalMode)); + + if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED) + { + /* Configure QSPI: AR register with address value */ + WRITE_REG(hqspi->Instance->AR, cmd->Address); + } + } + else + { + /*---- Command with only instruction ----*/ + /* Configure QSPI: CCR register with all communications parameters */ + WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | + cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateByteMode | + cmd->AddressMode | cmd->InstructionMode | cmd->Instruction | + FunctionalMode)); + } + } + } + else + { + if (cmd->AlternateByteMode != QSPI_ALTERNATE_BYTES_NONE) + { + /* Configure QSPI: ABR register with alternate bytes value */ + WRITE_REG(hqspi->Instance->ABR, cmd->AlternateBytes); + + if (cmd->AddressMode != QSPI_ADDRESS_NONE) + { + /*---- Command with address and alternate bytes ----*/ + /* Configure QSPI: CCR register with all communications parameters */ + WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | + cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateBytesSize | + cmd->AlternateByteMode | cmd->AddressSize | cmd->AddressMode | + cmd->InstructionMode | FunctionalMode)); + + if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED) + { + /* Configure QSPI: AR register with address value */ + WRITE_REG(hqspi->Instance->AR, cmd->Address); + } + } + else + { + /*---- Command with only alternate bytes ----*/ + /* Configure QSPI: CCR register with all communications parameters */ + WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | + cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateBytesSize | + cmd->AlternateByteMode | cmd->AddressMode | cmd->InstructionMode | + FunctionalMode)); + } + } + else + { + if (cmd->AddressMode != QSPI_ADDRESS_NONE) + { + /*---- Command with only address ----*/ + /* Configure QSPI: CCR register with all communications parameters */ + WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | + cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateByteMode | + cmd->AddressSize | cmd->AddressMode | cmd->InstructionMode | + FunctionalMode)); + + if (FunctionalMode != QSPI_FUNCTIONAL_MODE_MEMORY_MAPPED) + { + /* Configure QSPI: AR register with address value */ + WRITE_REG(hqspi->Instance->AR, cmd->Address); + } + } + else + { + /*---- Command with only data phase ----*/ + if (cmd->DataMode != QSPI_DATA_NONE) + { + /* Configure QSPI: CCR register with all communications parameters */ + WRITE_REG(hqspi->Instance->CCR, (cmd->DdrMode | cmd->DdrHoldHalfCycle | cmd->SIOOMode | + cmd->DataMode | (cmd->DummyCycles << 18) | cmd->AlternateByteMode | + cmd->AddressMode | cmd->InstructionMode | FunctionalMode)); + } + } + } + } +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F446xx */ + +#endif /* HAL_QSPI_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c new file mode 100644 index 0000000..2103007 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c @@ -0,0 +1,1237 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_rcc.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief RCC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Reset and Clock Control (RCC) peripheral: + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + @verbatim + ============================================================================== + ##### RCC specific features ##### + ============================================================================== + [..] + After reset the device is running from Internal High Speed oscillator + (HSI 16MHz) with Flash 0 wait state, Flash prefetch buffer, D-Cache + and I-Cache are disabled, and all peripherals are off except internal + SRAM, Flash and JTAG. + (+) There is no prescaler on High speed (AHB) and Low speed (APB) busses; + all peripherals mapped on these busses are running at HSI speed. + (+) The clock for all peripherals is switched off, except the SRAM and FLASH. + (+) All GPIOs are in input floating state, except the JTAG pins which + are assigned to be used for debug purpose. + + [..] + Once the device started from reset, the user application has to: + (+) Configure the clock source to be used to drive the System clock + (if the application needs higher frequency/performance) + (+) Configure the System clock frequency and Flash settings + (+) Configure the AHB and APB busses prescalers + (+) Enable the clock for the peripheral(s) to be used + (+) Configure the clock source(s) for peripherals which clocks are not + derived from the System clock (I2S, RTC, ADC, USB OTG FS/SDIO/RNG) + + ##### RCC Limitations ##### + ============================================================================== + [..] + A delay between an RCC peripheral clock enable and the effective peripheral + enabling should be taken into account in order to manage the peripheral read/write + from/to registers. + (+) This delay depends on the peripheral mapping. + (+) If peripheral is mapped on AHB: the delay is 2 AHB clock cycle + after the clock enable bit is set on the hardware register + (+) If peripheral is mapped on APB: the delay is 2 APB clock cycle + after the clock enable bit is set on the hardware register + + [..] + Possible Workarounds: + (#) Enable the peripheral clock sometimes before the peripheral read/write + register is required. + (#) For AHB peripheral, insert two dummy read to the peripheral register. + (#) For APB peripheral, insert a dummy read to the peripheral register. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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. + * + ****************************************************************************** + * + * Modifications by Robert Fisk + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup RCC RCC + * @brief RCC HAL module driver + * @{ + */ + +#ifdef HAL_RCC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup RCC_Private_Constants + * @{ + */ +#define CLOCKSWITCH_TIMEOUT_VALUE ((uint32_t)5000) /* 5 s */ + +/* Private macro -------------------------------------------------------------*/ +#define __MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define MCO1_GPIO_PORT GPIOA +#define MCO1_PIN GPIO_PIN_8 + +#define __MCO2_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() +#define MCO2_GPIO_PORT GPIOC +#define MCO2_PIN GPIO_PIN_9 +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup RCC_Private_Variables RCC Private Variables + * @{ + */ +const uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9}; +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup RCC_Exported_Functions RCC Exported Functions + * @{ + */ + +/** @defgroup RCC_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 configure the internal/external oscillators + (HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System busses clocks (SYSCLK, AHB, APB1 + and APB2). + + [..] Internal/external clock and PLL configuration + (#) HSI (high-speed internal), 16 MHz factory-trimmed RC used directly or through + the PLL as System clock source. + + (#) LSI (low-speed internal), 32 KHz low consumption RC used as IWDG and/or RTC + clock source. + + (#) HSE (high-speed external), 4 to 26 MHz crystal oscillator used directly or + through the PLL as System clock source. Can be used also as RTC clock source. + + (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source. + + (#) PLL (clocked by HSI or HSE), featuring two different output clocks: + (++) The first output is used to generate the high speed system clock (up to 168 MHz) + (++) The second output is used to generate the clock for the USB OTG FS (48 MHz), + the random analog generator (<=48 MHz) and the SDIO (<= 48 MHz). + + (#) CSS (Clock security system), once enable using the macro __HAL_RCC_CSS_ENABLE() + and if a HSE clock failure occurs(HSE used directly or through PLL as System + clock source), the System clocks automatically switched to HSI and an interrupt + is generated if enabled. The interrupt is linked to the Cortex-M4 NMI + (Non-Maskable Interrupt) exception vector. + + (#) MCO1 (microcontroller clock output), used to output HSI, LSE, HSE or PLL + clock (through a configurable prescaler) on PA8 pin. + + (#) MCO2 (microcontroller clock output), used to output HSE, PLL, SYSCLK or PLLI2S + clock (through a configurable prescaler) on PC9 pin. + + [..] System, AHB and APB busses clocks configuration + (#) Several clock sources can be used to drive the System clock (SYSCLK): HSI, + HSE and PLL. + The AHB clock (HCLK) is derived from System clock through configurable + prescaler and used to clock the CPU, memory and peripherals mapped + on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived + from AHB clock through configurable prescalers and used to clock + the peripherals mapped on these busses. You can use + "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks. + + -@- All the peripheral clocks are derived from the System clock (SYSCLK) except: + (+@) I2S: the I2S clock can be derived either from a specific PLL (PLLI2S) or + from an external clock mapped on the I2S_CKIN pin. + You have to use __HAL_RCC_PLLI2S_CONFIG() macro to configure this clock. + (+@) SAI: the SAI clock can be derived either from a specific PLL (PLLI2S) or (PLLSAI) or + from an external clock mapped on the I2S_CKIN pin. + You have to use __HAL_RCC_PLLI2S_CONFIG() macro to configure this clock. + (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock + divided by 2 to 31. You have to use __HAL_RCC_RTC_CONFIG() and __HAL_RCC_RTC_ENABLE() + macros to configure this clock. + (+@) USB OTG FS, SDIO and RTC: USB OTG FS require a frequency equal to 48 MHz + to work correctly, while the SDIO require a frequency equal or lower than + to 48. This clock is derived of the main PLL through PLLQ divider. + (+@) IWDG clock which is always the LSI clock. + + (#) For the STM32F405xx/07xx and STM32F415xx/17xx devices, the maximum + frequency of the SYSCLK and HCLK is 168 MHz, PCLK2 84 MHz and PCLK1 42 MHz. + Depending on the device voltage range, the maximum frequency should + be adapted accordingly (refer to the product datasheets for more details). + + (#) For the STM32F42xxx and STM32F43xxx devices, the maximum frequency + of the SYSCLK and HCLK is 180 MHz, PCLK2 90 MHz and PCLK1 45 MHz. + Depending on the device voltage range, the maximum frequency should + be adapted accordingly (refer to the product datasheets for more details). + + (#) For the STM32F401xx, the maximum frequency of the SYSCLK and HCLK is 84 MHz, + PCLK2 84 MHz and PCLK1 42 MHz. + Depending on the device voltage range, the maximum frequency should + be adapted accordingly (refer to the product datasheets for more details). +@endverbatim + * @{ + */ + +/** + * @brief Resets the RCC clock configuration to the default reset state. + * @note The default reset state of the clock configuration is given below: + * - HSI ON and used as system clock source + * - HSE, PLL and PLLI2S OFF + * - AHB, APB1 and APB2 prescaler set to 1. + * - CSS, MCO1 and MCO2 OFF + * - All interrupts disabled + * @note This function doesn't modify the configuration of the + * - Peripheral clocks + * - LSI, LSE and RTC clocks + * @retval None + */ +void HAL_RCC_DeInit(void) +{ + /* Set HSION bit */ + SET_BIT(RCC->CR, RCC_CR_HSION | RCC_CR_HSITRIM_4); + + /* Reset CFGR register */ + CLEAR_REG(RCC->CFGR); + + /* Reset HSEON, CSSON, PLLON, PLLI2S */ + CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON| RCC_CR_PLLI2SON); + + /* Reset PLLCFGR register */ + CLEAR_REG(RCC->PLLCFGR); + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_2); + + /* Reset PLLI2SCFGR register */ + CLEAR_REG(RCC->PLLI2SCFGR); + SET_BIT(RCC->PLLI2SCFGR, RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SR_1); + + /* Reset HSEBYP bit */ + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); + + /* Disable all interrupts */ + CLEAR_REG(RCC->CIR); +} + +/** + * @brief Initializes the RCC Oscillators according to the specified parameters in the + * RCC_OscInitTypeDef. + * @param RCC_OscInitStruct: pointer to an RCC_OscInitTypeDef structure that + * contains the configuration information for the RCC Oscillators. + * @note The PLL is not disabled when used as system clock. + * @retval HAL status + */ +__weak HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) +{ + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType)); + /*------------------------------- HSE Configuration ------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) + { + /* Check the parameters */ + assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState)); + /* When the HSE is used as system clock or clock source for PLL in these cases HSE will not disabled */ + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE) ||\ + ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE))) + { +// if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)) +// { + return HAL_ERROR; +// } + } + else + { + /* Reset HSEON and HSEBYP bits before configuring the HSE --------------*/ + __HAL_RCC_HSE_CONFIG(RCC_HSE_OFF); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSE is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Set the new HSE configuration ---------------------------------------*/ + __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState); + + /* Check the HSE State */ + if((RCC_OscInitStruct->HSEState) != RCC_HSE_OFF) + { + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSE is bypassed or disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } + /*----------------------------- HSI Configuration --------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) + { + /* Check the parameters */ + assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState)); + assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue)); + + /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */ + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI) ||\ + ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI))) + { + /* When HSI is used as system clock it will not disabled */ + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON)) + { + return HAL_ERROR; + } + /* Otherwise, just the calibration is allowed */ + else + { + /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); + } + } + else + { + /* Check the HSI State */ + if((RCC_OscInitStruct->HSIState)!= RCC_HSI_OFF) + { + /* Enable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); + } + else + { + /* Disable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } + /*------------------------------ LSI Configuration -------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) + { + /* Check the parameters */ + assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState)); + + /* Check the LSI State */ + if((RCC_OscInitStruct->LSIState)!= RCC_LSI_OFF) + { + /* Enable the Internal Low Speed oscillator (LSI). */ + __HAL_RCC_LSI_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Disable the Internal Low Speed oscillator (LSI). */ + __HAL_RCC_LSI_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + /*------------------------------ LSE Configuration -------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) + { + /* Check the parameters */ + assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState)); + + /* Enable Power Clock*/ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* Enable write access to Backup domain */ + PWR->CR |= PWR_CR_DBP; + + /* Wait for Backup domain Write protection disable */ + tickstart = HAL_GetTick(); + + while((PWR->CR & PWR_CR_DBP) == RESET) + { + if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Reset LSEON and LSEBYP bits before configuring the LSE ----------------*/ + __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Set the new LSE configuration -----------------------------------------*/ + __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState); + /* Check the LSE State */ + if((RCC_OscInitStruct->LSEState) != RCC_LSE_OFF) + { + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + /*-------------------------------- PLL Configuration -----------------------*/ + /* Check the parameters */ + assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState)); + if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE) + { + /* Check if the PLL is used as system clock or not */ + if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL) + { + if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON) + { + /* Check the parameters */ + assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource)); + assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM)); + assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN)); + assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP)); + assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ)); + + /* Disable the main PLL. */ + __HAL_RCC_PLL_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Configure the main PLL clock source, multiplication and division factors. */ + WRITE_REG(RCC->PLLCFGR, (RCC_OscInitStruct->PLL.PLLSource | \ + RCC_OscInitStruct->PLL.PLLM | \ + (RCC_OscInitStruct->PLL.PLLN << POSITION_VAL(RCC_PLLCFGR_PLLN)) | \ + (((RCC_OscInitStruct->PLL.PLLP >> 1) -1) << POSITION_VAL(RCC_PLLCFGR_PLLP)) | \ + (RCC_OscInitStruct->PLL.PLLQ << POSITION_VAL(RCC_PLLCFGR_PLLQ)))); + /* Enable the main PLL. */ + __HAL_RCC_PLL_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Disable the main PLL. */ + __HAL_RCC_PLL_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + else + { + return HAL_ERROR; + } + } + return HAL_OK; +} + +/** + * @brief Initializes the CPU, AHB and APB busses clocks according to the specified + * parameters in the RCC_ClkInitStruct. + * @param RCC_ClkInitStruct: pointer to an RCC_OscInitTypeDef structure that + * contains the configuration information for the RCC peripheral. + * @param FLatency: FLASH Latency, this parameter depend on device selected + * + * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency + * and updated by HAL_RCC_GetHCLKFreq() function called within this function + * + * @note The HSI is used (enabled by hardware) as system clock source after + * startup from Reset, wake-up from STOP and STANDBY mode, or in case + * of failure of the HSE used directly or indirectly as system clock + * (if the Clock Security System CSS is enabled). + * + * @note A switch from one clock source to another occurs only if the target + * clock source is ready (clock stable after startup delay or PLL locked). + * If a clock source which is not yet ready is selected, the switch will + * occur when the clock source will be ready. + * + * @note Depending on the device voltage range, the software has to set correctly + * HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency + * (for more details refer to section above "Initialization/de-initialization functions") + * @retval None + */ +HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency) +{ + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType)); + assert_param(IS_FLASH_LATENCY(FLatency)); + + /* To correctly read data from FLASH memory, the number of wait states (LATENCY) + must be correctly programmed according to the frequency of the CPU clock + (HCLK) and the supply voltage of the device. */ + + /* Increasing the CPU frequency */ + if(FLatency > (FLASH->ACR & FLASH_ACR_LATENCY)) + { + /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ + __HAL_FLASH_SET_LATENCY(FLatency); + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency) + { + return HAL_ERROR; + } + + /*-------------------------- HCLK Configuration --------------------------*/ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) + { + assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider)); + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider); + } + + /*------------------------- SYSCLK Configuration ---------------------------*/ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) + { + assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource)); + + /* HSE is selected as System Clock Source */ + if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) + { + /* Check the HSE ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) + { + return HAL_ERROR; + } + } + /* PLL is selected as System Clock Source */ + else if((RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) || + (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLRCLK)) + { + /* Check the PLL ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) + { + return HAL_ERROR; + } + } + /* HSI is selected as System Clock Source */ + else + { + /* Check the HSI ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) + { + return HAL_ERROR; + } + } + + __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource); + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) + { + while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE) + { + if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) + { + while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) + { + if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLRCLK) + { + while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLRCLK) + { + if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + while(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI) + { + if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } + /* Decreasing the CPU frequency */ + else + { + /*-------------------------- HCLK Configuration --------------------------*/ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) + { + assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider)); + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider); + } + + /*------------------------- SYSCLK Configuration -------------------------*/ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) + { + assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource)); + + /* HSE is selected as System Clock Source */ + if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) + { + /* Check the HSE ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) + { + return HAL_ERROR; + } + } + /* PLL is selected as System Clock Source */ + else if((RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) || + (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLRCLK)) + { + /* Check the PLL ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) + { + return HAL_ERROR; + } + } + /* HSI is selected as System Clock Source */ + else + { + /* Check the HSI ready flag */ + if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) + { + return HAL_ERROR; + } + } + __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource); + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) + { + while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE) + { + if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) + { + while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) + { + if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLRCLK) + { + while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLRCLK) + { + if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + while(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI) + { + if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + + /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ + __HAL_FLASH_SET_LATENCY(FLatency); + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency) + { + return HAL_ERROR; + } + } + + /*-------------------------- PCLK1 Configuration ---------------------------*/ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) + { + assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider)); + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider); + } + + /*-------------------------- PCLK2 Configuration ---------------------------*/ + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2) + { + assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider)); + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3)); + } + + /* Configure the source of time base considering new system clocks settings*/ + HAL_InitTick (TICK_INT_PRIORITY); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions + * @brief RCC clocks control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the RCC Clocks + frequencies. + +@endverbatim + * @{ + */ + +/** + * @brief Selects the clock source to output on MCO1 pin(PA8) or on MCO2 pin(PC9). + * @note PA8/PC9 should be configured in alternate function mode. + * @param RCC_MCOx: specifies the output direction for the clock source. + * This parameter can be one of the following values: + * @arg RCC_MCO1: Clock source to output on MCO1 pin(PA8). + * @arg RCC_MCO2: Clock source to output on MCO2 pin(PC9). + * @param RCC_MCOSource: specifies the clock source to output. + * This parameter can be one of the following values: + * @arg RCC_MCO1SOURCE_HSI: HSI clock selected as MCO1 source + * @arg RCC_MCO1SOURCE_LSE: LSE clock selected as MCO1 source + * @arg RCC_MCO1SOURCE_HSE: HSE clock selected as MCO1 source + * @arg RCC_MCO1SOURCE_PLLCLK: main PLL clock selected as MCO1 source + * @arg RCC_MCO2SOURCE_SYSCLK: System clock (SYSCLK) selected as MCO2 source + * @arg RCC_MCO2SOURCE_PLLI2SCLK: PLLI2S clock selected as MCO2 source + * @arg RCC_MCO2SOURCE_HSE: HSE clock selected as MCO2 source + * @arg RCC_MCO2SOURCE_PLLCLK: main PLL clock selected as MCO2 source + * @param RCC_MCODiv: specifies the MCOx prescaler. + * This parameter can be one of the following values: + * @arg RCC_MCODIV_1: no division applied to MCOx clock + * @arg RCC_MCODIV_2: division by 2 applied to MCOx clock + * @arg RCC_MCODIV_3: division by 3 applied to MCOx clock + * @arg RCC_MCODIV_4: division by 4 applied to MCOx clock + * @arg RCC_MCODIV_5: division by 5 applied to MCOx clock + * @retval None + */ +void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv) +{ + GPIO_InitTypeDef GPIO_InitStruct; + /* Check the parameters */ + assert_param(IS_RCC_MCO(RCC_MCOx)); + assert_param(IS_RCC_MCODIV(RCC_MCODiv)); + /* RCC_MCO1 */ + if(RCC_MCOx == RCC_MCO1) + { + assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource)); + + /* MCO1 Clock Enable */ + __MCO1_CLK_ENABLE(); + + /* Configure the MCO1 pin in alternate function mode */ + GPIO_InitStruct.Pin = MCO1_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = GPIO_AF0_MCO; + HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct); + + /* Mask MCO1 and MCO1PRE[2:0] bits then Select MCO1 clock source and prescaler */ + MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCO1 | RCC_CFGR_MCO1PRE), (RCC_MCOSource | RCC_MCODiv)); + } + else + { + assert_param(IS_RCC_MCO2SOURCE(RCC_MCOSource)); + + /* MCO2 Clock Enable */ + __MCO2_CLK_ENABLE(); + + /* Configure the MCO2 pin in alternate function mode */ + GPIO_InitStruct.Pin = MCO2_PIN; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = GPIO_AF0_MCO; + HAL_GPIO_Init(MCO2_GPIO_PORT, &GPIO_InitStruct); + + /* Mask MCO2 and MCO2PRE[2:0] bits then Select MCO2 clock source and prescaler */ + MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCO2 | RCC_CFGR_MCO2PRE), (RCC_MCOSource | (RCC_MCODiv << 3))); + } +} + +/** + * @brief Enables the Clock Security System. + * @note If a failure is detected on the HSE oscillator clock, this oscillator + * is automatically disabled and an interrupt is generated to inform the + * software about the failure (Clock Security System Interrupt, CSSI), + * allowing the MCU to perform rescue operations. The CSSI is linked to + * the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector. + * @retval None + */ +void HAL_RCC_EnableCSS(void) +{ + *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)ENABLE; +} + +/** + * @brief Disables the Clock Security System. + * @retval None + */ +void HAL_RCC_DisableCSS(void) +{ + *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)DISABLE; +} + +/** + * @brief Returns the SYSCLK frequency + * + * @note The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*) + * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**) + * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * @note (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * @note (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value + * 25 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * @note The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @note This function can be used by the user application to compute the + * baudrate for the communication peripherals or configure other parameters. + * + * @note Each time SYSCLK changes, this function must be called to update the + * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect. + * + * + * @retval SYSCLK frequency + */ +__weak uint32_t HAL_RCC_GetSysClockFreq(void) +{ + uint32_t pllm = 0, pllvco = 0, pllp = 0; + uint32_t sysclockfreq = 0; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (RCC->CFGR & RCC_CFGR_SWS) + { + case RCC_CFGR_SWS_HSI: /* HSI used as system clock source */ + { + sysclockfreq = HSI_VALUE; + break; + } + case RCC_CFGR_SWS_HSE: /* HSE used as system clock source */ + { + //sysclockfreq = HSE_VALUE; + sysclockfreq = (HAL_GetHSECrystalFreqMHz() * (uint32_t)1000000); + break; + } + case RCC_CFGR_SWS_PLL: /* PLL used as system clock source */ + { + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN + SYSCLK = PLL_VCO / PLLP */ + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI) + { + /* HSE used as PLL clock source */ + pllvco = (((HAL_GetHSECrystalFreqMHz() * (uint32_t)1000000) / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN))); + } + else + { + /* HSI used as PLL clock source */ + pllvco = ((HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN))); + } + pllp = ((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> POSITION_VAL(RCC_PLLCFGR_PLLP)) + 1 ) *2); + + sysclockfreq = pllvco/pllp; + break; + } + default: + { + sysclockfreq = HSI_VALUE; + break; + } + } + return sysclockfreq; +} + +/** + * @brief Returns the HCLK frequency + * @note Each time HCLK changes, this function must be called to update the + * right HCLK value. Otherwise, any configuration based on this function will be incorrect. + * + * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency + * and updated within this function + * @retval HCLK frequency + */ +uint32_t HAL_RCC_GetHCLKFreq(void) +{ + SystemCoreClock = HAL_RCC_GetSysClockFreq() >> APBAHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> POSITION_VAL(RCC_CFGR_HPRE)]; + return SystemCoreClock; +} + +/** + * @brief Returns the PCLK1 frequency + * @note Each time PCLK1 changes, this function must be called to update the + * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect. + * @retval PCLK1 frequency + */ +uint32_t HAL_RCC_GetPCLK1Freq(void) +{ + /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/ + return (HAL_RCC_GetHCLKFreq() >> APBAHBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1)>> POSITION_VAL(RCC_CFGR_PPRE1)]); +} + +/** + * @brief Returns the PCLK2 frequency + * @note Each time PCLK2 changes, this function must be called to update the + * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect. + * @retval PCLK2 frequency + */ +uint32_t HAL_RCC_GetPCLK2Freq(void) +{ + /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/ + return (HAL_RCC_GetHCLKFreq()>> APBAHBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2)>> POSITION_VAL(RCC_CFGR_PPRE2)]); +} + +/** + * @brief Configures the RCC_OscInitStruct according to the internal + * RCC configuration registers. + * @param RCC_OscInitStruct: pointer to an RCC_OscInitTypeDef structure that + * will be configured. + * @retval None + */ +__weak void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) +{ + /* Set all possible values for the Oscillator type parameter ---------------*/ + RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI; + + /* Get the HSE configuration -----------------------------------------------*/ + if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP) + { + RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS; + } + else if((RCC->CR &RCC_CR_HSEON) == RCC_CR_HSEON) + { + RCC_OscInitStruct->HSEState = RCC_HSE_ON; + } + else + { + RCC_OscInitStruct->HSEState = RCC_HSE_OFF; + } + + /* Get the HSI configuration -----------------------------------------------*/ + if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION) + { + RCC_OscInitStruct->HSIState = RCC_HSI_ON; + } + else + { + RCC_OscInitStruct->HSIState = RCC_HSI_OFF; + } + + RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR &RCC_CR_HSITRIM) >> POSITION_VAL(RCC_CR_HSITRIM)); + + /* Get the LSE configuration -----------------------------------------------*/ + if((RCC->BDCR &RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP) + { + RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS; + } + else if((RCC->BDCR &RCC_BDCR_LSEON) == RCC_BDCR_LSEON) + { + RCC_OscInitStruct->LSEState = RCC_LSE_ON; + } + else + { + RCC_OscInitStruct->LSEState = RCC_LSE_OFF; + } + + /* Get the LSI configuration -----------------------------------------------*/ + if((RCC->CSR &RCC_CSR_LSION) == RCC_CSR_LSION) + { + RCC_OscInitStruct->LSIState = RCC_LSI_ON; + } + else + { + RCC_OscInitStruct->LSIState = RCC_LSI_OFF; + } + + /* Get the PLL configuration -----------------------------------------------*/ + if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON) + { + RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON; + } + else + { + RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF; + } + RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); + RCC_OscInitStruct->PLL.PLLM = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM); + RCC_OscInitStruct->PLL.PLLN = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN)); + RCC_OscInitStruct->PLL.PLLP = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) + RCC_PLLCFGR_PLLP_0) << 1) >> POSITION_VAL(RCC_PLLCFGR_PLLP)); + RCC_OscInitStruct->PLL.PLLQ = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ) >> POSITION_VAL(RCC_PLLCFGR_PLLQ)); +} + +/** + * @brief Configures the RCC_ClkInitStruct according to the internal + * RCC configuration registers. + * @param RCC_ClkInitStruct: pointer to an RCC_ClkInitTypeDef structure that + * will be configured. + * @param pFLatency: Pointer on the Flash Latency. + * @retval None + */ +void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency) +{ + /* Set all possible values for the Clock type parameter --------------------*/ + RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + + /* Get the SYSCLK configuration --------------------------------------------*/ + RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW); + + /* Get the HCLK configuration ----------------------------------------------*/ + RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE); + + /* Get the APB1 configuration ----------------------------------------------*/ + RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1); + + /* Get the APB2 configuration ----------------------------------------------*/ + RCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3); + + /* Get the Flash Wait State (Latency) configuration ------------------------*/ + *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY); +} + +/** + * @brief This function handles the RCC CSS interrupt request. + * @note This API should be called under the NMI_Handler(). + * @retval None + */ +void HAL_RCC_NMI_IRQHandler(void) +{ + /* Check RCC CSSF flag */ + if(__HAL_RCC_GET_IT(RCC_IT_CSS)) + { + /* RCC Clock Security System interrupt user callback */ + HAL_RCC_CSSCallback(); + + /* Clear RCC CSS pending bit */ + __HAL_RCC_CLEAR_IT(RCC_IT_CSS); + } +} + +/** + * @brief RCC Clock Security System interrupt callback + * @retval None + */ +__weak void HAL_RCC_CSSCallback(void) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_RCC_CSSCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_RCC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c new file mode 100644 index 0000000..87ebc8b --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c @@ -0,0 +1,1676 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_rcc_ex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief Extension RCC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities RCC extension peripheral: + * + Extended Peripheral Control functions + * + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 RCCEx RCCEx + * @brief RCCEx HAL module driver + * @{ + */ + +#ifdef HAL_RCC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup RCCEx_Private_Constants + * @{ + */ +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions + * @{ + */ + +/** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions + * @brief Extended Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Extended Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the RCC Clocks + frequencies. + [..] + (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to + select the RTC clock source; in this case the Backup domain will be reset in + order to modify the RTC Clock source, as consequence RTC registers (including + the backup registers) and RCC_BDCR register are set to their reset values. + +@endverbatim + * @{ + */ +#if defined(STM32F446xx) +/** + * @brief Initializes the RCC extended peripherals clocks according to the specified + * parameters in the RCC_PeriphCLKInitTypeDef. + * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that + * contains the configuration information for the Extended Peripherals + * clocks(I2S, SAI, LTDC RTC and TIM). + * + * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select + * the RTC clock source; in this case the Backup domain will be reset in + * order to modify the RTC Clock source, as consequence RTC registers (including + * the backup registers) and RCC_BDCR register are set to their reset values. + * + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) +{ + uint32_t tickstart = 0; + uint32_t tmpreg1 = 0; + uint32_t plli2sp = 0; + uint32_t plli2sq = 0; + uint32_t plli2sr = 0; + uint32_t pllsaip = 0; + uint32_t pllsaiq = 0; + uint32_t plli2sused = 0; + uint32_t pllsaiused = 0; + + /* Check the peripheral clock selection parameters */ + assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); + + /*----------------------------------- I2S APB1 configuration ----------------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == (RCC_PERIPHCLK_I2S_APB1)) + { + /* Check the parameters */ + assert_param(IS_RCC_I2SAPB1CLKSOURCE(PeriphClkInit->I2sApb1ClockSelection)); + + /* Configure I2S Clock source */ + __HAL_RCC_I2S_APB1_CONFIG(PeriphClkInit->I2sApb1ClockSelection); + /* Enable the PLLI2S when it's used as clock source for I2S */ + if(PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S) + { + plli2sused = 1; + } + } + + /*----------------------------------- I2S APB2 configuration -----------------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == (RCC_PERIPHCLK_I2S_APB2)) + { + /* Check the parameters */ + assert_param(IS_RCC_I2SAPB2CLKSOURCE(PeriphClkInit->I2sApb2ClockSelection)); + + /* Configure I2S Clock source */ + __HAL_RCC_I2S_APB2_CONFIG(PeriphClkInit->I2sApb2ClockSelection); + /* Enable the PLLI2S when it's used as clock source for I2S */ + if(PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S) + { + plli2sused = 1; + } + } + + /*------------------------------------ SAI1 configuration --------------------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == (RCC_PERIPHCLK_SAI1)) + { + /* Check the parameters */ + assert_param(IS_RCC_SAI1CLKSOURCE(PeriphClkInit->Sai1ClockSelection)); + + /* Configure SAI1 Clock source */ + __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection); + /* Enable the PLLI2S when it's used as clock source for SAI */ + if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S) + { + plli2sused = 1; + } + /* Enable the PLLSAI when it's used as clock source for SAI */ + if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI) + { + pllsaiused = 1; + } + } + + /*------------------------------------ SAI2 configuration --------------------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == (RCC_PERIPHCLK_SAI2)) + { + /* Check the parameters */ + assert_param(IS_RCC_SAI2CLKSOURCE(PeriphClkInit->Sai2ClockSelection)); + + /* Configure SAI2 Clock source */ + __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection); + + /* Enable the PLLI2S when it's used as clock source for SAI */ + if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S) + { + plli2sused = 1; + } + /* Enable the PLLSAI when it's used as clock source for SAI */ + if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI) + { + pllsaiused = 1; + } + } + + /*------------------------------------ RTC configuration --------------------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) + { + /* Enable Power Clock*/ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* Enable write access to Backup domain */ + PWR->CR |= PWR_CR_DBP; + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((PWR->CR & PWR_CR_DBP) == RESET) + { + if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + /* Reset the Backup domain only if the RTC Clock source selction is modified */ + if((RCC->BDCR & RCC_BDCR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)) + { + /* Store the content of BDCR register before the reset of Backup Domain */ + tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); + /* RTC Clock selection can be changed only if the Backup Domain is reset */ + __HAL_RCC_BACKUPRESET_FORCE(); + __HAL_RCC_BACKUPRESET_RELEASE(); + /* Restore the Content of BDCR register */ + RCC->BDCR = tmpreg1; + + /* Wait for LSERDY if LSE was enabled */ + if(HAL_IS_BIT_SET(tmpreg1, RCC_BDCR_LSERDY)) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till LSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); + } + } + + /*------------------------------------ TIM configuration --------------------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM)) + { + /* Configure Timer Prescaler */ + __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection); + } + + /*------------------------------------- FMPI2C1 Configuration ----------------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1) + { + /* Check the parameters */ + assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection)); + + /* Configure the FMPI2C1 clock source */ + __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection); + } + + /*--------------------------------------- CEC Configuration -----------------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC) + { + /* Check the parameters */ + assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection)); + + /* Configure the CEC clock source */ + __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection); + } + + /*-------------------------------------- CK48 Configuration -----------------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CK48) == RCC_PERIPHCLK_CK48) + { + /* Check the parameters */ + assert_param(IS_RCC_CK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection)); + + /* Configure the SDIO clock source */ + __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection); + + /* Enable the PLLSAI when it's used as clock source for CK48 */ + if(PeriphClkInit->Clk48ClockSelection == RCC_CK48CLKSOURCE_PLLSAIP) + { + pllsaiused = 1; + } + } + + /*------------------------------------- SDIO Configuration ------------------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO) + { + /* Check the parameters */ + assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection)); + + /* Configure the SDIO clock source */ + __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection); + } + + /*------------------------------------- SPDIFRX Configuration --------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX) + { + /* Check the parameters */ + assert_param(IS_RCC_SPDIFRXCLKSOURCE(PeriphClkInit->SpdifClockSelection)); + + /* Configure the SPDIFRX clock source */ + __HAL_RCC_SPDIFRX_CONFIG(PeriphClkInit->SpdifClockSelection); + /* Enable the PLLI2S when it's used as clock source for SPDIFRX */ + if(PeriphClkInit->SpdifClockSelection == RCC_SPDIFRXCLKSOURCE_PLLI2SP) + { + plli2sused = 1; + } + } + + /*-------------------------------------- PLLI2S Configuration --------------*/ + /* PLLI2S is configured when a peripheral will use it as source clock : SAI1, SAI2, I2S on APB1, + I2S on APB2 or SPDIFRX */ + if((plli2sused == 1) || (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S)) + { + /* Disable the PLLI2S */ + __HAL_RCC_PLLI2S_DISABLE(); + /* Get tick */ + tickstart = HAL_GetTick(); + /* Wait till PLLI2S is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) + { + /* return in case of Timeout detected */ + return HAL_TIMEOUT; + } + } + + /* check for common PLLI2S Parameters */ + assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM)); + assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN)); + + /*----------------- In Case of PLLI2S is selected as source clock for I2S -------------------*/ + if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == RCC_PERIPHCLK_I2S_APB1) && (PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)) || + ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == RCC_PERIPHCLK_I2S_APB2) && (PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S))) + { + /* check for Parameters */ + assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); + + /* Read PLLI2SP/PLLI2SQ value from PLLI2SCFGR register (this value is not needed for I2S configuration) */ + plli2sp = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP)) + 1) << 1); + plli2sq = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ)); + /* Configure the PLLI2S division factors */ + /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLI2SM) */ + /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ + __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , plli2sp, plli2sq, PeriphClkInit->PLLI2S.PLLI2SR); + } + + /*----------------- In Case of PLLI2S is selected as source clock for SAI -------------------*/ + if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)) || + ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S))) + { + /* Check for PLLI2S Parameters */ + assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); + /* Check for PLLI2S/DIVQ parameters */ + assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ)); + + /* Read PLLI2SP/PLLI2SR value from PLLI2SCFGR register (this value is not needed for SAI configuration) */ + plli2sp = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP)) + 1) << 1); + plli2sr = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR)); + /* Configure the PLLI2S division factors */ + /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ + /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ + /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */ + __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , plli2sp, PeriphClkInit->PLLI2S.PLLI2SQ, plli2sr); + + /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */ + __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ); + } + + /*----------------- In Case of PLLI2S is selected as source clock for SPDIFRX -------------------*/ + if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX) && (PeriphClkInit->SpdifClockSelection == RCC_SPDIFRXCLKSOURCE_PLLI2SP)) + { + /* check for Parameters */ + assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP)); + /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */ + plli2sq = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP)) + 1) << 1); + plli2sr = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR)); + /* Configure the PLLI2S division factors */ + /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLI2SM) */ + /* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */ + __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, plli2sq, plli2sr); + } + + /*----------------- In Case of PLLI2S is just selected -----------------*/ + if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S) + { + /* Check for Parameters */ + assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP)); + assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); + assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); + + /* Configure the PLLI2S division factors */ + /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLI2SM) */ + __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR); + } + + /* Enable the PLLI2S */ + __HAL_RCC_PLLI2S_ENABLE(); + /* Get tick */ + tickstart = HAL_GetTick(); + /* Wait till PLLI2S is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) + { + /* return in case of Timeout detected */ + return HAL_TIMEOUT; + } + } + } + /*-------------------------------------- PLLSAI Configuration ---------------------------------*/ + /* PLLSAI is configured when a peripheral will use it as source clock : SAI1, SAI2, CK48 or SDIO */ + if(pllsaiused == 1) + { + /* Disable PLLSAI Clock */ + __HAL_RCC_PLLSAI_DISABLE(); + /* Get tick */ + tickstart = HAL_GetTick(); + /* Wait till PLLSAI is disabled */ + while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET) + { + if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) + { + /* return in case of Timeout detected */ + return HAL_TIMEOUT; + } + } + + /* Check the PLLSAI division factors */ + assert_param(IS_RCC_PLLSAIM_VALUE(PeriphClkInit->PLLSAI.PLLSAIM)); + assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN)); + + /*----------------- In Case of PLLSAI is selected as source clock for SAI -------------------*/ + if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)) || + ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI))) + { + /* check for PLLSAIQ Parameter */ + assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ)); + /* check for PLLSAI/DIVQ Parameter */ + assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ)); + + /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */ + pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIP)) + 1) << 1); + /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ + /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ + /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */ + __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIM, PeriphClkInit->PLLSAI.PLLSAIN , pllsaip, PeriphClkInit->PLLSAI.PLLSAIQ, 0); + + /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */ + __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ); + } + + /*----------------- In Case of PLLSAI is selected as source clock for CK48 -------------------*/ + /* In Case of PLLI2S is selected as source clock for CK48 */ + if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CK48) == RCC_PERIPHCLK_CK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CK48CLKSOURCE_PLLSAIP)) + { + /* check for Parameters */ + assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP)); + /* Read PLLSAIQ value from PLLI2SCFGR register (this value is not need for SAI configuration) */ + pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ)); + /* Configure the PLLSAI division factors */ + /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) × (PLLI2SN/PLLSAIM) */ + /* 48CLK = f(PLLSAI clock output) = f(VCO clock) / PLLSAIP */ + __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIM, PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIP, pllsaiq, 0); + } + + /* Enable PLLSAI Clock */ + __HAL_RCC_PLLSAI_ENABLE(); + /* Get tick */ + tickstart = HAL_GetTick(); + /* Wait till PLLSAI is ready */ + while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET) + { + if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) + { + /* return in case of Timeout detected */ + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @brief Get the RCC_PeriphCLKInitTypeDef according to the internal + * RCC configuration registers. + * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that + * will be configured. + * @retval None + */ +void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) +{ + uint32_t tempreg; + + /* Set all possible values for the extended clock type parameter------------*/ + PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 |\ + RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 |\ + RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\ + RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_FMPI2C1 |\ + RCC_PERIPHCLK_CK48 | RCC_PERIPHCLK_SDIO |\ + RCC_PERIPHCLK_SPDIFRX; + + /* Get the PLLI2S Clock configuration -----------------------------------------------*/ + PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SM)); + PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN)); + PeriphClkInit->PLLI2S.PLLI2SP = (uint32_t)((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP)) + 1) << 1); + PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ)); + PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR)); + /* Get the PLLSAI Clock configuration -----------------------------------------------*/ + PeriphClkInit->PLLSAI.PLLSAIM = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIM)); + PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIN)); + PeriphClkInit->PLLSAI.PLLSAIP = (uint32_t)((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIP)) + 1) << 1); + PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ)); + /* Get the PLLSAI/PLLI2S division factors -------------------------------------------*/ + PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> POSITION_VAL(RCC_DCKCFGR_PLLI2SDIVQ)); + PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> POSITION_VAL(RCC_DCKCFGR_PLLSAIDIVQ)); + + /* Get the SAI1 clock configuration ----------------------------------------------*/ + PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE(); + + /* Get the SAI2 clock configuration ----------------------------------------------*/ + PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE(); + + /* Get the I2S APB1 clock configuration ------------------------------------------*/ + PeriphClkInit->I2sApb1ClockSelection = __HAL_RCC_GET_I2S_APB1_SOURCE(); + + /* Get the I2S APB2 clock configuration ------------------------------------------*/ + PeriphClkInit->I2sApb2ClockSelection = __HAL_RCC_GET_I2S_APB2_SOURCE(); + + /* Get the RTC Clock configuration -----------------------------------------------*/ + tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE); + PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL)); + + /* Get the CEC clock configuration -----------------------------------------------*/ + PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE(); + + /* Get the FMPI2C1 clock configuration -----------------------------------------------*/ + PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE(); + + /* Get the CK48 clock configuration -----------------------------------------------*/ + PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE(); + + /* Get the SDIO clock configuration -----------------------------------------------*/ + PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE(); + + /* Get the SPDIFRX clock configuration ----------------------------------------------*/ + PeriphClkInit->SpdifClockSelection = __HAL_RCC_GET_SPDIFRX_SOURCE(); + + /* Get the TIM Prescaler configuration --------------------------------------------*/ + if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET) + { + PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED; + } + else + { + PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED; + } +} + +/** + * @brief Return the peripheral clock frequency for a given peripheral(SAI..) + * @note Return 0 if peripheral clock identifier not managed by this API + * @param PeriphClk: Peripheral clock identifier + * This parameter can be one of the following values: + * @arg RCC_PERIPHCLK_SAI1: SAI1 peripheral clock + * @arg RCC_PERIPHCLK_SAI2: SAI2 peripheral clock + * @retval Frequency in KHz + */ +uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) +{ + uint32_t tmpreg1 = 0; + /* This variable used to store the SAI clock frequency (value in Hz) */ + uint32_t frequency = 0; + /* This variable used to store the VCO Input (value in Hz) */ + uint32_t vcoinput = 0; + /* This variable used to store the SAI clock source */ + uint32_t saiclocksource = 0; + if ((PeriphClk == RCC_PERIPHCLK_SAI1) || (PeriphClk == RCC_PERIPHCLK_SAI2)) + { + saiclocksource = RCC->DCKCFGR; + saiclocksource &= (RCC_DCKCFGR_SAI1SRC | RCC_DCKCFGR_SAI2SRC); + switch (saiclocksource) + { + case 0: /* PLLSAI is the clock source for SAI*/ + { + /* Configure the PLLSAI division factor */ + /* PLLSAI_VCO Input = PLL_SOURCE/PLLSAIM */ + if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI) + { + /* In Case the PLL Source is HSI (Internal Clock) */ + vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM)); + } + else + { + /* In Case the PLL Source is HSE (External Clock) */ + vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM))); + } + /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ + /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */ + tmpreg1 = (RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24; + frequency = (vcoinput * ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> 6))/(tmpreg1); + + /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */ + tmpreg1 = (((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> 8) + 1); + frequency = frequency/(tmpreg1); + break; + } + case RCC_DCKCFGR_SAI1SRC_0: /* PLLI2S is the clock source for SAI*/ + case RCC_DCKCFGR_SAI2SRC_0: /* PLLI2S is the clock source for SAI*/ + { + /* Configure the PLLI2S division factor */ + /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ + if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI) + { + /* In Case the PLL Source is HSI (Internal Clock) */ + vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); + } + else + { + /* In Case the PLL Source is HSE (External Clock) */ + vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM))); + } + + /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ + /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */ + tmpreg1 = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> 24; + frequency = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6))/(tmpreg1); + + /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */ + tmpreg1 = ((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) + 1); + frequency = frequency/(tmpreg1); + break; + } + case RCC_DCKCFGR_SAI1SRC_1: /* PLLR is the clock source for SAI*/ + case RCC_DCKCFGR_SAI2SRC_1: /* PLLR is the clock source for SAI*/ + { + /* Configure the PLLI2S division factor */ + /* PLL_VCO Input = PLL_SOURCE/PLLM */ + if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI) + { + /* In Case the PLL Source is HSI (Internal Clock) */ + vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); + } + else + { + /* In Case the PLL Source is HSE (External Clock) */ + vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM))); + } + + /* PLL_VCO Output = PLL_VCO Input * PLLN */ + /* SAI_CLK_x = PLL_VCO Output/PLLR */ + tmpreg1 = (RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28; + frequency = (vcoinput * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6))/(tmpreg1); + break; + } + case RCC_DCKCFGR_SAI1SRC: /* External clock is the clock source for SAI*/ + { + frequency = EXTERNAL_CLOCK_VALUE; + break; + } + case RCC_DCKCFGR_SAI2SRC: /* PLLSRC(HSE or HSI) is the clock source for SAI*/ + { + if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI) + { + /* In Case the PLL Source is HSI (Internal Clock) */ + frequency = (uint32_t)(HSI_VALUE); + } + else + { + /* In Case the PLL Source is HSE (External Clock) */ + frequency = (uint32_t)(HSE_VALUE); + } + break; + } + default : + { + break; + } + } + } + return frequency; +} + +#endif /* STM32F446xx */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) +/** + * @brief Initializes the RCC extended peripherals clocks according to the specified + * parameters in the RCC_PeriphCLKInitTypeDef. + * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that + * contains the configuration information for the Extended Peripherals + * clocks(I2S, SAI, LTDC RTC and TIM). + * + * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select + * the RTC clock source; in this case the Backup domain will be reset in + * order to modify the RTC Clock source, as consequence RTC registers (including + * the backup registers) and RCC_BDCR register are set to their reset values. + * + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) +{ + uint32_t tickstart = 0; + uint32_t tmpreg1 = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); + + /*----------------------- SAI/I2S Configuration (PLLI2S) -------------------------*/ + + /*----------------------- Common configuration SAI/I2S ---------------------------*/ + /* In Case of SAI or I2S Clock Configuration through PLLI2S, PLLI2SN division + factor is common parameters for both peripherals */ + if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) || + (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == RCC_PERIPHCLK_SAI_PLLI2S)) + { + /* check for Parameters */ + assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN)); + + /* Disable the PLLI2S */ + __HAL_RCC_PLLI2S_DISABLE(); + /* Get tick */ + tickstart = HAL_GetTick(); + /* Wait till PLLI2S is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) + { + /* return in case of Timeout detected */ + return HAL_TIMEOUT; + } + } + + /*---------------------------- I2S configuration -------------------------------*/ + /* In Case of I2S Clock Configuration through PLLI2S, PLLI2SR must be added + only for I2S configuration */ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S)) + { + /* check for Parameters */ + assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); + /* Configure the PLLI2S division factors */ + /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLM) */ + /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ + __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR); + } + + /*---------------------------- SAI configuration -------------------------------*/ + /* In Case of SAI Clock Configuration through PLLI2S, PLLI2SQ and PLLI2S_DIVQ must + be added only for SAI configuration */ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == (RCC_PERIPHCLK_SAI_PLLI2S)) + { + /* Check the PLLI2S division factors */ + assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); + assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ)); + + /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */ + tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR)); + /* Configure the PLLI2S division factors */ + /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */ + /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ + /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */ + __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ , tmpreg1); + /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */ + __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ); + } + + /* Enable the PLLI2S */ + __HAL_RCC_PLLI2S_ENABLE(); + /* Get tick */ + tickstart = HAL_GetTick(); + /* Wait till PLLI2S is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) + { + /* return in case of Timeout detected */ + return HAL_TIMEOUT; + } + } + } + + /*----------------------- SAI/LTDC Configuration (PLLSAI) ------------------*/ + + /*----------------------- Common configuration SAI/LTDC --------------------*/ + /* In Case of SAI or LTDC Clock Configuration through PLLSAI, PLLSAIN division + factor is common parameters for both peripherals */ + if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == RCC_PERIPHCLK_SAI_PLLSAI) || + (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC)) + { + /* Check the PLLSAI division factors */ + assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN)); + + /* Disable PLLSAI Clock */ + __HAL_RCC_PLLSAI_DISABLE(); + /* Get tick */ + tickstart = HAL_GetTick(); + /* Wait till PLLSAI is disabled */ + while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET) + { + if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) + { + /* return in case of Timeout detected */ + return HAL_TIMEOUT; + } + } + + /*---------------------------- SAI configuration -------------------------*/ + /* In Case of SAI Clock Configuration through PLLSAI, PLLSAIQ and PLLSAI_DIVQ must + be added only for SAI configuration */ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == (RCC_PERIPHCLK_SAI_PLLSAI)) + { + assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ)); + assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ)); + + /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */ + tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR)); + /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ + /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ + /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */ + __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIQ, tmpreg1); + /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */ + __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ); + } + + /*---------------------------- LTDC configuration ------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC)) + { + assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR)); + assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR)); + + /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */ + tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ)); + /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ + /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ + /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */ + __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg1, PeriphClkInit->PLLSAI.PLLSAIR); + /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */ + __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR); + } + /* Enable PLLSAI Clock */ + __HAL_RCC_PLLSAI_ENABLE(); + /* Get tick */ + tickstart = HAL_GetTick(); + /* Wait till PLLSAI is ready */ + while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET) + { + if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) + { + /* return in case of Timeout detected */ + return HAL_TIMEOUT; + } + } + } + + + /*---------------------------- RTC configuration ---------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) + { + /* Enable Power Clock*/ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* Enable write access to Backup domain */ + PWR->CR |= PWR_CR_DBP; + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((PWR->CR & PWR_CR_DBP) == RESET) + { + if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + /* Reset the Backup domain only if the RTC Clock source selection is modified */ + if((RCC->BDCR & RCC_BDCR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)) + { + /* Store the content of BDCR register before the reset of Backup Domain */ + tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); + /* RTC Clock selection can be changed only if the Backup Domain is reset */ + __HAL_RCC_BACKUPRESET_FORCE(); + __HAL_RCC_BACKUPRESET_RELEASE(); + /* Restore the Content of BDCR register */ + RCC->BDCR = tmpreg1; + /* Wait for LSERDY if LSE was enabled */ + if(HAL_IS_BIT_SET(tmpreg1, RCC_BDCR_LSERDY)) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till LSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); + } + } + + /*---------------------------- TIM configuration ---------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM)) + { + __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection); + } + return HAL_OK; +} + +/** + * @brief Configures the RCC_OscInitStruct according to the internal + * RCC configuration registers. + * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that + * will be configured. + * @retval None + */ +void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) +{ + uint32_t tempreg; + + /* Set all possible values for the extended clock type parameter------------*/ + PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_SAI_PLLSAI | RCC_PERIPHCLK_SAI_PLLI2S | RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC; + + /* Get the PLLI2S Clock configuration -----------------------------------------------*/ + PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN)); + PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR)); + PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ)); + /* Get the PLLSAI Clock configuration -----------------------------------------------*/ + PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIN)); + PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR)); + PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ)); + /* Get the PLLSAI/PLLI2S division factors -----------------------------------------------*/ + PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> POSITION_VAL(RCC_DCKCFGR_PLLI2SDIVQ)); + PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> POSITION_VAL(RCC_DCKCFGR_PLLSAIDIVQ)); + PeriphClkInit->PLLSAIDivR = (uint32_t)(RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVR); + /* Get the RTC Clock configuration -----------------------------------------------*/ + tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE); + PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL)); + + if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET) + { + PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED; + } + else + { + PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED; + } +} + +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) +/** + * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the + * RCC_PeriphCLKInitTypeDef. + * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that + * contains the configuration information for the Extended Peripherals clocks(I2S and RTC clocks). + * + * @note A caution to be taken when HAL_RCCEx_PeriphCLKConfig() is used to select RTC clock selection, in this case + * the Reset of Backup domain will be applied in order to modify the RTC Clock source as consequence all backup + * domain (RTC and RCC_BDCR register expect BKPSRAM) will be reset + * + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) +{ + uint32_t tickstart = 0; + uint32_t tmpreg1 = 0; + + /* Check the parameters */ + assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); + + /*---------------------------- I2S configuration ---------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S)) + { + /* check for Parameters */ + assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); + assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN)); +#if defined(STM32F411xE) + assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM)); +#endif /* STM32F411xE */ + /* Disable the PLLI2S */ + __HAL_RCC_PLLI2S_DISABLE(); + /* Get tick */ + tickstart = HAL_GetTick(); + /* Wait till PLLI2S is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) + { + /* return in case of Timeout detected */ + return HAL_TIMEOUT; + } + } + +#if defined(STM32F411xE) + /* Configure the PLLI2S division factors */ + /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLI2SM) */ + /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ + __HAL_RCC_PLLI2S_I2SCLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SR); +#else + /* Configure the PLLI2S division factors */ + /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLM) */ + /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ + __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR); +#endif /* STM32F411xE */ + + /* Enable the PLLI2S */ + __HAL_RCC_PLLI2S_ENABLE(); + /* Get tick */ + tickstart = HAL_GetTick(); + /* Wait till PLLI2S is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) + { + /* return in case of Timeout detected */ + return HAL_TIMEOUT; + } + } + } + + /*---------------------------- RTC configuration ---------------------------*/ + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) + { + /* Enable Power Clock*/ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* Enable write access to Backup domain */ + PWR->CR |= PWR_CR_DBP; + + /* Get tick */ + tickstart = HAL_GetTick(); + + while((PWR->CR & PWR_CR_DBP) == RESET) + { + if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + /* Reset the Backup domain only if the RTC Clock source selection is modified */ + if((RCC->BDCR & RCC_BDCR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)) + { + /* Store the content of BDCR register before the reset of Backup Domain */ + tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); + /* RTC Clock selection can be changed only if the Backup Domain is reset */ + __HAL_RCC_BACKUPRESET_FORCE(); + __HAL_RCC_BACKUPRESET_RELEASE(); + /* Restore the Content of BDCR register */ + RCC->BDCR = tmpreg1; + /* Wait for LSERDY if LSE was enabled */ + if(HAL_IS_BIT_SET(tmpreg1, RCC_BDCR_LSERDY)) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till LSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); + } + } + + return HAL_OK; +} + +/** + * @brief Configures the RCC_OscInitStruct according to the internal + * RCC configuration registers. + * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that + * will be configured. + * @retval None + */ +void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) +{ + uint32_t tempreg; + + /* Set all possible values for the extended clock type parameter------------*/ + PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_RTC; + + /* Get the PLLI2S Clock configuration -----------------------------------------------*/ + PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN)); + PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR)); +#if defined(STM32F411xE) + PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM); +#endif /* STM32F411xE */ + /* Get the RTC Clock configuration -----------------------------------------------*/ + tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE); + PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL)); + +} +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F411xE */ + +#if defined(STM32F411xE) || defined(STM32F446xx) +/** + * @brief Select LSE mode + * + * @note This mode is only available for STM32F411xx devices. + * + * @param Mode: specifies the LSE mode. + * This parameter can be one of the following values: + * @arg RCC_LSE_LOWPOWER_MODE: LSE oscillator in low power mode selection + * @arg RCC_LSE_HIGHDRIVE_MODE: LSE oscillator in High Drive mode selection + * @retval None + */ +void HAL_RCCEx_SelectLSEMode(uint8_t Mode) +{ + /* Check the parameters */ + assert_param(IS_RCC_LSE_MODE(Mode)); + if(Mode == RCC_LSE_HIGHDRIVE_MODE) + { + SET_BIT(RCC->BDCR, RCC_BDCR_LSEMOD); + } + else + { + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEMOD); + } +} + +#endif /* STM32F411xE || STM32F446xx */ + +#if defined(STM32F446xx) +/** + * @brief Initializes the RCC Oscillators according to the specified parameters in the + * RCC_OscInitTypeDef. + * @param RCC_OscInitStruct: pointer to an RCC_OscInitTypeDef structure that + * contains the configuration information for the RCC Oscillators. + * @note The PLL is not disabled when used as system clock. + * @note This function add the PLL/PLLR factor management during PLL configuration this feature is only available in STM32F446xx devices + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) +{ + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType)); + /*------------------------------- HSE Configuration ------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) + { + /* Check the parameters */ + assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState)); + /* When the HSE is used as system clock or clock source for PLL in these cases HSE will not disabled */ + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE) ||\ + ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)) ||\ + ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLLR) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE))) + { + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)) + { + return HAL_ERROR; + } + } + else + { + /* Reset HSEON and HSEBYP bits before configuring the HSE --------------*/ + __HAL_RCC_HSE_CONFIG(RCC_HSE_OFF); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSE is disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Set the new HSE configuration ---------------------------------------*/ + __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState); + + /* Check the HSE State */ + if((RCC_OscInitStruct->HSEState) != RCC_HSE_OFF) + { + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSE is bypassed or disabled */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } + /*----------------------------- HSI Configuration --------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) + { + /* Check the parameters */ + assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState)); + assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue)); + + /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */ + if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI) ||\ + ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)) ||\ + ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLLR) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI))) + { + /* When HSI is used as system clock it will not disabled */ + if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON)) + { + return HAL_ERROR; + } + /* Otherwise, just the calibration is allowed */ + else + { + /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); + } + } + else + { + /* Check the HSI State */ + if((RCC_OscInitStruct->HSIState)!= RCC_HSI_OFF) + { + /* Enable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); + } + else + { + /* Disable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } + /*------------------------------ LSI Configuration -------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) + { + /* Check the parameters */ + assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState)); + + /* Check the LSI State */ + if((RCC_OscInitStruct->LSIState)!= RCC_LSI_OFF) + { + /* Enable the Internal Low Speed oscillator (LSI). */ + __HAL_RCC_LSI_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Disable the Internal Low Speed oscillator (LSI). */ + __HAL_RCC_LSI_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSI is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + /*------------------------------ LSE Configuration -------------------------*/ + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) + { + /* Check the parameters */ + assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState)); + + /* Enable Power Clock*/ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* Enable write access to Backup domain */ + PWR->CR |= PWR_CR_DBP; + + /* Wait for Backup domain Write protection disable */ + tickstart = HAL_GetTick(); + + while((PWR->CR & PWR_CR_DBP) == RESET) + { + if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Reset LSEON and LSEBYP bits before configuring the LSE ----------------*/ + __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Set the new LSE configuration -----------------------------------------*/ + __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState); + /* Check the LSE State */ + if((RCC_OscInitStruct->LSEState) != RCC_LSE_OFF) + { + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSE is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + /*-------------------------------- PLL Configuration -----------------------*/ + /* Check the parameters */ + assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState)); + if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE) + { + /* Check if the PLL is used as system clock or not */ + if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL) + { + if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON) + { + /* Check the parameters */ + assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource)); + assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM)); + assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN)); + assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP)); + assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ)); + assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR)); + + /* Disable the main PLL. */ + __HAL_RCC_PLL_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Configure the main PLL clock source, multiplication and division factors. */ + __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource, + RCC_OscInitStruct->PLL.PLLM, + RCC_OscInitStruct->PLL.PLLN, + RCC_OscInitStruct->PLL.PLLP, + RCC_OscInitStruct->PLL.PLLQ, + RCC_OscInitStruct->PLL.PLLR); + + /* Enable the main PLL. */ + __HAL_RCC_PLL_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Disable the main PLL. */ + __HAL_RCC_PLL_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) + { + if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + else + { + return HAL_ERROR; + } + } + return HAL_OK; +} + +/** + * @brief Configures the RCC_OscInitStruct according to the internal + * RCC configuration registers. + * @param RCC_OscInitStruct: pointer to an RCC_OscInitTypeDef structure that will be configured. + * + * @note This function is only available in case of STM32F446xx devices. + * @note This function add the PLL/PLLR factor management + * @retval None + */ +void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) +{ + /* Set all possible values for the Oscillator type parameter ---------------*/ + RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI; + + /* Get the HSE configuration -----------------------------------------------*/ + if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP) + { + RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS; + } + else if((RCC->CR &RCC_CR_HSEON) == RCC_CR_HSEON) + { + RCC_OscInitStruct->HSEState = RCC_HSE_ON; + } + else + { + RCC_OscInitStruct->HSEState = RCC_HSE_OFF; + } + + /* Get the HSI configuration -----------------------------------------------*/ + if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION) + { + RCC_OscInitStruct->HSIState = RCC_HSI_ON; + } + else + { + RCC_OscInitStruct->HSIState = RCC_HSI_OFF; + } + + RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR &RCC_CR_HSITRIM) >> POSITION_VAL(RCC_CR_HSITRIM)); + + /* Get the LSE configuration -----------------------------------------------*/ + if((RCC->BDCR &RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP) + { + RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS; + } + else if((RCC->BDCR &RCC_BDCR_LSEON) == RCC_BDCR_LSEON) + { + RCC_OscInitStruct->LSEState = RCC_LSE_ON; + } + else + { + RCC_OscInitStruct->LSEState = RCC_LSE_OFF; + } + + /* Get the LSI configuration -----------------------------------------------*/ + if((RCC->CSR &RCC_CSR_LSION) == RCC_CSR_LSION) + { + RCC_OscInitStruct->LSIState = RCC_LSI_ON; + } + else + { + RCC_OscInitStruct->LSIState = RCC_LSI_OFF; + } + + /* Get the PLL configuration -----------------------------------------------*/ + if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON) + { + RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON; + } + else + { + RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF; + } + RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); + RCC_OscInitStruct->PLL.PLLM = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM); + RCC_OscInitStruct->PLL.PLLN = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN)); + RCC_OscInitStruct->PLL.PLLP = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) + RCC_PLLCFGR_PLLP_0) << 1) >> POSITION_VAL(RCC_PLLCFGR_PLLP)); + RCC_OscInitStruct->PLL.PLLQ = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ) >> POSITION_VAL(RCC_PLLCFGR_PLLQ)); + RCC_OscInitStruct->PLL.PLLR = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> POSITION_VAL(RCC_PLLCFGR_PLLR)); +} + +/** + * @brief Returns the SYSCLK frequency + * + * @note This function is only available in case of STM32F446xx devices. + * @note This function add the PLL/PLLR System clock source + * + * @note The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*) + * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**) + * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * @note (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * @note (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value + * 25 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * @note The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @note This function can be used by the user application to compute the + * baudrate for the communication peripherals or configure other parameters. + * + * @note Each time SYSCLK changes, this function must be called to update the + * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect. + * + * + * @retval SYSCLK frequency + */ +uint32_t HAL_RCC_GetSysClockFreq(void) +{ + uint32_t pllm = 0; + uint32_t pllvco = 0; + uint32_t pllp = 0; + uint32_t pllr = 0; + uint32_t sysclockfreq = 0; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (RCC->CFGR & RCC_CFGR_SWS) + { + case RCC_CFGR_SWS_HSI: /* HSI used as system clock source */ + { + sysclockfreq = HSI_VALUE; + break; + } + case RCC_CFGR_SWS_HSE: /* HSE used as system clock source */ + { + sysclockfreq = HSE_VALUE; + break; + } + case RCC_CFGR_SWS_PLL: /* PLL/PLLP used as system clock source */ + { + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN + SYSCLK = PLL_VCO / PLLP */ + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI) + { + /* HSE used as PLL clock source */ + pllvco = ((HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN))); + } + else + { + /* HSI used as PLL clock source */ + pllvco = ((HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN))); + } + pllp = ((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> POSITION_VAL(RCC_PLLCFGR_PLLP)) + 1 ) *2); + + sysclockfreq = pllvco/pllp; + break; + } + case RCC_CFGR_SWS_PLLR: /* PLL/PLLR used as system clock source */ + { + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN + SYSCLK = PLL_VCO / PLLR */ + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI) + { + /* HSE used as PLL clock source */ + pllvco = ((HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN))); + } + else + { + /* HSI used as PLL clock source */ + pllvco = ((HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN))); + } + pllr = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> POSITION_VAL(RCC_PLLCFGR_PLLR)); + + sysclockfreq = pllvco/pllr; + break; + } + default: + { + sysclockfreq = HSI_VALUE; + break; + } + } + return sysclockfreq; +} +#endif /* STM32F446xx */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_RCC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rng.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rng.c new file mode 100644 index 0000000..136c5d6 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rng.c @@ -0,0 +1,515 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_rng.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief RNG HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Random Number Generator (RNG) peripheral: + * + Initialization/de-initialization functions + * + Peripheral Control functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The RNG HAL driver can be used as follows: + + (#) Enable the RNG controller clock using __HAL_RCC_RNG_CLK_ENABLE() macro + in HAL_RNG_MspInit(). + (#) Activate the RNG peripheral using HAL_RNG_Init() function. + (#) Wait until the 32 bit Random Number Generator contains a valid + random data using (polling/interrupt) mode. + (#) Get the 32 bit random number using HAL_RNG_GenerateRandomNumber() function. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 + * @{ + */ + +/** @addtogroup RNG + * @{ + */ + +#ifdef HAL_RNG_MODULE_ENABLED + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + + +/* Private types -------------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @addtogroup RNG_Private_Constants + * @{ + */ +#define RNG_TIMEOUT_VALUE 2 +/** + * @} + */ +/* Private macros ------------------------------------------------------------*/ +/* Private functions prototypes ----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @addtogroup RNG_Exported_Functions + * @{ + */ + +/** @addtogroup RNG_Exported_Functions_Group1 + * @brief Initialization and de-initialization functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initialize the RNG according to the specified parameters + in the RNG_InitTypeDef and create the associated handle + (+) DeInitialize the RNG peripheral + (+) Initialize the RNG MSP + (+) DeInitialize RNG MSP + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the RNG peripheral and creates the associated handle. + * @param hrng: pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng) +{ + /* Check the RNG handle allocation */ + if(hrng == NULL) + { + return HAL_ERROR; + } + + __HAL_LOCK(hrng); + + if(hrng->State == HAL_RNG_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hrng->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_RNG_MspInit(hrng); + } + + /* Change RNG peripheral state */ + hrng->State = HAL_RNG_STATE_BUSY; + + /* Enable the RNG Peripheral */ + __HAL_RNG_ENABLE(hrng); + + /* Initialize the RNG state */ + hrng->State = HAL_RNG_STATE_READY; + + __HAL_UNLOCK(hrng); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief DeInitializes the RNG peripheral. + * @param hrng: pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng) +{ + /* Check the RNG handle allocation */ + if(hrng == NULL) + { + return HAL_ERROR; + } + /* Disable the RNG Peripheral */ + CLEAR_BIT(hrng->Instance->CR, RNG_CR_IE | RNG_CR_RNGEN); + + /* Clear RNG interrupt status flags */ + CLEAR_BIT(hrng->Instance->SR, RNG_SR_CEIS | RNG_SR_SEIS); + + /* DeInit the low level hardware */ + HAL_RNG_MspDeInit(hrng); + + /* Update the RNG state */ + hrng->State = HAL_RNG_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hrng); + + /* Return the function status */ + return HAL_OK; +} + +/** + * @brief Initializes the RNG MSP. + * @param hrng: pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval None + */ +__weak void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng) +{ + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_RNG_MspInit must be implemented in the user file. + */ +} + +/** + * @brief DeInitializes the RNG MSP. + * @param hrng: pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval None + */ +__weak void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng) +{ + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_RNG_MspDeInit must be implemented in the user file. + */ +} + +/** + * @} + */ + +/** @addtogroup RNG_Exported_Functions_Group2 + * @brief Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Get the 32 bit Random number + (+) Get the 32 bit Random number with interrupt enabled + (+) Handle RNG interrupt request + +@endverbatim + * @{ + */ + +/** + * @brief Generates a 32-bit random number. + * @note Each time the random number data is read the RNG_FLAG_DRDY flag + * is automatically cleared. + * @param hrng: pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @param random32bit: pointer to generated random number variable if successful. + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit) +{ + uint32_t tickstart = 0; + HAL_StatusTypeDef status = HAL_OK; + + /* Process Locked */ + __HAL_LOCK(hrng); + + /* Check RNG peripheral state */ + if(hrng->State == HAL_RNG_STATE_READY) + { + /* Change RNG peripheral state */ + hrng->State = HAL_RNG_STATE_BUSY; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Check if data register contains valid random data */ + while(__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET) + { + if((HAL_GetTick() - tickstart ) > RNG_TIMEOUT_VALUE) + { + hrng->State = HAL_RNG_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hrng); + + return HAL_TIMEOUT; + } + } + + /* Get a 32bit Random number */ + hrng->RandomNumber = hrng->Instance->DR; + *random32bit = hrng->RandomNumber; + + hrng->State = HAL_RNG_STATE_READY; + } + else + { + status = HAL_ERROR; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hrng); + + return status; +} + +/** + * @brief Generates a 32-bit random number in interrupt mode. + * @param hrng: pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process Locked */ + __HAL_LOCK(hrng); + + /* Check RNG peripheral state */ + if(hrng->State == HAL_RNG_STATE_READY) + { + /* Change RNG peripheral state */ + hrng->State = HAL_RNG_STATE_BUSY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrng); + + /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */ + __HAL_RNG_ENABLE_IT(hrng); + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hrng); + + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Handles RNG interrupt request. + * @note In the case of a clock error, the RNG is no more able to generate + * random numbers because the PLL48CLK clock is not correct. User has + * to check that the clock controller is correctly configured to provide + * the RNG clock and clear the CEIS bit using __HAL_RNG_CLEAR_IT(). + * The clock error has no impact on the previously generated + * random numbers, and the RNG_DR register contents can be used. + * @note In the case of a seed error, the generation of random numbers is + * interrupted as long as the SECS bit is '1'. If a number is + * available in the RNG_DR register, it must not be used because it may + * not have enough entropy. In this case, it is recommended to clear the + * SEIS bit using __HAL_RNG_CLEAR_IT(), then disable and enable + * the RNG peripheral to reinitialize and restart the RNG. + * @note User-written HAL_RNG_ErrorCallback() API is called once whether SEIS + * or CEIS are set. + * @param hrng: pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval None + + */ +void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng) +{ + /* RNG clock error interrupt occurred */ + if((__HAL_RNG_GET_IT(hrng, RNG_IT_CEI) != RESET) || (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)) + { + /* Change RNG peripheral state */ + hrng->State = HAL_RNG_STATE_ERROR; + + HAL_RNG_ErrorCallback(hrng); + + /* Clear the clock error flag */ + __HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI|RNG_IT_SEI); + + } + + /* Check RNG data ready interrupt occurred */ + if(__HAL_RNG_GET_IT(hrng, RNG_IT_DRDY) != RESET) + { + /* Generate random number once, so disable the IT */ + __HAL_RNG_DISABLE_IT(hrng); + + /* Get the 32bit Random number (DRDY flag automatically cleared) */ + hrng->RandomNumber = hrng->Instance->DR; + + if(hrng->State != HAL_RNG_STATE_ERROR) + { + /* Change RNG peripheral state */ + hrng->State = HAL_RNG_STATE_READY; + + /* Data Ready callback */ + HAL_RNG_ReadyDataCallback(hrng, hrng->RandomNumber); + } + } +} + +/** + * @brief Returns generated random number in polling mode (Obsolete) + * Use HAL_RNG_GenerateRandomNumber() API instead. + * @param hrng: pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval Random value + */ +uint32_t HAL_RNG_GetRandomNumber(RNG_HandleTypeDef *hrng) +{ + if(HAL_RNG_GenerateRandomNumber(hrng, &(hrng->RandomNumber)) == HAL_OK) + { + return hrng->RandomNumber; + } + else + { + return 0; + } +} + +/** + * @brief Returns a 32-bit random number with interrupt enabled (Obsolete), + * Use HAL_RNG_GenerateRandomNumber_IT() API instead. + * @param hrng: pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval 32-bit random number + */ +uint32_t HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef *hrng) +{ + uint32_t random32bit = 0; + + /* Process locked */ + __HAL_LOCK(hrng); + + /* Change RNG peripheral state */ + hrng->State = HAL_RNG_STATE_BUSY; + + /* Get a 32bit Random number */ + random32bit = hrng->Instance->DR; + + /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */ + __HAL_RNG_ENABLE_IT(hrng); + + /* Return the 32 bit random number */ + return random32bit; +} + +/** + * @brief Read latest generated random number. + * @param hrng: pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval random value + */ +uint32_t HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef *hrng) +{ + return(hrng->RandomNumber); +} + +/** + * @brief Data Ready callback in non-blocking mode. + * @param hrng: pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @param random32bit: generated random number. + * @retval None + */ +__weak void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit) +{ + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_RNG_ReadyDataCallback must be implemented in the user file. + */ +} + +/** + * @brief RNG error callbacks. + * @param hrng: pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval None + */ +__weak void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng) +{ + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_RNG_ErrorCallback must be implemented in the user file. + */ +} +/** + * @} + */ + + +/** @addtogroup RNG_Exported_Functions_Group3 + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the RNG state. + * @param hrng: pointer to a RNG_HandleTypeDef structure that contains + * the configuration information for RNG. + * @retval HAL state + */ +HAL_RNG_StateTypeDef HAL_RNG_GetState(RNG_HandleTypeDef *hrng) +{ + return hrng->State; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + +#endif /* HAL_RNG_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c new file mode 100644 index 0000000..735205e --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c @@ -0,0 +1,1545 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_rtc.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief RTC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Real Time Clock (RTC) peripheral: + * + Initialization and de-initialization functions + * + RTC Time and Date functions + * + RTC Alarm functions + * + Peripheral Control functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### Backup Domain Operating Condition ##### + ============================================================================== + [..] The real-time clock (RTC), the RTC backup registers, and the backup + SRAM (BKP SRAM) can be powered from the VBAT voltage when the main + VDD supply is powered off. + To retain the content of the RTC backup registers, backup SRAM, and supply + the RTC when VDD is turned off, VBAT pin can be connected to an optional + standby voltage supplied by a battery or by another source. + + [..] To allow the RTC operating even when the main digital supply (VDD) is turned + off, the VBAT pin powers the following blocks: + (#) The RTC + (#) The LSE oscillator + (#) The backup SRAM when the low power backup regulator is enabled + (#) PC13 to PC15 I/Os, plus PI8 I/O (when available) + + [..] When the backup domain is supplied by VDD (analog switch connected to VDD), + the following pins are available: + (#) PC14 and PC15 can be used as either GPIO or LSE pins + (#) PC13 can be used as a GPIO or as the RTC_AF1 pin + (#) PI8 can be used as a GPIO or as the RTC_AF2 pin + + [..] When the backup domain is supplied by VBAT (analog switch connected to VBAT + because VDD is not present), the following pins are available: + (#) PC14 and PC15 can be used as LSE pins only + (#) PC13 can be used as the RTC_AF1 pin + (#) PI8 can be used as the RTC_AF2 pin + + ##### Backup Domain Reset ##### + ================================================================== + [..] The backup domain reset sets all RTC registers and the RCC_BDCR register + to their reset values. The BKPSRAM is not affected by this reset. The only + way to reset the BKPSRAM is through the Flash interface by requesting + a protection level change from 1 to 0. + [..] A backup domain reset is generated when one of the following events occurs: + (#) Software reset, triggered by setting the BDRST bit in the + RCC Backup domain control register (RCC_BDCR). + (#) VDD or VBAT power on, if both supplies have previously been powered off. + + ##### Backup Domain Access ##### + ================================================================== + [..] After reset, the backup domain (RTC registers, RTC backup data + registers and backup SRAM) is protected against possible unwanted write + accesses. + [..] To enable access to the RTC Domain and RTC registers, proceed as follows: + (+) Enable the Power Controller (PWR) APB1 interface clock using the + __HAL_RCC_PWR_CLK_ENABLE() function. + (+) Enable access to RTC domain using the HAL_PWR_EnableBkUpAccess() function. + (+) Select the RTC clock source using the __HAL_RCC_RTC_CONFIG() function. + (+) Enable RTC Clock using the __HAL_RCC_RTC_ENABLE() function. + + + ##### How to use this driver ##### + ================================================================== + [..] + (+) Enable the RTC domain access (see description in the section above). + (+) Configure the RTC Prescaler (Asynchronous and Synchronous) and RTC hour + format using the HAL_RTC_Init() function. + + *** Time and Date configuration *** + =================================== + [..] + (+) To configure the RTC Calendar (Time and Date) use the HAL_RTC_SetTime() + and HAL_RTC_SetDate() functions. + (+) To read the RTC Calendar, use the HAL_RTC_GetTime() and HAL_RTC_GetDate() functions. + + *** Alarm configuration *** + =========================== + [..] + (+) To configure the RTC Alarm use the HAL_RTC_SetAlarm() function. + You can also configure the RTC Alarm with interrupt mode using the HAL_RTC_SetAlarm_IT() function. + (+) To read the RTC Alarm, use the HAL_RTC_GetAlarm() function. + + ##### RTC and low power modes ##### + ================================================================== + [..] The MCU can be woken up from a low power mode by an RTC alternate + function. + [..] The RTC alternate functions are the RTC alarms (Alarm A and Alarm B), + RTC wake-up, RTC tamper event detection and RTC time stamp event detection. + These RTC alternate functions can wake up the system from the Stop and + Standby low power modes. + [..] The system can also wake up from low power modes without depending + on an external interrupt (Auto-wake-up mode), by using the RTC alarm + or the RTC wake-up events. + [..] The RTC provides a programmable time base for waking up from the + Stop or Standby mode at regular intervals. + Wake-up from STOP and STANDBY modes is possible only when the RTC clock source + is LSE or LSI. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 RTC RTC + * @brief RTC HAL module driver + * @{ + */ + +#ifdef HAL_RTC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup RTC_Exported_Functions RTC Exported Functions + * @{ + */ + +/** @defgroup RTC_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 and configure the + RTC Prescaler (Synchronous and Asynchronous), RTC Hour format, disable + RTC registers Write protection, enter and exit the RTC initialization mode, + RTC registers synchronization check and reference clock detection enable. + (#) The RTC Prescaler is programmed to generate the RTC 1Hz time base. + It is split into 2 programmable prescalers to minimize power consumption. + (++) A 7-bit asynchronous prescaler and a 13-bit synchronous prescaler. + (++) When both prescalers are used, it is recommended to configure the + asynchronous prescaler to a high value to minimize power consumption. + (#) All RTC registers are Write protected. Writing to the RTC registers + is enabled by writing a key into the Write Protection register, RTC_WPR. + (#) To configure the RTC Calendar, user application should enter + initialization mode. In this mode, the calendar counter is stopped + and its value can be updated. When the initialization sequence is + complete, the calendar restarts counting after 4 RTCCLK cycles. + (#) To read the calendar through the shadow registers after Calendar + initialization, calendar update or after wake-up from low power modes + the software must first clear the RSF flag. The software must then + wait until it is set again before reading the calendar, which means + that the calendar registers have been correctly copied into the + RTC_TR and RTC_DR shadow registers.The HAL_RTC_WaitForSynchro() function + implements the above software sequence (RSF clear and RSF check). + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the RTC peripheral + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc) +{ + /* Check the RTC peripheral state */ + if(hrtc == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_RTC_HOUR_FORMAT(hrtc->Init.HourFormat)); + assert_param(IS_RTC_ASYNCH_PREDIV(hrtc->Init.AsynchPrediv)); + assert_param(IS_RTC_SYNCH_PREDIV(hrtc->Init.SynchPrediv)); + assert_param (IS_RTC_OUTPUT(hrtc->Init.OutPut)); + assert_param (IS_RTC_OUTPUT_POL(hrtc->Init.OutPutPolarity)); + assert_param(IS_RTC_OUTPUT_TYPE(hrtc->Init.OutPutType)); + + if(hrtc->State == HAL_RTC_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hrtc->Lock = HAL_UNLOCKED; + /* Initialize RTC MSP */ + HAL_RTC_MspInit(hrtc); + } + + /* Set RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Set Initialization mode */ + if(RTC_EnterInitMode(hrtc) != HAL_OK) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Set RTC state */ + hrtc->State = HAL_RTC_STATE_ERROR; + + return HAL_ERROR; + } + else + { + /* Clear RTC_CR FMT, OSEL and POL Bits */ + hrtc->Instance->CR &= ((uint32_t)~(RTC_CR_FMT | RTC_CR_OSEL | RTC_CR_POL)); + /* Set RTC_CR register */ + hrtc->Instance->CR |= (uint32_t)(hrtc->Init.HourFormat | hrtc->Init.OutPut | hrtc->Init.OutPutPolarity); + + /* Configure the RTC PRER */ + hrtc->Instance->PRER = (uint32_t)(hrtc->Init.SynchPrediv); + hrtc->Instance->PRER |= (uint32_t)(hrtc->Init.AsynchPrediv << 16); + + /* Exit Initialization mode */ + hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT; + + hrtc->Instance->TAFCR &= (uint32_t)~RTC_TAFCR_ALARMOUTTYPE; + hrtc->Instance->TAFCR |= (uint32_t)(hrtc->Init.OutPutType); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Set RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + return HAL_OK; + } +} + +/** + * @brief DeInitializes the RTC peripheral + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @note This function doesn't reset the RTC Backup Data registers. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_DeInit(RTC_HandleTypeDef *hrtc) +{ + uint32_t tickstart = 0; + + /* Set RTC state */ + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Set Initialization mode */ + if(RTC_EnterInitMode(hrtc) != HAL_OK) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Set RTC state */ + hrtc->State = HAL_RTC_STATE_ERROR; + + return HAL_ERROR; + } + else + { + /* Reset TR, DR and CR registers */ + hrtc->Instance->TR = (uint32_t)0x00000000; + hrtc->Instance->DR = (uint32_t)0x00002101; + /* Reset All CR bits except CR[2:0] */ + hrtc->Instance->CR &= (uint32_t)0x00000007; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till WUTWF flag is set and if Time out is reached exit */ + while(((hrtc->Instance->ISR) & RTC_ISR_WUTWF) == (uint32_t)RESET) + { + if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Set RTC state */ + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + return HAL_TIMEOUT; + } + } + + /* Reset all RTC CR register bits */ + hrtc->Instance->CR &= (uint32_t)0x00000000; + hrtc->Instance->WUTR = (uint32_t)0x0000FFFF; + hrtc->Instance->PRER = (uint32_t)0x007F00FF; + hrtc->Instance->CALIBR = (uint32_t)0x00000000; + hrtc->Instance->ALRMAR = (uint32_t)0x00000000; + hrtc->Instance->ALRMBR = (uint32_t)0x00000000; + hrtc->Instance->SHIFTR = (uint32_t)0x00000000; + hrtc->Instance->CALR = (uint32_t)0x00000000; + hrtc->Instance->ALRMASSR = (uint32_t)0x00000000; + hrtc->Instance->ALRMBSSR = (uint32_t)0x00000000; + + /* Reset ISR register and exit initialization mode */ + hrtc->Instance->ISR = (uint32_t)0x00000000; + + /* Reset Tamper and alternate functions configuration register */ + hrtc->Instance->TAFCR = 0x00000000; + + /* If RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */ + if((hrtc->Instance->CR & RTC_CR_BYPSHAD) == RESET) + { + if(HAL_RTC_WaitForSynchro(hrtc) != HAL_OK) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_ERROR; + + return HAL_ERROR; + } + } + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* De-Initialize RTC MSP */ + HAL_RTC_MspDeInit(hrtc); + + hrtc->State = HAL_RTC_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Initializes the RTC MSP. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval None + */ +__weak void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_RTC_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes the RTC MSP. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval None + */ +__weak void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_RTC_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup RTC_Exported_Functions_Group2 RTC Time and Date functions + * @brief RTC Time and Date functions + * +@verbatim + =============================================================================== + ##### RTC Time and Date functions ##### + =============================================================================== + + [..] This section provides functions allowing to configure Time and Date features + +@endverbatim + * @{ + */ + +/** + * @brief Sets RTC current time. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param sTime: Pointer to Time structure + * @param Format: Specifies the format of the entered parameters. + * This parameter can be one of the following values: + * @arg RTC_FORMAT_BIN: Binary data format + * @arg RTC_FORMAT_BCD: BCD data format + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(Format)); + assert_param(IS_RTC_DAYLIGHT_SAVING(sTime->DayLightSaving)); + assert_param(IS_RTC_STORE_OPERATION(sTime->StoreOperation)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + if(Format == RTC_FORMAT_BIN) + { + if((hrtc->Instance->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + assert_param(IS_RTC_HOUR12(sTime->Hours)); + assert_param(IS_RTC_HOURFORMAT12(sTime->TimeFormat)); + } + else + { + sTime->TimeFormat = 0x00; + assert_param(IS_RTC_HOUR24(sTime->Hours)); + } + assert_param(IS_RTC_MINUTES(sTime->Minutes)); + assert_param(IS_RTC_SECONDS(sTime->Seconds)); + + tmpreg = (uint32_t)(((uint32_t)RTC_ByteToBcd2(sTime->Hours) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(sTime->Minutes) << 8) | \ + ((uint32_t)RTC_ByteToBcd2(sTime->Seconds)) | \ + (((uint32_t)sTime->TimeFormat) << 16)); + } + else + { + if((hrtc->Instance->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + tmpreg = RTC_Bcd2ToByte(sTime->Hours); + assert_param(IS_RTC_HOUR12(tmpreg)); + assert_param(IS_RTC_HOURFORMAT12(sTime->TimeFormat)); + } + else + { + sTime->TimeFormat = 0x00; + assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sTime->Hours))); + } + assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sTime->Minutes))); + assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sTime->Seconds))); + tmpreg = (((uint32_t)(sTime->Hours) << 16) | \ + ((uint32_t)(sTime->Minutes) << 8) | \ + ((uint32_t)sTime->Seconds) | \ + ((uint32_t)(sTime->TimeFormat) << 16)); + } + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Set Initialization mode */ + if(RTC_EnterInitMode(hrtc) != HAL_OK) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Set RTC state */ + hrtc->State = HAL_RTC_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_ERROR; + } + else + { + /* Set the RTC_TR register */ + hrtc->Instance->TR = (uint32_t)(tmpreg & RTC_TR_RESERVED_MASK); + + /* Clear the bits to be configured */ + hrtc->Instance->CR &= (uint32_t)~RTC_CR_BCK; + + /* Configure the RTC_CR register */ + hrtc->Instance->CR |= (uint32_t)(sTime->DayLightSaving | sTime->StoreOperation); + + /* Exit Initialization mode */ + hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT; + + /* If CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */ + if((hrtc->Instance->CR & RTC_CR_BYPSHAD) == RESET) + { + if(HAL_RTC_WaitForSynchro(hrtc) != HAL_OK) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_ERROR; + } + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_READY; + + __HAL_UNLOCK(hrtc); + + return HAL_OK; + } +} + +/** + * @brief Gets RTC current time. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param sTime: Pointer to Time structure + * @param Format: Specifies the format of the entered parameters. + * This parameter can be one of the following values: + * @arg RTC_FORMAT_BIN: Binary data format + * @arg RTC_FORMAT_BCD: BCD data format + * @note You can use SubSeconds and SecondFraction (sTime structure fields returned) to convert SubSeconds + * value in second fraction ratio with time unit following generic formula: + * Second fraction ratio * time_unit= [(SecondFraction-SubSeconds)/(SecondFraction+1)] * time_unit + * This conversion can be performed only if no shift operation is pending (ie. SHFP=0) when PREDIV_S >= SS + * @note You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the values + * in the higher-order calendar shadow registers to ensure consistency between the time and date values. + * Reading RTC current time locks the values in calendar shadow registers until current date is read. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(Format)); + + /* Get subseconds structure field from the corresponding register */ + sTime->SubSeconds = (uint32_t)(hrtc->Instance->SSR); + + /* Get SecondFraction structure field from the corresponding register field */ + sTime->SecondFraction = (uint32_t)(hrtc->Instance->PRER & RTC_PRER_PREDIV_S); + + /* Get the TR register */ + tmpreg = (uint32_t)(hrtc->Instance->TR & RTC_TR_RESERVED_MASK); + + /* Fill the structure fields with the read parameters */ + sTime->Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16); + sTime->Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >>8); + sTime->Seconds = (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU)); + sTime->TimeFormat = (uint8_t)((tmpreg & (RTC_TR_PM)) >> 16); + + /* Check the input parameters format */ + if(Format == RTC_FORMAT_BIN) + { + /* Convert the time structure parameters to Binary format */ + sTime->Hours = (uint8_t)RTC_Bcd2ToByte(sTime->Hours); + sTime->Minutes = (uint8_t)RTC_Bcd2ToByte(sTime->Minutes); + sTime->Seconds = (uint8_t)RTC_Bcd2ToByte(sTime->Seconds); + } + + return HAL_OK; +} + +/** + * @brief Sets RTC current date. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param sDate: Pointer to date structure + * @param Format: specifies the format of the entered parameters. + * This parameter can be one of the following values: + * @arg RTC_FORMAT_BIN: Binary data format + * @arg RTC_FORMAT_BCD: BCD data format + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format) +{ + uint32_t datetmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(Format)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + if((Format == RTC_FORMAT_BIN) && ((sDate->Month & 0x10) == 0x10)) + { + sDate->Month = (uint8_t)((sDate->Month & (uint8_t)~(0x10)) + (uint8_t)0x0A); + } + + assert_param(IS_RTC_WEEKDAY(sDate->WeekDay)); + + if(Format == RTC_FORMAT_BIN) + { + assert_param(IS_RTC_YEAR(sDate->Year)); + assert_param(IS_RTC_MONTH(sDate->Month)); + assert_param(IS_RTC_DATE(sDate->Date)); + + datetmpreg = (((uint32_t)RTC_ByteToBcd2(sDate->Year) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(sDate->Month) << 8) | \ + ((uint32_t)RTC_ByteToBcd2(sDate->Date)) | \ + ((uint32_t)sDate->WeekDay << 13)); + } + else + { + assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(sDate->Year))); + datetmpreg = RTC_Bcd2ToByte(sDate->Month); + assert_param(IS_RTC_MONTH(datetmpreg)); + datetmpreg = RTC_Bcd2ToByte(sDate->Date); + assert_param(IS_RTC_DATE(datetmpreg)); + + datetmpreg = ((((uint32_t)sDate->Year) << 16) | \ + (((uint32_t)sDate->Month) << 8) | \ + ((uint32_t)sDate->Date) | \ + (((uint32_t)sDate->WeekDay) << 13)); + } + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Set Initialization mode */ + if(RTC_EnterInitMode(hrtc) != HAL_OK) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Set RTC state*/ + hrtc->State = HAL_RTC_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_ERROR; + } + else + { + /* Set the RTC_DR register */ + hrtc->Instance->DR = (uint32_t)(datetmpreg & RTC_DR_RESERVED_MASK); + + /* Exit Initialization mode */ + hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT; + + /* If CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */ + if((hrtc->Instance->CR & RTC_CR_BYPSHAD) == RESET) + { + if(HAL_RTC_WaitForSynchro(hrtc) != HAL_OK) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_ERROR; + } + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_READY ; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; + } +} + +/** + * @brief Gets RTC current date. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param sDate: Pointer to Date structure + * @param Format: Specifies the format of the entered parameters. + * This parameter can be one of the following values: + * @arg RTC_FORMAT_BIN: Binary data format + * @arg RTC_FORMAT_BCD: BCD data format + * @note You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the values + * in the higher-order calendar shadow registers to ensure consistency between the time and date values. + * Reading RTC current time locks the values in calendar shadow registers until Current date is read. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format) +{ + uint32_t datetmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(Format)); + + /* Get the DR register */ + datetmpreg = (uint32_t)(hrtc->Instance->DR & RTC_DR_RESERVED_MASK); + + /* Fill the structure fields with the read parameters */ + sDate->Year = (uint8_t)((datetmpreg & (RTC_DR_YT | RTC_DR_YU)) >> 16); + sDate->Month = (uint8_t)((datetmpreg & (RTC_DR_MT | RTC_DR_MU)) >> 8); + sDate->Date = (uint8_t)(datetmpreg & (RTC_DR_DT | RTC_DR_DU)); + sDate->WeekDay = (uint8_t)((datetmpreg & (RTC_DR_WDU)) >> 13); + + /* Check the input parameters format */ + if(Format == RTC_FORMAT_BIN) + { + /* Convert the date structure parameters to Binary format */ + sDate->Year = (uint8_t)RTC_Bcd2ToByte(sDate->Year); + sDate->Month = (uint8_t)RTC_Bcd2ToByte(sDate->Month); + sDate->Date = (uint8_t)RTC_Bcd2ToByte(sDate->Date); + } + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup RTC_Exported_Functions_Group3 RTC Alarm functions + * @brief RTC Alarm functions + * +@verbatim + =============================================================================== + ##### RTC Alarm functions ##### + =============================================================================== + + [..] This section provides functions allowing to configure Alarm feature + +@endverbatim + * @{ + */ +/** + * @brief Sets the specified RTC Alarm. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param sAlarm: Pointer to Alarm structure + * @param Format: Specifies the format of the entered parameters. + * This parameter can be one of the following values: + * @arg RTC_FORMAT_BIN: Binary data format + * @arg RTC_FORMAT_BCD: BCD data format + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format) +{ + uint32_t tickstart = 0; + uint32_t tmpreg = 0, subsecondtmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(Format)); + assert_param(IS_RTC_ALARM(sAlarm->Alarm)); + assert_param(IS_RTC_ALARM_MASK(sAlarm->AlarmMask)); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(sAlarm->AlarmDateWeekDaySel)); + assert_param(IS_RTC_ALARM_SUB_SECOND_VALUE(sAlarm->AlarmTime.SubSeconds)); + assert_param(IS_RTC_ALARM_SUB_SECOND_MASK(sAlarm->AlarmSubSecondMask)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + if(Format == RTC_FORMAT_BIN) + { + if((hrtc->Instance->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + assert_param(IS_RTC_HOUR12(sAlarm->AlarmTime.Hours)); + assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat)); + } + else + { + sAlarm->AlarmTime.TimeFormat = 0x00; + assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours)); + } + assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes)); + assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds)); + + if(sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE) + { + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(sAlarm->AlarmDateWeekDay)); + } + else + { + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(sAlarm->AlarmDateWeekDay)); + } + + tmpreg = (((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Hours) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes) << 8) | \ + ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds)) | \ + ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmDateWeekDay) << 24) | \ + ((uint32_t)sAlarm->AlarmDateWeekDaySel) | \ + ((uint32_t)sAlarm->AlarmMask)); + } + else + { + if((hrtc->Instance->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + tmpreg = RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours); + assert_param(IS_RTC_HOUR12(tmpreg)); + assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat)); + } + else + { + sAlarm->AlarmTime.TimeFormat = 0x00; + assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours))); + } + + assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes))); + assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds))); + + if(sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE) + { + tmpreg = RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(tmpreg)); + } + else + { + tmpreg = RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(tmpreg)); + } + + tmpreg = (((uint32_t)(sAlarm->AlarmTime.Hours) << 16) | \ + ((uint32_t)(sAlarm->AlarmTime.Minutes) << 8) | \ + ((uint32_t) sAlarm->AlarmTime.Seconds) | \ + ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << 16) | \ + ((uint32_t)(sAlarm->AlarmDateWeekDay) << 24) | \ + ((uint32_t)sAlarm->AlarmDateWeekDaySel) | \ + ((uint32_t)sAlarm->AlarmMask)); + } + + /* Configure the Alarm A or Alarm B Sub Second registers */ + subsecondtmpreg = (uint32_t)((uint32_t)(sAlarm->AlarmTime.SubSeconds) | (uint32_t)(sAlarm->AlarmSubSecondMask)); + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Configure the Alarm register */ + if(sAlarm->Alarm == RTC_ALARM_A) + { + /* Disable the Alarm A interrupt */ + __HAL_RTC_ALARMA_DISABLE(hrtc); + + /* In case of interrupt mode is used, the interrupt source must disabled */ + __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRA); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till RTC ALRAWF flag is set and if Time out is reached exit */ + while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAWF) == RESET) + { + if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_TIMEOUT; + } + } + + hrtc->Instance->ALRMAR = (uint32_t)tmpreg; + /* Configure the Alarm A Sub Second register */ + hrtc->Instance->ALRMASSR = subsecondtmpreg; + /* Configure the Alarm state: Enable Alarm */ + __HAL_RTC_ALARMA_ENABLE(hrtc); + } + else + { + /* Disable the Alarm B interrupt */ + __HAL_RTC_ALARMB_DISABLE(hrtc); + + /* In case of interrupt mode is used, the interrupt source must disabled */ + __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRB); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till RTC ALRBWF flag is set and if Time out is reached exit */ + while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRBWF) == RESET) + { + if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_TIMEOUT; + } + } + + hrtc->Instance->ALRMBR = (uint32_t)tmpreg; + /* Configure the Alarm B Sub Second register */ + hrtc->Instance->ALRMBSSR = subsecondtmpreg; + /* Configure the Alarm state: Enable Alarm */ + __HAL_RTC_ALARMB_ENABLE(hrtc); + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Sets the specified RTC Alarm with Interrupt + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param sAlarm: Pointer to Alarm structure + * @param Format: Specifies the format of the entered parameters. + * This parameter can be one of the following values: + * @arg RTC_FORMAT_BIN: Binary data format + * @arg RTC_FORMAT_BCD: BCD data format + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format) +{ + uint32_t tickstart = 0; + uint32_t tmpreg = 0, subsecondtmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(Format)); + assert_param(IS_RTC_ALARM(sAlarm->Alarm)); + assert_param(IS_RTC_ALARM_MASK(sAlarm->AlarmMask)); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(sAlarm->AlarmDateWeekDaySel)); + assert_param(IS_RTC_ALARM_SUB_SECOND_VALUE(sAlarm->AlarmTime.SubSeconds)); + assert_param(IS_RTC_ALARM_SUB_SECOND_MASK(sAlarm->AlarmSubSecondMask)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + if(Format == RTC_FORMAT_BIN) + { + if((hrtc->Instance->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + assert_param(IS_RTC_HOUR12(sAlarm->AlarmTime.Hours)); + assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat)); + } + else + { + sAlarm->AlarmTime.TimeFormat = 0x00; + assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours)); + } + assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes)); + assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds)); + + if(sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE) + { + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(sAlarm->AlarmDateWeekDay)); + } + else + { + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(sAlarm->AlarmDateWeekDay)); + } + tmpreg = (((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Hours) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes) << 8) | \ + ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds)) | \ + ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << 16) | \ + ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmDateWeekDay) << 24) | \ + ((uint32_t)sAlarm->AlarmDateWeekDaySel) | \ + ((uint32_t)sAlarm->AlarmMask)); + } + else + { + if((hrtc->Instance->CR & RTC_CR_FMT) != (uint32_t)RESET) + { + tmpreg = RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours); + assert_param(IS_RTC_HOUR12(tmpreg)); + assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat)); + } + else + { + sAlarm->AlarmTime.TimeFormat = 0x00; + assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours))); + } + + assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes))); + assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds))); + + if(sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE) + { + tmpreg = RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(tmpreg)); + } + else + { + tmpreg = RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay); + assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(tmpreg)); + } + tmpreg = (((uint32_t)(sAlarm->AlarmTime.Hours) << 16) | \ + ((uint32_t)(sAlarm->AlarmTime.Minutes) << 8) | \ + ((uint32_t) sAlarm->AlarmTime.Seconds) | \ + ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << 16) | \ + ((uint32_t)(sAlarm->AlarmDateWeekDay) << 24) | \ + ((uint32_t)sAlarm->AlarmDateWeekDaySel) | \ + ((uint32_t)sAlarm->AlarmMask)); + } + /* Configure the Alarm A or Alarm B Sub Second registers */ + subsecondtmpreg = (uint32_t)((uint32_t)(sAlarm->AlarmTime.SubSeconds) | (uint32_t)(sAlarm->AlarmSubSecondMask)); + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Configure the Alarm register */ + if(sAlarm->Alarm == RTC_ALARM_A) + { + /* Disable the Alarm A interrupt */ + __HAL_RTC_ALARMA_DISABLE(hrtc); + + /* Clear flag alarm A */ + __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till RTC ALRAWF flag is set and if Time out is reached exit */ + while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAWF) == RESET) + { + if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_TIMEOUT; + } + } + + hrtc->Instance->ALRMAR = (uint32_t)tmpreg; + /* Configure the Alarm A Sub Second register */ + hrtc->Instance->ALRMASSR = subsecondtmpreg; + /* Configure the Alarm state: Enable Alarm */ + __HAL_RTC_ALARMA_ENABLE(hrtc); + /* Configure the Alarm interrupt */ + __HAL_RTC_ALARM_ENABLE_IT(hrtc,RTC_IT_ALRA); + } + else + { + /* Disable the Alarm B interrupt */ + __HAL_RTC_ALARMB_DISABLE(hrtc); + + /* Clear flag alarm B */ + __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRBF); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till RTC ALRBWF flag is set and if Time out is reached exit */ + while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRBWF) == RESET) + { + if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_TIMEOUT; + } + } + + hrtc->Instance->ALRMBR = (uint32_t)tmpreg; + /* Configure the Alarm B Sub Second register */ + hrtc->Instance->ALRMBSSR = subsecondtmpreg; + /* Configure the Alarm state: Enable Alarm */ + __HAL_RTC_ALARMB_ENABLE(hrtc); + /* Configure the Alarm interrupt */ + __HAL_RTC_ALARM_ENABLE_IT(hrtc, RTC_IT_ALRB); + } + + /* RTC Alarm Interrupt Configuration: EXTI configuration */ + __HAL_RTC_ALARM_EXTI_ENABLE_IT(); + + EXTI->RTSR |= RTC_EXTI_LINE_ALARM_EVENT; + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Deactivate the specified RTC Alarm + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param Alarm: Specifies the Alarm. + * This parameter can be one of the following values: + * @arg RTC_ALARM_A: AlarmA + * @arg RTC_ALARM_B: AlarmB + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm) +{ + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_RTC_ALARM(Alarm)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + if(Alarm == RTC_ALARM_A) + { + /* AlarmA */ + __HAL_RTC_ALARMA_DISABLE(hrtc); + + /* In case of interrupt mode is used, the interrupt source must disabled */ + __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRA); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till RTC ALRxWF flag is set and if Time out is reached exit */ + while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAWF) == RESET) + { + if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_TIMEOUT; + } + } + } + else + { + /* AlarmB */ + __HAL_RTC_ALARMB_DISABLE(hrtc); + + /* In case of interrupt mode is used, the interrupt source must disabled */ + __HAL_RTC_ALARM_DISABLE_IT(hrtc,RTC_IT_ALRB); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till RTC ALRxWF flag is set and if Time out is reached exit */ + while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRBWF) == RESET) + { + if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_TIMEOUT; + } + } + } + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Gets the RTC Alarm value and masks. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param sAlarm: Pointer to Date structure + * @param Alarm: Specifies the Alarm. + * This parameter can be one of the following values: + * @arg RTC_ALARM_A: AlarmA + * @arg RTC_ALARM_B: AlarmB + * @param Format: Specifies the format of the entered parameters. + * This parameter can be one of the following values: + * @arg RTC_FORMAT_BIN: Binary data format + * @arg RTC_FORMAT_BCD: BCD data format + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_GetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Alarm, uint32_t Format) +{ + uint32_t tmpreg = 0, subsecondtmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(Format)); + assert_param(IS_RTC_ALARM(Alarm)); + + if(Alarm == RTC_ALARM_A) + { + /* AlarmA */ + sAlarm->Alarm = RTC_ALARM_A; + + tmpreg = (uint32_t)(hrtc->Instance->ALRMAR); + subsecondtmpreg = (uint32_t)((hrtc->Instance->ALRMASSR ) & RTC_ALRMASSR_SS); + } + else + { + sAlarm->Alarm = RTC_ALARM_B; + + tmpreg = (uint32_t)(hrtc->Instance->ALRMBR); + subsecondtmpreg = (uint32_t)((hrtc->Instance->ALRMBSSR) & RTC_ALRMBSSR_SS); + } + + /* Fill the structure with the read parameters */ + sAlarm->AlarmTime.Hours = (uint32_t)((tmpreg & (RTC_ALRMAR_HT | RTC_ALRMAR_HU)) >> 16); + sAlarm->AlarmTime.Minutes = (uint32_t)((tmpreg & (RTC_ALRMAR_MNT | RTC_ALRMAR_MNU)) >> 8); + sAlarm->AlarmTime.Seconds = (uint32_t)(tmpreg & (RTC_ALRMAR_ST | RTC_ALRMAR_SU)); + sAlarm->AlarmTime.TimeFormat = (uint32_t)((tmpreg & RTC_ALRMAR_PM) >> 16); + sAlarm->AlarmTime.SubSeconds = (uint32_t) subsecondtmpreg; + sAlarm->AlarmDateWeekDay = (uint32_t)((tmpreg & (RTC_ALRMAR_DT | RTC_ALRMAR_DU)) >> 24); + sAlarm->AlarmDateWeekDaySel = (uint32_t)(tmpreg & RTC_ALRMAR_WDSEL); + sAlarm->AlarmMask = (uint32_t)(tmpreg & RTC_ALARMMASK_ALL); + + if(Format == RTC_FORMAT_BIN) + { + sAlarm->AlarmTime.Hours = RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours); + sAlarm->AlarmTime.Minutes = RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes); + sAlarm->AlarmTime.Seconds = RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds); + sAlarm->AlarmDateWeekDay = RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay); + } + + return HAL_OK; +} + +/** + * @brief This function handles Alarm interrupt request. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval None + */ +void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef* hrtc) +{ + if(__HAL_RTC_ALARM_GET_IT(hrtc, RTC_IT_ALRA)) + { + /* Get the status of the Interrupt */ + if((uint32_t)(hrtc->Instance->CR & RTC_IT_ALRA) != (uint32_t)RESET) + { + /* AlarmA callback */ + HAL_RTC_AlarmAEventCallback(hrtc); + + /* Clear the Alarm interrupt pending bit */ + __HAL_RTC_ALARM_CLEAR_FLAG(hrtc,RTC_FLAG_ALRAF); + } + } + + if(__HAL_RTC_ALARM_GET_IT(hrtc, RTC_IT_ALRB)) + { + /* Get the status of the Interrupt */ + if((uint32_t)(hrtc->Instance->CR & RTC_IT_ALRB) != (uint32_t)RESET) + { + /* AlarmB callback */ + HAL_RTCEx_AlarmBEventCallback(hrtc); + + /* Clear the Alarm interrupt pending bit */ + __HAL_RTC_ALARM_CLEAR_FLAG(hrtc,RTC_FLAG_ALRBF); + } + } + + /* Clear the EXTI's line Flag for RTC Alarm */ + __HAL_RTC_ALARM_EXTI_CLEAR_FLAG(); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; +} + +/** + * @brief Alarm A callback. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval None + */ +__weak void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_RTC_AlarmAEventCallback could be implemented in the user file + */ +} + +/** + * @brief This function handles AlarmA Polling request. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) == RESET) + { + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hrtc->State = HAL_RTC_STATE_TIMEOUT; + return HAL_TIMEOUT; + } + } + } + + /* Clear the Alarm interrupt pending bit */ + __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup RTC_Exported_Functions_Group4 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to + (+) Wait for RTC Time and Date Synchronization + +@endverbatim + * @{ + */ + +/** + * @brief Waits until the RTC Time and Date registers (RTC_TR and RTC_DR) are + * synchronized with RTC APB clock. + * @note The RTC Resynchronization mode is write protected, use the + * __HAL_RTC_WRITEPROTECTION_DISABLE() before calling this function. + * @note To read the calendar through the shadow registers after Calendar + * initialization, calendar update or after wake-up from low power modes + * the software must first clear the RSF flag. + * The software must then wait until it is set again before reading + * the calendar, which means that the calendar registers have been + * correctly copied into the RTC_TR and RTC_DR shadow registers. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef* hrtc) +{ + uint32_t tickstart = 0; + + /* Clear RSF flag */ + hrtc->Instance->ISR &= (uint32_t)RTC_RSF_MASK; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait the registers to be synchronised */ + while((hrtc->Instance->ISR & RTC_ISR_RSF) == (uint32_t)RESET) + { + if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup RTC_Exported_Functions_Group5 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to + (+) Get RTC state + +@endverbatim + * @{ + */ +/** + * @brief Returns the RTC state. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval HAL state + */ +HAL_RTCStateTypeDef HAL_RTC_GetState(RTC_HandleTypeDef* hrtc) +{ + return hrtc->State; +} + +/** + * @} + */ + +/** + * @brief Enters the RTC Initialization mode. + * @note The RTC Initialization mode is write protected, use the + * __HAL_RTC_WRITEPROTECTION_DISABLE() before calling this function. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval HAL status + */ +HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef* hrtc) +{ + uint32_t tickstart = 0; + + /* Check if the Initialization mode is set */ + if((hrtc->Instance->ISR & RTC_ISR_INITF) == (uint32_t)RESET) + { + /* Set the Initialization mode */ + hrtc->Instance->ISR = (uint32_t)RTC_INIT_MASK; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till RTC is in INIT state and if Time out is reached exit */ + while((hrtc->Instance->ISR & RTC_ISR_INITF) == (uint32_t)RESET) + { + if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + return HAL_OK; +} + + +/** + * @brief Converts a 2 digit decimal to BCD format. + * @param Value: Byte to be converted + * @retval Converted byte + */ +uint8_t RTC_ByteToBcd2(uint8_t Value) +{ + uint32_t bcdhigh = 0; + + while(Value >= 10) + { + bcdhigh++; + Value -= 10; + } + + return ((uint8_t)(bcdhigh << 4) | Value); +} + +/** + * @brief Converts from 2 digit BCD to Binary. + * @param Value: BCD value to be converted + * @retval Converted word + */ +uint8_t RTC_Bcd2ToByte(uint8_t Value) +{ + uint32_t tmp = 0; + tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10; + return (tmp + (Value & (uint8_t)0x0F)); +} + +/** + * @} + */ + +#endif /* HAL_RTC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c new file mode 100644 index 0000000..11d046d --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c @@ -0,0 +1,1710 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_rtc_ex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief RTC HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Real Time Clock (RTC) Extension peripheral: + * + RTC Time Stamp functions + * + RTC Tamper functions + * + RTC Wake-up functions + * + Extension Control functions + * + Extension RTC features functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (+) Enable the RTC domain access. + (+) Configure the RTC Prescaler (Asynchronous and Synchronous) and RTC hour + format using the HAL_RTC_Init() function. + + *** RTC Wake-up configuration *** + ================================ + [..] + (+) To configure the RTC Wake-up Clock source and Counter use the HAL_RTC_SetWakeUpTimer() + function. You can also configure the RTC Wake-up timer in interrupt mode + using the HAL_RTC_SetWakeUpTimer_IT() function. + (+) To read the RTC Wake-up Counter register, use the HAL_RTC_GetWakeUpTimer() + function. + + *** TimeStamp configuration *** + =============================== + [..] + (+) Configure the RTC_AFx trigger and enable the RTC TimeStamp using the + HAL_RTC_SetTimeStamp() function. You can also configure the RTC TimeStamp with + interrupt mode using the HAL_RTC_SetTimeStamp_IT() function. + (+) To read the RTC TimeStamp Time and Date register, use the HAL_RTC_GetTimeStamp() + function. + (+) The TIMESTAMP alternate function can be mapped either to RTC_AF1 (PC13) + or RTC_AF2 (PI8 or PA0 only for STM32F446xx devices) depending on the value of TSINSEL bit in + RTC_TAFCR register. The corresponding pin is also selected by HAL_RTC_SetTimeStamp() + or HAL_RTC_SetTimeStamp_IT() function. + + *** Tamper configuration *** + ============================ + [..] + (+) Enable the RTC Tamper and configure the Tamper filter count, trigger Edge + or Level according to the Tamper filter (if equal to 0 Edge else Level) + value, sampling frequency, precharge or discharge and Pull-UP using the + HAL_RTC_SetTamper() function. You can configure RTC Tamper in interrupt + mode using HAL_RTC_SetTamper_IT() function. + (+) The TAMPER1 alternate function can be mapped either to RTC_AF1 (PC13) + or RTC_AF2 (PI8 or PA0 only for STM32F446xx devices) depending on the value of TAMP1INSEL bit in + RTC_TAFCR register. The corresponding pin is also selected by HAL_RTC_SetTamper() + or HAL_RTC_SetTamper_IT() function. + + *** Backup Data Registers configuration *** + =========================================== + [..] + (+) To write to the RTC Backup Data registers, use the HAL_RTC_BKUPWrite() + function. + (+) To read the RTC Backup Data registers, use the HAL_RTC_BKUPRead() + function. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 RTCEx RTCEx + * @brief RTC HAL module driver + * @{ + */ + +#ifdef HAL_RTC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup RTCEx_Exported_Functions RTCEx Exported Functions + * @{ + */ + +/** @defgroup RTCEx_Exported_Functions_Group1 RTC TimeStamp and Tamper functions + * @brief RTC TimeStamp and Tamper functions + * +@verbatim + =============================================================================== + ##### RTC TimeStamp and Tamper functions ##### + =============================================================================== + + [..] This section provides functions allowing to configure TimeStamp feature + +@endverbatim + * @{ + */ + +/** + * @brief Sets TimeStamp. + * @note This API must be called before enabling the TimeStamp feature. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param TimeStampEdge: Specifies the pin edge on which the TimeStamp is + * activated. + * This parameter can be one of the following values: + * @arg RTC_TIMESTAMPEDGE_RISING: the Time stamp event occurs on the + * rising edge of the related pin. + * @arg RTC_TIMESTAMPEDGE_FALLING: the Time stamp event occurs on the + * falling edge of the related pin. + * @param RTC_TimeStampPin: specifies the RTC TimeStamp Pin. + * This parameter can be one of the following values: + * @arg RTC_TIMESTAMPPIN_DEFAULT: PC13 is selected as RTC TimeStamp Pin. + * @arg RTC_TIMESTAMPPIN_POS1: PI8/PA0 is selected as RTC TimeStamp Pin. + * (PI8 for all STM32 devices except for STM32F446xx devices the PA0 is used) + * @arg RTC_TIMESTAMPPIN_PA0: PA0 is selected as RTC TimeStamp Pin only for STM32F446xx devices + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetTimeStamp(RTC_HandleTypeDef *hrtc, uint32_t TimeStampEdge, uint32_t RTC_TimeStampPin) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_TIMESTAMP_EDGE(TimeStampEdge)); + assert_param(IS_RTC_TIMESTAMP_PIN(RTC_TimeStampPin)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Get the RTC_CR register and clear the bits to be configured */ + tmpreg = (uint32_t)(hrtc->Instance->CR & (uint32_t)~(RTC_CR_TSEDGE | RTC_CR_TSE)); + + tmpreg|= TimeStampEdge; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + hrtc->Instance->TAFCR &= (uint32_t)~RTC_TAFCR_TSINSEL; + hrtc->Instance->TAFCR |= (uint32_t)(RTC_TimeStampPin); + + /* Configure the Time Stamp TSEDGE and Enable bits */ + hrtc->Instance->CR = (uint32_t)tmpreg; + + __HAL_RTC_TIMESTAMP_ENABLE(hrtc); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Sets TimeStamp with Interrupt. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @note This API must be called before enabling the TimeStamp feature. + * @param TimeStampEdge: Specifies the pin edge on which the TimeStamp is + * activated. + * This parameter can be one of the following values: + * @arg RTC_TIMESTAMPEDGE_RISING: the Time stamp event occurs on the + * rising edge of the related pin. + * @arg RTC_TIMESTAMPEDGE_FALLING: the Time stamp event occurs on the + * falling edge of the related pin. + * @param RTC_TimeStampPin: Specifies the RTC TimeStamp Pin. + * This parameter can be one of the following values: + * @arg RTC_TIMESTAMPPIN_PC13: PC13 is selected as RTC TimeStamp Pin. + * @arg RTC_TIMESTAMPPIN_PI8: PI8 is selected as RTC TimeStamp Pin. (not applicable in the case of STM32F446xx devices) + * @arg RTC_TIMESTAMPPIN_PA0: PA0 is selected as RTC TimeStamp Pin only for STM32F446xx devices + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetTimeStamp_IT(RTC_HandleTypeDef *hrtc, uint32_t TimeStampEdge, uint32_t RTC_TimeStampPin) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_TIMESTAMP_EDGE(TimeStampEdge)); + assert_param(IS_RTC_TIMESTAMP_PIN(RTC_TimeStampPin)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Get the RTC_CR register and clear the bits to be configured */ + tmpreg = (uint32_t)(hrtc->Instance->CR & (uint32_t)~(RTC_CR_TSEDGE | RTC_CR_TSE)); + + tmpreg |= TimeStampEdge; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Configure the Time Stamp TSEDGE and Enable bits */ + hrtc->Instance->CR = (uint32_t)tmpreg; + + hrtc->Instance->TAFCR &= (uint32_t)~RTC_TAFCR_TSINSEL; + hrtc->Instance->TAFCR |= (uint32_t)(RTC_TimeStampPin); + + __HAL_RTC_TIMESTAMP_ENABLE(hrtc); + + /* Enable IT timestamp */ + __HAL_RTC_TIMESTAMP_ENABLE_IT(hrtc,RTC_IT_TS); + + /* RTC timestamp Interrupt Configuration: EXTI configuration */ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_ENABLE_IT(); + + EXTI->RTSR |= RTC_EXTI_LINE_TAMPER_TIMESTAMP_EVENT; + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Deactivates TimeStamp. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_DeactivateTimeStamp(RTC_HandleTypeDef *hrtc) +{ + uint32_t tmpreg = 0; + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* In case of interrupt mode is used, the interrupt source must disabled */ + __HAL_RTC_TIMESTAMP_DISABLE_IT(hrtc, RTC_IT_TS); + + /* Get the RTC_CR register and clear the bits to be configured */ + tmpreg = (uint32_t)(hrtc->Instance->CR & (uint32_t)~(RTC_CR_TSEDGE | RTC_CR_TSE)); + + /* Configure the Time Stamp TSEDGE and Enable bits */ + hrtc->Instance->CR = (uint32_t)tmpreg; + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Gets the RTC TimeStamp value. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param sTimeStamp: Pointer to Time structure + * @param sTimeStampDate: Pointer to Date structure + * @param Format: specifies the format of the entered parameters. + * This parameter can be one of the following values: + * RTC_FORMAT_BIN: Binary data format + * RTC_FORMAT_BCD: BCD data format + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_GetTimeStamp(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef* sTimeStamp, RTC_DateTypeDef* sTimeStampDate, uint32_t Format) +{ + uint32_t tmptime = 0, tmpdate = 0; + + /* Check the parameters */ + assert_param(IS_RTC_FORMAT(Format)); + + /* Get the TimeStamp time and date registers values */ + tmptime = (uint32_t)(hrtc->Instance->TSTR & RTC_TR_RESERVED_MASK); + tmpdate = (uint32_t)(hrtc->Instance->TSDR & RTC_DR_RESERVED_MASK); + + /* Fill the Time structure fields with the read parameters */ + sTimeStamp->Hours = (uint8_t)((tmptime & (RTC_TR_HT | RTC_TR_HU)) >> 16); + sTimeStamp->Minutes = (uint8_t)((tmptime & (RTC_TR_MNT | RTC_TR_MNU)) >> 8); + sTimeStamp->Seconds = (uint8_t)(tmptime & (RTC_TR_ST | RTC_TR_SU)); + sTimeStamp->TimeFormat = (uint8_t)((tmptime & (RTC_TR_PM)) >> 16); + sTimeStamp->SubSeconds = (uint32_t) hrtc->Instance->TSSSR; + + /* Fill the Date structure fields with the read parameters */ + sTimeStampDate->Year = 0; + sTimeStampDate->Month = (uint8_t)((tmpdate & (RTC_DR_MT | RTC_DR_MU)) >> 8); + sTimeStampDate->Date = (uint8_t)(tmpdate & (RTC_DR_DT | RTC_DR_DU)); + sTimeStampDate->WeekDay = (uint8_t)((tmpdate & (RTC_DR_WDU)) >> 13); + + /* Check the input parameters format */ + if(Format == RTC_FORMAT_BIN) + { + /* Convert the TimeStamp structure parameters to Binary format */ + sTimeStamp->Hours = (uint8_t)RTC_Bcd2ToByte(sTimeStamp->Hours); + sTimeStamp->Minutes = (uint8_t)RTC_Bcd2ToByte(sTimeStamp->Minutes); + sTimeStamp->Seconds = (uint8_t)RTC_Bcd2ToByte(sTimeStamp->Seconds); + + /* Convert the DateTimeStamp structure parameters to Binary format */ + sTimeStampDate->Month = (uint8_t)RTC_Bcd2ToByte(sTimeStampDate->Month); + sTimeStampDate->Date = (uint8_t)RTC_Bcd2ToByte(sTimeStampDate->Date); + sTimeStampDate->WeekDay = (uint8_t)RTC_Bcd2ToByte(sTimeStampDate->WeekDay); + } + + /* Clear the TIMESTAMP Flag */ + __HAL_RTC_TIMESTAMP_CLEAR_FLAG(hrtc, RTC_FLAG_TSF); + + return HAL_OK; +} + +/** + * @brief Sets Tamper + * @note By calling this API we disable the tamper interrupt for all tampers. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param sTamper: Pointer to Tamper Structure. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetTamper(RTC_HandleTypeDef *hrtc, RTC_TamperTypeDef* sTamper) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_TAMPER(sTamper->Tamper)); + assert_param(IS_RTC_TAMPER_PIN(sTamper->PinSelection)); + assert_param(IS_RTC_TAMPER_TRIGGER(sTamper->Trigger)); + assert_param(IS_RTC_TAMPER_FILTER(sTamper->Filter)); + assert_param(IS_RTC_TAMPER_SAMPLING_FREQ(sTamper->SamplingFrequency)); + assert_param(IS_RTC_TAMPER_PRECHARGE_DURATION(sTamper->PrechargeDuration)); + assert_param(IS_RTC_TAMPER_PULLUP_STATE(sTamper->TamperPullUp)); + assert_param(IS_RTC_TAMPER_TIMESTAMPONTAMPER_DETECTION(sTamper->TimeStampOnTamperDetection)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + if(sTamper->Trigger != RTC_TAMPERTRIGGER_RISINGEDGE) + { + sTamper->Trigger = (uint32_t)(sTamper->Tamper << 1); + } + + tmpreg = ((uint32_t)sTamper->Tamper | (uint32_t)sTamper->PinSelection | (uint32_t)sTamper->Trigger |\ + (uint32_t)sTamper->Filter | (uint32_t)sTamper->SamplingFrequency | (uint32_t)sTamper->PrechargeDuration |\ + (uint32_t)sTamper->TamperPullUp | sTamper->TimeStampOnTamperDetection); + + hrtc->Instance->TAFCR &= (uint32_t)~((uint32_t)sTamper->Tamper | (uint32_t)(sTamper->Tamper << 1) | (uint32_t)RTC_TAFCR_TAMPTS |\ + (uint32_t)RTC_TAFCR_TAMPFREQ | (uint32_t)RTC_TAFCR_TAMPFLT | (uint32_t)RTC_TAFCR_TAMPPRCH |\ + (uint32_t)RTC_TAFCR_TAMPPUDIS | (uint32_t)RTC_TAFCR_TAMPINSEL | (uint32_t)RTC_TAFCR_TAMPIE); + + hrtc->Instance->TAFCR |= tmpreg; + + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Sets Tamper with interrupt. + * @note By calling this API we force the tamper interrupt for all tampers. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param sTamper: Pointer to RTC Tamper. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetTamper_IT(RTC_HandleTypeDef *hrtc, RTC_TamperTypeDef* sTamper) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_RTC_TAMPER(sTamper->Tamper)); + assert_param(IS_RTC_TAMPER_PIN(sTamper->PinSelection)); + assert_param(IS_RTC_TAMPER_TRIGGER(sTamper->Trigger)); + assert_param(IS_RTC_TAMPER_FILTER(sTamper->Filter)); + assert_param(IS_RTC_TAMPER_SAMPLING_FREQ(sTamper->SamplingFrequency)); + assert_param(IS_RTC_TAMPER_PRECHARGE_DURATION(sTamper->PrechargeDuration)); + assert_param(IS_RTC_TAMPER_PULLUP_STATE(sTamper->TamperPullUp)); + assert_param(IS_RTC_TAMPER_TIMESTAMPONTAMPER_DETECTION(sTamper->TimeStampOnTamperDetection)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Configure the tamper trigger */ + if(sTamper->Trigger != RTC_TAMPERTRIGGER_RISINGEDGE) + { + sTamper->Trigger = (uint32_t)(sTamper->Tamper << 1); + } + + tmpreg = ((uint32_t)sTamper->Tamper | (uint32_t)sTamper->PinSelection | (uint32_t)sTamper->Trigger |\ + (uint32_t)sTamper->Filter | (uint32_t)sTamper->SamplingFrequency | (uint32_t)sTamper->PrechargeDuration |\ + (uint32_t)sTamper->TamperPullUp | sTamper->TimeStampOnTamperDetection); + + hrtc->Instance->TAFCR &= (uint32_t)~((uint32_t)sTamper->Tamper | (uint32_t)(sTamper->Tamper << 1) | (uint32_t)RTC_TAFCR_TAMPTS |\ + (uint32_t)RTC_TAFCR_TAMPFREQ | (uint32_t)RTC_TAFCR_TAMPFLT | (uint32_t)RTC_TAFCR_TAMPPRCH |\ + (uint32_t)RTC_TAFCR_TAMPPUDIS | (uint32_t)RTC_TAFCR_TAMPINSEL); + + hrtc->Instance->TAFCR |= tmpreg; + + /* Configure the Tamper Interrupt in the RTC_TAFCR */ + hrtc->Instance->TAFCR |= (uint32_t)RTC_TAFCR_TAMPIE; + + /* RTC Tamper Interrupt Configuration: EXTI configuration */ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_ENABLE_IT(); + + EXTI->RTSR |= RTC_EXTI_LINE_TAMPER_TIMESTAMP_EVENT; + + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Deactivates Tamper. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param Tamper: Selected tamper pin. + * This parameter can be RTC_Tamper_1 and/or RTC_TAMPER_2. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_DeactivateTamper(RTC_HandleTypeDef *hrtc, uint32_t Tamper) +{ + assert_param(IS_RTC_TAMPER(Tamper)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the selected Tamper pin */ + hrtc->Instance->TAFCR &= (uint32_t)~Tamper; + + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief This function handles TimeStamp interrupt request. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval None + */ +void HAL_RTCEx_TamperTimeStampIRQHandler(RTC_HandleTypeDef *hrtc) +{ + if(__HAL_RTC_TIMESTAMP_GET_IT(hrtc, RTC_IT_TS)) + { + /* Get the status of the Interrupt */ + if((uint32_t)(hrtc->Instance->CR & RTC_IT_TS) != (uint32_t)RESET) + { + /* TIMESTAMP callback */ + HAL_RTCEx_TimeStampEventCallback(hrtc); + + /* Clear the TIMESTAMP interrupt pending bit */ + __HAL_RTC_TIMESTAMP_CLEAR_FLAG(hrtc,RTC_FLAG_TSF); + } + } + + /* Get the status of the Interrupt */ + if(__HAL_RTC_TAMPER_GET_IT(hrtc,RTC_IT_TAMP1)) + { + /* Get the TAMPER Interrupt enable bit and pending bit */ + if(((hrtc->Instance->TAFCR & (RTC_TAFCR_TAMPIE))) != (uint32_t)RESET) + { + /* Tamper callback */ + HAL_RTCEx_Tamper1EventCallback(hrtc); + + /* Clear the Tamper interrupt pending bit */ + __HAL_RTC_TAMPER_CLEAR_FLAG(hrtc,RTC_FLAG_TAMP1F); + } + } + + /* Get the status of the Interrupt */ + if(__HAL_RTC_TAMPER_GET_IT(hrtc, RTC_IT_TAMP2)) + { + /* Get the TAMPER Interrupt enable bit and pending bit */ + if(((hrtc->Instance->TAFCR & RTC_TAFCR_TAMPIE)) != (uint32_t)RESET) + { + /* Tamper callback */ + HAL_RTCEx_Tamper2EventCallback(hrtc); + + /* Clear the Tamper interrupt pending bit */ + __HAL_RTC_TAMPER_CLEAR_FLAG(hrtc, RTC_FLAG_TAMP2F); + } + } + /* Clear the EXTI's Flag for RTC TimeStamp and Tamper */ + __HAL_RTC_TAMPER_TIMESTAMP_EXTI_CLEAR_FLAG(); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; +} + +/** + * @brief TimeStamp callback. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval None + */ +__weak void HAL_RTCEx_TimeStampEventCallback(RTC_HandleTypeDef *hrtc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_RTC_TimeStampEventCallback could be implemented in the user file + */ +} + +/** + * @brief Tamper 1 callback. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval None + */ +__weak void HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_RTC_Tamper1EventCallback could be implemented in the user file + */ +} + +/** + * @brief Tamper 2 callback. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval None + */ +__weak void HAL_RTCEx_Tamper2EventCallback(RTC_HandleTypeDef *hrtc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_RTC_Tamper2EventCallback could be implemented in the user file + */ +} + +/** + * @brief This function handles TimeStamp polling request. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_PollForTimeStampEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(__HAL_RTC_TIMESTAMP_GET_FLAG(hrtc, RTC_FLAG_TSF) == RESET) + { + if(__HAL_RTC_TIMESTAMP_GET_FLAG(hrtc, RTC_FLAG_TSOVF) != RESET) + { + /* Clear the TIMESTAMP Overrun Flag */ + __HAL_RTC_TIMESTAMP_CLEAR_FLAG(hrtc, RTC_FLAG_TSOVF); + + /* Change TIMESTAMP state */ + hrtc->State = HAL_RTC_STATE_ERROR; + + return HAL_ERROR; + } + + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hrtc->State = HAL_RTC_STATE_TIMEOUT; + return HAL_TIMEOUT; + } + } + } + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + return HAL_OK; +} + +/** + * @brief This function handles Tamper1 Polling. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_PollForTamper1Event(RTC_HandleTypeDef *hrtc, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Get the status of the Interrupt */ + while(__HAL_RTC_TAMPER_GET_FLAG(hrtc, RTC_FLAG_TAMP1F)== RESET) + { + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hrtc->State = HAL_RTC_STATE_TIMEOUT; + return HAL_TIMEOUT; + } + } + } + + /* Clear the Tamper Flag */ + __HAL_RTC_TAMPER_CLEAR_FLAG(hrtc,RTC_FLAG_TAMP1F); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + return HAL_OK; +} + +/** + * @brief This function handles Tamper2 Polling. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_PollForTamper2Event(RTC_HandleTypeDef *hrtc, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Get the status of the Interrupt */ + while(__HAL_RTC_TAMPER_GET_FLAG(hrtc, RTC_FLAG_TAMP2F) == RESET) + { + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hrtc->State = HAL_RTC_STATE_TIMEOUT; + return HAL_TIMEOUT; + } + } + } + + /* Clear the Tamper Flag */ + __HAL_RTC_TAMPER_CLEAR_FLAG(hrtc,RTC_FLAG_TAMP2F); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup RTCEx_Exported_Functions_Group2 RTC Wake-up functions + * @brief RTC Wake-up functions + * +@verbatim + =============================================================================== + ##### RTC Wake-up functions ##### + =============================================================================== + + [..] This section provides functions allowing to configure Wake-up feature + +@endverbatim + * @{ + */ + +/** + * @brief Sets wake up timer. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param WakeUpCounter: Wake up counter + * @param WakeUpClock: Wake up clock + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetWakeUpTimer(RTC_HandleTypeDef *hrtc, uint32_t WakeUpCounter, uint32_t WakeUpClock) +{ + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_RTC_WAKEUP_CLOCK(WakeUpClock)); + assert_param(IS_RTC_WAKEUP_COUNTER(WakeUpCounter)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + __HAL_RTC_WAKEUPTIMER_DISABLE(hrtc); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till RTC WUTWF flag is set and if Time out is reached exit */ + while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(hrtc, RTC_FLAG_WUTWF) == RESET) + { + if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_TIMEOUT; + } + } + + /* Clear the Wake-up Timer clock source bits in CR register */ + hrtc->Instance->CR &= (uint32_t)~RTC_CR_WUCKSEL; + + /* Configure the clock source */ + hrtc->Instance->CR |= (uint32_t)WakeUpClock; + + /* Configure the Wake-up Timer counter */ + hrtc->Instance->WUTR = (uint32_t)WakeUpCounter; + + /* Enable the Wake-up Timer */ + __HAL_RTC_WAKEUPTIMER_ENABLE(hrtc); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Sets wake up timer with interrupt + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param WakeUpCounter: Wake up counter + * @param WakeUpClock: Wake up clock + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetWakeUpTimer_IT(RTC_HandleTypeDef *hrtc, uint32_t WakeUpCounter, uint32_t WakeUpClock) +{ + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_RTC_WAKEUP_CLOCK(WakeUpClock)); + assert_param(IS_RTC_WAKEUP_COUNTER(WakeUpCounter)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + __HAL_RTC_WAKEUPTIMER_DISABLE(hrtc); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till RTC WUTWF flag is set and if Time out is reached exit */ + while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(hrtc, RTC_FLAG_WUTWF) == RESET) + { + if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_TIMEOUT; + } + } + + /* Configure the Wake-up Timer counter */ + hrtc->Instance->WUTR = (uint32_t)WakeUpCounter; + + /* Clear the Wake-up Timer clock source bits in CR register */ + hrtc->Instance->CR &= (uint32_t)~RTC_CR_WUCKSEL; + + /* Configure the clock source */ + hrtc->Instance->CR |= (uint32_t)WakeUpClock; + + /* RTC WakeUpTimer Interrupt Configuration: EXTI configuration */ + __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT(); + + EXTI->RTSR |= RTC_EXTI_LINE_WAKEUPTIMER_EVENT; + + /* Configure the Interrupt in the RTC_CR register */ + __HAL_RTC_WAKEUPTIMER_ENABLE_IT(hrtc,RTC_IT_WUT); + + /* Enable the Wake-up Timer */ + __HAL_RTC_WAKEUPTIMER_ENABLE(hrtc); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Deactivates wake up timer counter. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval HAL status + */ +uint32_t HAL_RTCEx_DeactivateWakeUpTimer(RTC_HandleTypeDef *hrtc) +{ + uint32_t tickstart = 0; + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Disable the Wake-up Timer */ + __HAL_RTC_WAKEUPTIMER_DISABLE(hrtc); + + /* In case of interrupt mode is used, the interrupt source must disabled */ + __HAL_RTC_WAKEUPTIMER_DISABLE_IT(hrtc,RTC_IT_WUT); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait till RTC WUTWF flag is set and if Time out is reached exit */ + while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(hrtc, RTC_FLAG_WUTWF) == RESET) + { + if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_TIMEOUT; + } + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Gets wake up timer counter. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval Counter value + */ +uint32_t HAL_RTCEx_GetWakeUpTimer(RTC_HandleTypeDef *hrtc) +{ + /* Get the counter value */ + return ((uint32_t)(hrtc->Instance->WUTR & RTC_WUTR_WUT)); +} + +/** + * @brief This function handles Wake Up Timer interrupt request. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval None + */ +void HAL_RTCEx_WakeUpTimerIRQHandler(RTC_HandleTypeDef *hrtc) +{ + if(__HAL_RTC_WAKEUPTIMER_GET_IT(hrtc, RTC_IT_WUT)) + { + /* Get the status of the Interrupt */ + if((uint32_t)(hrtc->Instance->CR & RTC_IT_WUT) != (uint32_t)RESET) + { + /* WAKEUPTIMER callback */ + HAL_RTCEx_WakeUpTimerEventCallback(hrtc); + + /* Clear the WAKEUPTIMER interrupt pending bit */ + __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(hrtc, RTC_FLAG_WUTF); + } + } + + /* Clear the EXTI's line Flag for RTC WakeUpTimer */ + __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; +} + +/** + * @brief Wake Up Timer callback. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval None + */ +__weak void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_RTC_WakeUpTimerEventCallback could be implemented in the user file + */ +} + +/** + * @brief This function handles Wake Up Timer Polling. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_PollForWakeUpTimerEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(hrtc, RTC_FLAG_WUTF) == RESET) + { + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + return HAL_TIMEOUT; + } + } + } + + /* Clear the WAKEUPTIMER Flag */ + __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(hrtc, RTC_FLAG_WUTF); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + return HAL_OK; +} + +/** + * @} + */ + + +/** @defgroup RTCEx_Exported_Functions_Group3 Extension Peripheral Control functions + * @brief Extension Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Extension Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides functions allowing to + (+) Write a data in a specified RTC Backup data register + (+) Read a data in a specified RTC Backup data register + (+) Set the Coarse calibration parameters. + (+) Deactivate the Coarse calibration parameters + (+) Set the Smooth calibration parameters. + (+) Configure the Synchronization Shift Control Settings. + (+) Configure the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz). + (+) Deactivate the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz). + (+) Enable the RTC reference clock detection. + (+) Disable the RTC reference clock detection. + (+) Enable the Bypass Shadow feature. + (+) Disable the Bypass Shadow feature. + +@endverbatim + * @{ + */ + +/** + * @brief Writes a data in a specified RTC Backup data register. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param BackupRegister: RTC Backup data Register number. + * This parameter can be: RTC_BKP_DRx where x can be from 0 to 19 to + * specify the register. + * @param Data: Data to be written in the specified RTC Backup data register. + * @retval None + */ +void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data) +{ + uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_RTC_BKP(BackupRegister)); + + tmp = (uint32_t)&(hrtc->Instance->BKP0R); + tmp += (BackupRegister * 4); + + /* Write the specified register */ + *(__IO uint32_t *)tmp = (uint32_t)Data; +} + +/** + * @brief Reads data from the specified RTC Backup data Register. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param BackupRegister: RTC Backup data Register number. + * This parameter can be: RTC_BKP_DRx where x can be from 0 to 19 to + * specify the register. + * @retval Read value + */ +uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister) +{ + uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_RTC_BKP(BackupRegister)); + + tmp = (uint32_t)&(hrtc->Instance->BKP0R); + tmp += (BackupRegister * 4); + + /* Read the specified register */ + return (*(__IO uint32_t *)tmp); +} + +/** + * @brief Sets the Coarse calibration parameters. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param CalibSign: Specifies the sign of the coarse calibration value. + * This parameter can be one of the following values : + * @arg RTC_CALIBSIGN_POSITIVE: The value sign is positive + * @arg RTC_CALIBSIGN_NEGATIVE: The value sign is negative + * @param Value: value of coarse calibration expressed in ppm (coded on 5 bits). + * + * @note This Calibration value should be between 0 and 63 when using negative + * sign with a 2-ppm step. + * + * @note This Calibration value should be between 0 and 126 when using positive + * sign with a 4-ppm step. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetCoarseCalib(RTC_HandleTypeDef* hrtc, uint32_t CalibSign, uint32_t Value) +{ + /* Check the parameters */ + assert_param(IS_RTC_CALIB_SIGN(CalibSign)); + assert_param(IS_RTC_CALIB_VALUE(Value)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Set Initialization mode */ + if(RTC_EnterInitMode(hrtc) != HAL_OK) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Set RTC state*/ + hrtc->State = HAL_RTC_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_ERROR; + } + else + { + /* Enable the Coarse Calibration */ + __HAL_RTC_COARSE_CALIB_ENABLE(hrtc); + + /* Set the coarse calibration value */ + hrtc->Instance->CALIBR = (uint32_t)(CalibSign|Value); + + /* Exit Initialization mode */ + hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT; + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Deactivates the Coarse calibration parameters. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_DeactivateCoarseCalib(RTC_HandleTypeDef* hrtc) +{ + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Set Initialization mode */ + if(RTC_EnterInitMode(hrtc) != HAL_OK) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Set RTC state*/ + hrtc->State = HAL_RTC_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_ERROR; + } + else + { + /* Enable the Coarse Calibration */ + __HAL_RTC_COARSE_CALIB_DISABLE(hrtc); + + /* Exit Initialization mode */ + hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT; + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Sets the Smooth calibration parameters. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param SmoothCalibPeriod: Select the Smooth Calibration Period. + * This parameter can be can be one of the following values : + * @arg RTC_SMOOTHCALIB_PERIOD_32SEC: The smooth calibration period is 32s. + * @arg RTC_SMOOTHCALIB_PERIOD_16SEC: The smooth calibration period is 16s. + * @arg RTC_SMOOTHCALIB_PERIOD_8SEC: The smooth calibration period is 8s. + * @param SmoothCalibPlusPulses: Select to Set or reset the CALP bit. + * This parameter can be one of the following values: + * @arg RTC_SMOOTHCALIB_PLUSPULSES_SET: Add one RTCCLK pulse every 2*11 pulses. + * @arg RTC_SMOOTHCALIB_PLUSPULSES_RESET: No RTCCLK pulses are added. + * @param SmouthCalibMinusPulsesValue: Select the value of CALM[8:0] bits. + * This parameter can be one any value from 0 to 0x000001FF. + * @note To deactivate the smooth calibration, the field SmoothCalibPlusPulses + * must be equal to SMOOTHCALIB_PLUSPULSES_RESET and the field + * SmouthCalibMinusPulsesValue must be equal to 0. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetSmoothCalib(RTC_HandleTypeDef* hrtc, uint32_t SmoothCalibPeriod, uint32_t SmoothCalibPlusPulses, uint32_t SmouthCalibMinusPulsesValue) +{ + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_RTC_SMOOTH_CALIB_PERIOD(SmoothCalibPeriod)); + assert_param(IS_RTC_SMOOTH_CALIB_PLUS(SmoothCalibPlusPulses)); + assert_param(IS_RTC_SMOOTH_CALIB_MINUS(SmouthCalibMinusPulsesValue)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* check if a calibration is pending*/ + if((hrtc->Instance->ISR & RTC_ISR_RECALPF) != RESET) + { + /* Get tick */ + tickstart = HAL_GetTick(); + + /* check if a calibration is pending*/ + while((hrtc->Instance->ISR & RTC_ISR_RECALPF) != RESET) + { + if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_TIMEOUT; + } + } + } + + /* Configure the Smooth calibration settings */ + hrtc->Instance->CALR = (uint32_t)((uint32_t)SmoothCalibPeriod | (uint32_t)SmoothCalibPlusPulses | (uint32_t)SmouthCalibMinusPulsesValue); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Configures the Synchronization Shift Control Settings. + * @note When REFCKON is set, firmware must not write to Shift control register. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param ShiftAdd1S: Select to add or not 1 second to the time calendar. + * This parameter can be one of the following values : + * @arg RTC_SHIFTADD1S_SET: Add one second to the clock calendar. + * @arg RTC_SHIFTADD1S_RESET: No effect. + * @param ShiftSubFS: Select the number of Second Fractions to substitute. + * This parameter can be one any value from 0 to 0x7FFF. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetSynchroShift(RTC_HandleTypeDef* hrtc, uint32_t ShiftAdd1S, uint32_t ShiftSubFS) +{ + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_RTC_SHIFT_ADD1S(ShiftAdd1S)); + assert_param(IS_RTC_SHIFT_SUBFS(ShiftSubFS)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until the shift is completed*/ + while((hrtc->Instance->ISR & RTC_ISR_SHPF) != RESET) + { + if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_TIMEOUT; + } + } + + /* Check if the reference clock detection is disabled */ + if((hrtc->Instance->CR & RTC_CR_REFCKON) == RESET) + { + /* Configure the Shift settings */ + hrtc->Instance->SHIFTR = (uint32_t)(uint32_t)(ShiftSubFS) | (uint32_t)(ShiftAdd1S); + + /* If RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */ + if((hrtc->Instance->CR & RTC_CR_BYPSHAD) == RESET) + { + if(HAL_RTC_WaitForSynchro(hrtc) != HAL_OK) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + hrtc->State = HAL_RTC_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_ERROR; + } + } + } + else + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_ERROR; + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Configures the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz). + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param CalibOutput: Select the Calibration output Selection . + * This parameter can be one of the following values: + * @arg RTC_CALIBOUTPUT_512HZ: A signal has a regular waveform at 512Hz. + * @arg RTC_CALIBOUTPUT_1HZ: A signal has a regular waveform at 1Hz. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetCalibrationOutPut(RTC_HandleTypeDef* hrtc, uint32_t CalibOutput) +{ + /* Check the parameters */ + assert_param(IS_RTC_CALIB_OUTPUT(CalibOutput)); + + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Clear flags before config */ + hrtc->Instance->CR &= (uint32_t)~RTC_CR_COSEL; + + /* Configure the RTC_CR register */ + hrtc->Instance->CR |= (uint32_t)CalibOutput; + + __HAL_RTC_CALIBRATION_OUTPUT_ENABLE(hrtc); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Deactivates the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz). + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_DeactivateCalibrationOutPut(RTC_HandleTypeDef* hrtc) +{ + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + __HAL_RTC_CALIBRATION_OUTPUT_DISABLE(hrtc); + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Enables the RTC reference clock detection. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_SetRefClock(RTC_HandleTypeDef* hrtc) +{ + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Set Initialization mode */ + if(RTC_EnterInitMode(hrtc) != HAL_OK) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Set RTC state*/ + hrtc->State = HAL_RTC_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_ERROR; + } + else + { + __HAL_RTC_CLOCKREF_DETECTION_ENABLE(hrtc); + + /* Exit Initialization mode */ + hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT; + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Disable the RTC reference clock detection. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_DeactivateRefClock(RTC_HandleTypeDef* hrtc) +{ + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Set Initialization mode */ + if(RTC_EnterInitMode(hrtc) != HAL_OK) + { + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Set RTC state*/ + hrtc->State = HAL_RTC_STATE_ERROR; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_ERROR; + } + else + { + __HAL_RTC_CLOCKREF_DETECTION_DISABLE(hrtc); + + /* Exit Initialization mode */ + hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT; + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Enables the Bypass Shadow feature. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @note When the Bypass Shadow is enabled the calendar value are taken + * directly from the Calendar counter. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_EnableBypassShadow(RTC_HandleTypeDef* hrtc) +{ + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Set the BYPSHAD bit */ + hrtc->Instance->CR |= (uint8_t)RTC_CR_BYPSHAD; + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @brief Disables the Bypass Shadow feature. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @note When the Bypass Shadow is enabled the calendar value are taken + * directly from the Calendar counter. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_DisableBypassShadow(RTC_HandleTypeDef* hrtc) +{ + /* Process Locked */ + __HAL_LOCK(hrtc); + + hrtc->State = HAL_RTC_STATE_BUSY; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); + + /* Reset the BYPSHAD bit */ + hrtc->Instance->CR &= (uint8_t)~RTC_CR_BYPSHAD; + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hrtc); + + return HAL_OK; +} + +/** + * @} + */ + + /** @defgroup RTCEx_Exported_Functions_Group4 Extended features functions + * @brief Extended features functions + * +@verbatim + =============================================================================== + ##### Extended features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) RTC Alarm B callback + (+) RTC Poll for Alarm B request + +@endverbatim + * @{ + */ + +/** + * @brief Alarm B callback. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @retval None + */ +__weak void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_RTC_AlarmBEventCallback could be implemented in the user file + */ +} + +/** + * @brief This function handles AlarmB Polling request. + * @param hrtc: pointer to a RTC_HandleTypeDef structure that contains + * the configuration information for RTC. + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RTCEx_PollForAlarmBEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Get tick */ + tickstart = HAL_GetTick(); + + while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRBF) == RESET) + { + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hrtc->State = HAL_RTC_STATE_TIMEOUT; + return HAL_TIMEOUT; + } + } + } + + /* Clear the Alarm Flag */ + __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRBF); + + /* Change RTC state */ + hrtc->State = HAL_RTC_STATE_READY; + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_RTC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai.c new file mode 100644 index 0000000..187c45b --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai.c @@ -0,0 +1,1908 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_sai.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief SAI HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Serial Audio Interface (SAI) peripheral: + * + Initialization/de-initialization functions + * + I/O operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + + [..] + The SAI HAL driver can be used as follows: + + (#) Declare a SAI_HandleTypeDef handle structure. + (#) Initialize the SAI low level resources by implementing the HAL_SAI_MspInit() API: + (##) Enable the SAI interface clock. + (##) SAI pins configuration: + (+++) Enable the clock for the SAI GPIOs. + (+++) Configure these SAI pins as alternate function pull-up. + (##) NVIC configuration if you need to use interrupt process (HAL_SAI_Transmit_IT() + and HAL_SAI_Receive_IT() APIs): + (+++) Configure the SAI interrupt priority. + (+++) Enable the NVIC SAI IRQ handle. + + (##) DMA Configuration if you need to use DMA process (HAL_SAI_Transmit_DMA() + and HAL_SAI_Receive_DMA() APIs): + (+++) Declare a DMA handle structure for the Tx/Rx stream. + (+++) Enable the DMAx interface clock. + (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. + (+++) Configure the DMA Tx/Rx Stream. + (+++) Associate the initialized DMA handle to the SAI DMA Tx/Rx handle. + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the + DMA Tx/Rx Stream. + + (#) Program the SAI Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity + using HAL_SAI_Init() function. + + -@- The specific SAI interrupts (FIFO request and Overrun underrun interrupt) + will be managed using the macros __SAI_ENABLE_IT() and __SAI_DISABLE_IT() + inside the transmit and receive process. + + [..] + (@) SAI Clock Source configuration is managed differently depending on the selected + STM32F4 devices : + (+@) For STM32F446xx devices, the configuration is managed through RCCEx_PeriphCLKConfig() + function in the HAL RCC drivers + (+@) For STM32F439xx/STM32F437xx/STM32F429xx/STM32F427xx devices, the configuration + is managed within HAL SAI drivers through HAL_SAI_Init() function using + ClockSource field of SAI_InitTypeDef structure. + [..] + (@) Make sure that either: + (+@) I2S PLL is configured or + (+@) SAI PLL is configured or + (+@) External clock source is configured after setting correctly + the define constant EXTERNAL_CLOCK_VALUE in the stm32f4xx_hal_conf.h file. + + [..] + (@) In master Tx mode: enabling the audio block immediately generates the bit clock + for the external slaves even if there is no data in the FIFO, However FS signal + generation is conditioned by the presence of data in the FIFO. + + [..] + (@) In master Rx mode: enabling the audio block immediately generates the bit clock + and FS signal for the external slaves. + + [..] + (@) It is mandatory to respect the following conditions in order to avoid bad SAI behavior: + (+@) First bit Offset <= (SLOT size - Data size) + (+@) Data size <= SLOT size + (+@) Number of SLOT x SLOT size = Frame length + (+@) The number of slots should be even when SAI_FS_CHANNEL_IDENTIFICATION is selected. + + [..] + Three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Send an amount of data in blocking mode using HAL_SAI_Transmit() + (+) Receive an amount of data in blocking mode using HAL_SAI_Receive() + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Send an amount of data in non blocking mode using HAL_SAI_Transmit_IT() + (+) At transmission end of transfer HAL_SAI_TxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_SAI_TxCpltCallback + (+) Receive an amount of data in non blocking mode using HAL_SAI_Receive_IT() + (+) At reception end of transfer HAL_SAI_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_SAI_RxCpltCallback + (+) In case of transfer Error, HAL_SAI_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_SAI_ErrorCallback + + *** DMA mode IO operation *** + ============================== + [..] + (+) Send an amount of data in non blocking mode (DMA) using HAL_SAI_Transmit_DMA() + (+) At transmission end of transfer HAL_SAI_TxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_SAI_TxCpltCallback + (+) Receive an amount of data in non blocking mode (DMA) using HAL_SAI_Receive_DMA() + (+) At reception end of transfer HAL_SAI_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_SAI_RxCpltCallback + (+) In case of transfer Error, HAL_SAI_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_SAI_ErrorCallback + (+) Pause the DMA Transfer using HAL_SAI_DMAPause() + (+) Resume the DMA Transfer using HAL_SAI_DMAResume() + (+) Stop the DMA Transfer using HAL_SAI_DMAStop() + + *** SAI HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in USART HAL driver : + + (+) __HAL_SAI_ENABLE: Enable the SAI peripheral + (+) __HAL_SAI_DISABLE: Disable the SAI peripheral + (+) __HAL_SAI_ENABLE_IT : Enable the specified SAI interrupts + (+) __HAL_SAI_DISABLE_IT : Disable the specified SAI interrupts + (+) __HAL_SAI_GET_IT_SOURCE: Check if the specified SAI interrupt source is + enabled or disabled + (+) __HAL_SAI_GET_FLAG: Check whether the specified SAI flag is set or not + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 SAI SAI + * @brief SAI HAL module driver + * @{ + */ + +#ifdef HAL_SAI_MODULE_ENABLED + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) + +/* Private typedef -----------------------------------------------------------*/ +/** @defgroup SAI_Private_Typedefs SAI Private Typedefs + * @{ + */ +typedef enum { + SAI_MODE_DMA, + SAI_MODE_IT +}SAI_ModeTypedef; +/** + * @} + */ +/* Private define ------------------------------------------------------------*/ +/** @defgroup SAI_Private_Constants SAI Private Constants + * @{ + */ +#define SAI_FIFO_SIZE 8 +#define SAI_DEFAULT_TIMEOUT 4 +/** + * @} + */ + +/* SAI registers Masks */ +#define CR1_CLEAR_MASK ((uint32_t)0xFF04C010) +#define FRCR_CLEAR_MASK ((uint32_t)0xFFF88000) +#define SLOTR_CLEAR_MASK ((uint32_t)0x0000F020) + +#define SAI_TIMEOUT_VALUE 10 +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static void SAI_FillFifo(SAI_HandleTypeDef *hsai); +static uint32_t SAI_InterruptFlag(SAI_HandleTypeDef *hsai, uint32_t mode); +static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot); +static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot); + +static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai); +static void SAI_Transmit_IT8Bit(SAI_HandleTypeDef *hsai); +static void SAI_Transmit_IT16Bit(SAI_HandleTypeDef *hsai); +static void SAI_Transmit_IT32Bit(SAI_HandleTypeDef *hsai); +static void SAI_Receive_IT8Bit(SAI_HandleTypeDef *hsai); +static void SAI_Receive_IT16Bit(SAI_HandleTypeDef *hsai); +static void SAI_Receive_IT32Bit(SAI_HandleTypeDef *hsai); + +static void SAI_DMATxCplt(DMA_HandleTypeDef *hdma); +static void SAI_DMATxHalfCplt(DMA_HandleTypeDef *hdma); +static void SAI_DMARxCplt(DMA_HandleTypeDef *hdma); +static void SAI_DMARxHalfCplt(DMA_HandleTypeDef *hdma); +static void SAI_DMAError(DMA_HandleTypeDef *hdma); + +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup SAI_Exported_Functions SAI Exported Functions + * @{ + */ + +/** @defgroup SAI_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the SAIx peripheral: + + (+) User must implement HAL_SAI_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). + + (+) Call the function HAL_SAI_Init() to configure the selected device with + the selected configuration: + (++) Mode (Master/slave TX/RX) + (++) Protocol + (++) Data Size + (++) MCLK Output + (++) Audio frequency + (++) FIFO Threshold + (++) Frame Config + (++) Slot Config + + (+) Call the function HAL_SAI_DeInit() to restore the default configuration + of the selected SAI peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the structure FrameInit, SlotInit and the low part of + * Init according to the specified parameters and call the function + * HAL_SAI_Init to initialize the SAI block. + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param protocol : one of the supported protocol @ref SAI_Protocol + * @param datasize : one of the supported datasize @ref SAI_Protocol_DataSize + * the configuration information for SAI module. + * @param nbslot : Number of slot. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_InitProtocol(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_SAI_SUPPORTED_PROTOCOL(protocol)); + assert_param(IS_SAI_PROTOCOL_DATASIZE(datasize)); + + switch(protocol) + { + case SAI_I2S_STANDARD : + case SAI_I2S_MSBJUSTIFIED : + case SAI_I2S_LSBJUSTIFIED : + status = SAI_InitI2S(hsai, protocol, datasize, nbslot); + break; + case SAI_PCM_LONG : + case SAI_PCM_SHORT : + status = SAI_InitPCM(hsai, protocol, datasize, nbslot); + break; + default : + status = HAL_ERROR; + break; + } + + if(status == HAL_OK) + { + status = HAL_SAI_Init(hsai); + } + + return status; +} + +/** + * @brief Initializes the SAI according to the specified parameters + * in the SAI_InitTypeDef and create the associated handle. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_Init(SAI_HandleTypeDef *hsai) +{ + uint32_t tmpclock = 0; + + /* This variable used to store the SAI_CK_x (value in Hz) */ + uint32_t freq = 0; + + /* Check the SAI handle allocation */ + if(hsai == NULL) + { + return HAL_ERROR; + } + + /* Check the SAI Block parameters */ + assert_param(IS_SAI_AUDIO_FREQUENCY(hsai->Init.AudioFrequency)); + assert_param(IS_SAI_BLOCK_PROTOCOL(hsai->Init.Protocol)); + assert_param(IS_SAI_BLOCK_MODE(hsai->Init.AudioMode)); + assert_param(IS_SAI_BLOCK_SYNCEXT(hsai->Init.SynchroExt)); + assert_param(IS_SAI_BLOCK_DATASIZE(hsai->Init.DataSize)); + assert_param(IS_SAI_BLOCK_FIRST_BIT(hsai->Init.FirstBit)); + assert_param(IS_SAI_BLOCK_CLOCK_STROBING(hsai->Init.ClockStrobing)); + assert_param(IS_SAI_BLOCK_SYNCHRO(hsai->Init.Synchro)); + assert_param(IS_SAI_BLOCK_OUTPUT_DRIVE(hsai->Init.OutputDrive)); + assert_param(IS_SAI_BLOCK_NODIVIDER(hsai->Init.NoDivider)); + assert_param(IS_SAI_BLOCK_FIFO_THRESHOLD(hsai->Init.FIFOThreshold)); + assert_param(IS_SAI_MONO_STEREO_MODE(hsai->Init.MonoStereoMode)); + assert_param(IS_SAI_BLOCK_COMPANDING_MODE(hsai->Init.CompandingMode)); + assert_param(IS_SAI_BLOCK_TRISTATE_MANAGEMENT(hsai->Init.TriState)); + + /* Check the SAI Block Frame parameters */ + assert_param(IS_SAI_BLOCK_FRAME_LENGTH(hsai->FrameInit.FrameLength)); + assert_param(IS_SAI_BLOCK_ACTIVE_FRAME(hsai->FrameInit.ActiveFrameLength)); + assert_param(IS_SAI_BLOCK_FS_DEFINITION(hsai->FrameInit.FSDefinition)); + assert_param(IS_SAI_BLOCK_FS_POLARITY(hsai->FrameInit.FSPolarity)); + assert_param(IS_SAI_BLOCK_FS_OFFSET(hsai->FrameInit.FSOffset)); + + /* Check the SAI Block Slot parameters */ + assert_param(IS_SAI_BLOCK_FIRSTBIT_OFFSET(hsai->SlotInit.FirstBitOffset)); + assert_param(IS_SAI_BLOCK_SLOT_SIZE(hsai->SlotInit.SlotSize)); + assert_param(IS_SAI_BLOCK_SLOT_NUMBER(hsai->SlotInit.SlotNumber)); + assert_param(IS_SAI_SLOT_ACTIVE(hsai->SlotInit.SlotActive)); + + if(hsai->State == HAL_SAI_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hsai->Lock = HAL_UNLOCKED; + + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_SAI_MspInit(hsai); + } + + hsai->State = HAL_SAI_STATE_BUSY; + + /* Disable the selected SAI peripheral */ + SAI_Disable(hsai); + + /* SAI Block Synchro Configuration -----------------------------------------*/ + SAI_BlockSynchroConfig(hsai); + + /* Configure Master Clock using the following formula : + MCLK_x = SAI_CK_x / (MCKDIV[3:0] * 2) with MCLK_x = 256 * FS + FS = SAI_CK_x / (MCKDIV[3:0] * 2) * 256 + MCKDIV[3:0] = SAI_CK_x / FS * 512 */ + if(hsai->Init.AudioFrequency != SAI_AUDIO_FREQUENCY_MCKDIV) + { + /* Get SAI clock source based on Source clock selection from RCC */ + freq = SAI_GetInputClock(hsai); + + /* (saiclocksource x 10) to keep Significant digits */ + tmpclock = (((freq * 10) / ((hsai->Init.AudioFrequency) * 512))); + + hsai->Init.Mckdiv = tmpclock / 10; + + /* Round result to the nearest integer */ + if((tmpclock % 10) > 8) + { + hsai->Init.Mckdiv+= 1; + } + } + + /* SAI Block Configuration ------------------------------------------------------------*/ + /* SAI CR1 Configuration */ + hsai->Instance->CR1&=~(SAI_xCR1_MODE | SAI_xCR1_PRTCFG | SAI_xCR1_DS | \ + SAI_xCR1_LSBFIRST | SAI_xCR1_CKSTR | SAI_xCR1_SYNCEN |\ + SAI_xCR1_MONO | SAI_xCR1_OUTDRIV | SAI_xCR1_DMAEN | \ + SAI_xCR1_NODIV | SAI_xCR1_MCKDIV); + + hsai->Instance->CR1|= (hsai->Init.AudioMode | hsai->Init.Protocol | \ + hsai->Init.DataSize | hsai->Init.FirstBit | \ + hsai->Init.ClockStrobing | hsai->Init.Synchro | \ + hsai->Init.MonoStereoMode | hsai->Init.OutputDrive | \ + hsai->Init.NoDivider | (hsai->Init.Mckdiv << 20) | hsai->Init.CompandingMode); + + /* SAI CR2 Configuration */ + hsai->Instance->CR2&= ~(SAI_xCR2_FTH | SAI_xCR2_FFLUSH | SAI_xCR2_COMP); + hsai->Instance->CR2|= (hsai->Init.FIFOThreshold | hsai->Init.CompandingMode | hsai->Init.TriState); + + + /* SAI Frame Configuration -----------------------------------------*/ + hsai->Instance->FRCR&=(~(SAI_xFRCR_FRL | SAI_xFRCR_FSALL | SAI_xFRCR_FSDEF | \ + SAI_xFRCR_FSPO | SAI_xFRCR_FSOFF)); + hsai->Instance->FRCR|=((hsai->FrameInit.FrameLength - 1) | + hsai->FrameInit.FSOffset | + hsai->FrameInit.FSDefinition | + hsai->FrameInit.FSPolarity | + ((hsai->FrameInit.ActiveFrameLength - 1) << 8)); + + /* SAI Block_x SLOT Configuration ------------------------------------------*/ + /* This register has no meaning in AC’97 and SPDIF audio protocol */ + hsai->Instance->SLOTR&= (~(SAI_xSLOTR_FBOFF | SAI_xSLOTR_SLOTSZ | \ + SAI_xSLOTR_NBSLOT | SAI_xSLOTR_SLOTEN )); + + hsai->Instance->SLOTR|= hsai->SlotInit.FirstBitOffset | hsai->SlotInit.SlotSize + | hsai->SlotInit.SlotActive | ((hsai->SlotInit.SlotNumber - 1) << 8); + + /* Initialise the error code */ + hsai->ErrorCode = HAL_SAI_ERROR_NONE; + + /* Initialize the SAI state */ + hsai->State= HAL_SAI_STATE_READY; + + /* Release Lock */ + __HAL_UNLOCK(hsai); + + return HAL_OK; +} + +/** + * @brief DeInitializes the SAI peripheral. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_DeInit(SAI_HandleTypeDef *hsai) +{ + /* Check the SAI handle allocation */ + if(hsai == NULL) + { + return HAL_ERROR; + } + + hsai->State = HAL_SAI_STATE_BUSY; + + /* Disabled All interrupt and clear all the flag */ + hsai->Instance->IMR = 0; + hsai->Instance->CLRFR = 0xFFFFFFFF; + + /* Disable the SAI */ + SAI_Disable(hsai); + + /* Flush the fifo */ + SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH); + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ + HAL_SAI_MspDeInit(hsai); + + /* Initialize the error code */ + hsai->ErrorCode = HAL_SAI_ERROR_NONE; + + /* Initialize the SAI state */ + hsai->State = HAL_SAI_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hsai); + + return HAL_OK; +} + +/** + * @brief SAI MSP Init. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +__weak void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SAI_MspInit could be implemented in the user file + */ +} + +/** + * @brief SAI MSP DeInit. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +__weak void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SAI_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup SAI_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the SAI data + transfers. + + (+) There are two modes of transfer: + (++) Blocking mode : The communication is performed in the polling mode. + The status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode : The communication is performed using Interrupts + or DMA. These functions return the status of the transfer startup. + The end of the data processing will be indicated through the + dedicated SAI IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + + (+) Blocking mode functions are : + (++) HAL_SAI_Transmit() + (++) HAL_SAI_Receive() + (++) HAL_SAI_TransmitReceive() + + (+) Non Blocking mode functions with Interrupt are : + (++) HAL_SAI_Transmit_IT() + (++) HAL_SAI_Receive_IT() + (++) HAL_SAI_TransmitReceive_IT() + + (+) Non Blocking mode functions with DMA are : + (++) HAL_SAI_Transmit_DMA() + (++) HAL_SAI_Receive_DMA() + (++) HAL_SAI_TransmitReceive_DMA() + + (+) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) HAL_SAI_TxCpltCallback() + (++) HAL_SAI_RxCpltCallback() + (++) HAL_SAI_ErrorCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Transmits an amount of data in blocking mode. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_Transmit(SAI_HandleTypeDef *hsai, uint8_t* pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + if(hsai->State == HAL_SAI_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsai); + + hsai->State = HAL_SAI_STATE_BUSY_TX; + hsai->ErrorCode = HAL_SAI_ERROR_NONE; + hsai->XferSize = Size; + hsai->XferCount = Size; + hsai->pBuffPtr = pData; + + /* Check if the SAI is already enabled */ + if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) != SAI_xCR1_SAIEN) + { + /* fill the fifo with data before to enabled the SAI */ + SAI_FillFifo(hsai); + /* Enable SAI peripheral */ + __HAL_SAI_ENABLE(hsai); + } + + while(hsai->XferCount > 0) + { + /* Write data if the FIFO is not full */ + if((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_FULL) + { + if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) + { + hsai->Instance->DR = (*hsai->pBuffPtr++); + } + else if(hsai->Init.DataSize <= SAI_DATASIZE_16) + { + hsai->Instance->DR = *((uint16_t *)hsai->pBuffPtr); + hsai->pBuffPtr+= 2; + } + else + { + hsai->Instance->DR = *((uint32_t *)hsai->pBuffPtr); + hsai->pBuffPtr+= 4; + } + hsai->XferCount--; + } + else + { + /* Get tick */ + tickstart = HAL_GetTick(); + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Update error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + /* Change the SAI state */ + hsai->State = HAL_SAI_STATE_TIMEOUT; + + return HAL_TIMEOUT; + } + } + } + } + + hsai->State = HAL_SAI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receives an amount of data in blocking mode. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be received + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_Receive(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + if(hsai->State == HAL_SAI_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hsai); + + hsai->State = HAL_SAI_STATE_BUSY_RX; + hsai->ErrorCode = HAL_SAI_ERROR_NONE; + hsai->pBuffPtr = pData; + hsai->XferSize = Size; + hsai->XferCount = Size; + + /* Check if the SAI is already enabled */ + if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) != SAI_xCR1_SAIEN) + { + /* Enable SAI peripheral */ + __HAL_SAI_ENABLE(hsai); + } + + /* Receive data */ + while(hsai->XferCount > 0) + { + + if((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_EMPTY) + { + if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) + { + (*hsai->pBuffPtr++) = hsai->Instance->DR; + } + else if(hsai->Init.DataSize <= SAI_DATASIZE_16) + { + *((uint16_t*)hsai->pBuffPtr) = hsai->Instance->DR; + hsai->pBuffPtr+= 2; + } + else + { + *((uint32_t*)hsai->pBuffPtr) = hsai->Instance->DR; + hsai->pBuffPtr+= 4; + } + hsai->XferCount--; + } + else + { + /* Get tick */ + tickstart = HAL_GetTick(); + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Update error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + /* Change the SAI state */ + hsai->State = HAL_SAI_STATE_TIMEOUT; + + return HAL_TIMEOUT; + } + } + } + } + + hsai->State = HAL_SAI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmits an amount of data in no-blocking mode with Interrupt. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_Transmit_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size) +{ + if(hsai->State == HAL_SAI_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + hsai->pBuffPtr = pData; + hsai->XferSize = Size; + hsai->XferCount = Size; + + /* Process Locked */ + __HAL_LOCK(hsai); + + hsai->State = HAL_SAI_STATE_BUSY_TX; + + if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) + { + hsai->InterruptServiceRoutine = SAI_Transmit_IT8Bit; + } + else if(hsai->Init.DataSize <= SAI_DATASIZE_16) + { + hsai->InterruptServiceRoutine = SAI_Transmit_IT16Bit; + } + else + { + hsai->InterruptServiceRoutine = SAI_Transmit_IT32Bit; + } + + /* Enable FRQ and OVRUDR interrupts */ + __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); + + /* Check if the SAI is already enabled */ + if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) != SAI_xCR1_SAIEN) + { + /* Fill the fifo before starting the communication */ + SAI_FillFifo(hsai); + + /* Enable SAI peripheral */ + __HAL_SAI_ENABLE(hsai); + } + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receives an amount of data in no-blocking mode with Interrupt. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_Receive_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size) +{ + + if(hsai->State == HAL_SAI_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + hsai->pBuffPtr = pData; + hsai->XferSize = Size; + hsai->XferCount = Size; + + /* Process Locked */ + __HAL_LOCK(hsai); + + hsai->State = HAL_SAI_STATE_BUSY_RX; + + if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) + { + hsai->InterruptServiceRoutine = SAI_Receive_IT8Bit; + } + else if(hsai->Init.DataSize <= SAI_DATASIZE_16) + { + hsai->InterruptServiceRoutine = SAI_Receive_IT16Bit; + } + else + { + hsai->InterruptServiceRoutine = SAI_Receive_IT32Bit; + } + /* Enable TXE and OVRUDR interrupts */ + __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); + + /* Check if the SAI is already enabled */ + if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) != SAI_xCR1_SAIEN) + { + /* Enable SAI peripheral */ + __HAL_SAI_ENABLE(hsai); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Pauses the audio stream playing from the Media. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_DMAPause(SAI_HandleTypeDef *hsai) +{ + /* Process Locked */ + __HAL_LOCK(hsai); + + /* Pause the audio file playing by disabling the SAI DMA requests */ + hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; +} + +/** + * @brief Resumes the audio stream playing from the Media. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_DMAResume(SAI_HandleTypeDef *hsai) +{ + /* Process Locked */ + __HAL_LOCK(hsai); + + /* Enable the SAI DMA requests */ + hsai->Instance->CR1 |= SAI_xCR1_DMAEN; + + /* If the SAI peripheral is still not enabled, enable it */ + if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET) + { + /* Enable SAI peripheral */ + __HAL_SAI_ENABLE(hsai); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; +} + +/** + * @brief Stops the audio stream playing from the Media. + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_DMAStop(SAI_HandleTypeDef *hsai) +{ + /* Process Locked */ + __HAL_LOCK(hsai); + + /* Disable the SAI DMA request */ + hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN; + + /* Abort the SAI DMA Tx Stream */ + if(hsai->hdmatx != NULL) + { + HAL_DMA_Abort(hsai->hdmatx); + } + /* Abort the SAI DMA Rx Stream */ + if(hsai->hdmarx != NULL) + { + HAL_DMA_Abort(hsai->hdmarx); + } + + /* Disable SAI peripheral */ + SAI_Disable(hsai); + + hsai->State = HAL_SAI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; +} + +/** + * @brief Abort the current transfer and disbaled the SAI. + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_Abort(SAI_HandleTypeDef *hsai) +{ + /* Disable the SAI DMA request */ + hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN; + + /* Abort the SAI DMA Tx Stream */ + if(hsai->hdmatx != NULL) + { + HAL_DMA_Abort(hsai->hdmatx); + } + /* Abort the SAI DMA Rx Stream */ + if(hsai->hdmarx != NULL) + { + HAL_DMA_Abort(hsai->hdmarx); + } + + /* Disabled All interrupt and clear all the flag */ + hsai->Instance->IMR = 0; + hsai->Instance->CLRFR = 0xFFFFFFFF; + + /* Disable SAI peripheral */ + SAI_Disable(hsai); + + /* Flush the fifo */ + SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH); + + hsai->State = HAL_SAI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; +} + +/** + * @brief Transmits an amount of data in no-blocking mode with DMA. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_Transmit_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size) +{ + uint32_t *tmp; + + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + if(hsai->State == HAL_SAI_STATE_READY) + { + hsai->pBuffPtr = pData; + hsai->XferSize = Size; + hsai->XferCount = Size; + + /* Process Locked */ + __HAL_LOCK(hsai); + + hsai->State = HAL_SAI_STATE_BUSY_TX; + + /* Set the SAI Tx DMA Half transfer complete callback */ + hsai->hdmatx->XferHalfCpltCallback = SAI_DMATxHalfCplt; + + /* Set the SAI TxDMA transfer complete callback */ + hsai->hdmatx->XferCpltCallback = SAI_DMATxCplt; + + /* Set the DMA error callback */ + hsai->hdmatx->XferErrorCallback = SAI_DMAError; + + /* Enable the Tx DMA Stream */ + tmp = (uint32_t*)&pData; + HAL_DMA_Start_IT(hsai->hdmatx, *(uint32_t*)tmp, (uint32_t)&hsai->Instance->DR, hsai->XferSize); + + /* Check if the SAI is already enabled */ + if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) != SAI_xCR1_SAIEN) + { + /* Enable SAI peripheral */ + __HAL_SAI_ENABLE(hsai); + } + + /* Enable the interrupts for error handling */ + __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA)); + + /* Enable SAI Tx DMA Request */ + hsai->Instance->CR1 |= SAI_xCR1_DMAEN; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receives an amount of data in no-blocking mode with DMA. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_Receive_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size) +{ + uint32_t *tmp; + + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + if(hsai->State == HAL_SAI_STATE_READY) + { + hsai->pBuffPtr = pData; + hsai->XferSize = Size; + hsai->XferCount = Size; + + /* Process Locked */ + __HAL_LOCK(hsai); + + hsai->State = HAL_SAI_STATE_BUSY_RX; + + /* Set the SAI Rx DMA Half transfer complete callback */ + hsai->hdmarx->XferHalfCpltCallback = SAI_DMARxHalfCplt; + + /* Set the SAI Rx DMA transfer complete callback */ + hsai->hdmarx->XferCpltCallback = SAI_DMARxCplt; + + /* Set the DMA error callback */ + hsai->hdmarx->XferErrorCallback = SAI_DMAError; + + /* Enable the Rx DMA Stream */ + tmp = (uint32_t*)&pData; + HAL_DMA_Start_IT(hsai->hdmarx, (uint32_t)&hsai->Instance->DR, *(uint32_t*)tmp, hsai->XferSize); + + /* Check if the SAI is already enabled */ + if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) != SAI_xCR1_SAIEN) + { + /* Enable SAI peripheral */ + __HAL_SAI_ENABLE(hsai); + } + + /* Enable the interrupts for error handling */ + __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA)); + + /* Enable SAI Rx DMA Request */ + hsai->Instance->CR1 |= SAI_xCR1_DMAEN; + + /* Process Unlocked */ + __HAL_UNLOCK(hsai); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Enable the tx mute mode. + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param val : value sent during the mute @ref SAI_Block_Mute_Value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_EnableTxMuteMode(SAI_HandleTypeDef *hsai, uint16_t val) +{ + assert_param(IS_SAI_BLOCK_MUTE_VALUE(val)); + + if(hsai->State != HAL_SAI_STATE_RESET) + { + CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTEVAL | SAI_xCR2_MUTE); + SET_BIT(hsai->Instance->CR2, SAI_xCR2_MUTE | val); + return HAL_OK; + } + return HAL_ERROR; +} + +/** + * @brief Disable the tx mute mode. + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_DisableTxMuteMode(SAI_HandleTypeDef *hsai) +{ + if(hsai->State != HAL_SAI_STATE_RESET) + { + CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTEVAL | SAI_xCR2_MUTE); + return HAL_OK; + } + return HAL_ERROR; +} + +/** + * @brief Enable the rx mute detection. + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param callback : function called when the mute is detected + * @param counter : number a data before mute detection max 63. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_EnableRxMuteMode(SAI_HandleTypeDef *hsai, SAIcallback callback, uint16_t counter) +{ + assert_param(IS_SAI_BLOCK_MUTE_COUNTER(counter)); + + if(hsai->State != HAL_SAI_STATE_RESET) + { + /* set the mute counter */ + CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTECNT); + SET_BIT(hsai->Instance->CR2, (uint32_t)((uint32_t)counter << 6)); + hsai->mutecallback = callback; + /* enable the IT interrupt */ + __HAL_SAI_ENABLE_IT(hsai, SAI_IT_MUTEDET); + return HAL_OK; + } + return HAL_ERROR; +} + +/** + * @brief Disable the rx mute detection. + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SAI_DisableRxMuteMode(SAI_HandleTypeDef *hsai) +{ + if(hsai->State != HAL_SAI_STATE_RESET) + { + /* set the mutecallback to NULL */ + hsai->mutecallback = (SAIcallback)NULL; + /* enable the IT interrupt */ + __HAL_SAI_DISABLE_IT(hsai, SAI_IT_MUTEDET); + return HAL_OK; + } + return HAL_ERROR; +} + +/** + * @brief This function handles SAI interrupt request. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL status + */ +void HAL_SAI_IRQHandler(SAI_HandleTypeDef *hsai) +{ + if(hsai->State != HAL_SAI_STATE_RESET) + { + uint32_t tmpFlag = hsai->Instance->SR; + uint32_t tmpItSource = hsai->Instance->IMR; + + if(((tmpFlag & SAI_xSR_FREQ) == SAI_xSR_FREQ) && ((tmpItSource & SAI_IT_FREQ) == SAI_IT_FREQ)) + { + hsai->InterruptServiceRoutine(hsai); + } + + /* check the flag only if one of them is set */ + if(tmpFlag != 0x00000000) + { + /* SAI Overrun error interrupt occurred ----------------------------------*/ + if(((tmpFlag & SAI_FLAG_OVRUDR) == SAI_FLAG_OVRUDR) && ((tmpItSource & SAI_IT_OVRUDR) == SAI_IT_OVRUDR)) + { + /* Clear the SAI Overrun flag */ + __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR); + /* Change the SAI error code */ + hsai->ErrorCode = ((hsai->State == HAL_SAI_STATE_BUSY_RX) ? HAL_SAI_ERROR_OVR : HAL_SAI_ERROR_UDR); + /* the transfer is not stopped, we will forward the information to the user and we let the user decide what needs to be done */ + HAL_SAI_ErrorCallback(hsai); + } + + /* SAI mutedet interrupt occurred ----------------------------------*/ + if(((tmpFlag & SAI_FLAG_MUTEDET) == SAI_FLAG_MUTEDET) && ((tmpItSource & SAI_IT_MUTEDET) == SAI_IT_MUTEDET)) + { + /* Clear the SAI mutedet flag */ + __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_MUTEDET); + /* call the call back function */ + if(hsai->mutecallback != (SAIcallback)NULL) + { + /* inform the user that an RX mute event has been detected */ + hsai->mutecallback(); + } + } + + /* SAI AFSDET interrupt occurred ----------------------------------*/ + if(((tmpFlag & SAI_FLAG_AFSDET) == SAI_FLAG_AFSDET) && ((tmpItSource & SAI_IT_AFSDET) == SAI_IT_AFSDET)) + { + /* Change the SAI error code */ + hsai->ErrorCode = HAL_SAI_ERROR_AFSDET; + HAL_SAI_Abort(hsai); + HAL_SAI_ErrorCallback(hsai); + } + + /* SAI LFSDET interrupt occurred ----------------------------------*/ + if(((tmpFlag & SAI_FLAG_LFSDET) == SAI_FLAG_LFSDET) && ((tmpItSource & SAI_IT_LFSDET) == SAI_IT_LFSDET)) + { + /* Change the SAI error code */ + hsai->ErrorCode = HAL_SAI_ERROR_LFSDET; + HAL_SAI_Abort(hsai); + HAL_SAI_ErrorCallback(hsai); + } + + /* SAI WCKCFG interrupt occurred ----------------------------------*/ + if(((tmpFlag & SAI_FLAG_WCKCFG) == SAI_FLAG_WCKCFG) && ((tmpItSource & SAI_IT_WCKCFG) == SAI_IT_WCKCFG)) + { + /* Change the SAI error code */ + hsai->ErrorCode = HAL_SAI_ERROR_WCKCFG; + HAL_SAI_Abort(hsai); + HAL_SAI_ErrorCallback(hsai); + } + } + } +} + +/** + * @brief Tx Transfer completed callbacks. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ + __weak void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SAI_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Tx Transfer Half completed callbacks + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ + __weak void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SAI_TxHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callbacks. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +__weak void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SAI_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer half completed callbacks + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +__weak void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SAI_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief SAI error callbacks. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None + */ +__weak void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SAI_ErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + + +/** @defgroup SAI_Exported_Functions_Group3 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the SAI state. + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval HAL state + */ +HAL_SAI_StateTypeDef HAL_SAI_GetState(SAI_HandleTypeDef *hsai) +{ + return hsai->State; +} + +/** +* @brief Return the SAI error code +* @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for the specified SAI Block. +* @retval SAI Error Code +*/ +uint32_t HAL_SAI_GetError(SAI_HandleTypeDef *hsai) +{ + return hsai->ErrorCode; +} +/** + * @} + */ + +/** + * @brief Initializes the SAI I2S protocol according to the specified parameters + * in the SAI_InitTypeDef and create the associated handle. + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param protocol : one of the supported protocol + * @param datasize : one of the supported datasize @ref SAI_Protocol_DataSize + * the configuration information for SAI module. + * @param nbslot : number of slot minimum value is 2 and max is 16. + * the value must be a multiple of 2. + * @retval HAL status + */ +static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot) +{ + /* Check the parameters */ + assert_param(IS_SAI_SUPPORTED_PROTOCOL(protocol)); + assert_param(IS_SAI_PROTOCOL_DATASIZE(datasize)); + + hsai->Init.Protocol = SAI_FREE_PROTOCOL; + hsai->Init.FirstBit = SAI_FIRSTBIT_MSB; + hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE; + hsai->FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION; + hsai->SlotInit.SlotActive = SAI_SLOTACTIVE_ALL; + hsai->SlotInit.FirstBitOffset = 0; + hsai->SlotInit.SlotNumber = nbslot; + + /* in IS2 the number of slot must be even */ + if((nbslot & 0x1) != 0 ) + { + return HAL_ERROR; + } + + switch(protocol) + { + case SAI_I2S_STANDARD : + hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW; + hsai->FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT; + break; + case SAI_I2S_MSBJUSTIFIED : + case SAI_I2S_LSBJUSTIFIED : + hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH; + hsai->FrameInit.FSOffset = SAI_FS_FIRSTBIT; + break; + default : + return HAL_ERROR; + } + + /* Frame definition */ + hsai->Init.DataSize = 0xFFFFFFFF; + switch(datasize) + { + case SAI_PROTOCOL_DATASIZE_16BIT: + hsai->Init.DataSize = SAI_DATASIZE_16; + hsai->FrameInit.FrameLength = 32*(nbslot/2); + hsai->FrameInit.ActiveFrameLength = 16*(nbslot/2); + hsai->SlotInit.SlotSize = SAI_SLOTSIZE_16B; + break; + case SAI_PROTOCOL_DATASIZE_16BITEXTENDED : + if(hsai->Init.DataSize == 0xFFFFFFFF) + { + hsai->Init.DataSize = SAI_DATASIZE_16; + } + break; + case SAI_PROTOCOL_DATASIZE_24BIT: + if(hsai->Init.DataSize == 0xFFFFFFFF) + { + hsai->Init.DataSize = SAI_DATASIZE_24; + } + break; + case SAI_PROTOCOL_DATASIZE_32BIT: + if(hsai->Init.DataSize == 0xFFFFFFFF) + { + hsai->Init.DataSize = SAI_DATASIZE_32; + } + hsai->FrameInit.FrameLength = 64*(nbslot/2); + hsai->FrameInit.ActiveFrameLength = 32*(nbslot/2); + hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B; + if(protocol == SAI_I2S_LSBJUSTIFIED) + { + if (datasize == SAI_PROTOCOL_DATASIZE_16BITEXTENDED) + { + hsai->SlotInit.FirstBitOffset = 16; + } + if (datasize == SAI_PROTOCOL_DATASIZE_24BIT) + { + hsai->SlotInit.FirstBitOffset = 8; + } + } + break; + default : + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Initializes the SAI PCM protocol according to the specified parameters + * in the SAI_InitTypeDef and create the associated handle. + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param protocol : one of the supported protocol + * @param datasize : one of the supported datasize @ref SAI_Protocol_DataSize + * @param nbslot : number of slot minimum value is 1 and the max is 16. + * @retval HAL status + */ +static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot) +{ + /* Check the parameters */ + assert_param(IS_SAI_SUPPORTED_PROTOCOL(protocol)); + assert_param(IS_SAI_PROTOCOL_DATASIZE(datasize)); + + hsai->Init.Protocol = SAI_FREE_PROTOCOL; + hsai->Init.FirstBit = SAI_FIRSTBIT_MSB; + hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE; + hsai->FrameInit.FSDefinition = SAI_FS_STARTFRAME; + hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH; + hsai->FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT; + hsai->SlotInit.FirstBitOffset = 0; + hsai->SlotInit.SlotNumber = nbslot; + hsai->SlotInit.SlotActive = SAI_SLOTACTIVE_ALL; + + switch(protocol) + { + case SAI_PCM_SHORT : + hsai->FrameInit.ActiveFrameLength = 1; + break; + case SAI_PCM_LONG : + hsai->FrameInit.ActiveFrameLength = 13; + break; + default : + return HAL_ERROR; + } + + switch(datasize) + { + case SAI_PROTOCOL_DATASIZE_16BIT: + hsai->Init.DataSize = SAI_DATASIZE_16; + hsai->FrameInit.FrameLength = 16 * nbslot; + hsai->SlotInit.SlotSize = SAI_SLOTSIZE_16B; + break; + case SAI_PROTOCOL_DATASIZE_16BITEXTENDED : + hsai->Init.DataSize = SAI_DATASIZE_16; + hsai->FrameInit.FrameLength = 32 * nbslot; + hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B; + break; + + case SAI_PROTOCOL_DATASIZE_32BIT: + hsai->Init.DataSize = SAI_DATASIZE_32; + hsai->FrameInit.FrameLength = 32 * nbslot; + hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B; + break; + default : + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Fill the fifo + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None. + */ +static void SAI_FillFifo(SAI_HandleTypeDef *hsai) +{ + /* fill the fifo with data before to enabled the SAI */ + while((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_FULL) + { + if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) + { + hsai->Instance->DR = (*hsai->pBuffPtr++); + } + else if(hsai->Init.DataSize <= SAI_DATASIZE_16) + { + hsai->Instance->DR = *((uint32_t *)hsai->pBuffPtr); + hsai->pBuffPtr+= 2; + } + else + { + hsai->Instance->DR = *((uint32_t *)hsai->pBuffPtr); + hsai->pBuffPtr+= 4; + } + hsai->XferCount--; + } +} + +/** + * @brief return the interrupt flag to set according the SAI setup + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @param mode : SAI_MODE_DMA or SAI_MODE_IT + * @retval the list of the IT flag to enable + */ +static uint32_t SAI_InterruptFlag(SAI_HandleTypeDef *hsai, uint32_t mode) +{ + uint32_t tmpIT = SAI_IT_OVRUDR; + + if(mode == SAI_MODE_IT) + { + tmpIT|= SAI_IT_FREQ; + } + + if((hsai->Init.AudioMode == SAI_MODESLAVE_RX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX)) + { + tmpIT|= SAI_IT_AFSDET | SAI_IT_LFSDET; + } + else + { + /* hsai has been configured in master mode */ + tmpIT|= SAI_IT_WCKCFG; + } + return tmpIT; +} + +/** + * @brief disabled the SAI and wait the disabling + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None. + */ +static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai) +{ + uint32_t tickstart = HAL_GetTick(); + HAL_StatusTypeDef status = HAL_OK; + + __HAL_SAI_DISABLE(hsai); + while((hsai->Instance->CR1 & SAI_xCR1_SAIEN) != RESET) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > SAI_TIMEOUT_VALUE) + { + /* Update error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT; + + status = HAL_TIMEOUT; + + /* Change the SAI state */ + HAL_SAI_ErrorCallback(hsai); + } + } + return status; +} + +/** + * @brief Tx Handler for Transmit in Interrupt mode 8Bit transfer + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None. + */ +static void SAI_Transmit_IT8Bit(SAI_HandleTypeDef *hsai) +{ + /* Write data on DR register */ + hsai->Instance->DR = (*hsai->pBuffPtr++); + hsai->XferCount--; + + /* Handle the end of the transmission */ + if(hsai->XferCount == 0) + { + /* Disable FREQ and OVRUDR interrupts */ + __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); + hsai->State = HAL_SAI_STATE_READY; + HAL_SAI_TxCpltCallback(hsai); + } +} + +/** + * @brief Tx Handler for Transmit in Interrupt mode for 16Bit transfer + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None. + */ +static void SAI_Transmit_IT16Bit(SAI_HandleTypeDef *hsai) +{ + /* Write data on DR register */ + hsai->Instance->DR = *(uint16_t *)hsai->pBuffPtr; + hsai->pBuffPtr+=2; + hsai->XferCount--; + + /* Handle the end of the transmission */ + if(hsai->XferCount == 0) + { + /* Disable FREQ and OVRUDR interrupts */ + __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); + hsai->State = HAL_SAI_STATE_READY; + HAL_SAI_TxCpltCallback(hsai); + } +} + +/** + * @brief Tx Handler for Transmit in Interrupt mode for 32Bit transfer + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None. + */ +static void SAI_Transmit_IT32Bit(SAI_HandleTypeDef *hsai) +{ + /* Write data on DR register */ + hsai->Instance->DR = *(uint32_t *)hsai->pBuffPtr; + hsai->pBuffPtr+=4; + hsai->XferCount--; + + /* Handle the end of the transmission */ + if(hsai->XferCount == 0) + { + /* Disable FREQ and OVRUDR interrupts */ + __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); + hsai->State = HAL_SAI_STATE_READY; + HAL_SAI_TxCpltCallback(hsai); + } +} + +/** + * @brief Rx Handler for Receive in Interrupt mode 8Bit transfer + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None. + */ +static void SAI_Receive_IT8Bit(SAI_HandleTypeDef *hsai) +{ + /* Receive data */ + (*hsai->pBuffPtr++) = hsai->Instance->DR; + hsai->XferCount--; + + /* Check end of the transfer */ + if(hsai->XferCount == 0) + { + /* Disable TXE and OVRUDR interrupts */ + __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); + + /* Clear the SAI Overrun flag */ + __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR); + + hsai->State = HAL_SAI_STATE_READY; + HAL_SAI_RxCpltCallback(hsai); + } +} + +/** + * @brief Rx Handler for Receive in Interrupt mode for 16Bit transfer + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None. + */ +static void SAI_Receive_IT16Bit(SAI_HandleTypeDef *hsai) +{ + /* Receive data */ + *(uint16_t*)hsai->pBuffPtr = hsai->Instance->DR; + hsai->pBuffPtr+=2; + hsai->XferCount--; + + /* Check end of the transfer */ + if(hsai->XferCount == 0) + { + /* Disable TXE and OVRUDR interrupts */ + __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); + + /* Clear the SAI Overrun flag */ + __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR); + + hsai->State = HAL_SAI_STATE_READY; + HAL_SAI_RxCpltCallback(hsai); + } +} +/** + * @brief Rx Handler for Receive in Interrupt mode for 32Bit transfer + * @param hsai : pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval None. + */ +static void SAI_Receive_IT32Bit(SAI_HandleTypeDef *hsai) +{ + /* Receive data */ + *(uint32_t*)hsai->pBuffPtr = hsai->Instance->DR; + hsai->pBuffPtr+=4; + hsai->XferCount--; + + /* Check end of the transfer */ + if(hsai->XferCount == 0) + { + /* Disable TXE and OVRUDR interrupts */ + __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); + + /* Clear the SAI Overrun flag */ + __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR); + + hsai->State = HAL_SAI_STATE_READY; + HAL_SAI_RxCpltCallback(hsai); + } +} + +/** + * @brief DMA SAI transmit process complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SAI_DMATxCplt(DMA_HandleTypeDef *hdma) +{ + uint32_t tickstart = 0; + + SAI_HandleTypeDef* hsai = (SAI_HandleTypeDef*)((DMA_HandleTypeDef* )hdma)->Parent; + + if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) + { + hsai->XferCount = 0; + + /* Disable SAI Tx DMA Request */ + hsai->Instance->CR1 &= (uint32_t)(~SAI_xCR1_DMAEN); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Set timeout: 10 is the max delay to send the remaining data in the SAI FIFO */ + /* Wait until FIFO is empty */ + while(__HAL_SAI_GET_FLAG(hsai, SAI_xSR_FLVL) != RESET) + { + /* Check for the Timeout */ + if((HAL_GetTick() - tickstart ) > SAI_TIMEOUT_VALUE) + { + /* Update error code */ + hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT; + + /* Change the SAI state */ + HAL_SAI_ErrorCallback(hsai); + } + } + + /* Stop the interrupts error handling */ + __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA)); + + hsai->State= HAL_SAI_STATE_READY; + } + HAL_SAI_TxCpltCallback(hsai); +} + +/** + * @brief DMA SAI transmit process half complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SAI_DMATxHalfCplt(DMA_HandleTypeDef *hdma) +{ + SAI_HandleTypeDef* hsai = (SAI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + HAL_SAI_TxHalfCpltCallback(hsai); +} + +/** + * @brief DMA SAI receive process complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SAI_DMARxCplt(DMA_HandleTypeDef *hdma) +{ + SAI_HandleTypeDef* hsai = ( SAI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) + { + /* Disable Rx DMA Request */ + hsai->Instance->CR1 &= (uint32_t)(~SAI_xCR1_DMAEN); + hsai->XferCount = 0; + + /* Stop the interrupts error handling */ + __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA)); + + hsai->State = HAL_SAI_STATE_READY; + } + HAL_SAI_RxCpltCallback(hsai); +} + +/** + * @brief DMA SAI receive process half complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SAI_DMARxHalfCplt(DMA_HandleTypeDef *hdma) +{ + SAI_HandleTypeDef* hsai = (SAI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + HAL_SAI_RxHalfCpltCallback(hsai); +} +/** + * @brief DMA SAI communication error callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SAI_DMAError(DMA_HandleTypeDef *hdma) +{ + SAI_HandleTypeDef* hsai = ( SAI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Stop the DMA transfer */ + HAL_SAI_DMAStop(hsai); + + /* Set the SAI state ready to be able to start again the process */ + hsai->State= HAL_SAI_STATE_READY; + HAL_SAI_ErrorCallback(hsai); + + hsai->XferCount = 0; +} + +/** + * @} + */ + +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ +#endif /* HAL_SAI_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai_ex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai_ex.c new file mode 100644 index 0000000..275c27c --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai_ex.c @@ -0,0 +1,269 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_sai_ex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief SAI Extension HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of SAI extension peripheral: + * + Extension features functions + * + @verbatim + ============================================================================== + ##### SAI peripheral extension features ##### + ============================================================================== + + [..] Comparing to other previous devices, the SAI interface for STM32F446xx + devices contains the following additional features : + + (+) Possibility to be clocked from PLLR + + ##### How to use this driver ##### + ============================================================================== + [..] This driver provides functions to manage several sources to clock SAI + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 SAIEx SAIEx + * @brief SAI Extension HAL module driver + * @{ + */ + +#ifdef HAL_SAI_MODULE_ENABLED + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* SAI registers Masks */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup SAI_Private_Functions SAI Private Functions + * @{ + */ + /** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SAIEx_Exported_Functions SAI Extended Exported Functions + * @{ + */ + +/** @defgroup SAIEx_Exported_Functions_Group1 Extension features functions + * @brief Extension features functions + * +@verbatim + =============================================================================== + ##### Extension features Functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the possible + SAI clock sources. + +@endverbatim + * @{ + */ + +/** + * @brief Configure SAI Block synchronization mode + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval SAI Clock Input + */ +void SAI_BlockSynchroConfig(SAI_HandleTypeDef *hsai) +{ + uint32_t tmpregisterGCR = 0; + +#if defined(STM32F446xx) + /* This setting must be done with both audio block (A & B) disabled */ + switch(hsai->Init.SynchroExt) + { + case SAI_SYNCEXT_DISABLE : + tmpregisterGCR = 0; + break; + case SAI_SYNCEXT_IN_ENABLE : + tmpregisterGCR = SAI_GCR_SYNCIN_0; + break; + case SAI_SYNCEXT_OUTBLOCKA_ENABLE : + tmpregisterGCR = SAI_GCR_SYNCOUT_0; + break; + case SAI_SYNCEXT_OUTBLOCKB_ENABLE : + tmpregisterGCR = SAI_GCR_SYNCOUT_1; + break; + } + + if((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI1_Block_B)) + { + SAI1->GCR = tmpregisterGCR; + } + else + { + SAI2->GCR = tmpregisterGCR; + } +#endif /* STM32F446xx */ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + /* This setting must be done with both audio block (A & B) disabled */ + switch(hsai->Init.SynchroExt) + { + case SAI_SYNCEXT_DISABLE : + tmpregisterGCR = 0; + break; + case SAI_SYNCEXT_OUTBLOCKA_ENABLE : + tmpregisterGCR = SAI_GCR_SYNCOUT_0; + break; + case SAI_SYNCEXT_OUTBLOCKB_ENABLE : + tmpregisterGCR = SAI_GCR_SYNCOUT_1; + break; + } + SAI1->GCR = tmpregisterGCR; +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ +} + /** + * @brief Get SAI Input Clock based on SAI source clock selection + * @param hsai: pointer to a SAI_HandleTypeDef structure that contains + * the configuration information for SAI module. + * @retval SAI Clock Input + */ +uint32_t SAI_GetInputClock(SAI_HandleTypeDef *hsai) +{ + /* This variable used to store the SAI_CK_x (value in Hz) */ + uint32_t saiclocksource = 0; + +#if defined(STM32F446xx) + if ((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI1_Block_B)) + { + saiclocksource = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI1); + } + else /* SAI2_Block_A || SAI2_Block_B*/ + { + saiclocksource = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI2); + } +#endif /* STM32F446xx */ +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + uint32_t vcoinput = 0, tmpreg = 0; + + /* Check the SAI Block parameters */ + assert_param(IS_SAI_CLK_SOURCE(hsai->Init.ClockSource)); + + /* SAI Block clock source selection */ + if(hsai->Instance == SAI1_Block_A) + { + __HAL_RCC_SAI_BLOCKACLKSOURCE_CONFIG(hsai->Init.ClockSource); + } + else + { + __HAL_RCC_SAI_BLOCKBCLKSOURCE_CONFIG((uint32_t)(hsai->Init.ClockSource << 2)); + } + + /* VCO Input Clock value calculation */ + if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI) + { + /* In Case the PLL Source is HSI (Internal Clock) */ + vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); + } + else + { + /* In Case the PLL Source is HSE (External Clock) */ + vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM))); + } + + /* SAI_CLK_x : SAI Block Clock configuration for different clock sources selected */ + if(hsai->Init.ClockSource == SAI_CLKSOURCE_PLLSAI) + { + /* Configure the PLLI2S division factor */ + /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ + /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ + /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */ + tmpreg = (RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24; + saiclocksource = (vcoinput * ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> 6))/(tmpreg); + + /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */ + tmpreg = (((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> 8) + 1); + saiclocksource = saiclocksource/(tmpreg); + + } + else if(hsai->Init.ClockSource == SAI_CLKSOURCE_PLLI2S) + { + /* Configure the PLLI2S division factor */ + /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */ + /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ + /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */ + tmpreg = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> 24; + saiclocksource = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6))/(tmpreg); + + /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */ + tmpreg = ((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) + 1); + saiclocksource = saiclocksource/(tmpreg); + } + else /* sConfig->ClockSource == SAI_CLKSource_Ext */ + { + /* Enable the External Clock selection */ + __HAL_RCC_I2S_CONFIG(RCC_I2SCLKSOURCE_EXT); + + saiclocksource = EXTERNAL_CLOCK_VALUE; + } +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + /* the return result is the value of SAI clock */ + return saiclocksource; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ +#endif /* HAL_SAI_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c new file mode 100644 index 0000000..c9e9a46 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c @@ -0,0 +1,3488 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_sd.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief SD card HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Secure Digital (SD) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + This driver implements a high level communication layer for read and write from/to + this memory. The needed STM32 hardware resources (SDIO and GPIO) are performed by + the user in HAL_SD_MspInit() function (MSP layer). + Basically, the MSP layer configuration should be the same as we provide in the + examples. + You can easily tailor this configuration according to hardware resources. + + [..] + This driver is a generic layered driver for SDIO memories which uses the HAL + SDIO driver functions to interface with SD and uSD cards devices. + It is used as follows: + + (#)Initialize the SDIO low level resources by implement the HAL_SD_MspInit() API: + (##) Enable the SDIO interface clock using __HAL_RCC_SDIO_CLK_ENABLE(); + (##) SDIO pins configuration for SD card + (+++) Enable the clock for the SDIO GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE(); + (+++) Configure these SDIO pins as alternate function pull-up using HAL_GPIO_Init() + and according to your pin assignment; + (##) DMA Configuration if you need to use DMA process (HAL_SD_ReadBlocks_DMA() + and HAL_SD_WriteBlocks_DMA() APIs). + (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE(); + (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled. + (##) NVIC configuration if you need to use interrupt process when using DMA transfer. + (+++) Configure the SDIO and DMA interrupt priorities using functions + HAL_NVIC_SetPriority(); DMA priority is superior to SDIO's priority + (+++) Enable the NVIC DMA and SDIO IRQs using function HAL_NVIC_EnableIRQ() + (+++) SDIO interrupts are managed using the macros __HAL_SD_SDIO_ENABLE_IT() + and __HAL_SD_SDIO_DISABLE_IT() inside the communication process. + (+++) SDIO interrupts pending bits are managed using the macros __HAL_SD_SDIO_GET_IT() + and __HAL_SD_SDIO_CLEAR_IT() + (#) At this stage, you can perform SD read/write/erase operations after SD card initialization + + + *** SD Card Initialization and configuration *** + ================================================ + [..] + To initialize the SD Card, use the HAL_SD_Init() function. It Initializes + the SD Card and put it into Standby State (Ready for data transfer). + This function provide the following operations: + + (#) Apply the SD Card initialization process at 400KHz and check the SD Card + type (Standard Capacity or High Capacity). You can change or adapt this + frequency by adjusting the "ClockDiv" field. + The SD Card frequency (SDIO_CK) is computed as follows: + + SDIO_CK = SDIOCLK / (ClockDiv + 2) + + In initialization mode and according to the SD Card standard, + make sure that the SDIO_CK frequency doesn't exceed 400KHz. + + (#) Get the SD CID and CSD data. All these information are managed by the SDCardInfo + structure. This structure provide also ready computed SD Card capacity + and Block size. + + -@- These information are stored in SD handle structure in case of future use. + + (#) Configure the SD Card Data transfer frequency. By Default, the card transfer + frequency is set to 24MHz. You can change or adapt this frequency by adjusting + the "ClockDiv" field. + In transfer mode and according to the SD Card standard, make sure that the + SDIO_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch. + To be able to use a frequency higher than 24MHz, you should use the SDIO + peripheral in bypass mode. Refer to the corresponding reference manual + for more details. + + (#) Select the corresponding SD Card according to the address read with the step 2. + + (#) Configure the SD Card in wide bus mode: 4-bits data. + + *** SD Card Read operation *** + ============================== + [..] + (+) You can read from SD card in polling mode by using function HAL_SD_ReadBlocks(). + This function support only 512-bytes block length (the block size should be + chosen as 512 bytes). + You can choose either one block read operation or multiple block read operation + by adjusting the "NumberOfBlocks" parameter. + + (+) You can read from SD card in DMA mode by using function HAL_SD_ReadBlocks_DMA(). + This function support only 512-bytes block length (the block size should be + chosen as 512 bytes). + You can choose either one block read operation or multiple block read operation + by adjusting the "NumberOfBlocks" parameter. + After this, you have to call the function HAL_SD_CheckReadOperation(), to insure + that the read transfer is done correctly in both DMA and SD sides. + + *** SD Card Write operation *** + =============================== + [..] + (+) You can write to SD card in polling mode by using function HAL_SD_WriteBlocks(). + This function support only 512-bytes block length (the block size should be + chosen as 512 bytes). + You can choose either one block read operation or multiple block read operation + by adjusting the "NumberOfBlocks" parameter. + + (+) You can write to SD card in DMA mode by using function HAL_SD_WriteBlocks_DMA(). + This function support only 512-bytes block length (the block size should be + chosen as 512 byte). + You can choose either one block read operation or multiple block read operation + by adjusting the "NumberOfBlocks" parameter. + After this, you have to call the function HAL_SD_CheckWriteOperation(), to insure + that the write transfer is done correctly in both DMA and SD sides. + + *** SD card status *** + ====================== + [..] + (+) At any time, you can check the SD Card status and get the SD card state + by using the HAL_SD_GetStatus() function. This function checks first if the + SD card is still connected and then get the internal SD Card transfer state. + (+) You can also get the SD card SD Status register by using the HAL_SD_SendSDStatus() + function. + + *** SD HAL driver macros list *** + ================================== + [..] + Below the list of most used macros in SD HAL driver. + + (+) __HAL_SD_SDIO_ENABLE : Enable the SD device + (+) __HAL_SD_SDIO_DISABLE : Disable the SD device + (+) __HAL_SD_SDIO_DMA_ENABLE: Enable the SDIO DMA transfer + (+) __HAL_SD_SDIO_DMA_DISABLE: Disable the SDIO DMA transfer + (+) __HAL_SD_SDIO_ENABLE_IT: Enable the SD device interrupt + (+) __HAL_SD_SDIO_DISABLE_IT: Disable the SD device interrupt + (+) __HAL_SD_SDIO_GET_FLAG:Check whether the specified SD flag is set or not + (+) __HAL_SD_SDIO_CLEAR_FLAG: Clear the SD's pending flags + + (@) You can refer to the SD HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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" + +#ifdef HAL_SD_MODULE_ENABLED + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup SD + * @{ + */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup SD_Private_Defines + * @{ + */ +/** + * @brief SDIO Data block size + */ +#define DATA_BLOCK_SIZE ((uint32_t)(9 << 4)) +/** + * @brief SDIO Static flags, Timeout, FIFO Address + */ +#define SDIO_STATIC_FLAGS ((uint32_t)(SDIO_FLAG_CCRCFAIL | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_CTIMEOUT |\ + SDIO_FLAG_DTIMEOUT | SDIO_FLAG_TXUNDERR | SDIO_FLAG_RXOVERR |\ + SDIO_FLAG_CMDREND | SDIO_FLAG_CMDSENT | SDIO_FLAG_DATAEND |\ + SDIO_FLAG_DBCKEND)) + +#define SDIO_CMD0TIMEOUT ((uint32_t)0x00010000) + +/** + * @brief Mask for errors Card Status R1 (OCR Register) + */ +#define SD_OCR_ADDR_OUT_OF_RANGE ((uint32_t)0x80000000) +#define SD_OCR_ADDR_MISALIGNED ((uint32_t)0x40000000) +#define SD_OCR_BLOCK_LEN_ERR ((uint32_t)0x20000000) +#define SD_OCR_ERASE_SEQ_ERR ((uint32_t)0x10000000) +#define SD_OCR_BAD_ERASE_PARAM ((uint32_t)0x08000000) +#define SD_OCR_WRITE_PROT_VIOLATION ((uint32_t)0x04000000) +#define SD_OCR_LOCK_UNLOCK_FAILED ((uint32_t)0x01000000) +#define SD_OCR_COM_CRC_FAILED ((uint32_t)0x00800000) +#define SD_OCR_ILLEGAL_CMD ((uint32_t)0x00400000) +#define SD_OCR_CARD_ECC_FAILED ((uint32_t)0x00200000) +#define SD_OCR_CC_ERROR ((uint32_t)0x00100000) +#define SD_OCR_GENERAL_UNKNOWN_ERROR ((uint32_t)0x00080000) +#define SD_OCR_STREAM_READ_UNDERRUN ((uint32_t)0x00040000) +#define SD_OCR_STREAM_WRITE_OVERRUN ((uint32_t)0x00020000) +#define SD_OCR_CID_CSD_OVERWRITE ((uint32_t)0x00010000) +#define SD_OCR_WP_ERASE_SKIP ((uint32_t)0x00008000) +#define SD_OCR_CARD_ECC_DISABLED ((uint32_t)0x00004000) +#define SD_OCR_ERASE_RESET ((uint32_t)0x00002000) +#define SD_OCR_AKE_SEQ_ERROR ((uint32_t)0x00000008) +#define SD_OCR_ERRORBITS ((uint32_t)0xFDFFE008) + +/** + * @brief Masks for R6 Response + */ +#define SD_R6_GENERAL_UNKNOWN_ERROR ((uint32_t)0x00002000) +#define SD_R6_ILLEGAL_CMD ((uint32_t)0x00004000) +#define SD_R6_COM_CRC_FAILED ((uint32_t)0x00008000) + +#define SD_VOLTAGE_WINDOW_SD ((uint32_t)0x80100000) +#define SD_HIGH_CAPACITY ((uint32_t)0x40000000) +#define SD_STD_CAPACITY ((uint32_t)0x00000000) +#define SD_CHECK_PATTERN ((uint32_t)0x000001AA) + +#define SD_MAX_VOLT_TRIAL ((uint32_t)0x0000FFFF) +#define SD_ALLZERO ((uint32_t)0x00000000) + +#define SD_WIDE_BUS_SUPPORT ((uint32_t)0x00040000) +#define SD_SINGLE_BUS_SUPPORT ((uint32_t)0x00010000) +#define SD_CARD_LOCKED ((uint32_t)0x02000000) + +#define SD_DATATIMEOUT ((uint32_t)0xFFFFFFFF) +#define SD_0TO7BITS ((uint32_t)0x000000FF) +#define SD_8TO15BITS ((uint32_t)0x0000FF00) +#define SD_16TO23BITS ((uint32_t)0x00FF0000) +#define SD_24TO31BITS ((uint32_t)0xFF000000) +#define SD_MAX_DATA_LENGTH ((uint32_t)0x01FFFFFF) + +#define SD_HALFFIFO ((uint32_t)0x00000008) +#define SD_HALFFIFOBYTES ((uint32_t)0x00000020) + +/** + * @brief Command Class Supported + */ +#define SD_CCCC_LOCK_UNLOCK ((uint32_t)0x00000080) +#define SD_CCCC_WRITE_PROT ((uint32_t)0x00000040) +#define SD_CCCC_ERASE ((uint32_t)0x00000020) + +/** + * @brief Following commands are SD Card Specific commands. + * SDIO_APP_CMD should be sent before sending these commands. + */ +#define SD_SDIO_SEND_IF_COND ((uint32_t)SD_CMD_HS_SEND_EXT_CSD) + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup SD_Private_Functions_Prototypes + * @{ + */ +static HAL_SD_ErrorTypedef SD_Initialize_Cards(SD_HandleTypeDef *hsd); +static HAL_SD_ErrorTypedef SD_Select_Deselect(SD_HandleTypeDef *hsd, uint64_t addr); +static HAL_SD_ErrorTypedef SD_PowerON(SD_HandleTypeDef *hsd); +static HAL_SD_ErrorTypedef SD_PowerOFF(SD_HandleTypeDef *hsd); +static HAL_SD_ErrorTypedef SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus); +static HAL_SD_CardStateTypedef SD_GetState(SD_HandleTypeDef *hsd); +static HAL_SD_ErrorTypedef SD_IsCardProgramming(SD_HandleTypeDef *hsd, uint8_t *pStatus); +static HAL_SD_ErrorTypedef SD_CmdError(SD_HandleTypeDef *hsd); +static HAL_SD_ErrorTypedef SD_CmdResp1Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD); +static HAL_SD_ErrorTypedef SD_CmdResp7Error(SD_HandleTypeDef *hsd); +static HAL_SD_ErrorTypedef SD_CmdResp3Error(SD_HandleTypeDef *hsd); +static HAL_SD_ErrorTypedef SD_CmdResp2Error(SD_HandleTypeDef *hsd); +static HAL_SD_ErrorTypedef SD_CmdResp6Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD, uint16_t *pRCA); +static HAL_SD_ErrorTypedef SD_WideBus_Enable(SD_HandleTypeDef *hsd); +static HAL_SD_ErrorTypedef SD_WideBus_Disable(SD_HandleTypeDef *hsd); +static HAL_SD_ErrorTypedef SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR); +static void SD_DMA_RxCplt(DMA_HandleTypeDef *hdma); +static void SD_DMA_RxError(DMA_HandleTypeDef *hdma); +static void SD_DMA_TxCplt(DMA_HandleTypeDef *hdma); +static void SD_DMA_TxError(DMA_HandleTypeDef *hdma); +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup SD_Exported_Functions + * @{ + */ + +/** @addtogroup SD_Exported_Functions_Group1 + * @brief Initialization and de-initialization functions + * +@verbatim + ============================================================================== + ##### Initialization and de-initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to initialize/de-initialize the SD + card device to be ready for use. + + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the SD card according to the specified parameters in the + SD_HandleTypeDef and create the associated handle. + * @param hsd: SD handle + * @param SDCardInfo: HAL_SD_CardInfoTypedef structure for SD card information + * @retval HAL SD error state + */ +HAL_SD_ErrorTypedef HAL_SD_Init(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *SDCardInfo) +{ + __IO HAL_SD_ErrorTypedef errorstate = SD_OK; + SD_InitTypeDef tmpinit; + + /* Allocate lock resource and initialize it */ + hsd->Lock = HAL_UNLOCKED; + /* Initialize the low level hardware (MSP) */ + HAL_SD_MspInit(hsd); + + /* Default SDIO peripheral configuration for SD card initialization */ + tmpinit.ClockEdge = SDIO_CLOCK_EDGE_RISING; + tmpinit.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; + tmpinit.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; + tmpinit.BusWide = SDIO_BUS_WIDE_1B; + tmpinit.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; + tmpinit.ClockDiv = SDIO_INIT_CLK_DIV; + + /* Initialize SDIO peripheral interface with default configuration */ + SDIO_Init(hsd->Instance, tmpinit); + + /* Identify card operating voltage */ + errorstate = SD_PowerON(hsd); + + if(errorstate != SD_OK) + { + return errorstate; + } + + /* Initialize the present SDIO card(s) and put them in idle state */ + errorstate = SD_Initialize_Cards(hsd); + + if (errorstate != SD_OK) + { + return errorstate; + } + + /* Read CSD/CID MSD registers */ + errorstate = HAL_SD_Get_CardInfo(hsd, SDCardInfo); + + if (errorstate == SD_OK) + { + /* Select the Card */ + errorstate = SD_Select_Deselect(hsd, (uint32_t)(((uint32_t)SDCardInfo->RCA) << 16)); + } + + /* Configure SDIO peripheral interface */ + SDIO_Init(hsd->Instance, hsd->Init); + + return errorstate; +} + +/** + * @brief De-Initializes the SD card. + * @param hsd: SD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SD_DeInit(SD_HandleTypeDef *hsd) +{ + + /* Set SD power state to off */ + SD_PowerOFF(hsd); + + /* De-Initialize the MSP layer */ + HAL_SD_MspDeInit(hsd); + + return HAL_OK; +} + + +/** + * @brief Initializes the SD MSP. + * @param hsd: SD handle + * @retval None + */ +__weak void HAL_SD_MspInit(SD_HandleTypeDef *hsd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SD_MspInit could be implemented in the user file + */ +} + +/** + * @brief De-Initialize SD MSP. + * @param hsd: SD handle + * @retval None + */ +__weak void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SD_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @addtogroup SD_Exported_Functions_Group2 + * @brief Data transfer functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to manage the data + transfer from/to SD card. + +@endverbatim + * @{ + */ + +/** + * @brief Reads block(s) from a specified address in a card. The Data transfer + * is managed by polling mode. + * @param hsd: SD handle + * @param pReadBuffer: pointer to the buffer that will contain the received data + * @param ReadAddr: Address from where data is to be read + * @param BlockSize: SD card Data block size + * @note BlockSize must be 512 bytes. + * @param NumberOfBlocks: Number of SD blocks to read + * @retval SD Card error state + */ +HAL_SD_ErrorTypedef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks) +{ + SDIO_CmdInitTypeDef sdio_cmdinitstructure; + SDIO_DataInitTypeDef sdio_datainitstructure; + HAL_SD_ErrorTypedef errorstate = SD_OK; + uint32_t count = 0, *tempbuff = (uint32_t *)pReadBuffer; + + /* Initialize data control register */ + hsd->Instance->DCTRL = 0; + + if (hsd->CardType == HIGH_CAPACITY_SD_CARD) + { + BlockSize = 512; + ReadAddr /= 512; + } + + /* Set Block Size for Card */ + sdio_cmdinitstructure.Argument = (uint32_t) BlockSize; + sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN); + + if (errorstate != SD_OK) + { + return errorstate; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + sdio_datainitstructure.DataTimeOut = SD_DATATIMEOUT; + sdio_datainitstructure.DataLength = NumberOfBlocks * BlockSize; + sdio_datainitstructure.DataBlockSize = DATA_BLOCK_SIZE; + sdio_datainitstructure.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO; + sdio_datainitstructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK; + sdio_datainitstructure.DPSM = SDIO_DPSM_ENABLE; + SDIO_DataConfig(hsd->Instance, &sdio_datainitstructure); + + if(NumberOfBlocks > 1) + { + /* Send CMD18 READ_MULT_BLOCK with argument data address */ + sdio_cmdinitstructure.CmdIndex = SD_CMD_READ_MULT_BLOCK; + } + else + { + /* Send CMD17 READ_SINGLE_BLOCK */ + sdio_cmdinitstructure.CmdIndex = SD_CMD_READ_SINGLE_BLOCK; + } + + sdio_cmdinitstructure.Argument = (uint32_t)ReadAddr; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Read block(s) in polling mode */ + if(NumberOfBlocks > 1) + { + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_MULT_BLOCK); + + if (errorstate != SD_OK) + { + return errorstate; + } + + /* Poll on SDIO flags */ +#ifdef SDIO_STA_STBITERR + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR)) +#else /* SDIO_STA_STBITERR not defined */ + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND)) +#endif /* SDIO_STA_STBITERR */ + { + if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF)) + { + /* Read data from SDIO Rx FIFO */ + for (count = 0; count < 8; count++) + { + *(tempbuff + count) = SDIO_ReadFIFO(hsd->Instance); + } + + tempbuff += 8; + } + } + } + else + { + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_SINGLE_BLOCK); + + if (errorstate != SD_OK) + { + return errorstate; + } + + /* In case of single block transfer, no need of stop transfer at all */ +#ifdef SDIO_STA_STBITERR + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR)) +#else /* SDIO_STA_STBITERR not defined */ + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND)) +#endif /* SDIO_STA_STBITERR */ + { + if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF)) + { + /* Read data from SDIO Rx FIFO */ + for (count = 0; count < 8; count++) + { + *(tempbuff + count) = SDIO_ReadFIFO(hsd->Instance); + } + + tempbuff += 8; + } + } + } + + /* Send stop transmission command in case of multiblock read */ + if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1)) + { + if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) ||\ + (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\ + (hsd->CardType == HIGH_CAPACITY_SD_CARD)) + { + /* Send stop transmission command */ + errorstate = HAL_SD_StopTransfer(hsd); + } + } + + /* Get error state */ + if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT); + + errorstate = SD_DATA_TIMEOUT; + + return errorstate; + } + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL); + + errorstate = SD_DATA_CRC_FAIL; + + return errorstate; + } + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR); + + errorstate = SD_RX_OVERRUN; + + return errorstate; + } +#ifdef SDIO_STA_STBITERR + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR); + + errorstate = SD_START_BIT_ERR; + + return errorstate; + } +#endif /* SDIO_STA_STBITERR */ + else + { + /* No error flag set */ + } + + count = SD_DATATIMEOUT; + + /* Empty FIFO if there is still any data */ + while ((__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)) && (count > 0)) + { + *tempbuff = SDIO_ReadFIFO(hsd->Instance); + tempbuff++; + count--; + } + + /* Clear all the static flags */ + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS); + + return errorstate; +} + +/** + * @brief Allows to write block(s) to a specified address in a card. The Data + * transfer is managed by polling mode. + * @param hsd: SD handle + * @param pWriteBuffer: pointer to the buffer that will contain the data to transmit + * @param WriteAddr: Address from where data is to be written + * @param BlockSize: SD card Data block size + * @note BlockSize must be 512 bytes. + * @param NumberOfBlocks: Number of SD blocks to write + * @retval SD Card error state + */ +HAL_SD_ErrorTypedef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks) +{ + SDIO_CmdInitTypeDef sdio_cmdinitstructure; + SDIO_DataInitTypeDef sdio_datainitstructure; + HAL_SD_ErrorTypedef errorstate = SD_OK; + uint32_t totalnumberofbytes = 0, bytestransferred = 0, count = 0, restwords = 0; + uint32_t *tempbuff = (uint32_t *)pWriteBuffer; + uint8_t cardstate = 0; + + /* Initialize data control register */ + hsd->Instance->DCTRL = 0; + + if (hsd->CardType == HIGH_CAPACITY_SD_CARD) + { + BlockSize = 512; + WriteAddr /= 512; + } + + /* Set Block Size for Card */ + sdio_cmdinitstructure.Argument = (uint32_t)BlockSize; + sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN); + + if (errorstate != SD_OK) + { + return errorstate; + } + + if(NumberOfBlocks > 1) + { + /* Send CMD25 WRITE_MULT_BLOCK with argument data address */ + sdio_cmdinitstructure.CmdIndex = SD_CMD_WRITE_MULT_BLOCK; + } + else + { + /* Send CMD24 WRITE_SINGLE_BLOCK */ + sdio_cmdinitstructure.CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK; + } + + sdio_cmdinitstructure.Argument = (uint32_t)WriteAddr; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + if(NumberOfBlocks > 1) + { + errorstate = SD_CmdResp1Error(hsd, SD_CMD_WRITE_MULT_BLOCK); + } + else + { + errorstate = SD_CmdResp1Error(hsd, SD_CMD_WRITE_SINGLE_BLOCK); + } + + if (errorstate != SD_OK) + { + return errorstate; + } + + /* Set total number of bytes to write */ + totalnumberofbytes = NumberOfBlocks * BlockSize; + + /* Configure the SD DPSM (Data Path State Machine) */ + sdio_datainitstructure.DataTimeOut = SD_DATATIMEOUT; + sdio_datainitstructure.DataLength = NumberOfBlocks * BlockSize; + sdio_datainitstructure.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; + sdio_datainitstructure.TransferDir = SDIO_TRANSFER_DIR_TO_CARD; + sdio_datainitstructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK; + sdio_datainitstructure.DPSM = SDIO_DPSM_ENABLE; + SDIO_DataConfig(hsd->Instance, &sdio_datainitstructure); + + /* Write block(s) in polling mode */ + if(NumberOfBlocks > 1) + { +#ifdef SDIO_STA_STBITERR + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR)) +#else /* SDIO_STA_STBITERR not defined */ + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND)) +#endif /* SDIO_STA_STBITERR */ + { + if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXFIFOHE)) + { + if ((totalnumberofbytes - bytestransferred) < 32) + { + restwords = ((totalnumberofbytes - bytestransferred) % 4 == 0) ? ((totalnumberofbytes - bytestransferred) / 4) : (( totalnumberofbytes - bytestransferred) / 4 + 1); + + /* Write data to SDIO Tx FIFO */ + for (count = 0; count < restwords; count++) + { + SDIO_WriteFIFO(hsd->Instance, tempbuff); + tempbuff++; + bytestransferred += 4; + } + } + else + { + /* Write data to SDIO Tx FIFO */ + for (count = 0; count < 8; count++) + { + SDIO_WriteFIFO(hsd->Instance, (tempbuff + count)); + } + + tempbuff += 8; + bytestransferred += 32; + } + } + } + } + else + { + /* In case of single data block transfer no need of stop command at all */ +#ifdef SDIO_STA_STBITERR + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR)) +#else /* SDIO_STA_STBITERR not defined */ + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND)) +#endif /* SDIO_STA_STBITERR */ + { + if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXFIFOHE)) + { + if ((totalnumberofbytes - bytestransferred) < 32) + { + restwords = ((totalnumberofbytes - bytestransferred) % 4 == 0) ? ((totalnumberofbytes - bytestransferred) / 4) : (( totalnumberofbytes - bytestransferred) / 4 + 1); + + /* Write data to SDIO Tx FIFO */ + for (count = 0; count < restwords; count++) + { + SDIO_WriteFIFO(hsd->Instance, tempbuff); + tempbuff++; + bytestransferred += 4; + } + } + else + { + /* Write data to SDIO Tx FIFO */ + for (count = 0; count < 8; count++) + { + SDIO_WriteFIFO(hsd->Instance, (tempbuff + count)); + } + + tempbuff += 8; + bytestransferred += 32; + } + } + } + } + + /* Send stop transmission command in case of multiblock write */ + if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1)) + { + if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\ + (hsd->CardType == HIGH_CAPACITY_SD_CARD)) + { + /* Send stop transmission command */ + errorstate = HAL_SD_StopTransfer(hsd); + } + } + + /* Get error state */ + if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT); + + errorstate = SD_DATA_TIMEOUT; + + return errorstate; + } + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL); + + errorstate = SD_DATA_CRC_FAIL; + + return errorstate; + } + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXUNDERR)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_TXUNDERR); + + errorstate = SD_TX_UNDERRUN; + + return errorstate; + } +#ifdef SDIO_STA_STBITERR + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR); + + errorstate = SD_START_BIT_ERR; + + return errorstate; + } +#endif /* SDIO_STA_STBITERR */ + else + { + /* No error flag set */ + } + + /* Clear all the static flags */ + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS); + + /* Wait till the card is in programming state */ + errorstate = SD_IsCardProgramming(hsd, &cardstate); + + while ((errorstate == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING))) + { + errorstate = SD_IsCardProgramming(hsd, &cardstate); + } + + return errorstate; +} + +/** + * @brief Reads block(s) from a specified address in a card. The Data transfer + * is managed by DMA mode. + * @note This API should be followed by the function HAL_SD_CheckReadOperation() + * to check the completion of the read process + * @param hsd: SD handle + * @param pReadBuffer: Pointer to the buffer that will contain the received data + * @param ReadAddr: Address from where data is to be read + * @param BlockSize: SD card Data block size + * @note BlockSize must be 512 bytes. + * @param NumberOfBlocks: Number of blocks to read. + * @retval SD Card error state + */ +HAL_SD_ErrorTypedef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pReadBuffer, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumberOfBlocks) +{ + SDIO_CmdInitTypeDef sdio_cmdinitstructure; + SDIO_DataInitTypeDef sdio_datainitstructure; + HAL_SD_ErrorTypedef errorstate = SD_OK; + + /* Initialize data control register */ + hsd->Instance->DCTRL = 0; + + /* Initialize handle flags */ + hsd->SdTransferCplt = 0; + hsd->DmaTransferCplt = 0; + hsd->SdTransferErr = SD_OK; + + /* Initialize SD Read operation */ + if(NumberOfBlocks > 1) + { + hsd->SdOperation = SD_READ_MULTIPLE_BLOCK; + } + else + { + hsd->SdOperation = SD_READ_SINGLE_BLOCK; + } + + /* Enable transfer interrupts */ +#ifdef SDIO_STA_STBITERR + __HAL_SD_SDIO_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL |\ + SDIO_IT_DTIMEOUT |\ + SDIO_IT_DATAEND |\ + SDIO_IT_RXOVERR |\ + SDIO_IT_STBITERR)); +#else /* SDIO_STA_STBITERR not defined */ + __HAL_SD_SDIO_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL |\ + SDIO_IT_DTIMEOUT |\ + SDIO_IT_DATAEND |\ + SDIO_IT_RXOVERR)); +#endif /* SDIO_STA_STBITERR */ + + /* Enable SDIO DMA transfer */ + __HAL_SD_SDIO_DMA_ENABLE(); + + /* Configure DMA user callbacks */ + hsd->hdmarx->XferCpltCallback = SD_DMA_RxCplt; + hsd->hdmarx->XferErrorCallback = SD_DMA_RxError; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hsd->hdmarx, (uint32_t)&hsd->Instance->FIFO, (uint32_t)pReadBuffer, (uint32_t)(BlockSize * NumberOfBlocks)/4); + + if (hsd->CardType == HIGH_CAPACITY_SD_CARD) + { + BlockSize = 512; + ReadAddr /= 512; + } + + /* Set Block Size for Card */ + sdio_cmdinitstructure.Argument = (uint32_t)BlockSize; + sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN); + + if (errorstate != SD_OK) + { + return errorstate; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + sdio_datainitstructure.DataTimeOut = SD_DATATIMEOUT; + sdio_datainitstructure.DataLength = BlockSize * NumberOfBlocks; + sdio_datainitstructure.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; + sdio_datainitstructure.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO; + sdio_datainitstructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK; + sdio_datainitstructure.DPSM = SDIO_DPSM_ENABLE; + SDIO_DataConfig(hsd->Instance, &sdio_datainitstructure); + + /* Check number of blocks command */ + if(NumberOfBlocks > 1) + { + /* Send CMD18 READ_MULT_BLOCK with argument data address */ + sdio_cmdinitstructure.CmdIndex = SD_CMD_READ_MULT_BLOCK; + } + else + { + /* Send CMD17 READ_SINGLE_BLOCK */ + sdio_cmdinitstructure.CmdIndex = SD_CMD_READ_SINGLE_BLOCK; + } + + sdio_cmdinitstructure.Argument = (uint32_t)ReadAddr; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + if(NumberOfBlocks > 1) + { + errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_MULT_BLOCK); + } + else + { + errorstate = SD_CmdResp1Error(hsd, SD_CMD_READ_SINGLE_BLOCK); + } + + /* Update the SD transfer error in SD handle */ + hsd->SdTransferErr = errorstate; + + return errorstate; +} + + +/** + * @brief Writes block(s) to a specified address in a card. The Data transfer + * is managed by DMA mode. + * @note This API should be followed by the function HAL_SD_CheckWriteOperation() + * to check the completion of the write process (by SD current status polling). + * @param hsd: SD handle + * @param pWriteBuffer: pointer to the buffer that will contain the data to transmit + * @param WriteAddr: Address from where data is to be read + * @param BlockSize: the SD card Data block size + * @note BlockSize must be 512 bytes. + * @param NumberOfBlocks: Number of blocks to write + * @retval SD Card error state + */ +HAL_SD_ErrorTypedef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint32_t *pWriteBuffer, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumberOfBlocks) +{ + SDIO_CmdInitTypeDef sdio_cmdinitstructure; + SDIO_DataInitTypeDef sdio_datainitstructure; + HAL_SD_ErrorTypedef errorstate = SD_OK; + + /* Initialize data control register */ + hsd->Instance->DCTRL = 0; + + /* Initialize handle flags */ + hsd->SdTransferCplt = 0; + hsd->DmaTransferCplt = 0; + hsd->SdTransferErr = SD_OK; + + /* Initialize SD Write operation */ + if(NumberOfBlocks > 1) + { + hsd->SdOperation = SD_WRITE_MULTIPLE_BLOCK; + } + else + { + hsd->SdOperation = SD_WRITE_SINGLE_BLOCK; + } + + /* Enable transfer interrupts */ +#ifdef SDIO_STA_STBITERR + __HAL_SD_SDIO_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL |\ + SDIO_IT_DTIMEOUT |\ + SDIO_IT_DATAEND |\ + SDIO_IT_TXUNDERR |\ + SDIO_IT_STBITERR)); +#else /* SDIO_STA_STBITERR not defined */ + __HAL_SD_SDIO_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL |\ + SDIO_IT_DTIMEOUT |\ + SDIO_IT_DATAEND |\ + SDIO_IT_TXUNDERR)); +#endif /* SDIO_STA_STBITERR */ + + /* Configure DMA user callbacks */ + hsd->hdmatx->XferCpltCallback = SD_DMA_TxCplt; + hsd->hdmatx->XferErrorCallback = SD_DMA_TxError; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hsd->hdmatx, (uint32_t)pWriteBuffer, (uint32_t)&hsd->Instance->FIFO, (uint32_t)(BlockSize * NumberOfBlocks)/4); + + /* Enable SDIO DMA transfer */ + __HAL_SD_SDIO_DMA_ENABLE(); + + if (hsd->CardType == HIGH_CAPACITY_SD_CARD) + { + BlockSize = 512; + WriteAddr /= 512; + } + + /* Set Block Size for Card */ + sdio_cmdinitstructure.Argument = (uint32_t)BlockSize; + sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN); + + if (errorstate != SD_OK) + { + return errorstate; + } + + /* Check number of blocks command */ + if(NumberOfBlocks <= 1) + { + /* Send CMD24 WRITE_SINGLE_BLOCK */ + sdio_cmdinitstructure.CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK; + } + else + { + /* Send CMD25 WRITE_MULT_BLOCK with argument data address */ + sdio_cmdinitstructure.CmdIndex = SD_CMD_WRITE_MULT_BLOCK; + } + + sdio_cmdinitstructure.Argument = (uint32_t)WriteAddr; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + if(NumberOfBlocks > 1) + { + errorstate = SD_CmdResp1Error(hsd, SD_CMD_WRITE_MULT_BLOCK); + } + else + { + errorstate = SD_CmdResp1Error(hsd, SD_CMD_WRITE_SINGLE_BLOCK); + } + + if (errorstate != SD_OK) + { + return errorstate; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + sdio_datainitstructure.DataTimeOut = SD_DATATIMEOUT; + sdio_datainitstructure.DataLength = BlockSize * NumberOfBlocks; + sdio_datainitstructure.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; + sdio_datainitstructure.TransferDir = SDIO_TRANSFER_DIR_TO_CARD; + sdio_datainitstructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK; + sdio_datainitstructure.DPSM = SDIO_DPSM_ENABLE; + SDIO_DataConfig(hsd->Instance, &sdio_datainitstructure); + + hsd->SdTransferErr = errorstate; + + return errorstate; +} + +/** + * @brief This function waits until the SD DMA data read transfer is finished. + * This API should be called after HAL_SD_ReadBlocks_DMA() function + * to insure that all data sent by the card is already transferred by the + * DMA controller. + * @param hsd: SD handle + * @param Timeout: Timeout duration + * @retval SD Card error state + */ +HAL_SD_ErrorTypedef HAL_SD_CheckReadOperation(SD_HandleTypeDef *hsd, uint32_t Timeout) +{ + HAL_SD_ErrorTypedef errorstate = SD_OK; + uint32_t timeout = Timeout; + uint32_t tmp1, tmp2; + HAL_SD_ErrorTypedef tmp3; + + /* Wait for DMA/SD transfer end or SD error variables to be in SD handle */ + tmp1 = hsd->DmaTransferCplt; + tmp2 = hsd->SdTransferCplt; + tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr; + + while ((tmp1 == 0) && (tmp2 == 0) && (tmp3 == SD_OK) && (timeout > 0)) + { + tmp1 = hsd->DmaTransferCplt; + tmp2 = hsd->SdTransferCplt; + tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr; + timeout--; + } + + timeout = Timeout; + + /* Wait until the Rx transfer is no longer active */ + while((__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXACT)) && (timeout > 0)) + { + timeout--; + } + + /* Send stop command in multiblock read */ + if (hsd->SdOperation == SD_READ_MULTIPLE_BLOCK) + { + errorstate = HAL_SD_StopTransfer(hsd); + } + + if ((timeout == 0) && (errorstate == SD_OK)) + { + errorstate = SD_DATA_TIMEOUT; + } + + /* Clear all the static flags */ + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS); + + /* Return error state */ + if (hsd->SdTransferErr != SD_OK) + { + return (HAL_SD_ErrorTypedef)(hsd->SdTransferErr); + } + + return errorstate; +} + +/** + * @brief This function waits until the SD DMA data write transfer is finished. + * This API should be called after HAL_SD_WriteBlocks_DMA() function + * to insure that all data sent by the card is already transferred by the + * DMA controller. + * @param hsd: SD handle + * @param Timeout: Timeout duration + * @retval SD Card error state + */ +HAL_SD_ErrorTypedef HAL_SD_CheckWriteOperation(SD_HandleTypeDef *hsd, uint32_t Timeout) +{ + HAL_SD_ErrorTypedef errorstate = SD_OK; + uint32_t timeout = Timeout; + uint32_t tmp1, tmp2; + HAL_SD_ErrorTypedef tmp3; + + /* Wait for DMA/SD transfer end or SD error variables to be in SD handle */ + tmp1 = hsd->DmaTransferCplt; + tmp2 = hsd->SdTransferCplt; + tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr; + + while ((tmp1 == 0) && (tmp2 == 0) && (tmp3 == SD_OK) && (timeout > 0)) + { + tmp1 = hsd->DmaTransferCplt; + tmp2 = hsd->SdTransferCplt; + tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr; + timeout--; + } + + timeout = Timeout; + + /* Wait until the Tx transfer is no longer active */ + while((__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXACT)) && (timeout > 0)) + { + timeout--; + } + + /* Send stop command in multiblock write */ + if (hsd->SdOperation == SD_WRITE_MULTIPLE_BLOCK) + { + errorstate = HAL_SD_StopTransfer(hsd); + } + + if ((timeout == 0) && (errorstate == SD_OK)) + { + errorstate = SD_DATA_TIMEOUT; + } + + /* Clear all the static flags */ + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS); + + /* Return error state */ + if (hsd->SdTransferErr != SD_OK) + { + return (HAL_SD_ErrorTypedef)(hsd->SdTransferErr); + } + + /* Wait until write is complete */ + while(HAL_SD_GetStatus(hsd) != SD_TRANSFER_OK) + { + } + + return errorstate; +} + +/** + * @brief Erases the specified memory area of the given SD card. + * @param hsd: SD handle + * @param startaddr: Start byte address + * @param endaddr: End byte address + * @retval SD Card error state + */ +HAL_SD_ErrorTypedef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint64_t startaddr, uint64_t endaddr) +{ + HAL_SD_ErrorTypedef errorstate = SD_OK; + SDIO_CmdInitTypeDef sdio_cmdinitstructure; + + uint32_t delay = 0; + __IO uint32_t maxdelay = 0; + uint8_t cardstate = 0; + + /* Check if the card command class supports erase command */ + if (((hsd->CSD[1] >> 20) & SD_CCCC_ERASE) == 0) + { + errorstate = SD_REQUEST_NOT_APPLICABLE; + + return errorstate; + } + + /* Get max delay value */ + maxdelay = 120000 / (((hsd->Instance->CLKCR) & 0xFF) + 2); + + if((SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED) + { + errorstate = SD_LOCK_UNLOCK_FAILED; + + return errorstate; + } + + /* Get start and end block for high capacity cards */ + if (hsd->CardType == HIGH_CAPACITY_SD_CARD) + { + startaddr /= 512; + endaddr /= 512; + } + + /* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */ + if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\ + (hsd->CardType == HIGH_CAPACITY_SD_CARD)) + { + /* Send CMD32 SD_ERASE_GRP_START with argument as addr */ + sdio_cmdinitstructure.Argument =(uint32_t)startaddr; + sdio_cmdinitstructure.CmdIndex = SD_CMD_SD_ERASE_GRP_START; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_SD_ERASE_GRP_START); + + if (errorstate != SD_OK) + { + return errorstate; + } + + /* Send CMD33 SD_ERASE_GRP_END with argument as addr */ + sdio_cmdinitstructure.Argument = (uint32_t)endaddr; + sdio_cmdinitstructure.CmdIndex = SD_CMD_SD_ERASE_GRP_END; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_SD_ERASE_GRP_END); + + if (errorstate != SD_OK) + { + return errorstate; + } + } + + /* Send CMD38 ERASE */ + sdio_cmdinitstructure.Argument = 0; + sdio_cmdinitstructure.CmdIndex = SD_CMD_ERASE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_ERASE); + + if (errorstate != SD_OK) + { + return errorstate; + } + + for (; delay < maxdelay; delay++) + { + } + + /* Wait until the card is in programming state */ + errorstate = SD_IsCardProgramming(hsd, &cardstate); + + delay = SD_DATATIMEOUT; + + while ((delay > 0) && (errorstate == SD_OK) && ((cardstate == SD_CARD_PROGRAMMING) || (cardstate == SD_CARD_RECEIVING))) + { + errorstate = SD_IsCardProgramming(hsd, &cardstate); + delay--; + } + + return errorstate; +} + +/** + * @brief This function handles SD card interrupt request. + * @param hsd: SD handle + * @retval None + */ +void HAL_SD_IRQHandler(SD_HandleTypeDef *hsd) +{ + /* Check for SDIO interrupt flags */ + if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_DATAEND)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_IT_DATAEND); + + /* SD transfer is complete */ + hsd->SdTransferCplt = 1; + + /* No transfer error */ + hsd->SdTransferErr = SD_OK; + + HAL_SD_XferCpltCallback(hsd); + } + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_DCRCFAIL)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL); + + hsd->SdTransferErr = SD_DATA_CRC_FAIL; + + HAL_SD_XferErrorCallback(hsd); + + } + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_DTIMEOUT)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT); + + hsd->SdTransferErr = SD_DATA_TIMEOUT; + + HAL_SD_XferErrorCallback(hsd); + } + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_RXOVERR)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR); + + hsd->SdTransferErr = SD_RX_OVERRUN; + + HAL_SD_XferErrorCallback(hsd); + } + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_TXUNDERR)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_TXUNDERR); + + hsd->SdTransferErr = SD_TX_UNDERRUN; + + HAL_SD_XferErrorCallback(hsd); + } +#ifdef SDIO_STA_STBITERR + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_IT_STBITERR)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR); + + hsd->SdTransferErr = SD_START_BIT_ERR; + + HAL_SD_XferErrorCallback(hsd); + } +#endif /* SDIO_STA_STBITERR */ + else + { + /* No error flag set */ + } + + /* Disable all SDIO peripheral interrupt sources */ +#ifdef SDIO_STA_STBITERR + __HAL_SD_SDIO_DISABLE_IT(hsd, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND |\ + SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |\ + SDIO_IT_RXOVERR | SDIO_IT_STBITERR); +#else /* SDIO_STA_STBITERR not defined */ + __HAL_SD_SDIO_DISABLE_IT(hsd, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND |\ + SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |\ + SDIO_IT_RXOVERR); +#endif /* SDIO_STA_STBITERR */ +} + + +/** + * @brief SD end of transfer callback. + * @param hsd: SD handle + * @retval None + */ +__weak void HAL_SD_XferCpltCallback(SD_HandleTypeDef *hsd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SD_XferCpltCallback could be implemented in the user file + */ +} + +/** + * @brief SD Transfer Error callback. + * @param hsd: SD handle + * @retval None + */ +__weak void HAL_SD_XferErrorCallback(SD_HandleTypeDef *hsd) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SD_XferErrorCallback could be implemented in the user file + */ +} + +/** + * @brief SD Transfer complete Rx callback in non blocking mode. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +__weak void HAL_SD_DMA_RxCpltCallback(DMA_HandleTypeDef *hdma) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SD_DMA_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief SD DMA transfer complete Rx error callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +__weak void HAL_SD_DMA_RxErrorCallback(DMA_HandleTypeDef *hdma) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SD_DMA_RxErrorCallback could be implemented in the user file + */ +} + +/** + * @brief SD Transfer complete Tx callback in non blocking mode. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +__weak void HAL_SD_DMA_TxCpltCallback(DMA_HandleTypeDef *hdma) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SD_DMA_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief SD DMA transfer complete error Tx callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +__weak void HAL_SD_DMA_TxErrorCallback(DMA_HandleTypeDef *hdma) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SD_DMA_TxErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @addtogroup SD_Exported_Functions_Group3 + * @brief management functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control the SD card + operations. + +@endverbatim + * @{ + */ + +/** + * @brief Returns information about specific card. + * @param hsd: SD handle + * @param pCardInfo: Pointer to a HAL_SD_CardInfoTypedef structure that + * contains all SD cardinformation + * @retval SD Card error state + */ +HAL_SD_ErrorTypedef HAL_SD_Get_CardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypedef *pCardInfo) +{ + HAL_SD_ErrorTypedef errorstate = SD_OK; + uint32_t tmp = 0; + + pCardInfo->CardType = (uint8_t)(hsd->CardType); + pCardInfo->RCA = (uint16_t)(hsd->RCA); + + /* Byte 0 */ + tmp = (hsd->CSD[0] & 0xFF000000) >> 24; + pCardInfo->SD_csd.CSDStruct = (uint8_t)((tmp & 0xC0) >> 6); + pCardInfo->SD_csd.SysSpecVersion = (uint8_t)((tmp & 0x3C) >> 2); + pCardInfo->SD_csd.Reserved1 = tmp & 0x03; + + /* Byte 1 */ + tmp = (hsd->CSD[0] & 0x00FF0000) >> 16; + pCardInfo->SD_csd.TAAC = (uint8_t)tmp; + + /* Byte 2 */ + tmp = (hsd->CSD[0] & 0x0000FF00) >> 8; + pCardInfo->SD_csd.NSAC = (uint8_t)tmp; + + /* Byte 3 */ + tmp = hsd->CSD[0] & 0x000000FF; + pCardInfo->SD_csd.MaxBusClkFrec = (uint8_t)tmp; + + /* Byte 4 */ + tmp = (hsd->CSD[1] & 0xFF000000) >> 24; + pCardInfo->SD_csd.CardComdClasses = (uint16_t)(tmp << 4); + + /* Byte 5 */ + tmp = (hsd->CSD[1] & 0x00FF0000) >> 16; + pCardInfo->SD_csd.CardComdClasses |= (uint16_t)((tmp & 0xF0) >> 4); + pCardInfo->SD_csd.RdBlockLen = (uint8_t)(tmp & 0x0F); + + /* Byte 6 */ + tmp = (hsd->CSD[1] & 0x0000FF00) >> 8; + pCardInfo->SD_csd.PartBlockRead = (uint8_t)((tmp & 0x80) >> 7); + pCardInfo->SD_csd.WrBlockMisalign = (uint8_t)((tmp & 0x40) >> 6); + pCardInfo->SD_csd.RdBlockMisalign = (uint8_t)((tmp & 0x20) >> 5); + pCardInfo->SD_csd.DSRImpl = (uint8_t)((tmp & 0x10) >> 4); + pCardInfo->SD_csd.Reserved2 = 0; /*!< Reserved */ + + if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0)) + { + pCardInfo->SD_csd.DeviceSize = (tmp & 0x03) << 10; + + /* Byte 7 */ + tmp = (uint8_t)(hsd->CSD[1] & 0x000000FF); + pCardInfo->SD_csd.DeviceSize |= (tmp) << 2; + + /* Byte 8 */ + tmp = (uint8_t)((hsd->CSD[2] & 0xFF000000) >> 24); + pCardInfo->SD_csd.DeviceSize |= (tmp & 0xC0) >> 6; + + pCardInfo->SD_csd.MaxRdCurrentVDDMin = (tmp & 0x38) >> 3; + pCardInfo->SD_csd.MaxRdCurrentVDDMax = (tmp & 0x07); + + /* Byte 9 */ + tmp = (uint8_t)((hsd->CSD[2] & 0x00FF0000) >> 16); + pCardInfo->SD_csd.MaxWrCurrentVDDMin = (tmp & 0xE0) >> 5; + pCardInfo->SD_csd.MaxWrCurrentVDDMax = (tmp & 0x1C) >> 2; + pCardInfo->SD_csd.DeviceSizeMul = (tmp & 0x03) << 1; + /* Byte 10 */ + tmp = (uint8_t)((hsd->CSD[2] & 0x0000FF00) >> 8); + pCardInfo->SD_csd.DeviceSizeMul |= (tmp & 0x80) >> 7; + + pCardInfo->CardCapacity = (pCardInfo->SD_csd.DeviceSize + 1) ; + pCardInfo->CardCapacity *= (1 << (pCardInfo->SD_csd.DeviceSizeMul + 2)); + pCardInfo->CardBlockSize = 1 << (pCardInfo->SD_csd.RdBlockLen); + pCardInfo->CardCapacity *= pCardInfo->CardBlockSize; + } + else if (hsd->CardType == HIGH_CAPACITY_SD_CARD) + { + /* Byte 7 */ + tmp = (uint8_t)(hsd->CSD[1] & 0x000000FF); + pCardInfo->SD_csd.DeviceSize = (tmp & 0x3F) << 16; + + /* Byte 8 */ + tmp = (uint8_t)((hsd->CSD[2] & 0xFF000000) >> 24); + + pCardInfo->SD_csd.DeviceSize |= (tmp << 8); + + /* Byte 9 */ + tmp = (uint8_t)((hsd->CSD[2] & 0x00FF0000) >> 16); + + pCardInfo->SD_csd.DeviceSize |= (tmp); + + /* Byte 10 */ + tmp = (uint8_t)((hsd->CSD[2] & 0x0000FF00) >> 8); + + pCardInfo->CardCapacity = (uint64_t)((((uint64_t)pCardInfo->SD_csd.DeviceSize + 1)) * 512 * 1024); + pCardInfo->CardBlockSize = 512; + } + else + { + /* Not supported card type */ + errorstate = SD_ERROR; + } + + pCardInfo->SD_csd.EraseGrSize = (tmp & 0x40) >> 6; + pCardInfo->SD_csd.EraseGrMul = (tmp & 0x3F) << 1; + + /* Byte 11 */ + tmp = (uint8_t)(hsd->CSD[2] & 0x000000FF); + pCardInfo->SD_csd.EraseGrMul |= (tmp & 0x80) >> 7; + pCardInfo->SD_csd.WrProtectGrSize = (tmp & 0x7F); + + /* Byte 12 */ + tmp = (uint8_t)((hsd->CSD[3] & 0xFF000000) >> 24); + pCardInfo->SD_csd.WrProtectGrEnable = (tmp & 0x80) >> 7; + pCardInfo->SD_csd.ManDeflECC = (tmp & 0x60) >> 5; + pCardInfo->SD_csd.WrSpeedFact = (tmp & 0x1C) >> 2; + pCardInfo->SD_csd.MaxWrBlockLen = (tmp & 0x03) << 2; + + /* Byte 13 */ + tmp = (uint8_t)((hsd->CSD[3] & 0x00FF0000) >> 16); + pCardInfo->SD_csd.MaxWrBlockLen |= (tmp & 0xC0) >> 6; + pCardInfo->SD_csd.WriteBlockPaPartial = (tmp & 0x20) >> 5; + pCardInfo->SD_csd.Reserved3 = 0; + pCardInfo->SD_csd.ContentProtectAppli = (tmp & 0x01); + + /* Byte 14 */ + tmp = (uint8_t)((hsd->CSD[3] & 0x0000FF00) >> 8); + pCardInfo->SD_csd.FileFormatGrouop = (tmp & 0x80) >> 7; + pCardInfo->SD_csd.CopyFlag = (tmp & 0x40) >> 6; + pCardInfo->SD_csd.PermWrProtect = (tmp & 0x20) >> 5; + pCardInfo->SD_csd.TempWrProtect = (tmp & 0x10) >> 4; + pCardInfo->SD_csd.FileFormat = (tmp & 0x0C) >> 2; + pCardInfo->SD_csd.ECC = (tmp & 0x03); + + /* Byte 15 */ + tmp = (uint8_t)(hsd->CSD[3] & 0x000000FF); + pCardInfo->SD_csd.CSD_CRC = (tmp & 0xFE) >> 1; + pCardInfo->SD_csd.Reserved4 = 1; + + /* Byte 0 */ + tmp = (uint8_t)((hsd->CID[0] & 0xFF000000) >> 24); + pCardInfo->SD_cid.ManufacturerID = tmp; + + /* Byte 1 */ + tmp = (uint8_t)((hsd->CID[0] & 0x00FF0000) >> 16); + pCardInfo->SD_cid.OEM_AppliID = tmp << 8; + + /* Byte 2 */ + tmp = (uint8_t)((hsd->CID[0] & 0x000000FF00) >> 8); + pCardInfo->SD_cid.OEM_AppliID |= tmp; + + /* Byte 3 */ + tmp = (uint8_t)(hsd->CID[0] & 0x000000FF); + pCardInfo->SD_cid.ProdName1 = tmp << 24; + + /* Byte 4 */ + tmp = (uint8_t)((hsd->CID[1] & 0xFF000000) >> 24); + pCardInfo->SD_cid.ProdName1 |= tmp << 16; + + /* Byte 5 */ + tmp = (uint8_t)((hsd->CID[1] & 0x00FF0000) >> 16); + pCardInfo->SD_cid.ProdName1 |= tmp << 8; + + /* Byte 6 */ + tmp = (uint8_t)((hsd->CID[1] & 0x0000FF00) >> 8); + pCardInfo->SD_cid.ProdName1 |= tmp; + + /* Byte 7 */ + tmp = (uint8_t)(hsd->CID[1] & 0x000000FF); + pCardInfo->SD_cid.ProdName2 = tmp; + + /* Byte 8 */ + tmp = (uint8_t)((hsd->CID[2] & 0xFF000000) >> 24); + pCardInfo->SD_cid.ProdRev = tmp; + + /* Byte 9 */ + tmp = (uint8_t)((hsd->CID[2] & 0x00FF0000) >> 16); + pCardInfo->SD_cid.ProdSN = tmp << 24; + + /* Byte 10 */ + tmp = (uint8_t)((hsd->CID[2] & 0x0000FF00) >> 8); + pCardInfo->SD_cid.ProdSN |= tmp << 16; + + /* Byte 11 */ + tmp = (uint8_t)(hsd->CID[2] & 0x000000FF); + pCardInfo->SD_cid.ProdSN |= tmp << 8; + + /* Byte 12 */ + tmp = (uint8_t)((hsd->CID[3] & 0xFF000000) >> 24); + pCardInfo->SD_cid.ProdSN |= tmp; + + /* Byte 13 */ + tmp = (uint8_t)((hsd->CID[3] & 0x00FF0000) >> 16); + pCardInfo->SD_cid.Reserved1 |= (tmp & 0xF0) >> 4; + pCardInfo->SD_cid.ManufactDate = (tmp & 0x0F) << 8; + + /* Byte 14 */ + tmp = (uint8_t)((hsd->CID[3] & 0x0000FF00) >> 8); + pCardInfo->SD_cid.ManufactDate |= tmp; + + /* Byte 15 */ + tmp = (uint8_t)(hsd->CID[3] & 0x000000FF); + pCardInfo->SD_cid.CID_CRC = (tmp & 0xFE) >> 1; + pCardInfo->SD_cid.Reserved2 = 1; + + return errorstate; +} + +/** + * @brief Enables wide bus operation for the requested card if supported by + * card. + * @param hsd: SD handle + * @param WideMode: Specifies the SD card wide bus mode + * This parameter can be one of the following values: + * @arg SDIO_BUS_WIDE_8B: 8-bit data transfer (Only for MMC) + * @arg SDIO_BUS_WIDE_4B: 4-bit data transfer + * @arg SDIO_BUS_WIDE_1B: 1-bit data transfer + * @retval SD Card error state + */ +HAL_SD_ErrorTypedef HAL_SD_WideBusOperation_Config(SD_HandleTypeDef *hsd, uint32_t WideMode) +{ + HAL_SD_ErrorTypedef errorstate = SD_OK; + SDIO_InitTypeDef tmpinit; + + /* MMC Card does not support this feature */ + if (hsd->CardType == MULTIMEDIA_CARD) + { + errorstate = SD_UNSUPPORTED_FEATURE; + + return errorstate; + } + else if ((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\ + (hsd->CardType == HIGH_CAPACITY_SD_CARD)) + { + if (WideMode == SDIO_BUS_WIDE_8B) + { + errorstate = SD_UNSUPPORTED_FEATURE; + } + else if (WideMode == SDIO_BUS_WIDE_4B) + { + errorstate = SD_WideBus_Enable(hsd); + } + else if (WideMode == SDIO_BUS_WIDE_1B) + { + errorstate = SD_WideBus_Disable(hsd); + } + else + { + /* WideMode is not a valid argument*/ + errorstate = SD_INVALID_PARAMETER; + } + + if (errorstate == SD_OK) + { + /* Configure the SDIO peripheral */ + tmpinit.ClockEdge = hsd->Init.ClockEdge; + tmpinit.ClockBypass = hsd->Init.ClockBypass; + tmpinit.ClockPowerSave = hsd->Init.ClockPowerSave; + tmpinit.BusWide = WideMode; + tmpinit.HardwareFlowControl = hsd->Init.HardwareFlowControl; + tmpinit.ClockDiv = hsd->Init.ClockDiv; + SDIO_Init(hsd->Instance, tmpinit); + } + } + + return errorstate; +} + +/** + * @brief Aborts an ongoing data transfer. + * @param hsd: SD handle + * @retval SD Card error state + */ +HAL_SD_ErrorTypedef HAL_SD_StopTransfer(SD_HandleTypeDef *hsd) +{ + SDIO_CmdInitTypeDef sdio_cmdinitstructure; + HAL_SD_ErrorTypedef errorstate = SD_OK; + + /* Send CMD12 STOP_TRANSMISSION */ + sdio_cmdinitstructure.Argument = 0; + sdio_cmdinitstructure.CmdIndex = SD_CMD_STOP_TRANSMISSION; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_STOP_TRANSMISSION); + + return errorstate; +} + +/** + * @brief Switches the SD card to High Speed mode. + * This API must be used after "Transfer State" + * @note This operation should be followed by the configuration + * of PLL to have SDIOCK clock between 67 and 75 MHz + * @param hsd: SD handle + * @retval SD Card error state + */ +HAL_SD_ErrorTypedef HAL_SD_HighSpeed (SD_HandleTypeDef *hsd) +{ + HAL_SD_ErrorTypedef errorstate = SD_OK; + SDIO_CmdInitTypeDef sdio_cmdinitstructure; + SDIO_DataInitTypeDef sdio_datainitstructure; + + uint8_t SD_hs[64] = {0}; + uint32_t SD_scr[2] = {0, 0}; + uint32_t SD_SPEC = 0 ; + uint32_t count = 0, *tempbuff = (uint32_t *)SD_hs; + + /* Initialize the Data control register */ + hsd->Instance->DCTRL = 0; + + /* Get SCR Register */ + errorstate = SD_FindSCR(hsd, SD_scr); + + if (errorstate != SD_OK) + { + return errorstate; + } + + /* Test the Version supported by the card*/ + SD_SPEC = (SD_scr[1] & 0x01000000) | (SD_scr[1] & 0x02000000); + + if (SD_SPEC != SD_ALLZERO) + { + /* Set Block Size for Card */ + sdio_cmdinitstructure.Argument = (uint32_t)64; + sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN); + + if (errorstate != SD_OK) + { + return errorstate; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + sdio_datainitstructure.DataTimeOut = SD_DATATIMEOUT; + sdio_datainitstructure.DataLength = 64; + sdio_datainitstructure.DataBlockSize = SDIO_DATABLOCK_SIZE_64B ; + sdio_datainitstructure.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO; + sdio_datainitstructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK; + sdio_datainitstructure.DPSM = SDIO_DPSM_ENABLE; + SDIO_DataConfig(hsd->Instance, &sdio_datainitstructure); + + /* Send CMD6 switch mode */ + sdio_cmdinitstructure.Argument = 0x80FFFF01; + sdio_cmdinitstructure.CmdIndex = SD_CMD_HS_SWITCH; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_HS_SWITCH); + + if (errorstate != SD_OK) + { + return errorstate; + } +#ifdef SDIO_STA_STBITERR + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR)) +#else /* SDIO_STA_STBITERR */ + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND)) +#endif /* SDIO_STA_STBITERR */ + { + if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF)) + { + for (count = 0; count < 8; count++) + { + *(tempbuff + count) = SDIO_ReadFIFO(hsd->Instance); + } + + tempbuff += 8; + } + } + + if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT); + + errorstate = SD_DATA_TIMEOUT; + + return errorstate; + } + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL); + + errorstate = SD_DATA_CRC_FAIL; + + return errorstate; + } + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR); + + errorstate = SD_RX_OVERRUN; + + return errorstate; + } +#ifdef SDIO_STA_STBITERR + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR); + + errorstate = SD_START_BIT_ERR; + + return errorstate; + } +#endif /* SDIO_STA_STBITERR */ + else + { + /* No error flag set */ + } + + count = SD_DATATIMEOUT; + + while ((__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)) && (count > 0)) + { + *tempbuff = SDIO_ReadFIFO(hsd->Instance); + tempbuff++; + count--; + } + + /* Clear all the static flags */ + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS); + + /* Test if the switch mode HS is ok */ + if ((SD_hs[13]& 2) != 2) + { + errorstate = SD_UNSUPPORTED_FEATURE; + } + } + + return errorstate; +} + +/** + * @} + */ + +/** @addtogroup SD_Exported_Functions_Group4 + * @brief Peripheral State functions + * +@verbatim + ============================================================================== + ##### Peripheral State functions ##### + ============================================================================== + [..] + This subsection permits to get in runtime the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the current SD card's status. + * @param hsd: SD handle + * @param pSDstatus: Pointer to the buffer that will contain the SD card status + * SD Status register) + * @retval SD Card error state + */ +HAL_SD_ErrorTypedef HAL_SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus) +{ + SDIO_CmdInitTypeDef sdio_cmdinitstructure; + SDIO_DataInitTypeDef sdio_datainitstructure; + HAL_SD_ErrorTypedef errorstate = SD_OK; + uint32_t count = 0; + + /* Check SD response */ + if ((SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED) + { + errorstate = SD_LOCK_UNLOCK_FAILED; + + return errorstate; + } + + /* Set block size for card if it is not equal to current block size for card */ + sdio_cmdinitstructure.Argument = 64; + sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN); + + if (errorstate != SD_OK) + { + return errorstate; + } + + /* Send CMD55 */ + sdio_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16); + sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD); + + if (errorstate != SD_OK) + { + return errorstate; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + sdio_datainitstructure.DataTimeOut = SD_DATATIMEOUT; + sdio_datainitstructure.DataLength = 64; + sdio_datainitstructure.DataBlockSize = SDIO_DATABLOCK_SIZE_64B; + sdio_datainitstructure.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO; + sdio_datainitstructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK; + sdio_datainitstructure.DPSM = SDIO_DPSM_ENABLE; + SDIO_DataConfig(hsd->Instance, &sdio_datainitstructure); + + /* Send ACMD13 (SD_APP_STATUS) with argument as card's RCA */ + sdio_cmdinitstructure.Argument = 0; + sdio_cmdinitstructure.CmdIndex = SD_CMD_SD_APP_STATUS; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_SD_APP_STATUS); + + if (errorstate != SD_OK) + { + return errorstate; + } + + /* Get status data */ +#ifdef SDIO_STA_STBITERR + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR)) +#else /* SDIO_STA_STBITERR not defined */ + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND)) +#endif /* SDIO_STA_STBITERR */ + { + if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXFIFOHF)) + { + for (count = 0; count < 8; count++) + { + *(pSDstatus + count) = SDIO_ReadFIFO(hsd->Instance); + } + + pSDstatus += 8; + } + } + + if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT); + + errorstate = SD_DATA_TIMEOUT; + + return errorstate; + } + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL); + + errorstate = SD_DATA_CRC_FAIL; + + return errorstate; + } + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR); + + errorstate = SD_RX_OVERRUN; + + return errorstate; + } +#ifdef SDIO_STA_STBITERR + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR); + + errorstate = SD_START_BIT_ERR; + + return errorstate; + } +#endif /* SDIO_STA_STBITERR */ + else + { + /* No error flag set */ + } + + count = SD_DATATIMEOUT; + while ((__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)) && (count > 0)) + { + *pSDstatus = SDIO_ReadFIFO(hsd->Instance); + pSDstatus++; + count--; + } + + /* Clear all the static status flags*/ + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS); + + return errorstate; +} + +/** + * @brief Gets the current sd card data status. + * @param hsd: SD handle + * @retval Data Transfer state + */ +HAL_SD_TransferStateTypedef HAL_SD_GetStatus(SD_HandleTypeDef *hsd) +{ + HAL_SD_CardStateTypedef cardstate = SD_CARD_TRANSFER; + + /* Get SD card state */ + cardstate = SD_GetState(hsd); + + /* Find SD status according to card state*/ + if (cardstate == SD_CARD_TRANSFER) + { + return SD_TRANSFER_OK; + } + else if(cardstate == SD_CARD_ERROR) + { + return SD_TRANSFER_ERROR; + } + else + { + return SD_TRANSFER_BUSY; + } +} + +/** + * @brief Gets the SD card status. + * @param hsd: SD handle + * @param pCardStatus: Pointer to the HAL_SD_CardStatusTypedef structure that + * will contain the SD card status information + * @retval SD Card error state + */ +HAL_SD_ErrorTypedef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypedef *pCardStatus) +{ + HAL_SD_ErrorTypedef errorstate = SD_OK; + uint32_t tmp = 0; + uint32_t sd_status[16]; + + errorstate = HAL_SD_SendSDStatus(hsd, sd_status); + + if (errorstate != SD_OK) + { + return errorstate; + } + + /* Byte 0 */ + tmp = (sd_status[0] & 0xC0) >> 6; + pCardStatus->DAT_BUS_WIDTH = (uint8_t)tmp; + + /* Byte 0 */ + tmp = (sd_status[0] & 0x20) >> 5; + pCardStatus->SECURED_MODE = (uint8_t)tmp; + + /* Byte 2 */ + tmp = (sd_status[2] & 0xFF); + pCardStatus->SD_CARD_TYPE = (uint8_t)(tmp << 8); + + /* Byte 3 */ + tmp = (sd_status[3] & 0xFF); + pCardStatus->SD_CARD_TYPE |= (uint8_t)tmp; + + /* Byte 4 */ + tmp = (sd_status[4] & 0xFF); + pCardStatus->SIZE_OF_PROTECTED_AREA = (uint8_t)(tmp << 24); + + /* Byte 5 */ + tmp = (sd_status[5] & 0xFF); + pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)(tmp << 16); + + /* Byte 6 */ + tmp = (sd_status[6] & 0xFF); + pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)(tmp << 8); + + /* Byte 7 */ + tmp = (sd_status[7] & 0xFF); + pCardStatus->SIZE_OF_PROTECTED_AREA |= (uint8_t)tmp; + + /* Byte 8 */ + tmp = (sd_status[8] & 0xFF); + pCardStatus->SPEED_CLASS = (uint8_t)tmp; + + /* Byte 9 */ + tmp = (sd_status[9] & 0xFF); + pCardStatus->PERFORMANCE_MOVE = (uint8_t)tmp; + + /* Byte 10 */ + tmp = (sd_status[10] & 0xF0) >> 4; + pCardStatus->AU_SIZE = (uint8_t)tmp; + + /* Byte 11 */ + tmp = (sd_status[11] & 0xFF); + pCardStatus->ERASE_SIZE = (uint8_t)(tmp << 8); + + /* Byte 12 */ + tmp = (sd_status[12] & 0xFF); + pCardStatus->ERASE_SIZE |= (uint8_t)tmp; + + /* Byte 13 */ + tmp = (sd_status[13] & 0xFC) >> 2; + pCardStatus->ERASE_TIMEOUT = (uint8_t)tmp; + + /* Byte 13 */ + tmp = (sd_status[13] & 0x3); + pCardStatus->ERASE_OFFSET = (uint8_t)tmp; + + return errorstate; +} + +/** + * @} + */ + +/** + * @} + */ + +/* Private function ----------------------------------------------------------*/ +/** @addtogroup SD_Private_Functions + * @{ + */ + +/** + * @brief SD DMA transfer complete Rx callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SD_DMA_RxCplt(DMA_HandleTypeDef *hdma) +{ + SD_HandleTypeDef *hsd = (SD_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* DMA transfer is complete */ + hsd->DmaTransferCplt = 1; + + /* Wait until SD transfer is complete */ + while(hsd->SdTransferCplt == 0) + { + } + + /* Disable the DMA channel */ + HAL_DMA_Abort(hdma); + + /* Transfer complete user callback */ + HAL_SD_DMA_RxCpltCallback(hsd->hdmarx); +} + +/** + * @brief SD DMA transfer Error Rx callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SD_DMA_RxError(DMA_HandleTypeDef *hdma) +{ + SD_HandleTypeDef *hsd = (SD_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Transfer complete user callback */ + HAL_SD_DMA_RxErrorCallback(hsd->hdmarx); +} + +/** + * @brief SD DMA transfer complete Tx callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SD_DMA_TxCplt(DMA_HandleTypeDef *hdma) +{ + SD_HandleTypeDef *hsd = (SD_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* DMA transfer is complete */ + hsd->DmaTransferCplt = 1; + + /* Wait until SD transfer is complete */ + while(hsd->SdTransferCplt == 0) + { + } + + /* Disable the DMA channel */ + HAL_DMA_Abort(hdma); + + /* Transfer complete user callback */ + HAL_SD_DMA_TxCpltCallback(hsd->hdmatx); +} + +/** + * @brief SD DMA transfer Error Tx callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SD_DMA_TxError(DMA_HandleTypeDef *hdma) +{ + SD_HandleTypeDef *hsd = ( SD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Transfer complete user callback */ + HAL_SD_DMA_TxErrorCallback(hsd->hdmatx); +} + +/** + * @brief Returns the SD current state. + * @param hsd: SD handle + * @retval SD card current state + */ +static HAL_SD_CardStateTypedef SD_GetState(SD_HandleTypeDef *hsd) +{ + uint32_t resp1 = 0; + + if (SD_SendStatus(hsd, &resp1) != SD_OK) + { + return SD_CARD_ERROR; + } + else + { + return (HAL_SD_CardStateTypedef)((resp1 >> 9) & 0x0F); + } +} + +/** + * @brief Initializes all cards or single card as the case may be Card(s) come + * into standby state. + * @param hsd: SD handle + * @retval SD Card error state + */ +static HAL_SD_ErrorTypedef SD_Initialize_Cards(SD_HandleTypeDef *hsd) +{ + SDIO_CmdInitTypeDef sdio_cmdinitstructure; + HAL_SD_ErrorTypedef errorstate = SD_OK; + uint16_t sd_rca = 1; + + if(SDIO_GetPowerState(hsd->Instance) == 0) /* Power off */ + { + errorstate = SD_REQUEST_NOT_APPLICABLE; + + return errorstate; + } + + if(hsd->CardType != SECURE_DIGITAL_IO_CARD) + { + /* Send CMD2 ALL_SEND_CID */ + sdio_cmdinitstructure.Argument = 0; + sdio_cmdinitstructure.CmdIndex = SD_CMD_ALL_SEND_CID; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_LONG; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp2Error(hsd); + + if(errorstate != SD_OK) + { + return errorstate; + } + + /* Get Card identification number data */ + hsd->CID[0] = SDIO_GetResponse(SDIO_RESP1); + hsd->CID[1] = SDIO_GetResponse(SDIO_RESP2); + hsd->CID[2] = SDIO_GetResponse(SDIO_RESP3); + hsd->CID[3] = SDIO_GetResponse(SDIO_RESP4); + } + + if((hsd->CardType == STD_CAPACITY_SD_CARD_V1_1) || (hsd->CardType == STD_CAPACITY_SD_CARD_V2_0) ||\ + (hsd->CardType == SECURE_DIGITAL_IO_COMBO_CARD) || (hsd->CardType == HIGH_CAPACITY_SD_CARD)) + { + /* Send CMD3 SET_REL_ADDR with argument 0 */ + /* SD Card publishes its RCA. */ + sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_REL_ADDR; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp6Error(hsd, SD_CMD_SET_REL_ADDR, &sd_rca); + + if(errorstate != SD_OK) + { + return errorstate; + } + } + + if (hsd->CardType != SECURE_DIGITAL_IO_CARD) + { + /* Get the SD card RCA */ + hsd->RCA = sd_rca; + + /* Send CMD9 SEND_CSD with argument as card's RCA */ + sdio_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16); + sdio_cmdinitstructure.CmdIndex = SD_CMD_SEND_CSD; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_LONG; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp2Error(hsd); + + if(errorstate != SD_OK) + { + return errorstate; + } + + /* Get Card Specific Data */ + hsd->CSD[0] = SDIO_GetResponse(SDIO_RESP1); + hsd->CSD[1] = SDIO_GetResponse(SDIO_RESP2); + hsd->CSD[2] = SDIO_GetResponse(SDIO_RESP3); + hsd->CSD[3] = SDIO_GetResponse(SDIO_RESP4); + } + + /* All cards are initialized */ + return errorstate; +} + +/** + * @brief Selects of Deselects the corresponding card. + * @param hsd: SD handle + * @param addr: Address of the card to be selected + * @retval SD Card error state + */ +static HAL_SD_ErrorTypedef SD_Select_Deselect(SD_HandleTypeDef *hsd, uint64_t addr) +{ + SDIO_CmdInitTypeDef sdio_cmdinitstructure; + HAL_SD_ErrorTypedef errorstate = SD_OK; + + /* Send CMD7 SDIO_SEL_DESEL_CARD */ + sdio_cmdinitstructure.Argument = (uint32_t)addr; + sdio_cmdinitstructure.CmdIndex = SD_CMD_SEL_DESEL_CARD; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_SEL_DESEL_CARD); + + return errorstate; +} + +/** + * @brief Enquires cards about their operating voltage and configures clock + * controls and stores SD information that will be needed in future + * in the SD handle. + * @param hsd: SD handle + * @retval SD Card error state + */ +static HAL_SD_ErrorTypedef SD_PowerON(SD_HandleTypeDef *hsd) +{ + SDIO_CmdInitTypeDef sdio_cmdinitstructure; + __IO HAL_SD_ErrorTypedef errorstate = SD_OK; + uint32_t response = 0, count = 0, validvoltage = 0; + uint32_t sdtype = SD_STD_CAPACITY; + + /* Power ON Sequence -------------------------------------------------------*/ + /* Disable SDIO Clock */ + __HAL_SD_SDIO_DISABLE(); + + /* Set Power State to ON */ + SDIO_PowerState_ON(hsd->Instance); + + /* 1ms: required power up waiting time before starting the SD initialization + sequence */ + HAL_Delay(1); + + /* Enable SDIO Clock */ + __HAL_SD_SDIO_ENABLE(); + + /* CMD0: GO_IDLE_STATE -----------------------------------------------------*/ + /* No CMD response required */ + sdio_cmdinitstructure.Argument = 0; + sdio_cmdinitstructure.CmdIndex = SD_CMD_GO_IDLE_STATE; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_NO; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdError(hsd); + + if(errorstate != SD_OK) + { + /* CMD Response Timeout (wait for CMDSENT flag) */ + return errorstate; + } + + /* CMD8: SEND_IF_COND ------------------------------------------------------*/ + /* Send CMD8 to verify SD card interface operating condition */ + /* Argument: - [31:12]: Reserved (shall be set to '0') + - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V) + - [7:0]: Check Pattern (recommended 0xAA) */ + /* CMD Response: R7 */ + sdio_cmdinitstructure.Argument = SD_CHECK_PATTERN; + sdio_cmdinitstructure.CmdIndex = SD_SDIO_SEND_IF_COND; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp7Error(hsd); + + if (errorstate == SD_OK) + { + /* SD Card 2.0 */ + hsd->CardType = STD_CAPACITY_SD_CARD_V2_0; + sdtype = SD_HIGH_CAPACITY; + } + + /* Send CMD55 */ + sdio_cmdinitstructure.Argument = 0; + sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD); + + /* If errorstate is Command Timeout, it is a MMC card */ + /* If errorstate is SD_OK it is a SD card: SD card 2.0 (voltage range mismatch) + or SD card 1.x */ + if(errorstate == SD_OK) + { + /* SD CARD */ + /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */ + while((!validvoltage) && (count < SD_MAX_VOLT_TRIAL)) + { + + /* SEND CMD55 APP_CMD with RCA as 0 */ + sdio_cmdinitstructure.Argument = 0; + sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD); + + if(errorstate != SD_OK) + { + return errorstate; + } + + /* Send CMD41 */ + sdio_cmdinitstructure.Argument = SD_VOLTAGE_WINDOW_SD | sdtype; + sdio_cmdinitstructure.CmdIndex = SD_CMD_SD_APP_OP_COND; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp3Error(hsd); + + if(errorstate != SD_OK) + { + return errorstate; + } + + /* Get command response */ + response = SDIO_GetResponse(SDIO_RESP1); + + /* Get operating voltage*/ + validvoltage = (((response >> 31) == 1) ? 1 : 0); + + count++; + } + + if(count >= SD_MAX_VOLT_TRIAL) + { + errorstate = SD_INVALID_VOLTRANGE; + + return errorstate; + } + + if((response & SD_HIGH_CAPACITY) == SD_HIGH_CAPACITY) /* (response &= SD_HIGH_CAPACITY) */ + { + hsd->CardType = HIGH_CAPACITY_SD_CARD; + } + + } /* else MMC Card */ + + return errorstate; +} + +/** + * @brief Turns the SDIO output signals off. + * @param hsd: SD handle + * @retval SD Card error state + */ +static HAL_SD_ErrorTypedef SD_PowerOFF(SD_HandleTypeDef *hsd) +{ + HAL_SD_ErrorTypedef errorstate = SD_OK; + + /* Set Power State to OFF */ + SDIO_PowerState_OFF(hsd->Instance); + + return errorstate; +} + +/** + * @brief Returns the current card's status. + * @param hsd: SD handle + * @param pCardStatus: pointer to the buffer that will contain the SD card + * status (Card Status register) + * @retval SD Card error state + */ +static HAL_SD_ErrorTypedef SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus) +{ + SDIO_CmdInitTypeDef sdio_cmdinitstructure; + HAL_SD_ErrorTypedef errorstate = SD_OK; + + if(pCardStatus == NULL) + { + errorstate = SD_INVALID_PARAMETER; + + return errorstate; + } + + /* Send Status command */ + sdio_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16); + sdio_cmdinitstructure.CmdIndex = SD_CMD_SEND_STATUS; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_SEND_STATUS); + + if(errorstate != SD_OK) + { + return errorstate; + } + + /* Get SD card status */ + *pCardStatus = SDIO_GetResponse(SDIO_RESP1); + + return errorstate; +} + +/** + * @brief Checks for error conditions for CMD0. + * @param hsd: SD handle + * @retval SD Card error state + */ +static HAL_SD_ErrorTypedef SD_CmdError(SD_HandleTypeDef *hsd) +{ + HAL_SD_ErrorTypedef errorstate = SD_OK; + uint32_t timeout, tmp; + + timeout = SDIO_CMD0TIMEOUT; + + tmp = __HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CMDSENT); + + while((timeout > 0) && (!tmp)) + { + tmp = __HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CMDSENT); + timeout--; + } + + if(timeout == 0) + { + errorstate = SD_CMD_RSP_TIMEOUT; + return errorstate; + } + + /* Clear all the static flags */ + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS); + + return errorstate; +} + +/** + * @brief Checks for error conditions for R7 response. + * @param hsd: SD handle + * @retval SD Card error state + */ +static HAL_SD_ErrorTypedef SD_CmdResp7Error(SD_HandleTypeDef *hsd) +{ + HAL_SD_ErrorTypedef errorstate = SD_ERROR; + uint32_t timeout = SDIO_CMD0TIMEOUT, tmp; + + tmp = __HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT); + + while((!tmp) && (timeout > 0)) + { + tmp = __HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT); + timeout--; + } + + tmp = __HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT); + + if((timeout == 0) || tmp) + { + /* Card is not V2.0 compliant or card does not support the set voltage range */ + errorstate = SD_CMD_RSP_TIMEOUT; + + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT); + + return errorstate; + } + + if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CMDREND)) + { + /* Card is SD V2.0 compliant */ + errorstate = SD_OK; + + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CMDREND); + + return errorstate; + } + + return errorstate; +} + +/** + * @brief Checks for error conditions for R1 response. + * @param hsd: SD handle + * @param SD_CMD: The sent command index + * @retval SD Card error state + */ +static HAL_SD_ErrorTypedef SD_CmdResp1Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD) +{ + HAL_SD_ErrorTypedef errorstate = SD_OK; + uint32_t response_r1; + + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) + { + } + + if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT)) + { + errorstate = SD_CMD_RSP_TIMEOUT; + + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT); + + return errorstate; + } + else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL)) + { + errorstate = SD_CMD_CRC_FAIL; + + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CCRCFAIL); + + return errorstate; + } + + /* Check response received is of desired command */ + if(SDIO_GetCommandResponse(hsd->Instance) != SD_CMD) + { + errorstate = SD_ILLEGAL_CMD; + + return errorstate; + } + + /* Clear all the static flags */ + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS); + + /* We have received response, retrieve it for analysis */ + response_r1 = SDIO_GetResponse(SDIO_RESP1); + + if((response_r1 & SD_OCR_ERRORBITS) == SD_ALLZERO) + { + return errorstate; + } + + if((response_r1 & SD_OCR_ADDR_OUT_OF_RANGE) == SD_OCR_ADDR_OUT_OF_RANGE) + { + return(SD_ADDR_OUT_OF_RANGE); + } + + if((response_r1 & SD_OCR_ADDR_MISALIGNED) == SD_OCR_ADDR_MISALIGNED) + { + return(SD_ADDR_MISALIGNED); + } + + if((response_r1 & SD_OCR_BLOCK_LEN_ERR) == SD_OCR_BLOCK_LEN_ERR) + { + return(SD_BLOCK_LEN_ERR); + } + + if((response_r1 & SD_OCR_ERASE_SEQ_ERR) == SD_OCR_ERASE_SEQ_ERR) + { + return(SD_ERASE_SEQ_ERR); + } + + if((response_r1 & SD_OCR_BAD_ERASE_PARAM) == SD_OCR_BAD_ERASE_PARAM) + { + return(SD_BAD_ERASE_PARAM); + } + + if((response_r1 & SD_OCR_WRITE_PROT_VIOLATION) == SD_OCR_WRITE_PROT_VIOLATION) + { + return(SD_WRITE_PROT_VIOLATION); + } + + if((response_r1 & SD_OCR_LOCK_UNLOCK_FAILED) == SD_OCR_LOCK_UNLOCK_FAILED) + { + return(SD_LOCK_UNLOCK_FAILED); + } + + if((response_r1 & SD_OCR_COM_CRC_FAILED) == SD_OCR_COM_CRC_FAILED) + { + return(SD_COM_CRC_FAILED); + } + + if((response_r1 & SD_OCR_ILLEGAL_CMD) == SD_OCR_ILLEGAL_CMD) + { + return(SD_ILLEGAL_CMD); + } + + if((response_r1 & SD_OCR_CARD_ECC_FAILED) == SD_OCR_CARD_ECC_FAILED) + { + return(SD_CARD_ECC_FAILED); + } + + if((response_r1 & SD_OCR_CC_ERROR) == SD_OCR_CC_ERROR) + { + return(SD_CC_ERROR); + } + + if((response_r1 & SD_OCR_GENERAL_UNKNOWN_ERROR) == SD_OCR_GENERAL_UNKNOWN_ERROR) + { + return(SD_GENERAL_UNKNOWN_ERROR); + } + + if((response_r1 & SD_OCR_STREAM_READ_UNDERRUN) == SD_OCR_STREAM_READ_UNDERRUN) + { + return(SD_STREAM_READ_UNDERRUN); + } + + if((response_r1 & SD_OCR_STREAM_WRITE_OVERRUN) == SD_OCR_STREAM_WRITE_OVERRUN) + { + return(SD_STREAM_WRITE_OVERRUN); + } + + if((response_r1 & SD_OCR_CID_CSD_OVERWRITE) == SD_OCR_CID_CSD_OVERWRITE) + { + return(SD_CID_CSD_OVERWRITE); + } + + if((response_r1 & SD_OCR_WP_ERASE_SKIP) == SD_OCR_WP_ERASE_SKIP) + { + return(SD_WP_ERASE_SKIP); + } + + if((response_r1 & SD_OCR_CARD_ECC_DISABLED) == SD_OCR_CARD_ECC_DISABLED) + { + return(SD_CARD_ECC_DISABLED); + } + + if((response_r1 & SD_OCR_ERASE_RESET) == SD_OCR_ERASE_RESET) + { + return(SD_ERASE_RESET); + } + + if((response_r1 & SD_OCR_AKE_SEQ_ERROR) == SD_OCR_AKE_SEQ_ERROR) + { + return(SD_AKE_SEQ_ERROR); + } + + return errorstate; +} + +/** + * @brief Checks for error conditions for R3 (OCR) response. + * @param hsd: SD handle + * @retval SD Card error state + */ +static HAL_SD_ErrorTypedef SD_CmdResp3Error(SD_HandleTypeDef *hsd) +{ + HAL_SD_ErrorTypedef errorstate = SD_OK; + + while (!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) + { + } + + if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT)) + { + errorstate = SD_CMD_RSP_TIMEOUT; + + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT); + + return errorstate; + } + + /* Clear all the static flags */ + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS); + + return errorstate; +} + +/** + * @brief Checks for error conditions for R2 (CID or CSD) response. + * @param hsd: SD handle + * @retval SD Card error state + */ +static HAL_SD_ErrorTypedef SD_CmdResp2Error(SD_HandleTypeDef *hsd) +{ + HAL_SD_ErrorTypedef errorstate = SD_OK; + + while (!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) + { + } + + if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT)) + { + errorstate = SD_CMD_RSP_TIMEOUT; + + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT); + + return errorstate; + } + else if (__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL)) + { + errorstate = SD_CMD_CRC_FAIL; + + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CCRCFAIL); + + return errorstate; + } + else + { + /* No error flag set */ + } + + /* Clear all the static flags */ + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS); + + return errorstate; +} + +/** + * @brief Checks for error conditions for R6 (RCA) response. + * @param hsd: SD handle + * @param SD_CMD: The sent command index + * @param pRCA: Pointer to the variable that will contain the SD card relative + * address RCA + * @retval SD Card error state + */ +static HAL_SD_ErrorTypedef SD_CmdResp6Error(SD_HandleTypeDef *hsd, uint8_t SD_CMD, uint16_t *pRCA) +{ + HAL_SD_ErrorTypedef errorstate = SD_OK; + uint32_t response_r1; + + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) + { + } + + if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT)) + { + errorstate = SD_CMD_RSP_TIMEOUT; + + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT); + + return errorstate; + } + else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL)) + { + errorstate = SD_CMD_CRC_FAIL; + + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CCRCFAIL); + + return errorstate; + } + else + { + /* No error flag set */ + } + + /* Check response received is of desired command */ + if(SDIO_GetCommandResponse(hsd->Instance) != SD_CMD) + { + errorstate = SD_ILLEGAL_CMD; + + return errorstate; + } + + /* Clear all the static flags */ + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS); + + /* We have received response, retrieve it. */ + response_r1 = SDIO_GetResponse(SDIO_RESP1); + + if((response_r1 & (SD_R6_GENERAL_UNKNOWN_ERROR | SD_R6_ILLEGAL_CMD | SD_R6_COM_CRC_FAILED)) == SD_ALLZERO) + { + *pRCA = (uint16_t) (response_r1 >> 16); + + return errorstate; + } + + if((response_r1 & SD_R6_GENERAL_UNKNOWN_ERROR) == SD_R6_GENERAL_UNKNOWN_ERROR) + { + return(SD_GENERAL_UNKNOWN_ERROR); + } + + if((response_r1 & SD_R6_ILLEGAL_CMD) == SD_R6_ILLEGAL_CMD) + { + return(SD_ILLEGAL_CMD); + } + + if((response_r1 & SD_R6_COM_CRC_FAILED) == SD_R6_COM_CRC_FAILED) + { + return(SD_COM_CRC_FAILED); + } + + return errorstate; +} + +/** + * @brief Enables the SDIO wide bus mode. + * @param hsd: SD handle + * @retval SD Card error state + */ +static HAL_SD_ErrorTypedef SD_WideBus_Enable(SD_HandleTypeDef *hsd) +{ + SDIO_CmdInitTypeDef sdio_cmdinitstructure; + HAL_SD_ErrorTypedef errorstate = SD_OK; + + uint32_t scr[2] = {0, 0}; + + if((SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED) + { + errorstate = SD_LOCK_UNLOCK_FAILED; + + return errorstate; + } + + /* Get SCR Register */ + errorstate = SD_FindSCR(hsd, scr); + + if(errorstate != SD_OK) + { + return errorstate; + } + + /* If requested card supports wide bus operation */ + if((scr[1] & SD_WIDE_BUS_SUPPORT) != SD_ALLZERO) + { + /* Send CMD55 APP_CMD with argument as card's RCA.*/ + sdio_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16); + sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD); + + if(errorstate != SD_OK) + { + return errorstate; + } + + /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */ + sdio_cmdinitstructure.Argument = 2; + sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_SD_SET_BUSWIDTH; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_SD_SET_BUSWIDTH); + + if(errorstate != SD_OK) + { + return errorstate; + } + + return errorstate; + } + else + { + errorstate = SD_REQUEST_NOT_APPLICABLE; + + return errorstate; + } +} + +/** + * @brief Disables the SDIO wide bus mode. + * @param hsd: SD handle + * @retval SD Card error state + */ +static HAL_SD_ErrorTypedef SD_WideBus_Disable(SD_HandleTypeDef *hsd) +{ + SDIO_CmdInitTypeDef sdio_cmdinitstructure; + HAL_SD_ErrorTypedef errorstate = SD_OK; + + uint32_t scr[2] = {0, 0}; + + if((SDIO_GetResponse(SDIO_RESP1) & SD_CARD_LOCKED) == SD_CARD_LOCKED) + { + errorstate = SD_LOCK_UNLOCK_FAILED; + + return errorstate; + } + + /* Get SCR Register */ + errorstate = SD_FindSCR(hsd, scr); + + if(errorstate != SD_OK) + { + return errorstate; + } + + /* If requested card supports 1 bit mode operation */ + if((scr[1] & SD_SINGLE_BUS_SUPPORT) != SD_ALLZERO) + { + /* Send CMD55 APP_CMD with argument as card's RCA */ + sdio_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16); + sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD); + + if(errorstate != SD_OK) + { + return errorstate; + } + + /* Send ACMD6 APP_CMD with argument as 0 for single bus mode */ + sdio_cmdinitstructure.Argument = 0; + sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_SD_SET_BUSWIDTH; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_SD_SET_BUSWIDTH); + + if(errorstate != SD_OK) + { + return errorstate; + } + + return errorstate; + } + else + { + errorstate = SD_REQUEST_NOT_APPLICABLE; + + return errorstate; + } +} + + +/** + * @brief Finds the SD card SCR register value. + * @param hsd: SD handle + * @param pSCR: pointer to the buffer that will contain the SCR value + * @retval SD Card error state + */ +static HAL_SD_ErrorTypedef SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR) +{ + SDIO_CmdInitTypeDef sdio_cmdinitstructure; + SDIO_DataInitTypeDef sdio_datainitstructure; + HAL_SD_ErrorTypedef errorstate = SD_OK; + uint32_t index = 0; + uint32_t tempscr[2] = {0, 0}; + + /* Set Block Size To 8 Bytes */ + /* Send CMD55 APP_CMD with argument as card's RCA */ + sdio_cmdinitstructure.Argument = (uint32_t)8; + sdio_cmdinitstructure.CmdIndex = SD_CMD_SET_BLOCKLEN; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_SET_BLOCKLEN); + + if(errorstate != SD_OK) + { + return errorstate; + } + + /* Send CMD55 APP_CMD with argument as card's RCA */ + sdio_cmdinitstructure.Argument = (uint32_t)((hsd->RCA) << 16); + sdio_cmdinitstructure.CmdIndex = SD_CMD_APP_CMD; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_APP_CMD); + + if(errorstate != SD_OK) + { + return errorstate; + } + sdio_datainitstructure.DataTimeOut = SD_DATATIMEOUT; + sdio_datainitstructure.DataLength = 8; + sdio_datainitstructure.DataBlockSize = SDIO_DATABLOCK_SIZE_8B; + sdio_datainitstructure.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO; + sdio_datainitstructure.TransferMode = SDIO_TRANSFER_MODE_BLOCK; + sdio_datainitstructure.DPSM = SDIO_DPSM_ENABLE; + SDIO_DataConfig(hsd->Instance, &sdio_datainitstructure); + + /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */ + sdio_cmdinitstructure.Argument = 0; + sdio_cmdinitstructure.CmdIndex = SD_CMD_SD_APP_SEND_SCR; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + /* Check for error conditions */ + errorstate = SD_CmdResp1Error(hsd, SD_CMD_SD_APP_SEND_SCR); + + if(errorstate != SD_OK) + { + return errorstate; + } +#ifdef SDIO_STA_STBITERR + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR)) +#else /* SDIO_STA_STBITERR not defined */ + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND)) +#endif /* SDIO_STA_STBITERR */ + { + if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXDAVL)) + { + *(tempscr + index) = SDIO_ReadFIFO(hsd->Instance); + index++; + } + } + + if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DTIMEOUT)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DTIMEOUT); + + errorstate = SD_DATA_TIMEOUT; + + return errorstate; + } + else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_DCRCFAIL)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_DCRCFAIL); + + errorstate = SD_DATA_CRC_FAIL; + + return errorstate; + } + else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_RXOVERR)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_RXOVERR); + + errorstate = SD_RX_OVERRUN; + + return errorstate; + } +#ifdef SDIO_STA_STBITERR + else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_STBITERR)) + { + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_STBITERR); + + errorstate = SD_START_BIT_ERR; + + return errorstate; + } +#endif /* SDIO_STA_STBITERR */ + else + { + /* No error flag set */ + } + + /* Clear all the static flags */ + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS); + + *(pSCR + 1) = ((tempscr[0] & SD_0TO7BITS) << 24) | ((tempscr[0] & SD_8TO15BITS) << 8) |\ + ((tempscr[0] & SD_16TO23BITS) >> 8) | ((tempscr[0] & SD_24TO31BITS) >> 24); + + *(pSCR) = ((tempscr[1] & SD_0TO7BITS) << 24) | ((tempscr[1] & SD_8TO15BITS) << 8) |\ + ((tempscr[1] & SD_16TO23BITS) >> 8) | ((tempscr[1] & SD_24TO31BITS) >> 24); + + return errorstate; +} + +/** + * @brief Checks if the SD card is in programming state. + * @param hsd: SD handle + * @param pStatus: pointer to the variable that will contain the SD card state + * @retval SD Card error state + */ +static HAL_SD_ErrorTypedef SD_IsCardProgramming(SD_HandleTypeDef *hsd, uint8_t *pStatus) +{ + SDIO_CmdInitTypeDef sdio_cmdinitstructure; + HAL_SD_ErrorTypedef errorstate = SD_OK; + __IO uint32_t responseR1 = 0; + + sdio_cmdinitstructure.Argument = (uint32_t)(hsd->RCA << 16); + sdio_cmdinitstructure.CmdIndex = SD_CMD_SEND_STATUS; + sdio_cmdinitstructure.Response = SDIO_RESPONSE_SHORT; + sdio_cmdinitstructure.WaitForInterrupt = SDIO_WAIT_NO; + sdio_cmdinitstructure.CPSM = SDIO_CPSM_ENABLE; + SDIO_SendCommand(hsd->Instance, &sdio_cmdinitstructure); + + while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) + { + } + + if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CTIMEOUT)) + { + errorstate = SD_CMD_RSP_TIMEOUT; + + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CTIMEOUT); + + return errorstate; + } + else if(__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL)) + { + errorstate = SD_CMD_CRC_FAIL; + + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_FLAG_CCRCFAIL); + + return errorstate; + } + else + { + /* No error flag set */ + } + + /* Check response received is of desired command */ + if((uint32_t)SDIO_GetCommandResponse(hsd->Instance) != SD_CMD_SEND_STATUS) + { + errorstate = SD_ILLEGAL_CMD; + + return errorstate; + } + + /* Clear all the static flags */ + __HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS); + + + /* We have received response, retrieve it for analysis */ + responseR1 = SDIO_GetResponse(SDIO_RESP1); + + /* Find out card status */ + *pStatus = (uint8_t)((responseR1 >> 9) & 0x0000000F); + + if((responseR1 & SD_OCR_ERRORBITS) == SD_ALLZERO) + { + return errorstate; + } + + if((responseR1 & SD_OCR_ADDR_OUT_OF_RANGE) == SD_OCR_ADDR_OUT_OF_RANGE) + { + return(SD_ADDR_OUT_OF_RANGE); + } + + if((responseR1 & SD_OCR_ADDR_MISALIGNED) == SD_OCR_ADDR_MISALIGNED) + { + return(SD_ADDR_MISALIGNED); + } + + if((responseR1 & SD_OCR_BLOCK_LEN_ERR) == SD_OCR_BLOCK_LEN_ERR) + { + return(SD_BLOCK_LEN_ERR); + } + + if((responseR1 & SD_OCR_ERASE_SEQ_ERR) == SD_OCR_ERASE_SEQ_ERR) + { + return(SD_ERASE_SEQ_ERR); + } + + if((responseR1 & SD_OCR_BAD_ERASE_PARAM) == SD_OCR_BAD_ERASE_PARAM) + { + return(SD_BAD_ERASE_PARAM); + } + + if((responseR1 & SD_OCR_WRITE_PROT_VIOLATION) == SD_OCR_WRITE_PROT_VIOLATION) + { + return(SD_WRITE_PROT_VIOLATION); + } + + if((responseR1 & SD_OCR_LOCK_UNLOCK_FAILED) == SD_OCR_LOCK_UNLOCK_FAILED) + { + return(SD_LOCK_UNLOCK_FAILED); + } + + if((responseR1 & SD_OCR_COM_CRC_FAILED) == SD_OCR_COM_CRC_FAILED) + { + return(SD_COM_CRC_FAILED); + } + + if((responseR1 & SD_OCR_ILLEGAL_CMD) == SD_OCR_ILLEGAL_CMD) + { + return(SD_ILLEGAL_CMD); + } + + if((responseR1 & SD_OCR_CARD_ECC_FAILED) == SD_OCR_CARD_ECC_FAILED) + { + return(SD_CARD_ECC_FAILED); + } + + if((responseR1 & SD_OCR_CC_ERROR) == SD_OCR_CC_ERROR) + { + return(SD_CC_ERROR); + } + + if((responseR1 & SD_OCR_GENERAL_UNKNOWN_ERROR) == SD_OCR_GENERAL_UNKNOWN_ERROR) + { + return(SD_GENERAL_UNKNOWN_ERROR); + } + + if((responseR1 & SD_OCR_STREAM_READ_UNDERRUN) == SD_OCR_STREAM_READ_UNDERRUN) + { + return(SD_STREAM_READ_UNDERRUN); + } + + if((responseR1 & SD_OCR_STREAM_WRITE_OVERRUN) == SD_OCR_STREAM_WRITE_OVERRUN) + { + return(SD_STREAM_WRITE_OVERRUN); + } + + if((responseR1 & SD_OCR_CID_CSD_OVERWRITE) == SD_OCR_CID_CSD_OVERWRITE) + { + return(SD_CID_CSD_OVERWRITE); + } + + if((responseR1 & SD_OCR_WP_ERASE_SKIP) == SD_OCR_WP_ERASE_SKIP) + { + return(SD_WP_ERASE_SKIP); + } + + if((responseR1 & SD_OCR_CARD_ECC_DISABLED) == SD_OCR_CARD_ECC_DISABLED) + { + return(SD_CARD_ECC_DISABLED); + } + + if((responseR1 & SD_OCR_ERASE_RESET) == SD_OCR_ERASE_RESET) + { + return(SD_ERASE_RESET); + } + + if((responseR1 & SD_OCR_AKE_SEQ_ERROR) == SD_OCR_AKE_SEQ_ERROR) + { + return(SD_AKE_SEQ_ERROR); + } + + return errorstate; +} + +/** + * @} + */ + +#endif /* HAL_SD_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c new file mode 100644 index 0000000..bcf1dfe --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c @@ -0,0 +1,842 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_sdram.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief SDRAM HAL module driver. + * This file provides a generic firmware to drive SDRAM memories mounted + * as external device. + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + This driver is a generic layered driver which contains a set of APIs used to + control SDRAM memories. It uses the FMC layer functions to interface + with SDRAM devices. + The following sequence should be followed to configure the FMC to interface + with SDRAM memories: + + (#) Declare a SDRAM_HandleTypeDef handle structure, for example: + SDRAM_HandleTypeDef hdsram + + (++) Fill the SDRAM_HandleTypeDef handle "Init" field with the allowed + values of the structure member. + + (++) Fill the SDRAM_HandleTypeDef handle "Instance" field with a predefined + base register instance for NOR or SDRAM device + + (#) Declare a FMC_SDRAM_TimingTypeDef structure; for example: + FMC_SDRAM_TimingTypeDef Timing; + and fill its fields with the allowed values of the structure member. + + (#) Initialize the SDRAM Controller by calling the function HAL_SDRAM_Init(). This function + performs the following sequence: + + (##) MSP hardware layer configuration using the function HAL_SDRAM_MspInit() + (##) Control register configuration using the FMC SDRAM interface function + FMC_SDRAM_Init() + (##) Timing register configuration using the FMC SDRAM interface function + FMC_SDRAM_Timing_Init() + (##) Program the SDRAM external device by applying its initialization sequence + according to the device plugged in your hardware. This step is mandatory + for accessing the SDRAM device. + + (#) At this stage you can perform read/write accesses from/to the memory connected + to the SDRAM Bank. You can perform either polling or DMA transfer using the + following APIs: + (++) HAL_SDRAM_Read()/HAL_SDRAM_Write() for polling read/write access + (++) HAL_SDRAM_Read_DMA()/HAL_SDRAM_Write_DMA() for DMA read/write transfer + + (#) You can also control the SDRAM device by calling the control APIs HAL_SDRAM_WriteOperation_Enable()/ + HAL_SDRAM_WriteOperation_Disable() to respectively enable/disable the SDRAM write operation or + the function HAL_SDRAM_SendCommand() to send a specified command to the SDRAM + device. The command to be sent must be configured with the FMC_SDRAM_CommandTypeDef + structure. + + (#) You can continuously monitor the SDRAM device HAL state by calling the function + HAL_SDRAM_GetState() + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 SDRAM SDRAM + * @brief SDRAM driver modules + * @{ + */ +#ifdef HAL_SDRAM_MODULE_ENABLED +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SDRAM_Exported_Functions SDRAM Exported Functions + * @{ + */ + +/** @defgroup SDRAM_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * + @verbatim + ============================================================================== + ##### SDRAM Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to initialize/de-initialize + the SDRAM memory + +@endverbatim + * @{ + */ + +/** + * @brief Performs the SDRAM device initialization sequence. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param Timing: Pointer to SDRAM control timing structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Init(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_TimingTypeDef *Timing) +{ + /* Check the SDRAM handle parameter */ + if(hsdram == NULL) + { + return HAL_ERROR; + } + + if(hsdram->State == HAL_SDRAM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hsdram->Lock = HAL_UNLOCKED; + /* Initialize the low level hardware (MSP) */ + HAL_SDRAM_MspInit(hsdram); + } + + /* Initialize the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Initialize SDRAM control Interface */ + FMC_SDRAM_Init(hsdram->Instance, &(hsdram->Init)); + + /* Initialize SDRAM timing Interface */ + FMC_SDRAM_Timing_Init(hsdram->Instance, Timing, hsdram->Init.SDBank); + + /* Update the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Perform the SDRAM device initialization sequence. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_DeInit(SDRAM_HandleTypeDef *hsdram) +{ + /* Initialize the low level hardware (MSP) */ + HAL_SDRAM_MspDeInit(hsdram); + + /* Configure the SDRAM registers with their reset values */ + FMC_SDRAM_DeInit(hsdram->Instance, hsdram->Init.SDBank); + + /* Reset the SDRAM controller state */ + hsdram->State = HAL_SDRAM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hsdram); + + return HAL_OK; +} + +/** + * @brief SDRAM MSP Init. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval None + */ +__weak void HAL_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_SDRAM_MspInit could be implemented in the user file + */ +} + +/** + * @brief SDRAM MSP DeInit. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval None + */ +__weak void HAL_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_SDRAM_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief This function handles SDRAM refresh error interrupt request. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval HAL status +*/ +void HAL_SDRAM_IRQHandler(SDRAM_HandleTypeDef *hsdram) +{ + /* Check SDRAM interrupt Rising edge flag */ + if(__FMC_SDRAM_GET_FLAG(hsdram->Instance, FMC_SDRAM_FLAG_REFRESH_IT)) + { + /* SDRAM refresh error interrupt callback */ + HAL_SDRAM_RefreshErrorCallback(hsdram); + + /* Clear SDRAM refresh error interrupt pending bit */ + __FMC_SDRAM_CLEAR_FLAG(hsdram->Instance, FMC_SDRAM_FLAG_REFRESH_ERROR); + } +} + +/** + * @brief SDRAM Refresh error callback. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval None + */ +__weak void HAL_SDRAM_RefreshErrorCallback(SDRAM_HandleTypeDef *hsdram) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_SDRAM_RefreshErrorCallback could be implemented in the user file + */ +} + +/** + * @brief DMA transfer complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +__weak void HAL_SDRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_SDRAM_DMA_XferCpltCallback could be implemented in the user file + */ +} + +/** + * @brief DMA transfer complete error callback. + * @param hdma: DMA handle + * @retval None + */ +__weak void HAL_SDRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_SDRAM_DMA_XferErrorCallback could be implemented in the user file + */ +} +/** + * @} + */ + +/** @defgroup SDRAM_Exported_Functions_Group2 Input and Output functions + * @brief Input Output and memory control functions + * + @verbatim + ============================================================================== + ##### SDRAM Input and Output functions ##### + ============================================================================== + [..] + This section provides functions allowing to use and control the SDRAM memory + +@endverbatim + * @{ + */ + +/** + * @brief Reads 8-bit data buffer from the SDRAM memory. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param pAddress: Pointer to read start address + * @param pDstBuffer: Pointer to destination buffer + * @param BufferSize: Size of the buffer to read from memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Read_8b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint8_t *pDstBuffer, uint32_t BufferSize) +{ + __IO uint8_t *pSdramAddress = (uint8_t *)pAddress; + + /* Process Locked */ + __HAL_LOCK(hsdram); + + /* Check the SDRAM controller state */ + if(hsdram->State == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if(hsdram->State == HAL_SDRAM_STATE_PRECHARGED) + { + return HAL_ERROR; + } + + /* Read data from source */ + for(; BufferSize != 0; BufferSize--) + { + *pDstBuffer = *(__IO uint8_t *)pSdramAddress; + pDstBuffer++; + pSdramAddress++; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + + return HAL_OK; +} + +/** + * @brief Writes 8-bit data buffer to SDRAM memory. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param pAddress: Pointer to write start address + * @param pSrcBuffer: Pointer to source buffer to write + * @param BufferSize: Size of the buffer to write to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Write_8b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint8_t *pSrcBuffer, uint32_t BufferSize) +{ + __IO uint8_t *pSdramAddress = (uint8_t *)pAddress; + uint32_t tmp = 0; + + /* Process Locked */ + __HAL_LOCK(hsdram); + + /* Check the SDRAM controller state */ + tmp = hsdram->State; + + if(tmp == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if((tmp == HAL_SDRAM_STATE_PRECHARGED) || (tmp == HAL_SDRAM_STATE_WRITE_PROTECTED)) + { + return HAL_ERROR; + } + + /* Write data to memory */ + for(; BufferSize != 0; BufferSize--) + { + *(__IO uint8_t *)pSdramAddress = *pSrcBuffer; + pSrcBuffer++; + pSdramAddress++; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + + return HAL_OK; +} + +/** + * @brief Reads 16-bit data buffer from the SDRAM memory. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param pAddress: Pointer to read start address + * @param pDstBuffer: Pointer to destination buffer + * @param BufferSize: Size of the buffer to read from memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Read_16b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint16_t *pDstBuffer, uint32_t BufferSize) +{ + __IO uint16_t *pSdramAddress = (uint16_t *)pAddress; + + /* Process Locked */ + __HAL_LOCK(hsdram); + + /* Check the SDRAM controller state */ + if(hsdram->State == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if(hsdram->State == HAL_SDRAM_STATE_PRECHARGED) + { + return HAL_ERROR; + } + + /* Read data from source */ + for(; BufferSize != 0; BufferSize--) + { + *pDstBuffer = *(__IO uint16_t *)pSdramAddress; + pDstBuffer++; + pSdramAddress++; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + + return HAL_OK; +} + +/** + * @brief Writes 16-bit data buffer to SDRAM memory. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param pAddress: Pointer to write start address + * @param pSrcBuffer: Pointer to source buffer to write + * @param BufferSize: Size of the buffer to write to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Write_16b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint16_t *pSrcBuffer, uint32_t BufferSize) +{ + __IO uint16_t *pSdramAddress = (uint16_t *)pAddress; + uint32_t tmp = 0; + + /* Process Locked */ + __HAL_LOCK(hsdram); + + /* Check the SDRAM controller state */ + tmp = hsdram->State; + + if(tmp == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if((tmp == HAL_SDRAM_STATE_PRECHARGED) || (tmp == HAL_SDRAM_STATE_WRITE_PROTECTED)) + { + return HAL_ERROR; + } + + /* Write data to memory */ + for(; BufferSize != 0; BufferSize--) + { + *(__IO uint16_t *)pSdramAddress = *pSrcBuffer; + pSrcBuffer++; + pSdramAddress++; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + + return HAL_OK; +} + +/** + * @brief Reads 32-bit data buffer from the SDRAM memory. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param pAddress: Pointer to read start address + * @param pDstBuffer: Pointer to destination buffer + * @param BufferSize: Size of the buffer to read from memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Read_32b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize) +{ + __IO uint32_t *pSdramAddress = (uint32_t *)pAddress; + + /* Process Locked */ + __HAL_LOCK(hsdram); + + /* Check the SDRAM controller state */ + if(hsdram->State == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if(hsdram->State == HAL_SDRAM_STATE_PRECHARGED) + { + return HAL_ERROR; + } + + /* Read data from source */ + for(; BufferSize != 0; BufferSize--) + { + *pDstBuffer = *(__IO uint32_t *)pSdramAddress; + pDstBuffer++; + pSdramAddress++; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + + return HAL_OK; +} + +/** + * @brief Writes 32-bit data buffer to SDRAM memory. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param pAddress: Pointer to write start address + * @param pSrcBuffer: Pointer to source buffer to write + * @param BufferSize: Size of the buffer to write to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Write_32b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize) +{ + __IO uint32_t *pSdramAddress = (uint32_t *)pAddress; + uint32_t tmp = 0; + + /* Process Locked */ + __HAL_LOCK(hsdram); + + /* Check the SDRAM controller state */ + tmp = hsdram->State; + + if(tmp == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if((tmp == HAL_SDRAM_STATE_PRECHARGED) || (tmp == HAL_SDRAM_STATE_WRITE_PROTECTED)) + { + return HAL_ERROR; + } + + /* Write data to memory */ + for(; BufferSize != 0; BufferSize--) + { + *(__IO uint32_t *)pSdramAddress = *pSrcBuffer; + pSrcBuffer++; + pSdramAddress++; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + + return HAL_OK; +} + +/** + * @brief Reads a Words data from the SDRAM memory using DMA transfer. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param pAddress: Pointer to read start address + * @param pDstBuffer: Pointer to destination buffer + * @param BufferSize: Size of the buffer to read from memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Read_DMA(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize) +{ + uint32_t tmp = 0; + + /* Process Locked */ + __HAL_LOCK(hsdram); + + /* Check the SDRAM controller state */ + tmp = hsdram->State; + + if(tmp == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if(tmp == HAL_SDRAM_STATE_PRECHARGED) + { + return HAL_ERROR; + } + + /* Configure DMA user callbacks */ + hsdram->hdma->XferCpltCallback = HAL_SDRAM_DMA_XferCpltCallback; + hsdram->hdma->XferErrorCallback = HAL_SDRAM_DMA_XferErrorCallback; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hsdram->hdma, (uint32_t)pAddress, (uint32_t)pDstBuffer, (uint32_t)BufferSize); + + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + + return HAL_OK; +} + +/** + * @brief Writes a Words data buffer to SDRAM memory using DMA transfer. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param pAddress: Pointer to write start address + * @param pSrcBuffer: Pointer to source buffer to write + * @param BufferSize: Size of the buffer to write to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_Write_DMA(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize) +{ + uint32_t tmp = 0; + + /* Process Locked */ + __HAL_LOCK(hsdram); + + /* Check the SDRAM controller state */ + tmp = hsdram->State; + + if(tmp == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + else if((tmp == HAL_SDRAM_STATE_PRECHARGED) || (tmp == HAL_SDRAM_STATE_WRITE_PROTECTED)) + { + return HAL_ERROR; + } + + /* Configure DMA user callbacks */ + hsdram->hdma->XferCpltCallback = HAL_SDRAM_DMA_XferCpltCallback; + hsdram->hdma->XferErrorCallback = HAL_SDRAM_DMA_XferErrorCallback; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hsdram->hdma, (uint32_t)pSrcBuffer, (uint32_t)pAddress, (uint32_t)BufferSize); + + /* Process Unlocked */ + __HAL_UNLOCK(hsdram); + + return HAL_OK; +} +/** + * @} + */ + +/** @defgroup SDRAM_Exported_Functions_Group3 Control functions + * @brief management functions + * +@verbatim + ============================================================================== + ##### SDRAM Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the SDRAM interface. + +@endverbatim + * @{ + */ + +/** + * @brief Enables dynamically SDRAM write protection. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_WriteProtection_Enable(SDRAM_HandleTypeDef *hsdram) +{ + /* Check the SDRAM controller state */ + if(hsdram->State == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Enable write protection */ + FMC_SDRAM_WriteProtection_Enable(hsdram->Instance, hsdram->Init.SDBank); + + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_WRITE_PROTECTED; + + return HAL_OK; +} + +/** + * @brief Disables dynamically SDRAM write protection. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_WriteProtection_Disable(SDRAM_HandleTypeDef *hsdram) +{ + /* Check the SDRAM controller state */ + if(hsdram->State == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Disable write protection */ + FMC_SDRAM_WriteProtection_Disable(hsdram->Instance, hsdram->Init.SDBank); + + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Sends Command to the SDRAM bank. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param Command: SDRAM command structure + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_SendCommand(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command, uint32_t Timeout) +{ + /* Check the SDRAM controller state */ + if(hsdram->State == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Send SDRAM command */ + FMC_SDRAM_SendCommand(hsdram->Instance, Command, Timeout); + + /* Update the SDRAM controller state */ + if(Command->CommandMode == FMC_SDRAM_CMD_PALL) + { + hsdram->State = HAL_SDRAM_STATE_PRECHARGED; + } + else + { + hsdram->State = HAL_SDRAM_STATE_READY; + } + + return HAL_OK; +} + +/** + * @brief Programs the SDRAM Memory Refresh rate. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param RefreshRate: The SDRAM refresh rate value + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_ProgramRefreshRate(SDRAM_HandleTypeDef *hsdram, uint32_t RefreshRate) +{ + /* Check the SDRAM controller state */ + if(hsdram->State == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Program the refresh rate */ + FMC_SDRAM_ProgramRefreshRate(hsdram->Instance ,RefreshRate); + + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Sets the Number of consecutive SDRAM Memory auto Refresh commands. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @param AutoRefreshNumber: The SDRAM auto Refresh number + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SDRAM_SetAutoRefreshNumber(SDRAM_HandleTypeDef *hsdram, uint32_t AutoRefreshNumber) +{ + /* Check the SDRAM controller state */ + if(hsdram->State == HAL_SDRAM_STATE_BUSY) + { + return HAL_BUSY; + } + + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_BUSY; + + /* Set the Auto-Refresh number */ + FMC_SDRAM_SetAutoRefreshNumber(hsdram->Instance ,AutoRefreshNumber); + + /* Update the SDRAM state */ + hsdram->State = HAL_SDRAM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Returns the SDRAM memory current mode. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval The SDRAM memory mode. + */ +uint32_t HAL_SDRAM_GetModeStatus(SDRAM_HandleTypeDef *hsdram) +{ + /* Return the SDRAM memory current mode */ + return(FMC_SDRAM_GetModeStatus(hsdram->Instance, hsdram->Init.SDBank)); +} + +/** + * @} + */ + +/** @defgroup SDRAM_Exported_Functions_Group4 State functions + * @brief Peripheral State functions + * +@verbatim + ============================================================================== + ##### SDRAM State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the SDRAM controller + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the SDRAM state. + * @param hsdram: pointer to a SDRAM_HandleTypeDef structure that contains + * the configuration information for SDRAM module. + * @retval HAL state + */ +HAL_SDRAM_StateTypeDef HAL_SDRAM_GetState(SDRAM_HandleTypeDef *hsdram) +{ + return hsdram->State; +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ +#endif /* HAL_SDRAM_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_smartcard.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_smartcard.c new file mode 100644 index 0000000..b3bc7e3 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_smartcard.c @@ -0,0 +1,1303 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_smartcard.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief SMARTCARD HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the SMARTCARD peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State and Errors functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The SMARTCARD HAL driver can be used as follows: + + (#) Declare a SMARTCARD_HandleTypeDef handle structure. + (#) Initialize the SMARTCARD low level resources by implementing the HAL_SMARTCARD_MspInit() API: + (##) Enable the USARTx interface clock. + (##) SMARTCARD pins configuration: + (+++) Enable the clock for the SMARTCARD GPIOs. + (+++) Configure these SMARTCARD pins as alternate function pull-up. + (##) NVIC configuration if you need to use interrupt process (HAL_SMARTCARD_Transmit_IT() + and HAL_SMARTCARD_Receive_IT() APIs): + (+++) Configure the USARTx interrupt priority. + (+++) Enable the NVIC USART IRQ handle. + (##) DMA Configuration if you need to use DMA process (HAL_SMARTCARD_Transmit_DMA() + and HAL_SMARTCARD_Receive_DMA() APIs): + (+++) Declare a DMA handle structure for the Tx/Rx stream. + (+++) Enable the DMAx interface clock. + (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. + (+++) Configure the DMA Tx/Rx Stream. + (+++) Associate the initialized DMA handle to the SMARTCARD DMA Tx/Rx handle. + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream. + + (#) Program the Baud Rate, Word Length , Stop Bit, Parity, Hardware + flow control and Mode(Receiver/Transmitter) in the SMARTCARD Init structure. + + (#) Initialize the SMARTCARD registers by calling the HAL_SMARTCARD_Init() API: + (++) These APIs configure also the low level Hardware GPIO, CLOCK, CORTEX...etc) + by calling the customized HAL_SMARTCARD_MspInit() API. + [..] + (@) The specific SMARTCARD interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) will be managed using the macros + __HAL_SMARTCARD_ENABLE_IT() and __HAL_SMARTCARD_DISABLE_IT() inside the transmit and receive process. + + [..] + Three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Send an amount of data in blocking mode using HAL_SMARTCARD_Transmit() + (+) Receive an amount of data in blocking mode using HAL_SMARTCARD_Receive() + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Send an amount of data in non blocking mode using HAL_SMARTCARD_Transmit_IT() + (+) At transmission end of transfer HAL_SMARTCARD_TxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_TxCpltCallback + (+) Receive an amount of data in non blocking mode using HAL_SMARTCARD_Receive_IT() + (+) At reception end of transfer HAL_SMARTCARD_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_RxCpltCallback + (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_ErrorCallback + + *** DMA mode IO operation *** + ============================== + [..] + (+) Send an amount of data in non blocking mode (DMA) using HAL_SMARTCARD_Transmit_DMA() + (+) At transmission end of transfer HAL_SMARTCARD_TxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_TxCpltCallback + (+) Receive an amount of data in non blocking mode (DMA) using HAL_SMARTCARD_Receive_DMA() + (+) At reception end of transfer HAL_SMARTCARD_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_RxCpltCallback + (+) In case of transfer Error, HAL_SMARTCARD_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_SMARTCARD_ErrorCallback + + *** SMARTCARD HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in SMARTCARD HAL driver. + + (+) __HAL_SMARTCARD_ENABLE: Enable the SMARTCARD peripheral + (+) __HAL_SMARTCARD_DISABLE: Disable the SMARTCARD peripheral + (+) __HAL_SMARTCARD_GET_FLAG : Check whether the specified SMARTCARD flag is set or not + (+) __HAL_SMARTCARD_CLEAR_FLAG : Clear the specified SMARTCARD pending flag + (+) __HAL_SMARTCARD_ENABLE_IT: Enable the specified SMARTCARD interrupt + (+) __HAL_SMARTCARD_DISABLE_IT: Disable the specified SMARTCARD interrupt + + [..] + (@) You can refer to the SMARTCARD HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 SMARTCARD SMARTCARD + * @brief HAL USART SMARTCARD module driver + * @{ + */ +#ifdef HAL_SMARTCARD_MODULE_ENABLED +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup SMARTCARD_Private_Constants + * @{ + */ +#define SMARTCARD_TIMEOUT_VALUE 22000 +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup SMARTCARD_Private_Functions + * @{ + */ +static void SMARTCARD_SetConfig (SMARTCARD_HandleTypeDef *hsc); +static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc); +static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard); +static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc); +static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma); +static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma); +static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma); +static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Timeout); +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SMARTCARD_Exported_Functions SMARTCARD Exported Functions + * @{ + */ + +/** @defgroup SMARTCARD_Exported_Functions_Group1 SmartCard Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and Configuration functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the USART + in Smartcard mode. + [..] + The Smartcard interface is designed to support asynchronous protocol Smartcards as + defined in the ISO 7816-3 standard. + [..] + The USART can provide a clock to the smartcard through the SCLK output. + In smartcard mode, SCLK is not associated to the communication but is simply derived + from the internal peripheral input clock through a 5-bit prescaler. + [..] + (+) For the Smartcard mode only these parameters can be configured: + (++) Baud Rate + (++) Word Length => Should be 9 bits (8 bits + parity) + (++) Stop Bit + (++) Parity: => Should be enabled + +-------------------------------------------------------------+ + | M bit | PCE bit | SMARTCARD frame | + |---------------------|---------------------------------------| + | 1 | 1 | | SB | 8 bit data | PB | STB | | + +-------------------------------------------------------------+ + (++) USART polarity + (++) USART phase + (++) USART LastBit + (++) Receiver/transmitter modes + (++) Prescaler + (++) GuardTime + (++) NACKState: The Smartcard NACK state + + (+) Recommended SmartCard interface configuration to get the Answer to Reset from the Card: + (++) Word Length = 9 Bits + (++) 1.5 Stop Bit + (++) Even parity + (++) BaudRate = 12096 baud + (++) Tx and Rx enabled + [..] + Please refer to the ISO 7816-3 specification for more details. + + -@- It is also possible to choose 0.5 stop bit for receiving but it is recommended + to use 1.5 stop bits for both transmitting and receiving to avoid switching + between the two configurations. + [..] + The HAL_SMARTCARD_Init() function follows the USART SmartCard configuration + procedure (details for the procedure are available in reference manual (RM0329)). + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the SmartCard mode according to the specified + * parameters in the SMARTCARD_InitTypeDef and create the associated handle . + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Init(SMARTCARD_HandleTypeDef *hsc) +{ + /* Check the SMARTCARD handle allocation */ + if(hsc == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance)); + assert_param(IS_SMARTCARD_NACK_STATE(hsc->Init.NACKState)); + + if(hsc->State == HAL_SMARTCARD_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hsc->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + HAL_SMARTCARD_MspInit(hsc); + } + + hsc->State = HAL_SMARTCARD_STATE_BUSY; + + /* Set the Prescaler */ + MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_PSC, hsc->Init.Prescaler); + + /* Set the Guard Time */ + MODIFY_REG(hsc->Instance->GTPR, USART_GTPR_GT, ((hsc->Init.GuardTime)<<8)); + + /* Set the Smartcard Communication parameters */ + SMARTCARD_SetConfig(hsc); + + /* In SmartCard mode, the following bits must be kept cleared: + - LINEN bit in the USART_CR2 register + - HDSEL and IREN bits in the USART_CR3 register.*/ + hsc->Instance->CR2 &= ~USART_CR2_LINEN; + hsc->Instance->CR3 &= ~(USART_CR3_IREN | USART_CR3_HDSEL); + + /* Enable the SMARTCARD Parity Error Interrupt */ + __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_PE); + + /* Enable the SMARTCARD Framing Error Interrupt */ + __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_ERR); + + /* Enable the Peripheral */ + __HAL_SMARTCARD_ENABLE(hsc); + + /* Configure the Smartcard NACK state */ + MODIFY_REG(hsc->Instance->CR3, USART_CR3_NACK, hsc->Init.NACKState); + + /* Enable the SC mode by setting the SCEN bit in the CR3 register */ + hsc->Instance->CR3 |= (USART_CR3_SCEN); + + /* Initialize the SMARTCARD state*/ + hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + hsc->State= HAL_SMARTCARD_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the USART SmartCard peripheral + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_DeInit(SMARTCARD_HandleTypeDef *hsc) +{ + /* Check the SMARTCARD handle allocation */ + if(hsc == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance)); + + hsc->State = HAL_SMARTCARD_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_SMARTCARD_DISABLE(hsc); + + /* DeInit the low level hardware */ + HAL_SMARTCARD_MspDeInit(hsc); + + hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + hsc->State = HAL_SMARTCARD_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hsc); + + return HAL_OK; +} + +/** + * @brief SMARTCARD MSP Init + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @retval None + */ + __weak void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef *hsc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SMARTCARD_MspInit could be implemented in the user file + */ +} + +/** + * @brief SMARTCARD MSP DeInit + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @retval None + */ + __weak void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef *hsc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SMARTCARD_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup SMARTCARD_Exported_Functions_Group2 IO operation functions + * @brief SMARTCARD Transmit and Receive functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + This subsection provides a set of functions allowing to manage the SMARTCARD data transfers. + [..] + Smartcard is a single wire half duplex communication protocol. + The Smartcard interface is designed to support asynchronous protocol Smartcards as + defined in the ISO 7816-3 standard. The USART should be configured as: + (+) 8 bits plus parity: where M=1 and PCE=1 in the USART_CR1 register + (+) 1.5 stop bits when transmitting and receiving: where STOP=11 in the USART_CR2 register. + + (#) There are two modes of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) Non Blocking mode: The communication is performed using Interrupts + or DMA, These APIs return the HAL status. + The end of the data processing will be indicated through the + dedicated SMARTCARD IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The HAL_SMARTCARD_TxCpltCallback(), HAL_SMARTCARD_RxCpltCallback() user callbacks + will be executed respectively at the end of the Transmit or Receive process + The HAL_SMARTCARD_ErrorCallback() user callback will be executed when a communication error is detected + + (#) Blocking mode APIs are : + (++) HAL_SMARTCARD_Transmit() + (++) HAL_SMARTCARD_Receive() + + (#) Non Blocking mode APIs with Interrupt are : + (++) HAL_SMARTCARD_Transmit_IT() + (++) HAL_SMARTCARD_Receive_IT() + (++) HAL_SMARTCARD_IRQHandler() + + (#) Non Blocking mode functions with DMA are : + (++) HAL_SMARTCARD_Transmit_DMA() + (++) HAL_SMARTCARD_Receive_DMA() + + (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) HAL_SMARTCARD_TxCpltCallback() + (++) HAL_SMARTCARD_RxCpltCallback() + (++) HAL_SMARTCARD_ErrorCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Send an amount of data in blocking mode + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @param pData: pointer to data buffer + * @param Size: amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Transmit(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint16_t* tmp; + uint32_t tmp1 = 0; + + tmp1 = hsc->State; + if((tmp1 == HAL_SMARTCARD_STATE_READY) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_RX)) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsc); + + hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + /* Check if a non-blocking receive process is ongoing or not */ + if(hsc->State == HAL_SMARTCARD_STATE_BUSY_RX) + { + hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; + } + else + { + hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; + } + + hsc->TxXferSize = Size; + hsc->TxXferCount = Size; + while(hsc->TxXferCount > 0) + { + hsc->TxXferCount--; + if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + tmp = (uint16_t*) pData; + hsc->Instance->DR = (*tmp & (uint16_t)0x01FF); + pData +=1; + } + + if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_TC, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Check if a non-blocking receive process is ongoing or not */ + if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) + { + hsc->State = HAL_SMARTCARD_STATE_BUSY_RX; + } + else + { + hsc->State = HAL_SMARTCARD_STATE_READY; + } + /* Process Unlocked */ + __HAL_UNLOCK(hsc); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in blocking mode + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @param pData: pointer to data buffer + * @param Size: amount of data to be received + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Receive(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint16_t* tmp; + uint32_t tmp1 = 0; + + tmp1 = hsc->State; + if((tmp1 == HAL_SMARTCARD_STATE_READY) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_TX)) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsc); + + hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + + /* Check if a non-blocking transmit process is ongoing or not */ + if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX) + { + hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; + } + else + { + hsc->State = HAL_SMARTCARD_STATE_BUSY_RX; + } + + hsc->RxXferSize = Size; + hsc->RxXferCount = Size; + + /* Check the remain data to be received */ + while(hsc->RxXferCount > 0) + { + hsc->RxXferCount--; + if(SMARTCARD_WaitOnFlagUntilTimeout(hsc, SMARTCARD_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + tmp = (uint16_t*) pData; + *tmp = (uint16_t)(hsc->Instance->DR & (uint16_t)0x00FF); + pData +=1; + } + + /* Check if a non-blocking transmit process is ongoing or not */ + if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) + { + hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; + } + else + { + hsc->State = HAL_SMARTCARD_STATE_READY; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsc); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Send an amount of data in non blocking mode + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @param pData: pointer to data buffer + * @param Size: amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size) +{ + uint32_t tmp1 = 0; + + tmp1 = hsc->State; + if((tmp1 == HAL_SMARTCARD_STATE_READY) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_RX)) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsc); + + hsc->pTxBuffPtr = pData; + hsc->TxXferSize = Size; + hsc->TxXferCount = Size; + + hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + /* Check if a non-blocking receive process is ongoing or not */ + if(hsc->State == HAL_SMARTCARD_STATE_BUSY_RX) + { + hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; + } + else + { + hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hsc); + + /* Enable the SMARTCARD Parity Error Interrupt */ + __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_PE); + + /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR); + + /* Enable the SMARTCARD Transmit data register empty Interrupt */ + __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TXE); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in non blocking mode + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @param pData: pointer to data buffer + * @param Size: amount of data to be received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size) +{ + uint32_t tmp1 = 0; + + tmp1 = hsc->State; + if((tmp1 == HAL_SMARTCARD_STATE_READY) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_TX)) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsc); + + hsc->pRxBuffPtr = pData; + hsc->RxXferSize = Size; + hsc->RxXferCount = Size; + + hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + /* Check if a non-blocking transmit process is ongoing or not */ + if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX) + { + hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; + } + else + { + hsc->State = HAL_SMARTCARD_STATE_BUSY_RX; + } + /* Process Unlocked */ + __HAL_UNLOCK(hsc); + + /* Enable the SMARTCARD Data Register not empty Interrupt */ + __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_RXNE); + + /* Enable the SMARTCARD Parity Error Interrupt */ + __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_PE); + + /* Enable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Send an amount of data in non blocking mode + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @param pData: pointer to data buffer + * @param Size: amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Transmit_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size) +{ + uint32_t *tmp; + uint32_t tmp1 = 0; + + tmp1 = hsc->State; + if((tmp1 == HAL_SMARTCARD_STATE_READY) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_RX)) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsc); + + hsc->pTxBuffPtr = pData; + hsc->TxXferSize = Size; + hsc->TxXferCount = Size; + + hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + /* Check if a non-blocking receive process is ongoing or not */ + if(hsc->State == HAL_SMARTCARD_STATE_BUSY_RX) + { + hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; + } + else + { + hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; + } + + /* Set the SMARTCARD DMA transfer complete callback */ + hsc->hdmatx->XferCpltCallback = SMARTCARD_DMATransmitCplt; + + /* Set the DMA error callback */ + hsc->hdmatx->XferErrorCallback = SMARTCARD_DMAError; + + /* Enable the SMARTCARD transmit DMA Stream */ + tmp = (uint32_t*)&pData; + HAL_DMA_Start_IT(hsc->hdmatx, *(uint32_t*)tmp, (uint32_t)&hsc->Instance->DR, Size); + + /* Clear the TC flag in the SR register by writing 0 to it */ + __HAL_SMARTCARD_CLEAR_FLAG(hsc, SMARTCARD_FLAG_TC); + + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the SMARTCARD CR3 register */ + hsc->Instance->CR3 |= USART_CR3_DMAT; + + /* Process Unlocked */ + __HAL_UNLOCK(hsc); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in non blocking mode + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @param pData: pointer to data buffer + * @param Size: amount of data to be received + * @note When the SMARTCARD parity is enabled (PCE = 1) the data received contain the parity bit.s + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SMARTCARD_Receive_DMA(SMARTCARD_HandleTypeDef *hsc, uint8_t *pData, uint16_t Size) +{ + uint32_t *tmp; + uint32_t tmp1 = 0; + + tmp1 = hsc->State; + if((tmp1 == HAL_SMARTCARD_STATE_READY) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_TX)) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsc); + + hsc->pRxBuffPtr = pData; + hsc->RxXferSize = Size; + + hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; + /* Check if a non-blocking transmit process is ongoing or not */ + if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX) + { + hsc->State = HAL_SMARTCARD_STATE_BUSY_TX_RX; + } + else + { + hsc->State = HAL_SMARTCARD_STATE_BUSY_RX; + } + + /* Set the SMARTCARD DMA transfer complete callback */ + hsc->hdmarx->XferCpltCallback = SMARTCARD_DMAReceiveCplt; + + /* Set the DMA error callback */ + hsc->hdmarx->XferErrorCallback = SMARTCARD_DMAError; + + /* Enable the DMA Stream */ + tmp = (uint32_t*)&pData; + HAL_DMA_Start_IT(hsc->hdmarx, (uint32_t)&hsc->Instance->DR, *(uint32_t*)tmp, Size); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the SMARTCARD CR3 register */ + hsc->Instance->CR3 |= USART_CR3_DMAR; + + /* Process Unlocked */ + __HAL_UNLOCK(hsc); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief This function handles SMARTCARD interrupt request. + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @retval None + */ +void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc) +{ + uint32_t tmp1 = 0, tmp2 = 0; + + tmp1 = hsc->Instance->SR; + tmp2 = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_PE); + + /* SMARTCARD parity error interrupt occurred --------------------------------*/ + if(((tmp1 & SMARTCARD_FLAG_PE) != RESET) && (tmp2 != RESET)) + { + __HAL_SMARTCARD_CLEAR_PEFLAG(hsc); + hsc->ErrorCode |= HAL_SMARTCARD_ERROR_PE; + } + + tmp2 = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_ERR); + /* SMARTCARD frame error interrupt occurred ---------------------------------*/ + if(((tmp1 & SMARTCARD_FLAG_FE) != RESET) && (tmp2 != RESET)) + { + __HAL_SMARTCARD_CLEAR_FEFLAG(hsc); + hsc->ErrorCode |= HAL_SMARTCARD_ERROR_FE; + } + + tmp2 = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_ERR); + /* SMARTCARD noise error interrupt occurred ---------------------------------*/ + if(((tmp1 & SMARTCARD_FLAG_NE) != RESET) && (tmp2 != RESET)) + { + __HAL_SMARTCARD_CLEAR_NEFLAG(hsc); + hsc->ErrorCode |= HAL_SMARTCARD_ERROR_NE; + } + + tmp2 = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_ERR); + /* SMARTCARD Over-Run interrupt occurred ------------------------------------*/ + if(((tmp1 & SMARTCARD_FLAG_ORE) != RESET) && (tmp2 != RESET)) + { + __HAL_SMARTCARD_CLEAR_OREFLAG(hsc); + hsc->ErrorCode |= HAL_SMARTCARD_ERROR_ORE; + } + + tmp2 = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_RXNE); + /* SMARTCARD in mode Receiver ----------------------------------------------*/ + if(((tmp1 & SMARTCARD_FLAG_RXNE) != RESET) && (tmp2 != RESET)) + { + SMARTCARD_Receive_IT(hsc); + } + + tmp2 = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_TXE); + /* SMARTCARD in mode Transmitter -------------------------------------------*/ + if(((tmp1 & SMARTCARD_FLAG_TXE) != RESET) && (tmp2 != RESET)) + { + SMARTCARD_Transmit_IT(hsc); + } + + tmp2 = __HAL_SMARTCARD_GET_IT_SOURCE(hsc, SMARTCARD_IT_TC); + /* SMARTCARD in mode Transmitter (transmission end) ------------------------*/ + if(((tmp1 & SMARTCARD_FLAG_TC) != RESET) && (tmp2 != RESET)) + { + SMARTCARD_EndTransmit_IT(hsc); + } + + /* Call the Error call Back in case of Errors */ + if(hsc->ErrorCode != HAL_SMARTCARD_ERROR_NONE) + { + /* Set the SMARTCARD state ready to be able to start again the process */ + hsc->State= HAL_SMARTCARD_STATE_READY; + HAL_SMARTCARD_ErrorCallback(hsc); + } +} + +/** + * @brief Tx Transfer completed callbacks + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @retval None + */ + __weak void HAL_SMARTCARD_TxCpltCallback(SMARTCARD_HandleTypeDef *hsc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SMARTCARD_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callbacks + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @retval None + */ +__weak void HAL_SMARTCARD_RxCpltCallback(SMARTCARD_HandleTypeDef *hsc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SMARTCARD_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief SMARTCARD error callbacks + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @retval None + */ + __weak void HAL_SMARTCARD_ErrorCallback(SMARTCARD_HandleTypeDef *hsc) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SMARTCARD_ErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup SMARTCARD_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief SMARTCARD State and Errors functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the SmartCard. + (+) HAL_SMARTCARD_GetState() API can be helpful to check in run-time the state of the SmartCard peripheral. + (+) HAL_SMARTCARD_GetError() check in run-time errors that could be occurred during communication. +@endverbatim + * @{ + */ + +/** + * @brief return the SMARTCARD state + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @retval HAL state + */ +HAL_SMARTCARD_StateTypeDef HAL_SMARTCARD_GetState(SMARTCARD_HandleTypeDef *hsc) +{ + return hsc->State; +} + +/** + * @brief Return the SMARTCARD error code + * @param hsc : pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD. + * @retval SMARTCARD Error Code + */ +uint32_t HAL_SMARTCARD_GetError(SMARTCARD_HandleTypeDef *hsc) +{ + return hsc->ErrorCode; +} + +/** + * @} + */ + +/** + * @brief DMA SMARTCARD transmit process complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SMARTCARD_DMATransmitCplt(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + hsc->TxXferCount = 0; + + /* Disable the DMA transfer for transmit request by setting the DMAT bit + in the USART CR3 register */ + hsc->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAT); + + /* Enable the SMARTCARD Transmit Complete Interrupt */ + __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TC); +} + +/** + * @brief DMA SMARTCARD receive process complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SMARTCARD_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + hsc->RxXferCount = 0; + + /* Disable the DMA transfer for the receiver request by setting the DMAR bit + in the USART CR3 register */ + hsc->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAR); + + /* Check if a non-blocking transmit process is ongoing or not */ + if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) + { + hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; + } + else + { + hsc->State = HAL_SMARTCARD_STATE_READY; + } + + HAL_SMARTCARD_RxCpltCallback(hsc); +} + +/** + * @brief DMA SMARTCARD communication error callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SMARTCARD_DMAError(DMA_HandleTypeDef *hdma) +{ + SMARTCARD_HandleTypeDef* hsc = ( SMARTCARD_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + hsc->RxXferCount = 0; + hsc->TxXferCount = 0; + hsc->ErrorCode = HAL_SMARTCARD_ERROR_DMA; + hsc->State= HAL_SMARTCARD_STATE_READY; + + HAL_SMARTCARD_ErrorCallback(hsc); +} + +/** + * @brief This function handles SMARTCARD Communication Timeout. + * @param hsc: SMARTCARD handle + * @param Flag: specifies the SMARTCARD flag to check. + * @param Status: The new Flag status (SET or RESET). + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef SMARTCARD_WaitOnFlagUntilTimeout(SMARTCARD_HandleTypeDef *hsc, uint32_t Flag, FlagStatus Status, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until flag is set */ + if(Status == RESET) + { + while(__HAL_SMARTCARD_GET_FLAG(hsc, Flag) == RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Disable TXE and RXNE interrupts for the interrupt process */ + __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE); + __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_RXNE); + + hsc->State= HAL_SMARTCARD_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsc); + + return HAL_TIMEOUT; + } + } + } + } + else + { + while(__HAL_SMARTCARD_GET_FLAG(hsc, Flag) != RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Disable TXE and RXNE interrupts for the interrupt process */ + __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE); + __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_RXNE); + + hsc->State= HAL_SMARTCARD_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hsc); + + return HAL_TIMEOUT; + } + } + } + } + return HAL_OK; +} + +/** + * @brief Send an amount of data in non blocking mode + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @retval HAL status + */ +static HAL_StatusTypeDef SMARTCARD_Transmit_IT(SMARTCARD_HandleTypeDef *hsc) +{ + uint16_t* tmp; + uint32_t tmp1 = 0; + + tmp1 = hsc->State; + if((tmp1 == HAL_SMARTCARD_STATE_BUSY_TX) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_TX_RX)) + { + tmp = (uint16_t*) hsc->pTxBuffPtr; + hsc->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF); + hsc->pTxBuffPtr += 1; + + if(--hsc->TxXferCount == 0) + { + /* Disable the SMARTCARD Transmit data register empty Interrupt */ + __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_TXE); + + /* Enable the SMARTCARD Transmit Complete Interrupt */ + __HAL_SMARTCARD_ENABLE_IT(hsc, SMARTCARD_IT_TC); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Wraps up transmission in non blocking mode. + * @param hsmartcard: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for the specified SMARTCARD module. + * @retval HAL status + */ +static HAL_StatusTypeDef SMARTCARD_EndTransmit_IT(SMARTCARD_HandleTypeDef *hsmartcard) +{ + /* Disable the SMARTCARD Transmit Complete Interrupt */ + __HAL_SMARTCARD_DISABLE_IT(hsmartcard, SMARTCARD_IT_TC); + + /* Check if a receive process is ongoing or not */ + if(hsmartcard->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) + { + hsmartcard->State = HAL_SMARTCARD_STATE_BUSY_RX; + } + else + { + /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_SMARTCARD_DISABLE_IT(hsmartcard, SMARTCARD_IT_ERR); + + hsmartcard->State = HAL_SMARTCARD_STATE_READY; + } + + HAL_SMARTCARD_TxCpltCallback(hsmartcard); + + return HAL_OK; +} + +/** + * @brief Receive an amount of data in non blocking mode + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @retval HAL status + */ +static HAL_StatusTypeDef SMARTCARD_Receive_IT(SMARTCARD_HandleTypeDef *hsc) +{ + uint16_t* tmp; + uint32_t tmp1 = 0; + + tmp1 = hsc->State; + if((tmp1 == HAL_SMARTCARD_STATE_BUSY_RX) || (tmp1 == HAL_SMARTCARD_STATE_BUSY_TX_RX)) + { + tmp = (uint16_t*) hsc->pRxBuffPtr; + *tmp = (uint16_t)(hsc->Instance->DR & (uint16_t)0x00FF); + hsc->pRxBuffPtr += 1; + + if(--hsc->RxXferCount == 0) + { + __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_RXNE); + + /* Disable the SMARTCARD Parity Error Interrupt */ + __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_PE); + + /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_SMARTCARD_DISABLE_IT(hsc, SMARTCARD_IT_ERR); + + /* Check if a non-blocking transmit process is ongoing or not */ + if(hsc->State == HAL_SMARTCARD_STATE_BUSY_TX_RX) + { + hsc->State = HAL_SMARTCARD_STATE_BUSY_TX; + } + else + { + hsc->State = HAL_SMARTCARD_STATE_READY; + } + + HAL_SMARTCARD_RxCpltCallback(hsc); + + return HAL_OK; + } + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Configure the SMARTCARD peripheral + * @param hsc: pointer to a SMARTCARD_HandleTypeDef structure that contains + * the configuration information for SMARTCARD module. + * @retval None + */ +static void SMARTCARD_SetConfig(SMARTCARD_HandleTypeDef *hsc) +{ + uint32_t tmpreg = 0x00; + + /* Check the parameters */ + assert_param(IS_SMARTCARD_INSTANCE(hsc->Instance)); + assert_param(IS_SMARTCARD_POLARITY(hsc->Init.CLKPolarity)); + assert_param(IS_SMARTCARD_PHASE(hsc->Init.CLKPhase)); + assert_param(IS_SMARTCARD_LASTBIT(hsc->Init.CLKLastBit)); + assert_param(IS_SMARTCARD_BAUDRATE(hsc->Init.BaudRate)); + assert_param(IS_SMARTCARD_WORD_LENGTH(hsc->Init.WordLength)); + assert_param(IS_SMARTCARD_STOPBITS(hsc->Init.StopBits)); + assert_param(IS_SMARTCARD_PARITY(hsc->Init.Parity)); + assert_param(IS_SMARTCARD_MODE(hsc->Init.Mode)); + assert_param(IS_SMARTCARD_NACK_STATE(hsc->Init.NACKState)); + + /* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the + receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */ + hsc->Instance->CR1 &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE)); + + /*---------------------------- USART CR2 Configuration ---------------------*/ + tmpreg = hsc->Instance->CR2; + /* Clear CLKEN, CPOL, CPHA and LBCL bits */ + tmpreg &= (uint32_t)~((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_LBCL)); + /* Configure the SMARTCARD Clock, CPOL, CPHA and LastBit -----------------------*/ + /* Set CPOL bit according to hsc->Init.CLKPolarity value */ + /* Set CPHA bit according to hsc->Init.CLKPhase value */ + /* Set LBCL bit according to hsc->Init.CLKLastBit value */ + /* Set Stop Bits: Set STOP[13:12] bits according to hsc->Init.StopBits value */ + tmpreg |= (uint32_t)(USART_CR2_CLKEN | hsc->Init.CLKPolarity | + hsc->Init.CLKPhase| hsc->Init.CLKLastBit | hsc->Init.StopBits); + /* Write to USART CR2 */ + hsc->Instance->CR2 = (uint32_t)tmpreg; + + tmpreg = hsc->Instance->CR2; + + /* Clear STOP[13:12] bits */ + tmpreg &= (uint32_t)~((uint32_t)USART_CR2_STOP); + + /* Set Stop Bits: Set STOP[13:12] bits according to hsc->Init.StopBits value */ + tmpreg |= (uint32_t)(hsc->Init.StopBits); + + /* Write to USART CR2 */ + hsc->Instance->CR2 = (uint32_t)tmpreg; + + /*-------------------------- USART CR1 Configuration -----------------------*/ + tmpreg = hsc->Instance->CR1; + + /* Clear M, PCE, PS, TE and RE bits */ + tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \ + USART_CR1_RE)); + + /* Configure the SMARTCARD Word Length, Parity and mode: + Set the M bits according to hsc->Init.WordLength value + Set PCE and PS bits according to hsc->Init.Parity value + Set TE and RE bits according to hsc->Init.Mode value */ + tmpreg |= (uint32_t)hsc->Init.WordLength | hsc->Init.Parity | hsc->Init.Mode; + + /* Write to USART CR1 */ + hsc->Instance->CR1 = (uint32_t)tmpreg; + + /*-------------------------- USART CR3 Configuration -----------------------*/ + /* Clear CTSE and RTSE bits */ + hsc->Instance->CR3 &= (uint32_t)~((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE)); + + /*-------------------------- USART BRR Configuration -----------------------*/ + if((hsc->Instance == USART1) || (hsc->Instance == USART6)) + { + hsc->Instance->BRR = SMARTCARD_BRR(HAL_RCC_GetPCLK2Freq(), hsc->Init.BaudRate); + } + else + { + hsc->Instance->BRR = SMARTCARD_BRR(HAL_RCC_GetPCLK1Freq(), hsc->Init.BaudRate); + } +} + +/** + * @} + */ + +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spdifrx.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spdifrx.c new file mode 100644 index 0000000..63a4095 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spdifrx.c @@ -0,0 +1,1210 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_spdifrx.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief This file provides firmware functions to manage the following + * functionalities of the SPDIFRX audio interface: + * + Initialization and Configuration + * + Data transfers functions + * + DMA transfers management + * + Interrupts and flags management + @verbatim + =============================================================================== + ##### How to use this driver ##### + =============================================================================== + [..] + The SPDIFRX HAL driver can be used as follow: + + (#) Declare SPDIFRX_HandleTypeDef handle structure. + (#) Initialize the SPDIFRX low level resources by implement the HAL_SPDIFRX_MspInit() API: + (##) Enable the SPDIFRX interface clock. + (##) SPDIFRX pins configuration: + (+++) Enable the clock for the SPDIFRX GPIOs. + (+++) Configure these SPDIFRX pins as alternate function pull-up. + (##) NVIC configuration if you need to use interrupt process (HAL_SPDIFRX_ReceiveControlFlow_IT() and HAL_SPDIFRX_ReceiveDataFlow_IT() API's). + (+++) Configure the SPDIFRX interrupt priority. + (+++) Enable the NVIC SPDIFRX IRQ handle. + (##) DMA Configuration if you need to use DMA process (HAL_SPDIFRX_ReceiveDataFlow_DMA() and HAL_SPDIFRX_ReceiveControlFlow_DMA() API's). + (+++) Declare a DMA handle structure for the reception of the Data Flow channel. + (+++) Declare a DMA handle structure for the reception of the Control Flow channel. + (+++) Enable the DMAx interface clock. + (+++) Configure the declared DMA handle structure CtrlRx/DataRx with the required parameters. + (+++) Configure the DMA Channel. + (+++) Associate the initialized DMA handle to the SPDIFRX DMA CtrlRx/DataRx handle. + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the + DMA CtrlRx/DataRx channel. + + (#) Program the input selection, re-tries number, wait for activity, channel status selection, data format, stereo mode and masking of user bits + using HAL_SPDIFRX_Init() function. + + -@- The specific SPDIFRX interrupts (RXNE/CSRNE and Error Interrupts) will be managed using the macros + __SPDIFRX_ENABLE_IT() and __SPDIFRX_DISABLE_IT() inside the receive process. + -@- Make sure that ck_spdif clock is configured. + + (#) Three operation modes are available within this driver : + + *** Polling mode for reception operation (for debug purpose) *** + ================================================================ + [..] + (+) Receive data flow in blocking mode using HAL_SPDIFRX_ReceiveDataFlow() + (+) Receive control flow of data in blocking mode using HAL_SPDIFRX_ReceiveControlFlow() + + *** Interrupt mode for reception operation *** + ========================================= + [..] + (+) Receive an amount of data (Data Flow) in non blocking mode using HAL_SPDIFRX_ReceiveDataFlow_IT() + (+) Receive an amount of data (Control Flow) in non blocking mode using HAL_SPDIFRX_ReceiveControlFlow_IT() + (+) At reception end of half transfer HAL_SPDIFRX_RxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_SPDIFRX_RxHalfCpltCallback + (+) At reception end of transfer HAL_SPDIFRX_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_SPDIFRX_RxCpltCallback + (+) In case of transfer Error, HAL_SPDIFRX_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_SPDIFRX_ErrorCallback + + *** DMA mode for reception operation *** + ======================================== + [..] + (+) Receive an amount of data (Data Flow) in non blocking mode (DMA) using HAL_SPDIFRX_ReceiveDataFlow_DMA() + (+) Receive an amount of data (Control Flow) in non blocking mode (DMA) using HAL_SPDIFRX_ReceiveControlFlow_DMA() + (+) At reception end of half transfer HAL_SPDIFRX_RxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_SPDIFRX_RxHalfCpltCallback + (+) At reception end of transfer HAL_SPDIFRX_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_SPDIFRX_RxCpltCallback + (+) In case of transfer Error, HAL_SPDIFRX_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_SPDIFRX_ErrorCallback + (+) Stop the DMA Transfer using HAL_SPDIFRX_DMAStop() + + *** SPDIFRX HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in USART HAL driver. + (+) __HAL_SPDIFRX_IDLE: Disable the specified SPDIFRX peripheral (IDEL State) + (+) __HAL_SPDIFRX_SYNC: Enable the synchronization state of the specified SPDIFRX peripheral (SYNC State) + (+) __HAL_SPDIFRX_RCV: Enable the receive state of the specified SPDIFRX peripheral (RCV State) + (+) __HAL_SPDIFRX_ENABLE_IT : Enable the specified SPDIFRX interrupts + (+) __HAL_SPDIFRX_DISABLE_IT : Disable the specified SPDIFRX interrupts + (+) __HAL_SPDIFRX_GET_FLAG: Check whether the specified SPDIFRX flag is set or not. + + [..] + (@) You can refer to the SPDIFRX HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 SPDIFRX SPDIFRX + * @brief SPDIFRX HAL module driver + * @{ + */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + +#if defined(STM32F446xx) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define SPDIFRX_TIMEOUT_VALUE 0xFFFF + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup SPDIFRX_Private_Functions + * @{ + */ +static void SPDIFRX_DMARxCplt(DMA_HandleTypeDef *hdma); +static void SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef *hdma); +static void SPDIFRX_DMACxCplt(DMA_HandleTypeDef *hdma); +static void SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef *hdma); +static void SPDIFRX_DMAError(DMA_HandleTypeDef *hdma); +static void SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif); +static void SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif); +static HAL_StatusTypeDef SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef *hspdif, uint32_t Flag, FlagStatus Status, uint32_t Timeout); +/** + * @} + */ +/* Exported functions ---------------------------------------------------------*/ + +/** @defgroup SPDIFRX_Exported_Functions SPDIFRX Exported Functions + * @{ + */ + +/** @defgroup SPDIFRX_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * + @verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the SPDIFRX peripheral: + + (+) User must Implement HAL_SPDIFRX_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). + + (+) Call the function HAL_SPDIFRX_Init() to configure the SPDIFRX peripheral with + the selected configuration: + (++) Input Selection (IN0, IN1,...) + (++) Maximum allowed re-tries during synchronization phase + (++) Wait for activity on SPDIF selected input + (++) Channel status selection (from channel A or B) + (++) Data format (LSB, MSB, ...) + (++) Stereo mode + (++) User bits masking (PT,C,U,V,...) + + (+) Call the function HAL_SPDIFRX_DeInit() to restore the default configuration + of the selected SPDIFRXx peripheral. + @endverbatim + * @{ + */ + +/** + * @brief Initializes the SPDIFRX according to the specified parameters + * in the SPDIFRX_InitTypeDef and create the associated handle. + * @param hspdif: SPDIFRX handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPDIFRX_Init(SPDIFRX_HandleTypeDef *hspdif) +{ + uint32_t tmpreg = 0; + + /* Check the SPDIFRX handle allocation */ + if(hspdif == NULL) + { + return HAL_ERROR; + } + + /* Check the SPDIFRX parameters */ + assert_param(IS_STEREO_MODE(hspdif->Init.StereoMode)); + assert_param(IS_SPDIFRX_INPUT_SELECT(hspdif->Init.InputSelection)); + assert_param(IS_SPDIFRX_MAX_RETRIES(hspdif->Init.Retries)); + assert_param(IS_SPDIFRX_WAIT_FOR_ACTIVITY(hspdif->Init.WaitForActivity)); + assert_param(IS_SPDIFRX_CHANNEL(hspdif->Init.ChannelSelection)); + assert_param(IS_SPDIFRX_DATA_FORMAT(hspdif->Init.DataFormat)); + assert_param(IS_PREAMBLE_TYPE_MASK(hspdif->Init.PreambleTypeMask)); + assert_param(IS_CHANNEL_STATUS_MASK(hspdif->Init.ChannelStatusMask)); + assert_param(IS_VALIDITY_MASK(hspdif->Init.ValidityBitMask)); + assert_param(IS_PARITY_ERROR_MASK(hspdif->Init.ParityErrorMask)); + + if(hspdif->State == HAL_SPDIFRX_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hspdif->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ + HAL_SPDIFRX_MspInit(hspdif); + } + + /* SPDIFRX peripheral state is BUSY*/ + hspdif->State = HAL_SPDIFRX_STATE_BUSY; + + /* Disable SPDIFRX interface (IDLE State) */ + __HAL_SPDIFRX_IDLE(hspdif); + + /* Reset the old SPDIFRX CR configuration */ + tmpreg = hspdif->Instance->CR; + + tmpreg &= ~((uint16_t) SPDIFRX_CR_RXSTEO | SPDIFRX_CR_DRFMT | SPDIFRX_CR_PMSK | + SPDIFRX_CR_VMSK | SPDIFRX_CR_CUMSK | SPDIFRX_CR_PTMSK | + SPDIFRX_CR_CHSEL | SPDIFRX_CR_NBTR | SPDIFRX_CR_WFA | + SPDIFRX_CR_INSEL); + + /* Sets the new configuration of the SPDIFRX peripheral */ + tmpreg |= ((uint16_t) hspdif->Init.StereoMode | + hspdif->Init.InputSelection | + hspdif->Init.Retries | + hspdif->Init.WaitForActivity | + hspdif->Init.ChannelSelection | + hspdif->Init.DataFormat | + hspdif->Init.PreambleTypeMask | + hspdif->Init.ChannelStatusMask | + hspdif->Init.ValidityBitMask | + hspdif->Init.ParityErrorMask); + + hspdif->Instance->CR = tmpreg; + + hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE; + + /* SPDIFRX peripheral state is READY*/ + hspdif->State = HAL_SPDIFRX_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the SPDIFRX peripheral + * @param hspdif: SPDIFRX handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPDIFRX_DeInit(SPDIFRX_HandleTypeDef *hspdif) +{ + /* Check the SPDIFRX handle allocation */ + if(hspdif == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SPDIFRX_ALL_INSTANCE(hspdif->Instance)); + + hspdif->State = HAL_SPDIFRX_STATE_BUSY; + + /* Disable SPDIFRX interface (IDLE state) */ + __HAL_SPDIFRX_IDLE(hspdif); + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ + HAL_SPDIFRX_MspDeInit(hspdif); + + hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE; + + /* SPDIFRX peripheral state is RESET*/ + hspdif->State = HAL_SPDIFRX_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hspdif); + + return HAL_OK; +} + +/** + * @brief SPDIFRX MSP Init + * @param hspdif: SPDIFRX handle + * @retval None + */ +__weak void HAL_SPDIFRX_MspInit(SPDIFRX_HandleTypeDef *hspdif) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SPDIFRX_MspInit could be implemented in the user file + */ +} + +/** + * @brief SPDIFRX MSP DeInit + * @param hspdif: SPDIFRX handle + * @retval None + */ +__weak void HAL_SPDIFRX_MspDeInit(SPDIFRX_HandleTypeDef *hspdif) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SPDIFRX_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Sets the SPDIFRX dtat format according to the specified parameters + * in the SPDIFRX_InitTypeDef. + * @param hspdif: SPDIFRX handle + * @param sDataFormat: SPDIFRX data format + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPDIFRX_SetDataFormat(SPDIFRX_HandleTypeDef *hspdif, SPDIFRX_SetDataFormatTypeDef sDataFormat) +{ + uint32_t tmpreg = 0; + + /* Check the SPDIFRX handle allocation */ + if(hspdif == NULL) + { + return HAL_ERROR; + } + + /* Check the SPDIFRX parameters */ + assert_param(IS_STEREO_MODE(sDataFormat.StereoMode)); + assert_param(IS_SPDIFRX_DATA_FORMAT(sDataFormat.DataFormat)); + assert_param(IS_PREAMBLE_TYPE_MASK(sDataFormat.PreambleTypeMask)); + assert_param(IS_CHANNEL_STATUS_MASK(sDataFormat.ChannelStatusMask)); + assert_param(IS_VALIDITY_MASK(sDataFormat.ValidityBitMask)); + assert_param(IS_PARITY_ERROR_MASK(sDataFormat.ParityErrorMask)); + + /* Reset the old SPDIFRX CR configuration */ + tmpreg = hspdif->Instance->CR; + + if(((tmpreg & SPDIFRX_STATE_RCV) == SPDIFRX_STATE_RCV) && + (((tmpreg & SPDIFRX_CR_DRFMT) != sDataFormat.DataFormat) || + ((tmpreg & SPDIFRX_CR_RXSTEO) != sDataFormat.StereoMode))) + { + return HAL_ERROR; + } + + tmpreg &= ~((uint16_t) SPDIFRX_CR_RXSTEO | SPDIFRX_CR_DRFMT | SPDIFRX_CR_PMSK | + SPDIFRX_CR_VMSK | SPDIFRX_CR_CUMSK | SPDIFRX_CR_PTMSK); + + /* Sets the new configuration of the SPDIFRX peripheral */ + tmpreg |= ((uint16_t) sDataFormat.StereoMode | + sDataFormat.DataFormat | + sDataFormat.PreambleTypeMask | + sDataFormat.ChannelStatusMask | + sDataFormat.ValidityBitMask | + sDataFormat.ParityErrorMask); + + hspdif->Instance->CR = tmpreg; + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup SPDIFRX_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim +=============================================================================== +##### IO operation functions ##### +=============================================================================== + [..] + This subsection provides a set of functions allowing to manage the SPDIFRX data + transfers. + + (#) There is two mode of transfer: + (++) Blocking mode : The communication is performed in the polling mode. + The status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode : The communication is performed using Interrupts + or DMA. These functions return the status of the transfer start-up. + The end of the data processing will be indicated through the + dedicated SPDIFRX IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + + (#) Blocking mode functions are : + (++) HAL_SPDIFRX_ReceiveDataFlow() + (++) HAL_SPDIFRX_ReceiveControlFlow() + (+@) Do not use blocking mode to receive both control and data flow at the same time. + + (#) No-Blocking mode functions with Interrupt are : + (++) HAL_SPDIFRX_ReceiveControlFlow_IT() + (++) HAL_SPDIFRX_ReceiveDataFlow_IT() + + (#) No-Blocking mode functions with DMA are : + (++) HAL_SPDIFRX_ReceiveControlFlow_DMA() + (++) HAL_SPDIFRX_ReceiveDataFlow_DMA() + + (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode: + (++) HAL_SPDIFRX_RxCpltCallback() + (++) HAL_SPDIFRX_ErrorCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Receives an amount of data (Data Flow) in blocking mode. + * @param hspdif: pointer to SPDIFRX_HandleTypeDef structure that contains + * the configuration information for SPDIFRX module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be received + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size, uint32_t Timeout) +{ + + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + if(hspdif->State == HAL_SPDIFRX_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hspdif); + + hspdif->State = HAL_SPDIFRX_STATE_BUSY; + + /* Start synchronisation */ + __HAL_SPDIFRX_SYNC(hspdif); + + /* Wait until SYNCD flag is set */ + if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Start reception */ + __HAL_SPDIFRX_RCV(hspdif); + + /* Receive data flow */ + while(Size > 0) + { + /* Wait until RXNE flag is set */ + if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + (*pData++) = hspdif->Instance->DR; + Size--; + } + + /* SPDIFRX ready */ + hspdif->State = HAL_SPDIFRX_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hspdif); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receives an amount of data (Control Flow) in blocking mode. + * @param hspdif: pointer to a SPDIFRX_HandleTypeDef structure that contains + * the configuration information for SPDIFRX module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be received + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size, uint32_t Timeout) +{ + + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + if(hspdif->State == HAL_SPDIFRX_STATE_READY) + { + /* Process Locked */ + __HAL_LOCK(hspdif); + + hspdif->State = HAL_SPDIFRX_STATE_BUSY; + + /* Start synchronization */ + __HAL_SPDIFRX_SYNC(hspdif); + + /* Wait until SYNCD flag is set */ + if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Start reception */ + __HAL_SPDIFRX_RCV(hspdif); + + /* Receive control flow */ + while(Size > 0) + { + /* Wait until CSRNE flag is set */ + if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_CSRNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + (*pData++) = hspdif->Instance->CSR; + Size--; + } + + /* SPDIFRX ready */ + hspdif->State = HAL_SPDIFRX_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hspdif); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +/** + * @brief Receive an amount of data (Data Flow) in non-blocking mode with Interrupt + * @param hspdif: SPDIFRX handle + * @param pData: a 32-bit pointer to the Receive data buffer. + * @param Size: number of data sample to be received . + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size) +{ + if((hspdif->State == HAL_SPDIFRX_STATE_READY) || (hspdif->State == HAL_SPDIFRX_STATE_BUSY_CX)) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hspdif); + + hspdif->pRxBuffPtr = pData; + hspdif->RxXferSize = Size; + hspdif->RxXferCount = Size; + + hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE; + + /* Check if a receive process is ongoing or not */ + hspdif->State = HAL_SPDIFRX_STATE_BUSY_RX; + + + /* Enable the SPDIFRX PE Error Interrupt */ + __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_PERRIE); + + /* Enable the SPDIFRX OVR Error Interrupt */ + __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_OVRIE); + + /* Process Unlocked */ + __HAL_UNLOCK(hspdif); + + /* Enable the SPDIFRX RXNE interrupt */ + __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_RXNE); + + if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_SYNC || (SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != 0x00) + { + /* Start synchronization */ + __HAL_SPDIFRX_SYNC(hspdif); + + /* Wait until SYNCD flag is set */ + if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, SPDIFRX_TIMEOUT_VALUE) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Start reception */ + __HAL_SPDIFRX_RCV(hspdif); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data (Control Flow) with Interrupt + * @param hspdif: SPDIFRX handle + * @param pData: a 32-bit pointer to the Receive data buffer. + * @param Size: number of data sample (Control Flow) to be received : + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size) +{ + if((hspdif->State == HAL_SPDIFRX_STATE_READY) || (hspdif->State == HAL_SPDIFRX_STATE_BUSY_RX)) + { + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hspdif); + + hspdif->pCsBuffPtr = pData; + hspdif->CsXferSize = Size; + hspdif->CsXferCount = Size; + + hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE; + + /* Check if a receive process is ongoing or not */ + hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX; + + + /* Enable the SPDIFRX PE Error Interrupt */ + __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_PERRIE); + + /* Enable the SPDIFRX OVR Error Interrupt */ + __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_OVRIE); + + /* Process Unlocked */ + __HAL_UNLOCK(hspdif); + + /* Enable the SPDIFRX CSRNE interrupt */ + __HAL_SPDIFRX_ENABLE_IT(hspdif, SPDIFRX_IT_CSRNE); + + if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_SYNC || (SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != 0x00) + { + /* Start synchronization */ + __HAL_SPDIFRX_SYNC(hspdif); + + /* Wait until SYNCD flag is set */ + if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, SPDIFRX_TIMEOUT_VALUE) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Start reception */ + __HAL_SPDIFRX_RCV(hspdif); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data (Data Flow) mode with DMA + * @param hspdif: SPDIFRX handle + * @param pData: a 32-bit pointer to the Receive data buffer. + * @param Size: number of data sample to be received : + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPDIFRX_ReceiveDataFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size) +{ + + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + if((hspdif->State == HAL_SPDIFRX_STATE_READY) || (hspdif->State == HAL_SPDIFRX_STATE_BUSY_CX)) + { + hspdif->pRxBuffPtr = pData; + hspdif->RxXferSize = Size; + hspdif->RxXferCount = Size; + + /* Process Locked */ + __HAL_LOCK(hspdif); + + hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE; + hspdif->State = HAL_SPDIFRX_STATE_BUSY_RX; + + /* Set the SPDIFRX Rx DMA Half transfer complete callback */ + hspdif->hdmaDrRx->XferHalfCpltCallback = SPDIFRX_DMARxHalfCplt; + + /* Set the SPDIFRX Rx DMA transfer complete callback */ + hspdif->hdmaDrRx->XferCpltCallback = SPDIFRX_DMARxCplt; + + /* Set the DMA error callback */ + hspdif->hdmaDrRx->XferErrorCallback = SPDIFRX_DMAError; + + /* Enable the DMA request */ + HAL_DMA_Start_IT(hspdif->hdmaDrRx, (uint32_t)&hspdif->Instance->DR, (uint32_t)hspdif->pRxBuffPtr, Size); + + /* Enable RXDMAEN bit in SPDIFRX CR register for data flow reception*/ + hspdif->Instance->CR |= SPDIFRX_CR_RXDMAEN; + + if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_SYNC || (SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != 0x00) + { + /* Start synchronization */ + __HAL_SPDIFRX_SYNC(hspdif); + + /* Wait until SYNCD flag is set */ + if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, SPDIFRX_TIMEOUT_VALUE) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Start reception */ + __HAL_SPDIFRX_RCV(hspdif); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hspdif); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data (Control Flow) with DMA + * @param hspdif: SPDIFRX handle + * @param pData: a 32-bit pointer to the Receive data buffer. + * @param Size: number of data (Control Flow) sample to be received : + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPDIFRX_ReceiveControlFlow_DMA(SPDIFRX_HandleTypeDef *hspdif, uint32_t *pData, uint16_t Size) +{ + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + if((hspdif->State == HAL_SPDIFRX_STATE_READY) || (hspdif->State == HAL_SPDIFRX_STATE_BUSY_RX)) + { + hspdif->pCsBuffPtr = pData; + hspdif->CsXferSize = Size; + hspdif->CsXferCount = Size; + + /* Process Locked */ + __HAL_LOCK(hspdif); + + hspdif->ErrorCode = HAL_SPDIFRX_ERROR_NONE; + hspdif->State = HAL_SPDIFRX_STATE_BUSY_CX; + + /* Set the SPDIFRX Rx DMA Half transfer complete callback */ + hspdif->hdmaCsRx->XferHalfCpltCallback = SPDIFRX_DMACxHalfCplt; + + /* Set the SPDIFRX Rx DMA transfer complete callback */ + hspdif->hdmaCsRx->XferCpltCallback = SPDIFRX_DMACxCplt; + + /* Set the DMA error callback */ + hspdif->hdmaCsRx->XferErrorCallback = SPDIFRX_DMAError; + + /* Enable the DMA request */ + HAL_DMA_Start_IT(hspdif->hdmaCsRx, (uint32_t)&hspdif->Instance->CSR, (uint32_t)hspdif->pCsBuffPtr, Size); + + /* Enable CBDMAEN bit in SPDIFRX CR register for control flow reception*/ + hspdif->Instance->CR |= SPDIFRX_CR_CBDMAEN; + + if ((SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != SPDIFRX_STATE_SYNC || (SPDIFRX->CR & SPDIFRX_CR_SPDIFEN) != 0x00) + { + /* Start synchronization */ + __HAL_SPDIFRX_SYNC(hspdif); + + /* Wait until SYNCD flag is set */ + if(SPDIFRX_WaitOnFlagUntilTimeout(hspdif, SPDIFRX_FLAG_SYNCD, RESET, SPDIFRX_TIMEOUT_VALUE) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Start reception */ + __HAL_SPDIFRX_RCV(hspdif); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hspdif); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief stop the audio stream receive from the Media. + * @param hspdif: SPDIFRX handle + * @retval None + */ +HAL_StatusTypeDef HAL_SPDIFRX_DMAStop(SPDIFRX_HandleTypeDef *hspdif) +{ + /* Process Locked */ + __HAL_LOCK(hspdif); + + /* Disable the SPDIFRX DMA requests */ + hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN); + hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN); + + /* Disable the SPDIFRX DMA channel */ + __HAL_DMA_DISABLE(hspdif->hdmaDrRx); + __HAL_DMA_DISABLE(hspdif->hdmaCsRx); + + /* Disable SPDIFRX peripheral */ + __HAL_SPDIFRX_IDLE(hspdif); + + hspdif->State = HAL_SPDIFRX_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hspdif); + + return HAL_OK; +} + +/** + * @brief This function handles SPDIFRX interrupt request. + * @param hspdif: SPDIFRX handle + * @retval HAL status + */ +void HAL_SPDIFRX_IRQHandler(SPDIFRX_HandleTypeDef *hspdif) +{ + /* SPDIFRX in mode Data Flow Reception ------------------------------------------------*/ + if((__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_RXNE) != RESET) && (__HAL_SPDIFRX_GET_IT_SOURCE(hspdif, SPDIFRX_IT_RXNE) != RESET)) + { + __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_RXNE); + SPDIFRX_ReceiveDataFlow_IT(hspdif); + } + + /* SPDIFRX in mode Control Flow Reception ------------------------------------------------*/ + if((__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_CSRNE) != RESET) && (__HAL_SPDIFRX_GET_IT_SOURCE(hspdif, SPDIFRX_IT_CSRNE) != RESET)) + { + __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_IT_CSRNE); + SPDIFRX_ReceiveControlFlow_IT(hspdif); + } + + /* SPDIFRX Overrun error interrupt occurred ---------------------------------*/ + if((__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_OVR) != RESET) && (__HAL_SPDIFRX_GET_IT_SOURCE(hspdif, SPDIFRX_IT_OVRIE) != RESET)) + { + __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_FLAG_OVR); + + /* Change the SPDIFRX error code */ + hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_OVR; + + /* the transfer is not stopped */ + HAL_SPDIFRX_ErrorCallback(hspdif); + } + + /* SPDIFRX Parity error interrupt occurred ---------------------------------*/ + if((__HAL_SPDIFRX_GET_FLAG(hspdif, SPDIFRX_FLAG_PERR) != RESET) && (__HAL_SPDIFRX_GET_IT_SOURCE(hspdif, SPDIFRX_IT_PERRIE) != RESET)) + { + __HAL_SPDIFRX_CLEAR_IT(hspdif, SPDIFRX_FLAG_PERR); + + /* Change the SPDIFRX error code */ + hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_PE; + + /* the transfer is not stopped */ + HAL_SPDIFRX_ErrorCallback(hspdif); + } + +} + +/** + * @brief Rx Transfer (Data flow) half completed callbacks + * @param hspdif: SPDIFRX handle + * @retval None + */ +__weak void HAL_SPDIFRX_RxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer (Data flow) completed callbacks + * @param hspdif: SPDIFRX handle + * @retval None + */ +__weak void HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef *hspdif) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx (Control flow) Transfer half completed callbacks + * @param hspdif: SPDIFRX handle + * @retval None + */ +__weak void HAL_SPDIFRX_CxHalfCpltCallback(SPDIFRX_HandleTypeDef *hspdif) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer (Control flow) completed callbacks + * @param hspdif: SPDIFRX handle + * @retval None + */ +__weak void HAL_SPDIFRX_CxCpltCallback(SPDIFRX_HandleTypeDef *hspdif) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SPDIFRX_RxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief SPDIFRX error callbacks + * @param hspdif: SPDIFRX handle + * @retval None + */ +__weak void HAL_SPDIFRX_ErrorCallback(SPDIFRX_HandleTypeDef *hspdif) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SPDIFRX_ErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup SPDIFRX_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief Peripheral State functions + * +@verbatim +=============================================================================== +##### Peripheral State and Errors functions ##### +=============================================================================== +[..] +This subsection permit to get in run-time the status of the peripheral +and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the SPDIFRX state + * @param hspdif : SPDIFRX handle + * @retval HAL state + */ +HAL_SPDIFRX_StateTypeDef HAL_SPDIFRX_GetState(SPDIFRX_HandleTypeDef *hspdif) +{ + return hspdif->State; +} + +/** + * @brief Return the SPDIFRX error code + * @param hspdif : SPDIFRX handle + * @retval SPDIFRX Error Code + */ +uint32_t HAL_SPDIFRX_GetError(SPDIFRX_HandleTypeDef *hspdif) +{ + return hspdif->ErrorCode; +} + +/** + * @} + */ + +/** + * @brief DMA SPDIFRX receive process (Data flow) complete callback + * @param hdma : DMA handle + * @retval None + */ +static void SPDIFRX_DMARxCplt(DMA_HandleTypeDef *hdma) +{ + SPDIFRX_HandleTypeDef* hspdif = ( SPDIFRX_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Disable Rx DMA Request */ + hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_RXDMAEN); + hspdif->RxXferCount = 0; + + hspdif->State = HAL_SPDIFRX_STATE_READY; + HAL_SPDIFRX_RxCpltCallback(hspdif); +} + +/** + * @brief DMA SPDIFRX receive process (Data flow) half complete callback + * @param hdma : DMA handle + * @retval None + */ +static void SPDIFRX_DMARxHalfCplt(DMA_HandleTypeDef *hdma) +{ + SPDIFRX_HandleTypeDef* hspdif = (SPDIFRX_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + HAL_SPDIFRX_RxHalfCpltCallback(hspdif); +} + + +/** + * @brief DMA SPDIFRX receive process (Control flow) complete callback + * @param hdma : DMA handle + * @retval None + */ +static void SPDIFRX_DMACxCplt(DMA_HandleTypeDef *hdma) +{ + SPDIFRX_HandleTypeDef* hspdif = ( SPDIFRX_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Disable Cb DMA Request */ + hspdif->Instance->CR &= (uint16_t)(~SPDIFRX_CR_CBDMAEN); + hspdif->CsXferCount = 0; + + hspdif->State = HAL_SPDIFRX_STATE_READY; + HAL_SPDIFRX_CxCpltCallback(hspdif); +} + +/** + * @brief DMA SPDIFRX receive process (Control flow) half complete callback + * @param hdma : DMA handle + * @retval None + */ +static void SPDIFRX_DMACxHalfCplt(DMA_HandleTypeDef *hdma) +{ + SPDIFRX_HandleTypeDef* hspdif = (SPDIFRX_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + HAL_SPDIFRX_CxHalfCpltCallback(hspdif); +} + +/** + * @brief DMA SPDIFRX communication error callback + * @param hdma : DMA handle + * @retval None + */ +static void SPDIFRX_DMAError(DMA_HandleTypeDef *hdma) +{ + SPDIFRX_HandleTypeDef* hspdif = ( SPDIFRX_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Disable Rx and Cb DMA Request */ + hspdif->Instance->CR &= (uint16_t)(~(SPDIFRX_CR_RXDMAEN | SPDIFRX_CR_CBDMAEN)); + hspdif->RxXferCount = 0; + + hspdif->State= HAL_SPDIFRX_STATE_READY; + + /* Set the error code and execute error callback*/ + hspdif->ErrorCode |= HAL_SPDIFRX_ERROR_DMA; + HAL_SPDIFRX_ErrorCallback(hspdif); +} + + +/** + * @brief Receive an amount of data (Data Flow) with Interrupt + * @param hspdif: SPDIFRX handle + * @retval None + */ +static void SPDIFRX_ReceiveDataFlow_IT(SPDIFRX_HandleTypeDef *hspdif) +{ + /* Receive data */ + (*hspdif->pRxBuffPtr++) = hspdif->Instance->DR; + hspdif->RxXferCount--; + + if(hspdif->RxXferCount == 0) + { + /* Disable RXNE/PE and OVR interrupts */ + __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE | SPDIFRX_IT_PERRIE | SPDIFRX_IT_RXNE); + + hspdif->State = HAL_SPDIFRX_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hspdif); + + HAL_SPDIFRX_RxCpltCallback(hspdif); + } +} + +/** + * @brief Receive an amount of data (Control Flow) with Interrupt + * @param hspdif: SPDIFRX handle + * @retval None + */ +static void SPDIFRX_ReceiveControlFlow_IT(SPDIFRX_HandleTypeDef *hspdif) +{ + /* Receive data */ + (*hspdif->pCsBuffPtr++) = hspdif->Instance->CSR; + hspdif->CsXferCount--; + + if(hspdif->CsXferCount == 0) + { + /* Disable CSRNE interrupt */ + __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE); + + hspdif->State = HAL_SPDIFRX_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hspdif); + + HAL_SPDIFRX_CxCpltCallback(hspdif); + } +} + +/** + * @brief This function handles SPDIFRX Communication Timeout. + * @param hspdif: SPDIFRX handle + * @param Flag: Flag checked + * @param Status: Value of the flag expected + * @param Timeout: Duration of the timeout + * @retval HAL status + */ +static HAL_StatusTypeDef SPDIFRX_WaitOnFlagUntilTimeout(SPDIFRX_HandleTypeDef *hspdif, uint32_t Flag, FlagStatus Status, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until flag is set */ + if(Status == RESET) + { + while(__HAL_SPDIFRX_GET_FLAG(hspdif, Flag) == RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ + __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE); + __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE); + __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE); + __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE); + __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE); + __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE); + __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE); + + hspdif->State= HAL_SPDIFRX_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hspdif); + + return HAL_TIMEOUT; + } + } + } + } + else + { + while(__HAL_SPDIFRX_GET_FLAG(hspdif, Flag) != RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ + __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_RXNE); + __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_CSRNE); + __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_PERRIE); + __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_OVRIE); + __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SBLKIE); + __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_SYNCDIE); + __HAL_SPDIFRX_DISABLE_IT(hspdif, SPDIFRX_IT_IFEIE); + + hspdif->State= HAL_SPDIFRX_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hspdif); + + return HAL_TIMEOUT; + } + } + } + } + return HAL_OK; +} + +/** + * @} + */ +#endif /* STM32F446xx */ + +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c new file mode 100644 index 0000000..ff7d643 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c @@ -0,0 +1,2305 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_spi.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief SPI HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the Serial Peripheral Interface (SPI) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State functions + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The SPI HAL driver can be used as follows: + + (#) Declare a SPI_HandleTypeDef handle structure, for example: + SPI_HandleTypeDef hspi; + + (#)Initialize the SPI low level resources by implementing the HAL_SPI_MspInit ()API: + (##) Enable the SPIx interface clock + (##) SPI pins configuration + (+++) Enable the clock for the SPI GPIOs + (+++) Configure these SPI pins as alternate function push-pull + (##) NVIC configuration if you need to use interrupt process + (+++) Configure the SPIx interrupt priority + (+++) Enable the NVIC SPI IRQ handle + (##) DMA Configuration if you need to use DMA process + (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive stream + (+++) Enable the DMAx interface clock using + (+++) Configure the DMA handle parameters + (+++) Configure the DMA Tx or Rx Stream + (+++) Associate the initialized hdma_tx handle to the hspi DMA Tx or Rx handle + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx or Rx Stream + + (#) Program the Mode, Direction , Data size, Baudrate Prescaler, NSS + management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure. + + (#) Initialize the SPI registers by calling the HAL_SPI_Init() API: + (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) + by calling the customized HAL_SPI_MspInit() API. + [..] + Circular mode restriction: + (#) The DMA circular mode cannot be used when the SPI is configured in these modes: + (##) Master 2Lines RxOnly + (##) Master 1Line Rx + (#) The CRC feature is not managed when the DMA circular mode is enabled + (#) When the SPI DMA Pause/Stop features are used, we must use the following APIs + the HAL_SPI_DMAPause()/ HAL_SPI_DMAStop() only under the SPI callbacks + + + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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. + * + ****************************************************************************** + * + * Modifications by Robert Fisk + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup SPI SPI + * @brief SPI HAL module driver + * @{ + */ + +#ifdef HAL_SPI_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define SPI_TIMEOUT_VALUE 2 +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup SPI_Private_Functions + * @{ + */ +static void SPI_TxCloseIRQHandler(SPI_HandleTypeDef *hspi); +static void SPI_TxISR(SPI_HandleTypeDef *hspi); +static void SPI_RxCloseIRQHandler(SPI_HandleTypeDef *hspi); +static void SPI_2LinesRxISR(SPI_HandleTypeDef *hspi); +static void SPI_RxISR(SPI_HandleTypeDef *hspi); +static void SPI_DMAEndTransmitReceive(SPI_HandleTypeDef *hspi); +static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma); +static void SPI_DMAError(DMA_HandleTypeDef *hdma); +static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus Status, uint32_t Timeout); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SPI_Exported_Functions SPI Exported Functions + * @{ + */ + +/** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the SPIx peripheral: + + (+) User must implement HAL_SPI_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). + + (+) Call the function HAL_SPI_Init() to configure the selected device with + the selected configuration: + (++) Mode + (++) Direction + (++) Data Size + (++) Clock Polarity and Phase + (++) NSS Management + (++) BaudRate Prescaler + (++) FirstBit + (++) TIMode + (++) CRC Calculation + (++) CRC Polynomial if CRC enabled + + (+) Call the function HAL_SPI_DeInit() to restore the default configuration + of the selected SPIx peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the SPI according to the specified parameters + * in the SPI_InitTypeDef and create the associated handle. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi) +{ + /* Check the SPI handle allocation */ + if(hspi == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SPI_MODE(hspi->Init.Mode)); + assert_param(IS_SPI_DIRECTION_MODE(hspi->Init.Direction)); + assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize)); + assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity)); + assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase)); + assert_param(IS_SPI_NSS(hspi->Init.NSS)); + assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler)); + assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit)); + assert_param(IS_SPI_TIMODE(hspi->Init.TIMode)); + assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation)); + assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial)); + + if(hspi->State == HAL_SPI_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hspi->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + HAL_SPI_MspInit(hspi); + } + + hspi->State = HAL_SPI_STATE_BUSY; + + /* Disable the selected SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + + /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/ + /* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management, + Communication speed, First bit and CRC calculation state */ + hspi->Instance->CR1 = (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.DataSize | + hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) | + hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit | hspi->Init.CRCCalculation); + + /* Configure : NSS management */ + hspi->Instance->CR2 = (((hspi->Init.NSS >> 16) & SPI_CR2_SSOE) | hspi->Init.TIMode); + + /*---------------------------- SPIx CRCPOLY Configuration ------------------*/ + /* Configure : CRC Polynomial */ + hspi->Instance->CRCPR = hspi->Init.CRCPolynomial; + + /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */ + hspi->Instance->I2SCFGR &= (uint32_t)(~SPI_I2SCFGR_I2SMOD); + + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->State = HAL_SPI_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the SPI peripheral + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi) +{ + /* Check the SPI handle allocation */ + if(hspi == NULL) + { + return HAL_ERROR; + } + + /* Disable the SPI Peripheral Clock */ + __HAL_SPI_DISABLE(hspi); + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ + HAL_SPI_MspDeInit(hspi); + + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->State = HAL_SPI_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hspi); + + return HAL_OK; +} + +/** + * @brief SPI MSP Init + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ + __weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi) + { + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SPI_MspInit could be implemented in the user file + */ +} + +/** + * @brief SPI MSP DeInit + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ + __weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SPI_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup SPI_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + =============================================================================== + This subsection provides a set of functions allowing to manage the SPI + data transfers. + + [..] The SPI supports master and slave mode : + + (#) There are two modes of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode: The communication is performed using Interrupts + or DMA, These APIs return the HAL status. + The end of the data processing will be indicated through the + dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks + will be executed respectively at the end of the transmit or Receive process + The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected + + (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA) + exist for 1Line (simplex) and 2Lines (full duplex) modes. + +@endverbatim + * @{ + */ + +/** + * @brief Transmit an amount of data in blocking mode + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData: pointer to data buffer + * @param Size: amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + + if(hspi->State == HAL_SPI_STATE_READY) + { + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction)); + + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Configure communication */ + hspi->State = HAL_SPI_STATE_BUSY_TX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + + hspi->pTxBuffPtr = pData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + + /*Init field not used in handle to zero */ + hspi->TxISR = 0; + hspi->RxISR = 0; + hspi->RxXferSize = 0; + hspi->RxXferCount = 0; + + /* Reset CRC Calculation */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } + + if(hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + /* Configure communication direction : 1Line */ + SPI_1LINE_TX(hspi); + } + + /* Check if the SPI is already enabled */ + if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + /* Transmit data in 8 Bit mode */ + if(hspi->Init.DataSize == SPI_DATASIZE_8BIT) + { + if((hspi->Init.Mode == SPI_MODE_SLAVE)|| (hspi->TxXferCount == 0x01)) + { + hspi->Instance->DR = (*hspi->pTxBuffPtr++); + hspi->TxXferCount--; + } + while(hspi->TxXferCount > 0) + { + /* Wait until TXE flag is set to send data */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + hspi->Instance->DR = (*hspi->pTxBuffPtr++); + hspi->TxXferCount--; + } + /* Enable CRC Transmission */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + hspi->Instance->CR1 |= SPI_CR1_CRCNEXT; + } + } + /* Transmit data in 16 Bit mode */ + else + { + if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01)) + { + hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr); + hspi->pTxBuffPtr+=2; + hspi->TxXferCount--; + } + while(hspi->TxXferCount > 0) + { + /* Wait until TXE flag is set to send data */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr); + hspi->pTxBuffPtr+=2; + hspi->TxXferCount--; + } + /* Enable CRC Transmission */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + hspi->Instance->CR1 |= SPI_CR1_CRCNEXT; + } + } + + /* Wait until TXE flag is set to send data */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + hspi->ErrorCode |= HAL_SPI_ERROR_FLAG; + return HAL_TIMEOUT; + } + + /* Wait until Busy flag is reset before disabling SPI */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, Timeout) != HAL_OK) + { + hspi->ErrorCode |= HAL_SPI_ERROR_FLAG; + return HAL_TIMEOUT; + } + + /* Clear OVERRUN flag in 2 Lines communication mode because received is not read */ + if(hspi->Init.Direction == SPI_DIRECTION_2LINES) + { + __HAL_SPI_CLEAR_OVRFLAG(hspi); + } + + hspi->State = HAL_SPI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in blocking mode + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData: pointer to data buffer + * @param Size: amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + __IO uint16_t tmpreg; + uint32_t tmp = 0; + + if(hspi->State == HAL_SPI_STATE_READY) + { + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Configure communication */ + hspi->State = HAL_SPI_STATE_BUSY_RX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + + hspi->pRxBuffPtr = pData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + /*Init field not used in handle to zero */ + hspi->RxISR = 0; + hspi->TxISR = 0; + hspi->TxXferSize = 0; + hspi->TxXferCount = 0; + + /* Configure communication direction : 1Line */ + if(hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + SPI_1LINE_RX(hspi); + } + + /* Reset CRC Calculation */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } + + if((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES)) + { + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */ + return HAL_SPI_TransmitReceive(hspi, pData, pData, Size, Timeout); + } + + /* Check if the SPI is already enabled */ + if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + /* Receive data in 8 Bit mode */ + if(hspi->Init.DataSize == SPI_DATASIZE_8BIT) + { + while(hspi->RxXferCount > 1) + { + /* Wait until RXNE flag is set */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + (*hspi->pRxBuffPtr++) = hspi->Instance->DR; + hspi->RxXferCount--; + } + /* Enable CRC Transmission */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + hspi->Instance->CR1 |= SPI_CR1_CRCNEXT; + } + } + /* Receive data in 16 Bit mode */ + else + { + while(hspi->RxXferCount > 1) + { + /* Wait until RXNE flag is set to read data */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR; + hspi->pRxBuffPtr+=2; + hspi->RxXferCount--; + } + /* Enable CRC Transmission */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + hspi->Instance->CR1 |= SPI_CR1_CRCNEXT; + } + } + + /* Wait until RXNE flag is set */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Receive last data in 8 Bit mode */ + if(hspi->Init.DataSize == SPI_DATASIZE_8BIT) + { + (*hspi->pRxBuffPtr++) = hspi->Instance->DR; + } + /* Receive last data in 16 Bit mode */ + else + { + *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR; + hspi->pRxBuffPtr+=2; + } + hspi->RxXferCount--; + + /* Wait until RXNE flag is set: CRC Received */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + hspi->ErrorCode |= HAL_SPI_ERROR_CRC; + return HAL_TIMEOUT; + } + + /* Read CRC to Flush RXNE flag */ + tmpreg = hspi->Instance->DR; + UNUSED(tmpreg); + } + + if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) + { + /* Disable SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + } + + hspi->State = HAL_SPI_STATE_READY; + + tmp = __HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR); + /* Check if CRC error occurred */ + if((hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) && (tmp != RESET)) + { + hspi->ErrorCode |= HAL_SPI_ERROR_CRC; + + /* Reset CRC Calculation */ + SPI_RESET_CRC(hspi); + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + return HAL_ERROR; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit and Receive an amount of data in blocking mode + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pTxData: pointer to transmission data buffer + * @param pRxData: pointer to reception data buffer to be + * @param Size: amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout) +{ + __IO uint16_t tmpreg; + uint32_t tmpstate = 0, tmp = 0; + + tmpstate = hspi->State; + if((tmpstate == HAL_SPI_STATE_READY) || (tmpstate == HAL_SPI_STATE_BUSY_RX)) + { + if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); + + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */ + if(hspi->State == HAL_SPI_STATE_READY) + { + hspi->State = HAL_SPI_STATE_BUSY_TX_RX; + } + + /* Configure communication */ + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + + hspi->pRxBuffPtr = pRxData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + hspi->pTxBuffPtr = pTxData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + + /*Init field not used in handle to zero */ + hspi->RxISR = 0; + hspi->TxISR = 0; + + /* Reset CRC Calculation */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } + + /* Check if the SPI is already enabled */ + if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + /* Transmit and Receive data in 16 Bit mode */ + if(hspi->Init.DataSize == SPI_DATASIZE_16BIT) + { + if((hspi->Init.Mode == SPI_MODE_SLAVE) || ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->TxXferCount == 0x01))) + { + hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr); + hspi->pTxBuffPtr+=2; + hspi->TxXferCount--; + } + if(hspi->TxXferCount == 0) + { + /* Enable CRC Transmission */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + hspi->Instance->CR1 |= SPI_CR1_CRCNEXT; + } + + /* Wait until RXNE flag is set */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR; + hspi->pRxBuffPtr+=2; + hspi->RxXferCount--; + } + else + { + while(hspi->TxXferCount > 0) + { + /* Wait until TXE flag is set to send data */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr); + hspi->pTxBuffPtr+=2; + hspi->TxXferCount--; + + /* Enable CRC Transmission */ + if((hspi->TxXferCount == 0) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) + { + hspi->Instance->CR1 |= SPI_CR1_CRCNEXT; + } + + /* Wait until RXNE flag is set */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR; + hspi->pRxBuffPtr+=2; + hspi->RxXferCount--; + } + /* Receive the last byte */ + if(hspi->Init.Mode == SPI_MODE_SLAVE) + { + /* Wait until RXNE flag is set */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR; + hspi->pRxBuffPtr+=2; + hspi->RxXferCount--; + } + } + } + /* Transmit and Receive data in 8 Bit mode */ + else + { + if((hspi->Init.Mode == SPI_MODE_SLAVE) || ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->TxXferCount == 0x01))) + { + hspi->Instance->DR = (*hspi->pTxBuffPtr++); + hspi->TxXferCount--; + } + if(hspi->TxXferCount == 0) + { + /* Enable CRC Transmission */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + hspi->Instance->CR1 |= SPI_CR1_CRCNEXT; + } + + /* Wait until RXNE flag is set */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + (*hspi->pRxBuffPtr) = hspi->Instance->DR; + hspi->RxXferCount--; + } + else + { + while(hspi->TxXferCount > 0) + { + /* Wait until TXE flag is set to send data */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + hspi->Instance->DR = (*hspi->pTxBuffPtr++); + hspi->TxXferCount--; + + /* Enable CRC Transmission */ + if((hspi->TxXferCount == 0) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) + { + hspi->Instance->CR1 |= SPI_CR1_CRCNEXT; + } + + /* Wait until RXNE flag is set */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + (*hspi->pRxBuffPtr++) = hspi->Instance->DR; + hspi->RxXferCount--; + } + if(hspi->Init.Mode == SPI_MODE_SLAVE) + { + /* Wait until RXNE flag is set */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + (*hspi->pRxBuffPtr++) = hspi->Instance->DR; + hspi->RxXferCount--; + } + } + } + + /* Read CRC from DR to close CRC calculation process */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + /* Wait until RXNE flag is set */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + hspi->ErrorCode |= HAL_SPI_ERROR_CRC; + return HAL_TIMEOUT; + } + /* Read CRC */ + tmpreg = hspi->Instance->DR; + UNUSED(tmpreg); + } + + /* Wait until Busy flag is reset before disabling SPI */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, Timeout) != HAL_OK) + { + hspi->ErrorCode |= HAL_SPI_ERROR_FLAG; + return HAL_TIMEOUT; + } + + hspi->State = HAL_SPI_STATE_READY; + + tmp = __HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR); + /* Check if CRC error occurred */ + if((hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) && (tmp != RESET)) + { + hspi->ErrorCode |= HAL_SPI_ERROR_CRC; + + /* Reset CRC Calculation */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + return HAL_ERROR; + } + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit an amount of data in no-blocking mode with Interrupt + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData: pointer to data buffer + * @param Size: amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) +{ + if(hspi->State == HAL_SPI_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction)); + + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Configure communication */ + hspi->State = HAL_SPI_STATE_BUSY_TX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + + hspi->TxISR = &SPI_TxISR; + hspi->pTxBuffPtr = pData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + + /*Init field not used in handle to zero */ + hspi->RxISR = 0; + hspi->RxXferSize = 0; + hspi->RxXferCount = 0; + + /* Configure communication direction : 1Line */ + if(hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + SPI_1LINE_TX(hspi); + } + + /* Reset CRC Calculation */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } + + if (hspi->Init.Direction == SPI_DIRECTION_2LINES) + { + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE)); + }else + { + /* Enable TXE and ERR interrupt */ + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR)); + } + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + /* Check if the SPI is already enabled */ + if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in no-blocking mode with Interrupt + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData: pointer to data buffer + * @param Size: amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) +{ + if(hspi->State == HAL_SPI_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Configure communication */ + hspi->State = HAL_SPI_STATE_BUSY_RX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + + hspi->RxISR = &SPI_RxISR; + hspi->pRxBuffPtr = pData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size ; + + /*Init field not used in handle to zero */ + hspi->TxISR = 0; + hspi->TxXferSize = 0; + hspi->TxXferCount = 0; + + /* Configure communication direction : 1Line */ + if(hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + SPI_1LINE_RX(hspi); + } + else if((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER)) + { + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */ + return HAL_SPI_TransmitReceive_IT(hspi, pData, pData, Size); + } + + /* Reset CRC Calculation */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } + + /* Enable TXE and ERR interrupt */ + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + /* Note : The SPI must be enabled after unlocking current process + to avoid the risk of SPI interrupt handle execution before current + process unlock */ + + /* Check if the SPI is already enabled */ + if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit and Receive an amount of data in no-blocking mode with Interrupt + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pTxData: pointer to transmission data buffer + * @param pRxData: pointer to reception data buffer to be + * @param Size: amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size) +{ + uint32_t tmpstate = 0; + + tmpstate = hspi->State; + if((tmpstate == HAL_SPI_STATE_READY) || \ + ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmpstate == HAL_SPI_STATE_BUSY_RX))) + { + if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); + + /* Process locked */ + __HAL_LOCK(hspi); + + /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */ + if(hspi->State != HAL_SPI_STATE_BUSY_RX) + { + hspi->State = HAL_SPI_STATE_BUSY_TX_RX; + } + + /* Configure communication */ + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + + hspi->TxISR = &SPI_TxISR; + hspi->pTxBuffPtr = pTxData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + + hspi->RxISR = &SPI_2LinesRxISR; + hspi->pRxBuffPtr = pRxData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + /* Reset CRC Calculation */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } + + /* Enable TXE, RXNE and ERR interrupt */ + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR)); + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + /* Check if the SPI is already enabled */ + if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit an amount of data in no-blocking mode with DMA + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData: pointer to data buffer + * @param Size: amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) +{ + if(hspi->State == HAL_SPI_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction)); + + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Configure communication */ + hspi->State = HAL_SPI_STATE_BUSY_TX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + + hspi->pTxBuffPtr = pData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + + /*Init field not used in handle to zero */ + hspi->TxISR = 0; + hspi->RxISR = 0; + hspi->RxXferSize = 0; + hspi->RxXferCount = 0; + + /* Configure communication direction : 1Line */ + if(hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + SPI_1LINE_TX(hspi); + } + + /* Reset CRC Calculation */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } + + /* Set the SPI TxDMA Half transfer complete callback */ + hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt; + + /* Set the SPI TxDMA transfer complete callback */ + hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt; + + /* Set the DMA error callback */ + hspi->hdmatx->XferErrorCallback = SPI_DMAError; + + /* Enable the Tx DMA Stream */ + HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount); + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + /* Check if the SPI is already enabled */ + if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + /* Enable Tx DMA Request */ + hspi->Instance->CR2 |= SPI_CR2_TXDMAEN; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive an amount of data in no-blocking mode with DMA + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pData: pointer to data buffer + * @note When the CRC feature is enabled the pData Length must be Size + 1. + * @param Size: amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) +{ + if(hspi->State == HAL_SPI_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Configure communication */ + hspi->State = HAL_SPI_STATE_BUSY_RX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + + hspi->pRxBuffPtr = pData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + /*Init field not used in handle to zero */ + hspi->RxISR = 0; + hspi->TxISR = 0; + hspi->TxXferSize = 0; + hspi->TxXferCount = 0; + + /* Configure communication direction : 1Line */ + if(hspi->Init.Direction == SPI_DIRECTION_1LINE) + { + SPI_1LINE_RX(hspi); + } + else if((hspi->Init.Direction == SPI_DIRECTION_2LINES)&&(hspi->Init.Mode == SPI_MODE_MASTER)) + { + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */ + return HAL_SPI_TransmitReceive_DMA(hspi, pData, pData, Size); + } + + /* Reset CRC Calculation */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } + + /* Set the SPI RxDMA Half transfer complete callback */ + hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt; + + /* Set the SPI Rx DMA transfer complete callback */ + hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt; + + /* Set the DMA error callback */ + hspi->hdmarx->XferErrorCallback = SPI_DMAError; + + /* Enable the Rx DMA Stream */ + HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount); + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + /* Check if the SPI is already enabled */ + if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + /* Enable Rx DMA Request */ + hspi->Instance->CR2 |= SPI_CR2_RXDMAEN; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit and Receive an amount of data in no-blocking mode with DMA + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param pTxData: pointer to transmission data buffer + * @param pRxData: pointer to reception data buffer + * @note When the CRC feature is enabled the pRxData Length must be Size + 1 + * @param Size: amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size) +{ + uint32_t tmpstate = 0; + tmpstate = hspi->State; + if((tmpstate == HAL_SPI_STATE_READY) || ((hspi->Init.Mode == SPI_MODE_MASTER) && \ + (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmpstate == HAL_SPI_STATE_BUSY_RX))) + { + if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); + + /* Process locked */ + __HAL_LOCK(hspi); + + /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */ + if(hspi->State != HAL_SPI_STATE_BUSY_RX) + { + hspi->State = HAL_SPI_STATE_BUSY_TX_RX; + } + + /* Configure communication */ + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + + hspi->pTxBuffPtr = (uint8_t*)pTxData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + + hspi->pRxBuffPtr = (uint8_t*)pRxData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + /*Init field not used in handle to zero */ + hspi->RxISR = 0; + hspi->TxISR = 0; + + /* Reset CRC Calculation */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } + + /* Check if we are in Rx only or in Rx/Tx Mode and configure the DMA transfer complete callback */ + if(hspi->State == HAL_SPI_STATE_BUSY_RX) + { + /* Set the SPI Rx DMA Half transfer complete callback */ + hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt; + + hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt; + } + else + { + /* Set the SPI Tx/Rx DMA Half transfer complete callback */ + hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt; + + hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt; + } + + /* Set the DMA error callback */ + hspi->hdmarx->XferErrorCallback = SPI_DMAError; + + /* Enable the Rx DMA Stream */ + HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount); + + /* Enable Rx DMA Request */ + hspi->Instance->CR2 |= SPI_CR2_RXDMAEN; + + /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing + is performed in DMA reception complete callback */ + hspi->hdmatx->XferCpltCallback = NULL; + + if(hspi->State == HAL_SPI_STATE_BUSY_TX_RX) + { + /* Set the DMA error callback */ + hspi->hdmatx->XferErrorCallback = SPI_DMAError; + } + else + { + hspi->hdmatx->XferErrorCallback = NULL; + } + + /* Enable the Tx DMA Stream */ + HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount); + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + /* Check if the SPI is already enabled */ + if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE) + { + /* Enable SPI peripheral */ + __HAL_SPI_ENABLE(hspi); + } + + /* Enable Tx DMA Request */ + hspi->Instance->CR2 |= SPI_CR2_TXDMAEN; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Pauses the DMA Transfer. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for the specified SPI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi) +{ + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Disable the SPI DMA Tx & Rx requests */ + hspi->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN); + hspi->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN); + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + return HAL_OK; +} + +/** + * @brief Resumes the DMA Transfer. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for the specified SPI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi) +{ + /* Process Locked */ + __HAL_LOCK(hspi); + + /* Enable the SPI DMA Tx & Rx requests */ + hspi->Instance->CR2 |= SPI_CR2_TXDMAEN; + hspi->Instance->CR2 |= SPI_CR2_RXDMAEN; + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + return HAL_OK; +} + +/** + * @brief Stops the DMA Transfer. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for the specified SPI module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi) +{ + /* The Lock is not implemented on this API to allow the user application + to call the HAL SPI API under callbacks HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback(): + when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated + and the correspond call back is executed HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback() + */ + + /* Abort the SPI DMA tx Stream */ + if(hspi->hdmatx != NULL) + { + HAL_DMA_Abort(hspi->hdmatx); + } + /* Abort the SPI DMA rx Stream */ + if(hspi->hdmarx != NULL) + { + HAL_DMA_Abort(hspi->hdmarx); + } + + /* Disable the SPI DMA Tx & Rx requests */ + hspi->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN); + hspi->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN); + + hspi->State = HAL_SPI_STATE_READY; + + return HAL_OK; +} + +/** + * @brief This function handles SPI interrupt request. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval HAL status + */ +void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi) +{ + uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0; + + tmp1 = __HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE); + tmp2 = __HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_RXNE); + tmp3 = __HAL_SPI_GET_FLAG(hspi, SPI_FLAG_OVR); + /* SPI in mode Receiver and Overrun not occurred ---------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET) && (tmp3 == RESET)) + { + hspi->RxISR(hspi); + //return; + } + + tmp1 = __HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE); + tmp2 = __HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_TXE); + /* SPI in mode Transmitter ---------------------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + hspi->TxISR(hspi); + return; + } + + if(__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_ERR) != RESET) + { + /* SPI CRC error interrupt occurred ---------------------------------------*/ + if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET) + { + hspi->ErrorCode |= HAL_SPI_ERROR_CRC; + __HAL_SPI_CLEAR_CRCERRFLAG(hspi); + } + /* SPI Mode Fault error interrupt occurred --------------------------------*/ + if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_MODF) != RESET) + { + hspi->ErrorCode |= HAL_SPI_ERROR_MODF; + __HAL_SPI_CLEAR_MODFFLAG(hspi); + } + + /* SPI Overrun error interrupt occurred -----------------------------------*/ + if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_OVR) != RESET) + { + if(hspi->State != HAL_SPI_STATE_BUSY_TX) + { + hspi->ErrorCode |= HAL_SPI_ERROR_OVR; + __HAL_SPI_CLEAR_OVRFLAG(hspi); + } + } + + /* SPI Frame error interrupt occurred -------------------------------------*/ + if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_FRE) != RESET) + { + hspi->ErrorCode |= HAL_SPI_ERROR_FRE; + __HAL_SPI_CLEAR_FREFLAG(hspi); + } + + /* Call the Error call Back in case of Errors */ + if(hspi->ErrorCode!=HAL_SPI_ERROR_NONE) + { + hspi->State = HAL_SPI_STATE_READY; + HAL_SPI_ErrorCallback(hspi); + } + } +} + +/** + * @brief Tx Transfer completed callbacks + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SPI_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callbacks + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SPI_RxCpltCallback() could be implemented in the user file + */ +} + +/** + * @brief Tx and Rx Transfer completed callbacks + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SPI_TxRxCpltCallback() could be implemented in the user file + */ +} + +/** + * @brief Tx Half Transfer completed callbacks + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SPI_TxHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Half Transfer completed callbacks + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SPI_RxHalfCpltCallback() could be implemented in the user file + */ +} + +/** + * @brief Tx and Rx Transfer completed callbacks + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +__weak void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SPI_TxRxHalfCpltCallback() could be implemented in the user file + */ +} + +/** + * @brief SPI error callbacks + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ + __weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) +{ + /* NOTE : - This function Should not be modified, when the callback is needed, + the HAL_SPI_ErrorCallback() could be implemented in the user file. + - The ErrorCode parameter in the hspi handle is updated by the SPI processes + and user can use HAL_SPI_GetError() API to check the latest error occurred. + */ +} + +/** + * @} + */ + +/** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief SPI control functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the SPI. + (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI peripheral + (+) HAL_SPI_GetError() check in run-time Errors occurring during communication +@endverbatim + * @{ + */ + +/** + * @brief Return the SPI state + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval HAL state + */ +HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi) +{ + return hspi->State; +} + +/** + * @brief Return the SPI error code + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval SPI Error Code + */ +uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi) +{ + return hspi->ErrorCode; +} + +/** + * @} + */ + + /** + * @brief Interrupt Handler to close Tx transfer + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval void + */ +static void SPI_TxCloseIRQHandler(SPI_HandleTypeDef *hspi) +{ +// /* Wait until TXE flag is set to send data */ +// if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK) +// { +// hspi->ErrorCode |= HAL_SPI_ERROR_FLAG; +// } + + /* Disable TXE interrupt */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE )); + + /* Disable ERR interrupt if Receive process is finished */ + if(__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_RXNE) == RESET) + { + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_ERR)); + + /* Wait until Busy flag is reset before disabling SPI */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, SPI_TIMEOUT_VALUE) != HAL_OK) + { + hspi->ErrorCode |= HAL_SPI_ERROR_FLAG; + } + + /* Clear OVERRUN flag in 2 Lines communication mode because received is not read */ + if(hspi->Init.Direction == SPI_DIRECTION_2LINES) + { + __HAL_SPI_CLEAR_OVRFLAG(hspi); + } + + /* Check if Errors has been detected during transfer */ + if(hspi->ErrorCode == HAL_SPI_ERROR_NONE) + { + /* Check if we are in Tx or in Rx/Tx Mode */ + if(hspi->State == HAL_SPI_STATE_BUSY_TX_RX) + { + /* Set state to READY before run the Callback Complete */ + hspi->State = HAL_SPI_STATE_READY; + HAL_SPI_TxRxCpltCallback(hspi); + } + else + { + /* Set state to READY before run the Callback Complete */ + hspi->State = HAL_SPI_STATE_READY; + HAL_SPI_TxCpltCallback(hspi); + } + } + else + { + /* Set state to READY before run the Callback Complete */ + hspi->State = HAL_SPI_STATE_READY; + /* Call Error call back in case of Error */ + HAL_SPI_ErrorCallback(hspi); + } + } +} + +/** + * @brief Interrupt Handler to transmit amount of data in no-blocking mode + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval void + */ +static void SPI_TxISR(SPI_HandleTypeDef *hspi) +{ + /* Transmit data in 8 Bit mode */ + if(hspi->Init.DataSize == SPI_DATASIZE_8BIT) + { + hspi->Instance->DR = (*hspi->pTxBuffPtr++); + } + /* Transmit data in 16 Bit mode */ + else + { + hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr); + hspi->pTxBuffPtr+=2; + } + hspi->TxXferCount--; + + if(hspi->TxXferCount == 0) + { + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + /* calculate and transfer CRC on Tx line */ + hspi->Instance->CR1 |= SPI_CR1_CRCNEXT; + } + SPI_TxCloseIRQHandler(hspi); + } +} + +/** + * @brief Interrupt Handler to close Rx transfer + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval void + */ +static void SPI_RxCloseIRQHandler(SPI_HandleTypeDef *hspi) +{ + __IO uint16_t tmpreg; + + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + /* Wait until RXNE flag is set to send data */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK) + { + hspi->ErrorCode |= HAL_SPI_ERROR_FLAG; + } + + /* Read CRC to reset RXNE flag */ + tmpreg = hspi->Instance->DR; + UNUSED(tmpreg); + + /* Wait until RXNE flag is set to send data */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_TIMEOUT_VALUE) != HAL_OK) + { + hspi->ErrorCode |= HAL_SPI_ERROR_FLAG; + } + + /* Check if CRC error occurred */ + if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET) + { + hspi->ErrorCode |= HAL_SPI_ERROR_CRC; + + /* Reset CRC Calculation */ + SPI_RESET_CRC(hspi); + } + } + + /* Disable RXNE and ERR interrupt */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE)); + + /* if Transmit process is finished */ + if(__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_TXE) == RESET) + { + /* Disable ERR interrupt */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_ERR)); + + if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) + { + /* Disable SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + } + + /* Check if Errors has been detected during transfer */ + if(hspi->ErrorCode == HAL_SPI_ERROR_NONE) + { + /* Check if we are in Rx or in Rx/Tx Mode */ + if(hspi->State == HAL_SPI_STATE_BUSY_TX_RX) + { + /* Set state to READY before run the Callback Complete */ + hspi->State = HAL_SPI_STATE_READY; + HAL_SPI_TxRxCpltCallback(hspi); + } + else + { + /* Set state to READY before run the Callback Complete */ + hspi->State = HAL_SPI_STATE_READY; + HAL_SPI_RxCpltCallback(hspi); + } + } + else + { + /* Set state to READY before run the Callback Complete */ + hspi->State = HAL_SPI_STATE_READY; + /* Call Error call back in case of Error */ + HAL_SPI_ErrorCallback(hspi); + } + } +} + +/** + * @brief Interrupt Handler to receive amount of data in 2Lines mode + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval void + */ +static void SPI_2LinesRxISR(SPI_HandleTypeDef *hspi) +{ + /* Receive data in 8 Bit mode */ + if(hspi->Init.DataSize == SPI_DATASIZE_8BIT) + { + (*hspi->pRxBuffPtr++) = hspi->Instance->DR; + } + /* Receive data in 16 Bit mode */ + else + { + *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR; + hspi->pRxBuffPtr+=2; + } + hspi->RxXferCount--; + + if(hspi->RxXferCount==0) + { + SPI_RxCloseIRQHandler(hspi); + } +} + +/** + * @brief Interrupt Handler to receive amount of data in no-blocking mode + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval void + */ +static void SPI_RxISR(SPI_HandleTypeDef *hspi) +{ + /* Receive data in 8 Bit mode */ + if(hspi->Init.DataSize == SPI_DATASIZE_8BIT) + { + (*hspi->pRxBuffPtr++) = hspi->Instance->DR; + } + /* Receive data in 16 Bit mode */ + else + { + *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR; + hspi->pRxBuffPtr+=2; + } + hspi->RxXferCount--; + + /* Enable CRC Transmission */ + if((hspi->RxXferCount == 1) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) + { + /* Set CRC Next to calculate CRC on Rx side */ + hspi->Instance->CR1 |= SPI_CR1_CRCNEXT; + } + + if(hspi->RxXferCount == 0) + { + SPI_RxCloseIRQHandler(hspi); + } +} + +/** + * @brief DMA SPI transmit process complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma) +{ + __IO uint16_t tmpreg; + + SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* DMA Normal Mode */ + if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) + { + /* Wait until TXE flag is set to send data */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK) + { + hspi->ErrorCode |= HAL_SPI_ERROR_FLAG; + } + /* Disable Tx DMA Request */ + hspi->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN); + + /* Wait until Busy flag is reset before disabling SPI */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, SPI_TIMEOUT_VALUE) != HAL_OK) + { + hspi->ErrorCode |= HAL_SPI_ERROR_FLAG; + } + + hspi->TxXferCount = 0; + + hspi->State = HAL_SPI_STATE_READY; + } + + /* Clear OVERRUN flag in 2 Lines communication mode because received is not read */ + if(hspi->Init.Direction == SPI_DIRECTION_2LINES) + { + __HAL_SPI_CLEAR_OVRFLAG(hspi); + } + + /* Check if Errors has been detected during transfer */ + if(hspi->ErrorCode != HAL_SPI_ERROR_NONE) + { + HAL_SPI_ErrorCallback(hspi); + } + else + { + HAL_SPI_TxCpltCallback(hspi); + } +} + +/** + * @brief DMA SPI receive process complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +{ + __IO uint16_t tmpreg; + + SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + /* DMA Normal mode */ + if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) + { + if((hspi->Init.Direction == SPI_DIRECTION_2LINES)&&(hspi->Init.Mode == SPI_MODE_MASTER)) + { + SPI_DMAEndTransmitReceive(hspi); + } + /* SPI_DIRECTION_1LINE or SPI_DIRECTION_2LINES_RXONLY */ + else + { + if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) + { + /* Disable SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + } + + /* Disable Rx DMA Request */ + hspi->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN); + + hspi->RxXferCount = 0; + + /* Reset CRC Calculation */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + /* Wait until RXNE flag is set to send data */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK) + { + hspi->ErrorCode |= HAL_SPI_ERROR_FLAG; + } + + /* Read CRC */ + tmpreg = hspi->Instance->DR; + UNUSED(tmpreg); + + /* Wait until RXNE flag is set */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_TIMEOUT_VALUE) != HAL_OK) + { + hspi->ErrorCode |= HAL_SPI_ERROR_FLAG; + } + + /* Check if CRC error occurred */ + if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET) + { + hspi->ErrorCode |= HAL_SPI_ERROR_CRC; + __HAL_SPI_CLEAR_CRCERRFLAG(hspi); + } + } + } + + hspi->State = HAL_SPI_STATE_READY; + + /* Check if Errors has been detected during transfer */ + if(hspi->ErrorCode != HAL_SPI_ERROR_NONE) + { + HAL_SPI_ErrorCallback(hspi); + } + else + { + HAL_SPI_RxCpltCallback(hspi); + } + } + else + { + HAL_SPI_RxCpltCallback(hspi); + } +} + +/** + * @brief End DMA SPI transmit receive process + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @retval None + */ +static void SPI_DMAEndTransmitReceive(SPI_HandleTypeDef *hspi) +{ + __IO uint16_t tmpreg; + + /* Reset CRC Calculation */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + /* Check if CRC is done on going (RXNE flag set) */ +// if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_TIMEOUT_VALUE) == HAL_OK) +// { + /* Wait until RXNE flag is set to send data */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK) + { + hspi->ErrorCode |= HAL_SPI_ERROR_FLAG; + } +// } + /* Read CRC */ + tmpreg = hspi->Instance->DR; + UNUSED(tmpreg); + + /* Check if CRC error occurred */ + if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET) + { + hspi->ErrorCode |= HAL_SPI_ERROR_CRC; + __HAL_SPI_CLEAR_CRCERRFLAG(hspi); + } + } + + /* Wait until TXE flag is set to send data */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK) + { + hspi->ErrorCode |= HAL_SPI_ERROR_FLAG; + } + /* Disable Tx DMA Request */ + hspi->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN); + + /* Wait until Busy flag is reset before disabling SPI */ + if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, SPI_TIMEOUT_VALUE) != HAL_OK) + { + //The Busy flag occasionally fails to reset within timeout. No idea why. + //But in this case WaitOnFlagUntilTimeout disables the SPI for us, + //so we can ignore the error and carry on. + //hspi->ErrorCode |= HAL_SPI_ERROR_FLAG; + } + + /* Disable Rx DMA Request */ + hspi->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN); + + hspi->TxXferCount = 0; + hspi->RxXferCount = 0; +} + +/** + * @brief DMA SPI transmit receive process complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) + { /**/ + SPI_DMAEndTransmitReceive(hspi); + + hspi->State = HAL_SPI_STATE_READY; + + /* Check if Errors has been detected during transfer */ + if(hspi->ErrorCode != HAL_SPI_ERROR_NONE) + { + HAL_SPI_ErrorCallback(hspi); + } + else + { + HAL_SPI_TxRxCpltCallback(hspi); + } + } + else + { + HAL_SPI_TxRxCpltCallback(hspi); + } +} + +/** + * @brief DMA SPI half transmit process complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + HAL_SPI_TxHalfCpltCallback(hspi); +} + +/** + * @brief DMA SPI half receive process complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + HAL_SPI_RxHalfCpltCallback(hspi); +} + +/** + * @brief DMA SPI Half transmit receive process complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + HAL_SPI_TxRxHalfCpltCallback(hspi); +} + +/** + * @brief DMA SPI communication error callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void SPI_DMAError(DMA_HandleTypeDef *hdma) +{ + SPI_HandleTypeDef* hspi = (SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + hspi->TxXferCount = 0; + hspi->RxXferCount = 0; + hspi->State= HAL_SPI_STATE_READY; + hspi->ErrorCode |= HAL_SPI_ERROR_DMA; + HAL_SPI_ErrorCallback(hspi); +} + +/** + * @brief This function handles SPI Communication Timeout. + * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * the configuration information for SPI module. + * @param Flag: SPI flag to check + * @param Status: Flag status to check: RESET or set + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus Status, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until flag is set */ + if(Status == RESET) + { + while(__HAL_SPI_GET_FLAG(hspi, Flag) == RESET) + { + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Disable the SPI and reset the CRC: the CRC value should be cleared + on both master and slave sides in order to resynchronize the master + and slave for their respective CRC calculation */ + + /* Disable TXE, RXNE and ERR interrupts for the interrupt process */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR)); + + /* Disable SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + + /* Reset CRC Calculation */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } + + hspi->State= HAL_SPI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + return HAL_TIMEOUT; + } + } + } + } + else + { + while(__HAL_SPI_GET_FLAG(hspi, Flag) != RESET) + { + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Disable the SPI and reset the CRC: the CRC value should be cleared + on both master and slave sides in order to resynchronize the master + and slave for their respective CRC calculation */ + + /* Disable TXE, RXNE and ERR interrupts for the interrupt process */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR)); + + /* Disable SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + + /* Reset CRC Calculation */ + if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + { + SPI_RESET_CRC(hspi); + } + + hspi->State= HAL_SPI_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hspi); + + return HAL_TIMEOUT; + } + } + } + } + return HAL_OK; +} + + +/** + * @} + */ + +#endif /* HAL_SPI_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c new file mode 100644 index 0000000..77f6fd3 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c @@ -0,0 +1,682 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_sram.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief SRAM HAL module driver. + * This file provides a generic firmware to drive SRAM memories + * mounted as external device. + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + This driver is a generic layered driver which contains a set of APIs used to + control SRAM memories. It uses the FMC layer functions to interface + with SRAM devices. + The following sequence should be followed to configure the FMC/FSMC to interface + with SRAM/PSRAM memories: + + (#) Declare a SRAM_HandleTypeDef handle structure, for example: + SRAM_HandleTypeDef hsram; and: + + (++) Fill the SRAM_HandleTypeDef handle "Init" field with the allowed + values of the structure member. + + (++) Fill the SRAM_HandleTypeDef handle "Instance" field with a predefined + base register instance for NOR or SRAM device + + (++) Fill the SRAM_HandleTypeDef handle "Extended" field with a predefined + base register instance for NOR or SRAM extended mode + + (#) Declare two FMC_NORSRAM_TimingTypeDef structures, for both normal and extended + mode timings; for example: + FMC_NORSRAM_TimingTypeDef Timing and FMC_NORSRAM_TimingTypeDef ExTiming; + and fill its fields with the allowed values of the structure member. + + (#) Initialize the SRAM Controller by calling the function HAL_SRAM_Init(). This function + performs the following sequence: + + (##) MSP hardware layer configuration using the function HAL_SRAM_MspInit() + (##) Control register configuration using the FMC NORSRAM interface function + FMC_NORSRAM_Init() + (##) Timing register configuration using the FMC NORSRAM interface function + FMC_NORSRAM_Timing_Init() + (##) Extended mode Timing register configuration using the FMC NORSRAM interface function + FMC_NORSRAM_Extended_Timing_Init() + (##) Enable the SRAM device using the macro __FMC_NORSRAM_ENABLE() + + (#) At this stage you can perform read/write accesses from/to the memory connected + to the NOR/SRAM Bank. You can perform either polling or DMA transfer using the + following APIs: + (++) HAL_SRAM_Read()/HAL_SRAM_Write() for polling read/write access + (++) HAL_SRAM_Read_DMA()/HAL_SRAM_Write_DMA() for DMA read/write transfer + + (#) You can also control the SRAM device by calling the control APIs HAL_SRAM_WriteOperation_Enable()/ + HAL_SRAM_WriteOperation_Disable() to respectively enable/disable the SRAM write operation + + (#) You can continuously monitor the SRAM device HAL state by calling the function + HAL_SRAM_GetState() + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 SRAM SRAM + * @brief SRAM driver modules + * @{ + */ +#ifdef HAL_SRAM_MODULE_ENABLED + +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\ + defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F446xx) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup SRAM_Exported_Functions SRAM Exported Functions + * @{ + */ +/** @defgroup SRAM_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * + @verbatim + ============================================================================== + ##### SRAM Initialization and de_initialization functions ##### + ============================================================================== + [..] This section provides functions allowing to initialize/de-initialize + the SRAM memory + +@endverbatim + * @{ + */ + +/** + * @brief Performs the SRAM device initialization sequence + * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param Timing: Pointer to SRAM control timing structure + * @param ExtTiming: Pointer to SRAM extended mode timing structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Init(SRAM_HandleTypeDef *hsram, FMC_NORSRAM_TimingTypeDef *Timing, FMC_NORSRAM_TimingTypeDef *ExtTiming) +{ + /* Check the SRAM handle parameter */ + if(hsram == NULL) + { + return HAL_ERROR; + } + + if(hsram->State == HAL_SRAM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hsram->Lock = HAL_UNLOCKED; + /* Initialize the low level hardware (MSP) */ + HAL_SRAM_MspInit(hsram); + } + + /* Initialize SRAM control Interface */ + FMC_NORSRAM_Init(hsram->Instance, &(hsram->Init)); + + /* Initialize SRAM timing Interface */ + FMC_NORSRAM_Timing_Init(hsram->Instance, Timing, hsram->Init.NSBank); + + /* Initialize SRAM extended mode timing Interface */ + FMC_NORSRAM_Extended_Timing_Init(hsram->Extended, ExtTiming, hsram->Init.NSBank, hsram->Init.ExtendedMode); + + /* Enable the NORSRAM device */ + __FMC_NORSRAM_ENABLE(hsram->Instance, hsram->Init.NSBank); + + return HAL_OK; +} + +/** + * @brief Performs the SRAM device De-initialization sequence. + * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_DeInit(SRAM_HandleTypeDef *hsram) +{ + /* De-Initialize the low level hardware (MSP) */ + HAL_SRAM_MspDeInit(hsram); + + /* Configure the SRAM registers with their reset values */ + FMC_NORSRAM_DeInit(hsram->Instance, hsram->Extended, hsram->Init.NSBank); + + hsram->State = HAL_SRAM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hsram); + + return HAL_OK; +} + +/** + * @brief SRAM MSP Init. + * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @retval None + */ +__weak void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SRAM_MspInit could be implemented in the user file + */ +} + +/** + * @brief SRAM MSP DeInit. + * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @retval None + */ +__weak void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef *hsram) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SRAM_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief DMA transfer complete callback. + * @param hdma: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @retval None + */ +__weak void HAL_SRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SRAM_DMA_XferCpltCallback could be implemented in the user file + */ +} + +/** + * @brief DMA transfer complete error callback. + * @param hdma: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @retval None + */ +__weak void HAL_SRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_SRAM_DMA_XferErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup SRAM_Exported_Functions_Group2 Input and Output functions + * @brief Input Output and memory control functions + * + @verbatim + ============================================================================== + ##### SRAM Input and Output functions ##### + ============================================================================== + [..] + This section provides functions allowing to use and control the SRAM memory + +@endverbatim + * @{ + */ + +/** + * @brief Reads 8-bit buffer from SRAM memory. + * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param pAddress: Pointer to read start address + * @param pDstBuffer: Pointer to destination buffer + * @param BufferSize: Size of the buffer to read from memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Read_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pDstBuffer, uint32_t BufferSize) +{ + __IO uint8_t * pSramAddress = (uint8_t *)pAddress; + + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Read data from memory */ + for(; BufferSize != 0; BufferSize--) + { + *pDstBuffer = *(__IO uint8_t *)pSramAddress; + pDstBuffer++; + pSramAddress++; + } + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + + return HAL_OK; +} + +/** + * @brief Writes 8-bit buffer to SRAM memory. + * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param pAddress: Pointer to write start address + * @param pSrcBuffer: Pointer to source buffer to write + * @param BufferSize: Size of the buffer to write to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Write_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pSrcBuffer, uint32_t BufferSize) +{ + __IO uint8_t * pSramAddress = (uint8_t *)pAddress; + + /* Check the SRAM controller state */ + if(hsram->State == HAL_SRAM_STATE_PROTECTED) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Write data to memory */ + for(; BufferSize != 0; BufferSize--) + { + *(__IO uint8_t *)pSramAddress = *pSrcBuffer; + pSrcBuffer++; + pSramAddress++; + } + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + + return HAL_OK; +} + +/** + * @brief Reads 16-bit buffer from SRAM memory. + * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param pAddress: Pointer to read start address + * @param pDstBuffer: Pointer to destination buffer + * @param BufferSize: Size of the buffer to read from memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Read_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pDstBuffer, uint32_t BufferSize) +{ + __IO uint16_t * pSramAddress = (uint16_t *)pAddress; + + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Read data from memory */ + for(; BufferSize != 0; BufferSize--) + { + *pDstBuffer = *(__IO uint16_t *)pSramAddress; + pDstBuffer++; + pSramAddress++; + } + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + + return HAL_OK; +} + +/** + * @brief Writes 16-bit buffer to SRAM memory. + * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param pAddress: Pointer to write start address + * @param pSrcBuffer: Pointer to source buffer to write + * @param BufferSize: Size of the buffer to write to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Write_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pSrcBuffer, uint32_t BufferSize) +{ + __IO uint16_t * pSramAddress = (uint16_t *)pAddress; + + /* Check the SRAM controller state */ + if(hsram->State == HAL_SRAM_STATE_PROTECTED) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Write data to memory */ + for(; BufferSize != 0; BufferSize--) + { + *(__IO uint16_t *)pSramAddress = *pSrcBuffer; + pSrcBuffer++; + pSramAddress++; + } + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + + return HAL_OK; +} + +/** + * @brief Reads 32-bit buffer from SRAM memory. + * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param pAddress: Pointer to read start address + * @param pDstBuffer: Pointer to destination buffer + * @param BufferSize: Size of the buffer to read from memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Read_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize) +{ + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Read data from memory */ + for(; BufferSize != 0; BufferSize--) + { + *pDstBuffer = *(__IO uint32_t *)pAddress; + pDstBuffer++; + pAddress++; + } + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + + return HAL_OK; +} + +/** + * @brief Writes 32-bit buffer to SRAM memory. + * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param pAddress: Pointer to write start address + * @param pSrcBuffer: Pointer to source buffer to write + * @param BufferSize: Size of the buffer to write to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Write_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize) +{ + /* Check the SRAM controller state */ + if(hsram->State == HAL_SRAM_STATE_PROTECTED) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Write data to memory */ + for(; BufferSize != 0; BufferSize--) + { + *(__IO uint32_t *)pAddress = *pSrcBuffer; + pSrcBuffer++; + pAddress++; + } + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + + return HAL_OK; +} + +/** + * @brief Reads a Words data from the SRAM memory using DMA transfer. + * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param pAddress: Pointer to read start address + * @param pDstBuffer: Pointer to destination buffer + * @param BufferSize: Size of the buffer to read from memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Read_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize) +{ + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Configure DMA user callbacks */ + hsram->hdma->XferCpltCallback = HAL_SRAM_DMA_XferCpltCallback; + hsram->hdma->XferErrorCallback = HAL_SRAM_DMA_XferErrorCallback; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hsram->hdma, (uint32_t)pAddress, (uint32_t)pDstBuffer, (uint32_t)BufferSize); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + + return HAL_OK; +} + +/** + * @brief Writes a Words data buffer to SRAM memory using DMA transfer. + * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @param pAddress: Pointer to write start address + * @param pSrcBuffer: Pointer to source buffer to write + * @param BufferSize: Size of the buffer to write to memory + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_Write_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize) +{ + /* Check the SRAM controller state */ + if(hsram->State == HAL_SRAM_STATE_PROTECTED) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Configure DMA user callbacks */ + hsram->hdma->XferCpltCallback = HAL_SRAM_DMA_XferCpltCallback; + hsram->hdma->XferErrorCallback = HAL_SRAM_DMA_XferErrorCallback; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hsram->hdma, (uint32_t)pSrcBuffer, (uint32_t)pAddress, (uint32_t)BufferSize); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup SRAM_Exported_Functions_Group3 Control functions + * @brief management functions + * +@verbatim + ============================================================================== + ##### SRAM Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the SRAM interface. + +@endverbatim + * @{ + */ + +/** + * @brief Enables dynamically SRAM write operation. + * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_WriteOperation_Enable(SRAM_HandleTypeDef *hsram) +{ + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Enable write operation */ + FMC_NORSRAM_WriteOperation_Enable(hsram->Instance, hsram->Init.NSBank); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_READY; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + + return HAL_OK; +} + +/** + * @brief Disables dynamically SRAM write operation. + * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SRAM_WriteOperation_Disable(SRAM_HandleTypeDef *hsram) +{ + /* Process Locked */ + __HAL_LOCK(hsram); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_BUSY; + + /* Disable write operation */ + FMC_NORSRAM_WriteOperation_Disable(hsram->Instance, hsram->Init.NSBank); + + /* Update the SRAM controller state */ + hsram->State = HAL_SRAM_STATE_PROTECTED; + + /* Process unlocked */ + __HAL_UNLOCK(hsram); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup SRAM_Exported_Functions_Group4 State functions + * @brief Peripheral State functions + * +@verbatim + ============================================================================== + ##### SRAM State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the SRAM controller + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the SRAM controller state + * @param hsram: pointer to a SRAM_HandleTypeDef structure that contains + * the configuration information for SRAM module. + * @retval HAL state + */ +HAL_SRAM_StateTypeDef HAL_SRAM_GetState(SRAM_HandleTypeDef *hsram) +{ + return hsram->State; +} +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ +#endif /* HAL_SRAM_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c new file mode 100644 index 0000000..7c8eaf8 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c @@ -0,0 +1,5335 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_tim.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief TIM HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Timer (TIM) peripheral: + * + Time Base Initialization + * + Time Base Start + * + Time Base Start Interruption + * + Time Base Start DMA + * + Time Output Compare/PWM Initialization + * + Time Output Compare/PWM Channel Configuration + * + Time Output Compare/PWM Start + * + Time Output Compare/PWM Start Interruption + * + Time Output Compare/PWM Start DMA + * + Time Input Capture Initialization + * + Time Input Capture Channel Configuration + * + Time Input Capture Start + * + Time Input Capture Start Interruption + * + Time Input Capture Start DMA + * + Time One Pulse Initialization + * + Time One Pulse Channel Configuration + * + Time One Pulse Start + * + Time Encoder Interface Initialization + * + Time Encoder Interface Start + * + Time Encoder Interface Start Interruption + * + Time Encoder Interface Start DMA + * + Commutation Event configuration with Interruption and DMA + * + Time OCRef clear configuration + * + Time External Clock configuration + @verbatim + ============================================================================== + ##### TIMER Generic features ##### + ============================================================================== + [..] The Timer features include: + (#) 16-bit up, down, up/down auto-reload counter. + (#) 16-bit programmable prescaler allowing dividing (also on the fly) the + counter clock frequency either by any factor between 1 and 65536. + (#) Up to 4 independent channels for: + (++) Input Capture + (++) Output Compare + (++) PWM generation (Edge and Center-aligned Mode) + (++) One-pulse mode output + + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Initialize the TIM low level resources by implementing the following functions + depending from feature used : + (++) Time Base : HAL_TIM_Base_MspInit() + (++) Input Capture : HAL_TIM_IC_MspInit() + (++) Output Compare : HAL_TIM_OC_MspInit() + (++) PWM generation : HAL_TIM_PWM_MspInit() + (++) One-pulse mode output : HAL_TIM_OnePulse_MspInit() + (++) Encoder mode output : HAL_TIM_Encoder_MspInit() + + (#) Initialize the TIM low level resources : + (##) Enable the TIM interface clock using __TIMx_CLK_ENABLE(); + (##) TIM pins configuration + (+++) Enable the clock for the TIM GPIOs using the following function: + __GPIOx_CLK_ENABLE(); + (+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init(); + + (#) The external Clock can be configured, if needed (the default clock is the + internal clock from the APBx), using the following function: + HAL_TIM_ConfigClockSource, the clock configuration should be done before + any start function. + + (#) Configure the TIM in the desired functioning mode using one of the + initialization function of this driver: + (++) HAL_TIM_Base_Init: to use the Timer to generate a simple time base + (++) HAL_TIM_OC_Init and HAL_TIM_OC_ConfigChannel: to use the Timer to generate an + Output Compare signal. + (++) HAL_TIM_PWM_Init and HAL_TIM_PWM_ConfigChannel: to use the Timer to generate a + PWM signal. + (++) HAL_TIM_IC_Init and HAL_TIM_IC_ConfigChannel: to use the Timer to measure an + external signal. + (++) HAL_TIM_OnePulse_Init and HAL_TIM_OnePulse_ConfigChannel: to use the Timer + in One Pulse Mode. + (++) HAL_TIM_Encoder_Init: to use the Timer Encoder Interface. + + (#) Activate the TIM peripheral using one of the start functions depending from the feature used: + (++) Time Base : HAL_TIM_Base_Start(), HAL_TIM_Base_Start_DMA(), HAL_TIM_Base_Start_IT() + (++) Input Capture : HAL_TIM_IC_Start(), HAL_TIM_IC_Start_DMA(), HAL_TIM_IC_Start_IT() + (++) Output Compare : HAL_TIM_OC_Start(), HAL_TIM_OC_Start_DMA(), HAL_TIM_OC_Start_IT() + (++) PWM generation : HAL_TIM_PWM_Start(), HAL_TIM_PWM_Start_DMA(), HAL_TIM_PWM_Start_IT() + (++) One-pulse mode output : HAL_TIM_OnePulse_Start(), HAL_TIM_OnePulse_Start_IT() + (++) Encoder mode output : HAL_TIM_Encoder_Start(), HAL_TIM_Encoder_Start_DMA(), HAL_TIM_Encoder_Start_IT(). + + (#) The DMA Burst is managed with the two following functions: + HAL_TIM_DMABurst_WriteStart() + HAL_TIM_DMABurst_ReadStart() + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 TIM TIM + * @brief TIM HAL module driver + * @{ + */ + +#ifdef HAL_TIM_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @addtogroup TIM_Private_Functions + * @{ + */ +/* Private function prototypes -----------------------------------------------*/ +static void TIM_OC1_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config); +static void TIM_OC3_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config); +static void TIM_OC4_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config); + +static void TIM_TI1_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter); +static void TIM_TI2_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter); +static void TIM_TI2_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter); +static void TIM_TI3_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter); +static void TIM_TI4_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter); + +static void TIM_ETR_SetConfig(TIM_TypeDef* TIMx, uint32_t TIM_ExtTRGPrescaler, + uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter); + +static void TIM_ITRx_SetConfig(TIM_TypeDef* TIMx, uint16_t TIM_ITRx); +static void TIM_DMAPeriodElapsedCplt(DMA_HandleTypeDef *hdma); +static void TIM_DMATriggerCplt(DMA_HandleTypeDef *hdma); +static void TIM_SlaveTimer_SetConfig(TIM_HandleTypeDef *htim, + TIM_SlaveConfigTypeDef * sSlaveConfig); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup TIM_Exported_Functions TIM Exported Functions + * @{ + */ + +/** @defgroup TIM_Exported_Functions_Group1 Time Base functions + * @brief Time Base functions + * +@verbatim + ============================================================================== + ##### Time Base functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM base. + (+) De-initialize the TIM base. + (+) Start the Time Base. + (+) Stop the Time Base. + (+) Start the Time Base and enable interrupt. + (+) Stop the Time Base and disable interrupt. + (+) Start the Time Base and enable DMA transfer. + (+) Stop the Time Base and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Time base Unit according to the specified + * parameters in the TIM_HandleTypeDef and create the associated handle. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim) +{ + /* Check the TIM handle allocation */ + if(htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + + if(htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + HAL_TIM_Base_MspInit(htim); + } + + /* Set the TIM state */ + htim->State= HAL_TIM_STATE_BUSY; + + /* Set the Time Base configuration */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Initialize the TIM state*/ + htim->State= HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM Base peripheral + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_TIM_Base_MspDeInit(htim); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Base MSP. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIM_Base_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Base MSP. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIM_Base_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Base generation. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + /* Set the TIM state */ + htim->State= HAL_TIM_STATE_BUSY; + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Change the TIM state*/ + htim->State= HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Base generation. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + /* Set the TIM state */ + htim->State= HAL_TIM_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the TIM state*/ + htim->State= HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Base generation in interrupt mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + /* Enable the TIM Update interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Base generation in interrupt mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + /* Disable the TIM Update interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_UPDATE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Base generation in DMA mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param pData: The source Buffer address. + * @param Length: The length of data to be transferred from memory to peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMA_INSTANCE(htim->Instance)); + + if((htim->State == HAL_TIM_STATE_BUSY)) + { + return HAL_BUSY; + } + else if((htim->State == HAL_TIM_STATE_READY)) + { + if((pData == 0 ) && (Length > 0)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)pData, (uint32_t)&htim->Instance->ARR, Length); + + /* Enable the TIM Update DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_UPDATE); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Base generation in DMA mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Stop_DMA(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMA_INSTANCE(htim->Instance)); + + /* Disable the TIM Update DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_UPDATE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group2 Time Output Compare functions + * @brief Time Output Compare functions + * +@verbatim + ============================================================================== + ##### Time Output Compare functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM Output Compare. + (+) De-initialize the TIM Output Compare. + (+) Start the Time Output Compare. + (+) Stop the Time Output Compare. + (+) Start the Time Output Compare and enable interrupt. + (+) Stop the Time Output Compare and disable interrupt. + (+) Start the Time Output Compare and enable DMA transfer. + (+) Stop the Time Output Compare and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Output Compare according to the specified + * parameters in the TIM_HandleTypeDef and create the associated handle. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Init(TIM_HandleTypeDef* htim) +{ + /* Check the TIM handle allocation */ + if(htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + + if(htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_OC_MspInit(htim); + } + + /* Set the TIM state */ + htim->State= HAL_TIM_STATE_BUSY; + + /* Init the base time for the Output Compare */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Initialize the TIM state*/ + htim->State= HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM peripheral + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_OC_MspDeInit(htim); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Output Compare MSP. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIM_OC_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Output Compare MSP. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_OC_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIM_OC_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Output Compare signal generation. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Enable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Output Compare signal generation. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Disable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Output Compare signal generation in interrupt mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Enable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Enable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + } + break; + + default: + break; + } + + /* Enable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Output Compare signal generation in interrupt mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + } + break; + + default: + break; + } + + /* Disable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Output Compare signal generation in DMA mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param pData: The source Buffer address. + * @param Length: The length of data to be transferred from memory to TIM peripheral + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + if((htim->State == HAL_TIM_STATE_BUSY)) + { + return HAL_BUSY; + } + else if((htim->State == HAL_TIM_STATE_READY)) + { + if(((uint32_t)pData == 0 ) && (Length > 0)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length); + + /* Enable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length); + + /* Enable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,Length); + + /* Enable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, Length); + + /* Enable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); + } + break; + + default: + break; + } + + /* Enable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Output Compare signal generation in DMA mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); + } + break; + + default: + break; + } + + /* Disable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group3 Time PWM functions + * @brief Time PWM functions + * +@verbatim + ============================================================================== + ##### Time PWM functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM OPWM. + (+) De-initialize the TIM PWM. + (+) Start the Time PWM. + (+) Stop the Time PWM. + (+) Start the Time PWM and enable interrupt. + (+) Stop the Time PWM and disable interrupt. + (+) Start the Time PWM and enable DMA transfer. + (+) Stop the Time PWM and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM PWM Time Base according to the specified + * parameters in the TIM_HandleTypeDef and create the associated handle. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim) +{ + /* Check the TIM handle allocation */ + if(htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + + if(htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_PWM_MspInit(htim); + } + + /* Set the TIM state */ + htim->State= HAL_TIM_STATE_BUSY; + + /* Init the base time for the PWM */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Initialize the TIM state*/ + htim->State= HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM peripheral + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_PWM_MspDeInit(htim); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM PWM MSP. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIM_PWM_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM PWM MSP. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIM_PWM_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the PWM signal generation. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the PWM signal generation. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Disable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the PWM signal generation in interrupt mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Enable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Enable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + } + break; + + default: + break; + } + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the PWM signal generation in interrupt mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT (TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + } + break; + + default: + break; + } + + /* Disable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM PWM signal generation in DMA mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param pData: The source Buffer address. + * @param Length: The length of data to be transferred from memory to TIM peripheral + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + if((htim->State == HAL_TIM_STATE_BUSY)) + { + return HAL_BUSY; + } + else if((htim->State == HAL_TIM_STATE_READY)) + { + if(((uint32_t)pData == 0 ) && (Length > 0)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length); + + /* Enable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length); + + /* Enable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,Length); + + /* Enable the TIM Output Capture/Compare 3 request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, Length); + + /* Enable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); + } + break; + + default: + break; + } + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM PWM signal generation in DMA mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); + } + break; + + default: + break; + } + + /* Disable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group4 Time Input Capture functions + * @brief Time Input Capture functions + * +@verbatim + ============================================================================== + ##### Time Input Capture functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM Input Capture. + (+) De-initialize the TIM Input Capture. + (+) Start the Time Input Capture. + (+) Stop the Time Input Capture. + (+) Start the Time Input Capture and enable interrupt. + (+) Stop the Time Input Capture and disable interrupt. + (+) Start the Time Input Capture and enable DMA transfer. + (+) Stop the Time Input Capture and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Input Capture Time base according to the specified + * parameters in the TIM_HandleTypeDef and create the associated handle. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef *htim) +{ + /* Check the TIM handle allocation */ + if(htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + + if(htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_IC_MspInit(htim); + } + + /* Set the TIM state */ + htim->State= HAL_TIM_STATE_BUSY; + + /* Init the base time for the input capture */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Initialize the TIM state*/ + htim->State= HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM peripheral + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_IC_MspDeInit(htim); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM INput Capture MSP. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIM_IC_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Input Capture MSP. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIM_IC_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Input Capture measurement. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Start (TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Enable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Input Capture measurement. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Disable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Input Capture measurement in interrupt mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Start_IT (TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Enable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Enable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + } + break; + + default: + break; + } + /* Enable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Input Capture measurement in interrupt mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + } + break; + + default: + break; + } + + /* Disable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Input Capture measurement on in DMA mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param pData: The destination Buffer address. + * @param Length: The length of data to be transferred from TIM peripheral to memory. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance)); + + if((htim->State == HAL_TIM_STATE_BUSY)) + { + return HAL_BUSY; + } + else if((htim->State == HAL_TIM_STATE_READY)) + { + if((pData == 0 ) && (Length > 0)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData, Length); + + /* Enable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData, Length); + + /* Enable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMACaptureCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)&htim->Instance->CCR3, (uint32_t)pData, Length); + + /* Enable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMACaptureCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)&htim->Instance->CCR4, (uint32_t)pData, Length); + + /* Enable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); + } + break; + + default: + break; + } + + /* Enable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Input Capture measurement on in DMA mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); + } + break; + + default: + break; + } + + /* Disable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group5 Time One Pulse functions + * @brief Time One Pulse functions + * +@verbatim + ============================================================================== + ##### Time One Pulse functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM One Pulse. + (+) De-initialize the TIM One Pulse. + (+) Start the Time One Pulse. + (+) Stop the Time One Pulse. + (+) Start the Time One Pulse and enable interrupt. + (+) Stop the Time One Pulse and disable interrupt. + (+) Start the Time One Pulse and enable DMA transfer. + (+) Stop the Time One Pulse and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM One Pulse Time Base according to the specified + * parameters in the TIM_HandleTypeDef and create the associated handle. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param OnePulseMode: Select the One pulse mode. + * This parameter can be one of the following values: + * @arg TIM_OPMODE_SINGLE: Only one pulse will be generated. + * @arg TIM_OPMODE_REPETITIVE: Repetitive pulses will be generated. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Init(TIM_HandleTypeDef *htim, uint32_t OnePulseMode) +{ + /* Check the TIM handle allocation */ + if(htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_OPM_MODE(OnePulseMode)); + + if(htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_OnePulse_MspInit(htim); + } + + /* Set the TIM state */ + htim->State= HAL_TIM_STATE_BUSY; + + /* Configure the Time base in the One Pulse Mode */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Reset the OPM Bit */ + htim->Instance->CR1 &= ~TIM_CR1_OPM; + + /* Configure the OPM Mode */ + htim->Instance->CR1 |= OnePulseMode; + + /* Initialize the TIM state*/ + htim->State= HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM One Pulse + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_TIM_OnePulse_MspDeInit(htim); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM One Pulse MSP. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_OnePulse_MspInit(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIM_OnePulse_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM One Pulse MSP. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_OnePulse_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIM_OnePulse_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM One Pulse signal generation. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param OutputChannel : TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Enable the Capture compare and the Input Capture channels + (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) + if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and + if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output + in all combinations, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be enabled together + + No need to enable the counter, it's enabled automatically by hardware + (the counter starts in response to a stimulus and generate a pulse */ + + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + + if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM One Pulse signal generation. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param OutputChannel : TIM Channels to be disable. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Disable the Capture compare and the Input Capture channels + (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) + if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and + if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output + in all combinations, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be disabled together */ + + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM One Pulse signal generation in interrupt mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param OutputChannel : TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Enable the Capture compare and the Input Capture channels + (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) + if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and + if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output + in all combinations, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be enabled together + + No need to enable the counter, it's enabled automatically by hardware + (the counter starts in response to a stimulus and generate a pulse */ + + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + + if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM One Pulse signal generation in interrupt mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param OutputChannel : TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + + /* Disable the Capture compare and the Input Capture channels + (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) + if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and + if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output + in all combinations, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be disabled together */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group6 Time Encoder functions + * @brief Time Encoder functions + * +@verbatim + ============================================================================== + ##### Time Encoder functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM Encoder. + (+) De-initialize the TIM Encoder. + (+) Start the Time Encoder. + (+) Stop the Time Encoder. + (+) Start the Time Encoder and enable interrupt. + (+) Stop the Time Encoder and disable interrupt. + (+) Start the Time Encoder and enable DMA transfer. + (+) Stop the Time Encoder and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Encoder Interface and create the associated handle. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param sConfig: TIM Encoder Interface configuration structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim, TIM_Encoder_InitTypeDef* sConfig) +{ + uint32_t tmpsmcr = 0; + uint32_t tmpccmr1 = 0; + uint32_t tmpccer = 0; + + /* Check the TIM handle allocation */ + if(htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + assert_param(IS_TIM_ENCODER_MODE(sConfig->EncoderMode)); + assert_param(IS_TIM_IC_SELECTION(sConfig->IC1Selection)); + assert_param(IS_TIM_IC_SELECTION(sConfig->IC2Selection)); + assert_param(IS_TIM_IC_POLARITY(sConfig->IC1Polarity)); + assert_param(IS_TIM_IC_POLARITY(sConfig->IC2Polarity)); + assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler)); + assert_param(IS_TIM_IC_PRESCALER(sConfig->IC2Prescaler)); + assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter)); + assert_param(IS_TIM_IC_FILTER(sConfig->IC2Filter)); + + if(htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_Encoder_MspInit(htim); + } + + /* Set the TIM state */ + htim->State= HAL_TIM_STATE_BUSY; + + /* Reset the SMS bits */ + htim->Instance->SMCR &= ~TIM_SMCR_SMS; + + /* Configure the Time base in the Encoder Mode */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Get the TIMx SMCR register value */ + tmpsmcr = htim->Instance->SMCR; + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = htim->Instance->CCMR1; + + /* Get the TIMx CCER register value */ + tmpccer = htim->Instance->CCER; + + /* Set the encoder Mode */ + tmpsmcr |= sConfig->EncoderMode; + + /* Select the Capture Compare 1 and the Capture Compare 2 as input */ + tmpccmr1 &= ~(TIM_CCMR1_CC1S | TIM_CCMR1_CC2S); + tmpccmr1 |= (sConfig->IC1Selection | (sConfig->IC2Selection << 8)); + + /* Set the Capture Compare 1 and the Capture Compare 2 prescalers and filters */ + tmpccmr1 &= ~(TIM_CCMR1_IC1PSC | TIM_CCMR1_IC2PSC); + tmpccmr1 &= ~(TIM_CCMR1_IC1F | TIM_CCMR1_IC2F); + tmpccmr1 |= sConfig->IC1Prescaler | (sConfig->IC2Prescaler << 8); + tmpccmr1 |= (sConfig->IC1Filter << 4) | (sConfig->IC2Filter << 12); + + /* Set the TI1 and the TI2 Polarities */ + tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC2P); + tmpccer &= ~(TIM_CCER_CC1NP | TIM_CCER_CC2NP); + tmpccer |= sConfig->IC1Polarity | (sConfig->IC2Polarity << 4); + + /* Write to TIMx SMCR */ + htim->Instance->SMCR = tmpsmcr; + + /* Write to TIMx CCMR1 */ + htim->Instance->CCMR1 = tmpccmr1; + + /* Write to TIMx CCER */ + htim->Instance->CCER = tmpccer; + + /* Initialize the TIM state*/ + htim->State= HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM Encoder interface + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_TIM_Encoder_MspDeInit(htim); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Encoder Interface MSP. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIM_Encoder_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Encoder Interface MSP. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIM_Encoder_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Encoder Interface. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Enable the encoder interface channels */ + switch (Channel) + { + case TIM_CHANNEL_1: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + break; + } + case TIM_CHANNEL_2: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + break; + } + default : + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + break; + } + } + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Encoder Interface. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1 and 2 + (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */ + switch (Channel) + { + case TIM_CHANNEL_1: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + break; + } + case TIM_CHANNEL_2: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + break; + } + default : + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + break; + } + } + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Encoder Interface in interrupt mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Enable the encoder interface channels */ + /* Enable the capture compare Interrupts 1 and/or 2 */ + switch (Channel) + { + case TIM_CHANNEL_1: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + case TIM_CHANNEL_2: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + default : + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + } + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Encoder Interface in interrupt mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1 and 2 + (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */ + if(Channel == TIM_CHANNEL_1) + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + /* Disable the capture compare Interrupts 1 */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + } + else if(Channel == TIM_CHANNEL_2) + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + /* Disable the capture compare Interrupts 2 */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + } + else + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + /* Disable the capture compare Interrupts 1 and 2 */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Encoder Interface in DMA mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @param pData1: The destination Buffer address for IC1. + * @param pData2: The destination Buffer address for IC2. + * @param Length: The length of data to be transferred from TIM peripheral to memory. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData1, uint32_t *pData2, uint16_t Length) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance)); + + if((htim->State == HAL_TIM_STATE_BUSY)) + { + return HAL_BUSY; + } + else if((htim->State == HAL_TIM_STATE_READY)) + { + if((((pData1 == 0) || (pData2 == 0) )) && (Length > 0)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t )pData1, Length); + + /* Enable the TIM Input Capture DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + } + break; + + case TIM_CHANNEL_2: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError; + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData2, Length); + + /* Enable the TIM Input Capture DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + } + break; + + case TIM_CHANNEL_ALL: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData1, Length); + + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData2, Length); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + + /* Enable the TIM Input Capture DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + /* Enable the TIM Input Capture DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + } + break; + + default: + break; + } + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Encoder Interface in DMA mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1 and 2 + (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */ + if(Channel == TIM_CHANNEL_1) + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + /* Disable the capture compare DMA Request 1 */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + } + else if(Channel == TIM_CHANNEL_2) + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + /* Disable the capture compare DMA Request 2 */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + } + else + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + /* Disable the capture compare DMA Request 1 and 2 */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group7 TIM IRQ handler management + * @brief IRQ handler management + * +@verbatim + ============================================================================== + ##### IRQ handler management ##### + ============================================================================== + [..] + This section provides Timer IRQ handler function. + +@endverbatim + * @{ + */ +/** + * @brief This function handles TIM interrupts requests. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim) +{ + /* Capture compare 1 event */ + if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET) + { + if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET) + { + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1); + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + + /* Input capture event */ + if((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00) + { + HAL_TIM_IC_CaptureCallback(htim); + } + /* Output compare event */ + else + { + HAL_TIM_OC_DelayElapsedCallback(htim); + HAL_TIM_PWM_PulseFinishedCallback(htim); + } + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; + } + } + } + /* Capture compare 2 event */ + if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET) + { + if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2); + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + /* Input capture event */ + if((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00) + { + HAL_TIM_IC_CaptureCallback(htim); + } + /* Output compare event */ + else + { + HAL_TIM_OC_DelayElapsedCallback(htim); + HAL_TIM_PWM_PulseFinishedCallback(htim); + } + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; + } + } + /* Capture compare 3 event */ + if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET) + { + if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) !=RESET) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3); + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + /* Input capture event */ + if((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00) + { + HAL_TIM_IC_CaptureCallback(htim); + } + /* Output compare event */ + else + { + HAL_TIM_OC_DelayElapsedCallback(htim); + HAL_TIM_PWM_PulseFinishedCallback(htim); + } + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; + } + } + /* Capture compare 4 event */ + if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET) + { + if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) !=RESET) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4); + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + /* Input capture event */ + if((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00) + { + HAL_TIM_IC_CaptureCallback(htim); + } + /* Output compare event */ + else + { + HAL_TIM_OC_DelayElapsedCallback(htim); + HAL_TIM_PWM_PulseFinishedCallback(htim); + } + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; + } + } + /* TIM Update event */ + if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET) + { + if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE); + HAL_TIM_PeriodElapsedCallback(htim); + } + } + /* TIM Break input event */ + if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET) + { + if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) !=RESET) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK); + HAL_TIMEx_BreakCallback(htim); + } + } + /* TIM Trigger detection event */ + if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET) + { + if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) !=RESET) + { + __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER); + HAL_TIM_TriggerCallback(htim); + } + } + /* TIM commutation event */ + if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET) + { + if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) !=RESET) + { + __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM); + HAL_TIMEx_CommutationCallback(htim); + } + } +} +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group8 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Configure The Input Output channels for OC, PWM, IC or One Pulse mode. + (+) Configure External Clock source. + (+) Configure Complementary channels, break features and dead time. + (+) Configure Master and the Slave synchronization. + (+) Configure the DMA Burst Mode. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the TIM Output Compare Channels according to the specified + * parameters in the TIM_OC_InitTypeDef. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param sConfig: TIM Output Compare configuration structure + * @param Channel: TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef* sConfig, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CHANNELS(Channel)); + assert_param(IS_TIM_OC_MODE(sConfig->OCMode)); + assert_param(IS_TIM_OC_POLARITY(sConfig->OCPolarity)); + assert_param(IS_TIM_OCN_POLARITY(sConfig->OCNPolarity)); + assert_param(IS_TIM_OCNIDLE_STATE(sConfig->OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(sConfig->OCIdleState)); + + /* Check input state */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + switch (Channel) + { + case TIM_CHANNEL_1: + { + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + /* Configure the TIM Channel 1 in Output Compare */ + TIM_OC1_SetConfig(htim->Instance, sConfig); + } + break; + + case TIM_CHANNEL_2: + { + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + /* Configure the TIM Channel 2 in Output Compare */ + TIM_OC2_SetConfig(htim->Instance, sConfig); + } + break; + + case TIM_CHANNEL_3: + { + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + /* Configure the TIM Channel 3 in Output Compare */ + TIM_OC3_SetConfig(htim->Instance, sConfig); + } + break; + + case TIM_CHANNEL_4: + { + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + /* Configure the TIM Channel 4 in Output Compare */ + TIM_OC4_SetConfig(htim->Instance, sConfig); + } + break; + + default: + break; + } + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Input Capture Channels according to the specified + * parameters in the TIM_IC_InitTypeDef. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param sConfig: TIM Input Capture configuration structure + * @param Channel: TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_IC_InitTypeDef* sConfig, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + assert_param(IS_TIM_IC_POLARITY(sConfig->ICPolarity)); + assert_param(IS_TIM_IC_SELECTION(sConfig->ICSelection)); + assert_param(IS_TIM_IC_PRESCALER(sConfig->ICPrescaler)); + assert_param(IS_TIM_IC_FILTER(sConfig->ICFilter)); + + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + if (Channel == TIM_CHANNEL_1) + { + /* TI1 Configuration */ + TIM_TI1_SetConfig(htim->Instance, + sConfig->ICPolarity, + sConfig->ICSelection, + sConfig->ICFilter); + + /* Reset the IC1PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC; + + /* Set the IC1PSC value */ + htim->Instance->CCMR1 |= sConfig->ICPrescaler; + } + else if (Channel == TIM_CHANNEL_2) + { + /* TI2 Configuration */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + TIM_TI2_SetConfig(htim->Instance, + sConfig->ICPolarity, + sConfig->ICSelection, + sConfig->ICFilter); + + /* Reset the IC2PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC; + + /* Set the IC2PSC value */ + htim->Instance->CCMR1 |= (sConfig->ICPrescaler << 8); + } + else if (Channel == TIM_CHANNEL_3) + { + /* TI3 Configuration */ + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + + TIM_TI3_SetConfig(htim->Instance, + sConfig->ICPolarity, + sConfig->ICSelection, + sConfig->ICFilter); + + /* Reset the IC3PSC Bits */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_IC3PSC; + + /* Set the IC3PSC value */ + htim->Instance->CCMR2 |= sConfig->ICPrescaler; + } + else + { + /* TI4 Configuration */ + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + + TIM_TI4_SetConfig(htim->Instance, + sConfig->ICPolarity, + sConfig->ICSelection, + sConfig->ICFilter); + + /* Reset the IC4PSC Bits */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_IC4PSC; + + /* Set the IC4PSC value */ + htim->Instance->CCMR2 |= (sConfig->ICPrescaler << 8); + } + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM PWM channels according to the specified + * parameters in the TIM_OC_InitTypeDef. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param sConfig: TIM PWM configuration structure + * @param Channel: TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OC_InitTypeDef* sConfig, uint32_t Channel) +{ + __HAL_LOCK(htim); + + /* Check the parameters */ + assert_param(IS_TIM_CHANNELS(Channel)); + assert_param(IS_TIM_PWM_MODE(sConfig->OCMode)); + assert_param(IS_TIM_OC_POLARITY(sConfig->OCPolarity)); + assert_param(IS_TIM_OCN_POLARITY(sConfig->OCNPolarity)); + assert_param(IS_TIM_OCNIDLE_STATE(sConfig->OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(sConfig->OCIdleState)); + assert_param(IS_TIM_FAST_STATE(sConfig->OCFastMode)); + + htim->State = HAL_TIM_STATE_BUSY; + + switch (Channel) + { + case TIM_CHANNEL_1: + { + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + /* Configure the Channel 1 in PWM mode */ + TIM_OC1_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel1 */ + htim->Instance->CCMR1 |= TIM_CCMR1_OC1PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_OC1FE; + htim->Instance->CCMR1 |= sConfig->OCFastMode; + } + break; + + case TIM_CHANNEL_2: + { + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + /* Configure the Channel 2 in PWM mode */ + TIM_OC2_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel2 */ + htim->Instance->CCMR1 |= TIM_CCMR1_OC2PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_OC2FE; + htim->Instance->CCMR1 |= sConfig->OCFastMode << 8; + } + break; + + case TIM_CHANNEL_3: + { + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + /* Configure the Channel 3 in PWM mode */ + TIM_OC3_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel3 */ + htim->Instance->CCMR2 |= TIM_CCMR2_OC3PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_OC3FE; + htim->Instance->CCMR2 |= sConfig->OCFastMode; + } + break; + + case TIM_CHANNEL_4: + { + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + /* Configure the Channel 4 in PWM mode */ + TIM_OC4_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel4 */ + htim->Instance->CCMR2 |= TIM_CCMR2_OC4PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_OC4FE; + htim->Instance->CCMR2 |= sConfig->OCFastMode << 8; + } + break; + + default: + break; + } + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM One Pulse Channels according to the specified + * parameters in the TIM_OnePulse_InitTypeDef. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param sConfig: TIM One Pulse configuration structure + * @param OutputChannel: TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @param InputChannel: TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OnePulse_InitTypeDef* sConfig, uint32_t OutputChannel, uint32_t InputChannel) +{ + TIM_OC_InitTypeDef temp1; + + /* Check the parameters */ + assert_param(IS_TIM_OPM_CHANNELS(OutputChannel)); + assert_param(IS_TIM_OPM_CHANNELS(InputChannel)); + + if(OutputChannel != InputChannel) + { + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Extract the Output compare configuration from sConfig structure */ + temp1.OCMode = sConfig->OCMode; + temp1.Pulse = sConfig->Pulse; + temp1.OCPolarity = sConfig->OCPolarity; + temp1.OCNPolarity = sConfig->OCNPolarity; + temp1.OCIdleState = sConfig->OCIdleState; + temp1.OCNIdleState = sConfig->OCNIdleState; + + switch (OutputChannel) + { + case TIM_CHANNEL_1: + { + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + TIM_OC1_SetConfig(htim->Instance, &temp1); + } + break; + case TIM_CHANNEL_2: + { + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + TIM_OC2_SetConfig(htim->Instance, &temp1); + } + break; + default: + break; + } + switch (InputChannel) + { + case TIM_CHANNEL_1: + { + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + TIM_TI1_SetConfig(htim->Instance, sConfig->ICPolarity, + sConfig->ICSelection, sConfig->ICFilter); + + /* Reset the IC1PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC; + + /* Select the Trigger source */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= TIM_TS_TI1FP1; + + /* Select the Slave Mode */ + htim->Instance->SMCR &= ~TIM_SMCR_SMS; + htim->Instance->SMCR |= TIM_SLAVEMODE_TRIGGER; + } + break; + case TIM_CHANNEL_2: + { + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + TIM_TI2_SetConfig(htim->Instance, sConfig->ICPolarity, + sConfig->ICSelection, sConfig->ICFilter); + + /* Reset the IC2PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC; + + /* Select the Trigger source */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= TIM_TS_TI2FP2; + + /* Select the Slave Mode */ + htim->Instance->SMCR &= ~TIM_SMCR_SMS; + htim->Instance->SMCR |= TIM_SLAVEMODE_TRIGGER; + } + break; + + default: + break; + } + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Configure the DMA Burst to transfer Data from the memory to the TIM peripheral + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param BurstBaseAddress: TIM Base address from when the DMA will starts the Data write. + * This parameters can be on of the following values: + * @arg TIM_DMABASE_CR1 + * @arg TIM_DMABASE_CR2 + * @arg TIM_DMABASE_SMCR + * @arg TIM_DMABASE_DIER + * @arg TIM_DMABASE_SR + * @arg TIM_DMABASE_EGR + * @arg TIM_DMABASE_CCMR1 + * @arg TIM_DMABASE_CCMR2 + * @arg TIM_DMABASE_CCER + * @arg TIM_DMABASE_CNT + * @arg TIM_DMABASE_PSC + * @arg TIM_DMABASE_ARR + * @arg TIM_DMABASE_RCR + * @arg TIM_DMABASE_CCR1 + * @arg TIM_DMABASE_CCR2 + * @arg TIM_DMABASE_CCR3 + * @arg TIM_DMABASE_CCR4 + * @arg TIM_DMABASE_BDTR + * @arg TIM_DMABASE_DCR + * @param BurstRequestSrc: TIM DMA Request sources. + * This parameters can be on of the following values: + * @arg TIM_DMA_UPDATE: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_TRIGGER: TIM Trigger DMA source + * @param BurstBuffer: The Buffer address. + * @param BurstLength: DMA Burst length. This parameter can be one value + * between TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_18TRANSFERS. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, uint32_t BurstRequestSrc, + uint32_t* BurstBuffer, uint32_t BurstLength) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMABURST_INSTANCE(htim->Instance)); + assert_param(IS_TIM_DMA_BASE(BurstBaseAddress)); + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + assert_param(IS_TIM_DMA_LENGTH(BurstLength)); + + if((htim->State == HAL_TIM_STATE_BUSY)) + { + return HAL_BUSY; + } + else if((htim->State == HAL_TIM_STATE_READY)) + { + if((BurstBuffer == 0 ) && (BurstLength > 0)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + switch(BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)BurstBuffer, (uint32_t)&htim->Instance->DMAR, ((BurstLength) >> 8) + 1); + } + break; + case TIM_DMA_CC1: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)BurstBuffer, (uint32_t)&htim->Instance->DMAR, ((BurstLength) >> 8) + 1); + } + break; + case TIM_DMA_CC2: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)BurstBuffer, (uint32_t)&htim->Instance->DMAR, ((BurstLength) >> 8) + 1); + } + break; + case TIM_DMA_CC3: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)BurstBuffer, (uint32_t)&htim->Instance->DMAR, ((BurstLength) >> 8) + 1); + } + break; + case TIM_DMA_CC4: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)BurstBuffer, (uint32_t)&htim->Instance->DMAR, ((BurstLength) >> 8) + 1); + } + break; + case TIM_DMA_COM: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_COMMUTATION], (uint32_t)BurstBuffer, (uint32_t)&htim->Instance->DMAR, ((BurstLength) >> 8) + 1); + } + break; + case TIM_DMA_TRIGGER: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_TRIGGER]->XferCpltCallback = TIM_DMATriggerCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_TRIGGER]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_TRIGGER], (uint32_t)BurstBuffer, (uint32_t)&htim->Instance->DMAR, ((BurstLength) >> 8) + 1); + } + break; + default: + break; + } + /* configure the DMA Burst Mode */ + htim->Instance->DCR = BurstBaseAddress | BurstLength; + + /* Enable the TIM DMA Request */ + __HAL_TIM_ENABLE_DMA(htim, BurstRequestSrc); + + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM DMA Burst mode + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param BurstRequestSrc: TIM DMA Request sources to disable + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + + /* Abort the DMA transfer (at least disable the DMA channel) */ + switch(BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_UPDATE]); + } + break; + case TIM_DMA_CC1: + { + HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_CC1]); + } + break; + case TIM_DMA_CC2: + { + HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_CC2]); + } + break; + case TIM_DMA_CC3: + { + HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_CC3]); + } + break; + case TIM_DMA_CC4: + { + HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_CC4]); + } + break; + case TIM_DMA_COM: + { + HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_COMMUTATION]); + } + break; + case TIM_DMA_TRIGGER: + { + HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_TRIGGER]); + } + break; + default: + break; + } + + /* Disable the TIM Update DMA request */ + __HAL_TIM_DISABLE_DMA(htim, BurstRequestSrc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Configure the DMA Burst to transfer Data from the TIM peripheral to the memory + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param BurstBaseAddress: TIM Base address from when the DMA will starts the Data read. + * This parameters can be on of the following values: + * @arg TIM_DMABASE_CR1 + * @arg TIM_DMABASE_CR2 + * @arg TIM_DMABASE_SMCR + * @arg TIM_DMABASE_DIER + * @arg TIM_DMABASE_SR + * @arg TIM_DMABASE_EGR + * @arg TIM_DMABASE_CCMR1 + * @arg TIM_DMABASE_CCMR2 + * @arg TIM_DMABASE_CCER + * @arg TIM_DMABASE_CNT + * @arg TIM_DMABASE_PSC + * @arg TIM_DMABASE_ARR + * @arg TIM_DMABASE_RCR + * @arg TIM_DMABASE_CCR1 + * @arg TIM_DMABASE_CCR2 + * @arg TIM_DMABASE_CCR3 + * @arg TIM_DMABASE_CCR4 + * @arg TIM_DMABASE_BDTR + * @arg TIM_DMABASE_DCR + * @param BurstRequestSrc: TIM DMA Request sources. + * This parameters can be on of the following values: + * @arg TIM_DMA_UPDATE: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_TRIGGER: TIM Trigger DMA source + * @param BurstBuffer: The Buffer address. + * @param BurstLength: DMA Burst length. This parameter can be one value + * between TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_18TRANSFERS. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, uint32_t BurstRequestSrc, + uint32_t *BurstBuffer, uint32_t BurstLength) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMABURST_INSTANCE(htim->Instance)); + assert_param(IS_TIM_DMA_BASE(BurstBaseAddress)); + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + assert_param(IS_TIM_DMA_LENGTH(BurstLength)); + + if((htim->State == HAL_TIM_STATE_BUSY)) + { + return HAL_BUSY; + } + else if((htim->State == HAL_TIM_STATE_READY)) + { + if((BurstBuffer == 0 ) && (BurstLength > 0)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + switch(BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, ((BurstLength) >> 8) + 1); + } + break; + case TIM_DMA_CC1: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, ((BurstLength) >> 8) + 1); + } + break; + case TIM_DMA_CC2: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, ((BurstLength) >> 8) + 1); + } + break; + case TIM_DMA_CC3: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMACaptureCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, ((BurstLength) >> 8) + 1); + } + break; + case TIM_DMA_CC4: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMACaptureCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, ((BurstLength) >> 8) + 1); + } + break; + case TIM_DMA_COM: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_COMMUTATION], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, ((BurstLength) >> 8) + 1); + } + break; + case TIM_DMA_TRIGGER: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_TRIGGER]->XferCpltCallback = TIM_DMATriggerCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_TRIGGER]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_TRIGGER], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, ((BurstLength) >> 8) + 1); + } + break; + default: + break; + } + + /* configure the DMA Burst Mode */ + htim->Instance->DCR = BurstBaseAddress | BurstLength; + + /* Enable the TIM DMA Request */ + __HAL_TIM_ENABLE_DMA(htim, BurstRequestSrc); + + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stop the DMA burst reading + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param BurstRequestSrc: TIM DMA Request sources to disable. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + + /* Abort the DMA transfer (at least disable the DMA channel) */ + switch(BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_UPDATE]); + } + break; + case TIM_DMA_CC1: + { + HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_CC1]); + } + break; + case TIM_DMA_CC2: + { + HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_CC2]); + } + break; + case TIM_DMA_CC3: + { + HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_CC3]); + } + break; + case TIM_DMA_CC4: + { + HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_CC4]); + } + break; + case TIM_DMA_COM: + { + HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_COMMUTATION]); + } + break; + case TIM_DMA_TRIGGER: + { + HAL_DMA_Abort(htim->hdma[TIM_DMA_ID_TRIGGER]); + } + break; + default: + break; + } + + /* Disable the TIM Update DMA request */ + __HAL_TIM_DISABLE_DMA(htim, BurstRequestSrc); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Generate a software event + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param EventSource: specifies the event source. + * This parameter can be one of the following values: + * @arg TIM_EVENTSOURCE_UPDATE: Timer update Event source + * @arg TIM_EVENTSOURCE_CC1: Timer Capture Compare 1 Event source + * @arg TIM_EVENTSOURCE_CC2: Timer Capture Compare 2 Event source + * @arg TIM_EVENTSOURCE_CC3: Timer Capture Compare 3 Event source + * @arg TIM_EVENTSOURCE_CC4: Timer Capture Compare 4 Event source + * @arg TIM_EVENTSOURCE_COM: Timer COM event source + * @arg TIM_EVENTSOURCE_TRIGGER: Timer Trigger Event source + * @arg TIM_EVENTSOURCE_BREAK: Timer Break event source + * @note TIM6 and TIM7 can only generate an update event. + * @note TIM_EVENTSOURCE_COM and TIM_EVENTSOURCE_BREAK are used only with TIM1 and TIM8. + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, uint32_t EventSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_EVENT_SOURCE(EventSource)); + + /* Process Locked */ + __HAL_LOCK(htim); + + /* Change the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Set the event sources */ + htim->Instance->EGR = EventSource; + + /* Change the TIM state */ + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Configures the OCRef clear feature + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param sClearInputConfig: pointer to a TIM_ClearInputConfigTypeDef structure that + * contains the OCREF clear feature and parameters for the TIM peripheral. + * @param Channel: specifies the TIM Channel. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_ConfigOCrefClear(TIM_HandleTypeDef *htim, TIM_ClearInputConfigTypeDef * sClearInputConfig, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + assert_param(IS_TIM_CHANNELS(Channel)); + assert_param(IS_TIM_CLEARINPUT_SOURCE(sClearInputConfig->ClearInputSource)); + assert_param(IS_TIM_CLEARINPUT_POLARITY(sClearInputConfig->ClearInputPolarity)); + assert_param(IS_TIM_CLEARINPUT_PRESCALER(sClearInputConfig->ClearInputPrescaler)); + assert_param(IS_TIM_CLEARINPUT_FILTER(sClearInputConfig->ClearInputFilter)); + + /* Process Locked */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + if(sClearInputConfig->ClearInputSource == TIM_CLEARINPUTSOURCE_ETR) + { + TIM_ETR_SetConfig(htim->Instance, + sClearInputConfig->ClearInputPrescaler, + sClearInputConfig->ClearInputPolarity, + sClearInputConfig->ClearInputFilter); + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + if(sClearInputConfig->ClearInputState != RESET) + { + /* Enable the Ocref clear feature for Channel 1 */ + htim->Instance->CCMR1 |= TIM_CCMR1_OC1CE; + } + else + { + /* Disable the Ocref clear feature for Channel 1 */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_OC1CE; + } + } + break; + case TIM_CHANNEL_2: + { + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + if(sClearInputConfig->ClearInputState != RESET) + { + /* Enable the Ocref clear feature for Channel 2 */ + htim->Instance->CCMR1 |= TIM_CCMR1_OC2CE; + } + else + { + /* Disable the Ocref clear feature for Channel 2 */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_OC2CE; + } + } + break; + case TIM_CHANNEL_3: + { + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + if(sClearInputConfig->ClearInputState != RESET) + { + /* Enable the Ocref clear feature for Channel 3 */ + htim->Instance->CCMR2 |= TIM_CCMR2_OC3CE; + } + else + { + /* Disable the Ocref clear feature for Channel 3 */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_OC3CE; + } + } + break; + case TIM_CHANNEL_4: + { + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + if(sClearInputConfig->ClearInputState != RESET) + { + /* Enable the Ocref clear feature for Channel 4 */ + htim->Instance->CCMR2 |= TIM_CCMR2_OC4CE; + } + else + { + /* Disable the Ocref clear feature for Channel 4 */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_OC4CE; + } + } + break; + default: + break; + } + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the clock source to be used + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param sClockSourceConfig: pointer to a TIM_ClockConfigTypeDef structure that + * contains the clock source information for the TIM peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_ConfigClockSource(TIM_HandleTypeDef *htim, TIM_ClockConfigTypeDef * sClockSourceConfig) +{ + uint32_t tmpsmcr = 0; + + /* Process Locked */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_TIM_CLOCKSOURCE(sClockSourceConfig->ClockSource)); + assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity)); + assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler)); + assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter)); + + /* Reset the SMS, TS, ECE, ETPS and ETRF bits */ + tmpsmcr = htim->Instance->SMCR; + tmpsmcr &= ~(TIM_SMCR_SMS | TIM_SMCR_TS); + tmpsmcr &= ~(TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP); + htim->Instance->SMCR = tmpsmcr; + + switch (sClockSourceConfig->ClockSource) + { + case TIM_CLOCKSOURCE_INTERNAL: + { + assert_param(IS_TIM_INSTANCE(htim->Instance)); + /* Disable slave mode to clock the prescaler directly with the internal clock */ + htim->Instance->SMCR &= ~TIM_SMCR_SMS; + } + break; + + case TIM_CLOCKSOURCE_ETRMODE1: + { + assert_param(IS_TIM_ETR_INSTANCE(htim->Instance)); + /* Configure the ETR Clock source */ + TIM_ETR_SetConfig(htim->Instance, + sClockSourceConfig->ClockPrescaler, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + /* Get the TIMx SMCR register value */ + tmpsmcr = htim->Instance->SMCR; + /* Reset the SMS and TS Bits */ + tmpsmcr &= ~(TIM_SMCR_SMS | TIM_SMCR_TS); + /* Select the External clock mode1 and the ETRF trigger */ + tmpsmcr |= (TIM_SLAVEMODE_EXTERNAL1 | TIM_CLOCKSOURCE_ETRMODE1); + /* Write to TIMx SMCR */ + htim->Instance->SMCR = tmpsmcr; + } + break; + + case TIM_CLOCKSOURCE_ETRMODE2: + { + assert_param(IS_TIM_ETR_INSTANCE(htim->Instance)); + /* Configure the ETR Clock source */ + TIM_ETR_SetConfig(htim->Instance, + sClockSourceConfig->ClockPrescaler, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + /* Enable the External clock mode2 */ + htim->Instance->SMCR |= TIM_SMCR_ECE; + } + break; + + case TIM_CLOCKSOURCE_TI1: + { + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + TIM_TI1_ConfigInputStage(htim->Instance, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1); + } + break; + case TIM_CLOCKSOURCE_TI2: + { + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + TIM_TI2_ConfigInputStage(htim->Instance, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI2); + } + break; + case TIM_CLOCKSOURCE_TI1ED: + { + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + TIM_TI1_ConfigInputStage(htim->Instance, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1ED); + } + break; + case TIM_CLOCKSOURCE_ITR0: + { + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR0); + } + break; + case TIM_CLOCKSOURCE_ITR1: + { + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR1); + } + break; + case TIM_CLOCKSOURCE_ITR2: + { + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR2); + } + break; + case TIM_CLOCKSOURCE_ITR3: + { + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_ITR3); + } + break; + + default: + break; + } + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Selects the signal connected to the TI1 input: direct from CH1_input + * or a XOR combination between CH1_input, CH2_input & CH3_input + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param TI1_Selection: Indicate whether or not channel 1 is connected to the + * output of a XOR gate. + * This parameter can be one of the following values: + * @arg TIM_TI1SELECTION_CH1: The TIMx_CH1 pin is connected to TI1 input + * @arg TIM_TI1SELECTION_XORCOMBINATION: The TIMx_CH1, CH2 and CH3 + * pins are connected to the TI1 input (XOR combination) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_ConfigTI1Input(TIM_HandleTypeDef *htim, uint32_t TI1_Selection) +{ + uint32_t tmpcr2 = 0; + + /* Check the parameters */ + assert_param(IS_TIM_XOR_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TI1SELECTION(TI1_Selection)); + + /* Get the TIMx CR2 register value */ + tmpcr2 = htim->Instance->CR2; + + /* Reset the TI1 selection */ + tmpcr2 &= ~TIM_CR2_TI1S; + + /* Set the TI1 selection */ + tmpcr2 |= TI1_Selection; + + /* Write to TIMxCR2 */ + htim->Instance->CR2 = tmpcr2; + + return HAL_OK; +} + +/** + * @brief Configures the TIM in Slave mode + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param sSlaveConfig: pointer to a TIM_SlaveConfigTypeDef structure that + * contains the selected trigger (internal trigger input, filtered + * timer input or external trigger input) and the ) and the Slave + * mode (Disable, Reset, Gated, Trigger, External clock mode 1). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchronization(TIM_HandleTypeDef *htim, TIM_SlaveConfigTypeDef * sSlaveConfig) +{ + /* Check the parameters */ + assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance)); + assert_param(IS_TIM_SLAVE_MODE(sSlaveConfig->SlaveMode)); + assert_param(IS_TIM_TRIGGER_SELECTION(sSlaveConfig->InputTrigger)); + + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + TIM_SlaveTimer_SetConfig(htim, sSlaveConfig); + + /* Disable Trigger Interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_TRIGGER); + + /* Disable Trigger DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_TRIGGER); + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the TIM in Slave mode in interrupt mode + * @param htim: TIM handle. + * @param sSlaveConfig: pointer to a TIM_SlaveConfigTypeDef structure that + * contains the selected trigger (internal trigger input, filtered + * timer input or external trigger input) and the ) and the Slave + * mode (Disable, Reset, Gated, Trigger, External clock mode 1). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchronization_IT(TIM_HandleTypeDef *htim, + TIM_SlaveConfigTypeDef * sSlaveConfig) +{ + /* Check the parameters */ + assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance)); + assert_param(IS_TIM_SLAVE_MODE(sSlaveConfig->SlaveMode)); + assert_param(IS_TIM_TRIGGER_SELECTION(sSlaveConfig->InputTrigger)); + + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + TIM_SlaveTimer_SetConfig(htim, sSlaveConfig); + + /* Enable Trigger Interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_TRIGGER); + + /* Disable Trigger DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_TRIGGER); + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Read the captured value from Capture Compare unit + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channels to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval Captured value + */ +uint32_t HAL_TIM_ReadCapturedValue(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpreg = 0; + + __HAL_LOCK(htim); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + /* Return the capture 1 value */ + tmpreg = htim->Instance->CCR1; + + break; + } + case TIM_CHANNEL_2: + { + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Return the capture 2 value */ + tmpreg = htim->Instance->CCR2; + + break; + } + + case TIM_CHANNEL_3: + { + /* Check the parameters */ + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + + /* Return the capture 3 value */ + tmpreg = htim->Instance->CCR3; + + break; + } + + case TIM_CHANNEL_4: + { + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + + /* Return the capture 4 value */ + tmpreg = htim->Instance->CCR4; + + break; + } + + default: + break; + } + + __HAL_UNLOCK(htim); + return tmpreg; +} +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group9 TIM Callbacks functions + * @brief TIM Callbacks functions + * +@verbatim + ============================================================================== + ##### TIM Callbacks functions ##### + ============================================================================== + [..] + This section provides TIM callback functions: + (+) Timer Period elapsed callback + (+) Timer Output Compare callback + (+) Timer Input capture callback + (+) Timer Trigger callback + (+) Timer Error callback + +@endverbatim + * @{ + */ + +/** + * @brief Period elapsed callback in non blocking mode + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the __HAL_TIM_PeriodElapsedCallback could be implemented in the user file + */ + +} +/** + * @brief Output Compare callback in non blocking mode + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the __HAL_TIM_OC_DelayElapsedCallback could be implemented in the user file + */ +} +/** + * @brief Input Capture callback in non blocking mode + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the __HAL_TIM_IC_CaptureCallback could be implemented in the user file + */ +} + +/** + * @brief PWM Pulse finished callback in non blocking mode + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the __HAL_TIM_PWM_PulseFinishedCallback could be implemented in the user file + */ +} + +/** + * @brief Hall Trigger detection callback in non blocking mode + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIM_TriggerCallback could be implemented in the user file + */ +} + +/** + * @brief Timer error callback in non blocking mode + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIM_ErrorCallback(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIM_ErrorCallback could be implemented in the user file + */ +} +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group10 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + ============================================================================== + ##### Peripheral State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the TIM Base state + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM OC state + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_OC_GetState(TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM PWM state + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_PWM_GetState(TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM Input Capture state + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_IC_GetState(TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM One Pulse Mode state + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_OnePulse_GetState(TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM Encoder Mode state + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_Encoder_GetState(TIM_HandleTypeDef *htim) +{ + return htim->State; +} +/** + * @} + */ + +/** + * @brief Time Base configuration + * @param TIMx: TIM peripheral + * @param Structure: pointer on TIM Time Base required parameters + * @retval None + */ +void TIM_Base_SetConfig(TIM_TypeDef *TIMx, TIM_Base_InitTypeDef *Structure) +{ + uint32_t tmpcr1 = 0; + tmpcr1 = TIMx->CR1; + + /* Set TIM Time Base Unit parameters ---------------------------------------*/ + if(IS_TIM_CC3_INSTANCE(TIMx) != RESET) + { + /* Select the Counter Mode */ + tmpcr1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS); + tmpcr1 |= Structure->CounterMode; + } + + if(IS_TIM_CC1_INSTANCE(TIMx) != RESET) + { + /* Set the clock division */ + tmpcr1 &= ~TIM_CR1_CKD; + tmpcr1 |= (uint32_t)Structure->ClockDivision; + } + + TIMx->CR1 = tmpcr1; + + /* Set the Auto-reload value */ + TIMx->ARR = (uint32_t)Structure->Period ; + + /* Set the Prescaler value */ + TIMx->PSC = (uint32_t)Structure->Prescaler; + + if(IS_TIM_ADVANCED_INSTANCE(TIMx) != RESET) + { + /* Set the Repetition Counter value */ + TIMx->RCR = Structure->RepetitionCounter; + } + + /* Generate an update event to reload the Prescaler + and the repetition counter(only for TIM1 and TIM8) value immediately */ + TIMx->EGR = TIM_EGR_UG; +} + +/** + * @brief Configure the TI1 as Input. + * @param TIMx to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 1 is selected to be connected to IC1. + * @arg TIM_ICSelection_IndirectTI: TIM Input 1 is selected to be connected to IC2. + * @arg TIM_ICSelection_TRC: TIM Input 1 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI2FP1 + * (on channel2 path) is used as the input signal. Therefore CCMR1 must be + * protected against un-initialized filter and polarity values. + * @retval None + */ +void TIM_TI1_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1 = 0; + uint32_t tmpccer = 0; + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= ~TIM_CCER_CC1E; + tmpccmr1 = TIMx->CCMR1; + tmpccer = TIMx->CCER; + + /* Select the Input */ + if(IS_TIM_CC2_INSTANCE(TIMx) != RESET) + { + tmpccmr1 &= ~TIM_CCMR1_CC1S; + tmpccmr1 |= TIM_ICSelection; + } + else + { + tmpccmr1 &= ~TIM_CCMR1_CC1S; + tmpccmr1 |= TIM_CCMR1_CC1S_0; + } + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC1F; + tmpccmr1 |= ((TIM_ICFilter << 4) & TIM_CCMR1_IC1F); + + /* Select the Polarity and set the CC1E Bit */ + tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP); + tmpccer |= (TIM_ICPolarity & (TIM_CCER_CC1P | TIM_CCER_CC1NP)); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1; + TIMx->CCER = tmpccer; +} + +/** + * @brief Time Output Compare 2 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config: The output configuration structure + * @retval None + */ +void TIM_OC2_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx = 0; + uint32_t tmpccer = 0; + uint32_t tmpcr2 = 0; + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= ~TIM_CCER_CC2E; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR1; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= ~TIM_CCMR1_OC2M; + tmpccmrx &= ~TIM_CCMR1_CC2S; + + /* Select the Output Compare Mode */ + tmpccmrx |= (OC_Config->OCMode << 8); + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC2P; + /* Set the Output Compare Polarity */ + tmpccer |= (OC_Config->OCPolarity << 4); + + if(IS_TIM_ADVANCED_INSTANCE(TIMx) != RESET) + { + assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity)); + assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState)); + + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC2NP; + /* Set the Output N Polarity */ + tmpccer |= (OC_Config->OCNPolarity << 4); + /* Reset the Output N State */ + tmpccer &= ~TIM_CCER_CC2NE; + + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS2; + tmpcr2 &= ~TIM_CR2_OIS2N; + /* Set the Output Idle state */ + tmpcr2 |= (OC_Config->OCIdleState << 2); + /* Set the Output N Idle state */ + tmpcr2 |= (OC_Config->OCNIdleState << 2); + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR2 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief TIM DMA Delay Pulse complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +void TIM_DMADelayPulseCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef* htim = ( TIM_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + htim->State= HAL_TIM_STATE_READY; + + if(hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + } + else if(hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + } + else if(hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + } + else if(hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + } + + HAL_TIM_PWM_PulseFinishedCallback(htim); + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA error callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +void TIM_DMAError(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef* htim = ( TIM_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + htim->State= HAL_TIM_STATE_READY; + + HAL_TIM_ErrorCallback(htim); +} + +/** + * @brief TIM DMA Capture complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +void TIM_DMACaptureCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef* htim = ( TIM_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + htim->State= HAL_TIM_STATE_READY; + + if(hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + } + else if(hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + } + else if(hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + } + else if(hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + } + + HAL_TIM_IC_CaptureCallback(htim); + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel x. + * @param TIMx to select the TIM peripheral + * @param Channel: specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @arg TIM_Channel_4: TIM Channel 4 + * @param ChannelState: specifies the TIM Channel CCxE bit new state. + * This parameter can be: TIM_CCx_ENABLE or TIM_CCx_Disable. + * @retval None + */ +void TIM_CCxChannelCmd(TIM_TypeDef* TIMx, uint32_t Channel, uint32_t ChannelState) +{ + uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(TIMx)); + assert_param(IS_TIM_CHANNELS(Channel)); + + tmp = TIM_CCER_CC1E << Channel; + + /* Reset the CCxE Bit */ + TIMx->CCER &= ~tmp; + + /* Set or reset the CCxE Bit */ + TIMx->CCER |= (uint32_t)(ChannelState << Channel); +} + +/** + * @brief TIM DMA Period Elapse complete callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void TIM_DMAPeriodElapsedCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef* htim = ( TIM_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + htim->State= HAL_TIM_STATE_READY; + + HAL_TIM_PeriodElapsedCallback(htim); +} + +/** + * @brief TIM DMA Trigger callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void TIM_DMATriggerCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef* htim = ( TIM_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + htim->State= HAL_TIM_STATE_READY; + + HAL_TIM_TriggerCallback(htim); +} + +/** + * @brief Time Output Compare 1 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config: The output configuration structure + * @retval None + */ +static void TIM_OC1_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx = 0; + uint32_t tmpccer = 0; + uint32_t tmpcr2 = 0; + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= ~TIM_CCER_CC1E; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR1; + + /* Reset the Output Compare Mode Bits */ + tmpccmrx &= ~TIM_CCMR1_OC1M; + tmpccmrx &= ~TIM_CCMR1_CC1S; + /* Select the Output Compare Mode */ + tmpccmrx |= OC_Config->OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC1P; + /* Set the Output Compare Polarity */ + tmpccer |= OC_Config->OCPolarity; + + + if(IS_TIM_ADVANCED_INSTANCE(TIMx) != RESET) + { + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC1NP; + /* Set the Output N Polarity */ + tmpccer |= OC_Config->OCNPolarity; + /* Reset the Output N State */ + tmpccer &= ~TIM_CCER_CC1NE; + + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS1; + tmpcr2 &= ~TIM_CR2_OIS1N; + /* Set the Output Idle state */ + tmpcr2 |= OC_Config->OCIdleState; + /* Set the Output N Idle state */ + tmpcr2 |= OC_Config->OCNIdleState; + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR1 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Time Output Compare 3 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config: The output configuration structure + * @retval None + */ +static void TIM_OC3_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx = 0; + uint32_t tmpccer = 0; + uint32_t tmpcr2 = 0; + + /* Disable the Channel 3: Reset the CC2E Bit */ + TIMx->CCER &= ~TIM_CCER_CC3E; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR2 register value */ + tmpccmrx = TIMx->CCMR2; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= ~TIM_CCMR2_OC3M; + tmpccmrx &= ~TIM_CCMR2_CC3S; + /* Select the Output Compare Mode */ + tmpccmrx |= OC_Config->OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC3P; + /* Set the Output Compare Polarity */ + tmpccer |= (OC_Config->OCPolarity << 8); + + if(IS_TIM_ADVANCED_INSTANCE(TIMx) != RESET) + { + assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity)); + assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState)); + + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC3NP; + /* Set the Output N Polarity */ + tmpccer |= (OC_Config->OCNPolarity << 8); + /* Reset the Output N State */ + tmpccer &= ~TIM_CCER_CC3NE; + + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS3; + tmpcr2 &= ~TIM_CR2_OIS3N; + /* Set the Output Idle state */ + tmpcr2 |= (OC_Config->OCIdleState << 4); + /* Set the Output N Idle state */ + tmpcr2 |= (OC_Config->OCNIdleState << 4); + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR3 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Time Output Compare 4 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config: The output configuration structure + * @retval None + */ +static void TIM_OC4_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx = 0; + uint32_t tmpccer = 0; + uint32_t tmpcr2 = 0; + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= ~TIM_CCER_CC4E; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR2 register value */ + tmpccmrx = TIMx->CCMR2; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= ~TIM_CCMR2_OC4M; + tmpccmrx &= ~TIM_CCMR2_CC4S; + + /* Select the Output Compare Mode */ + tmpccmrx |= (OC_Config->OCMode << 8); + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC4P; + /* Set the Output Compare Polarity */ + tmpccer |= (OC_Config->OCPolarity << 12); + + /*if((TIMx == TIM1) || (TIMx == TIM8))*/ + if(IS_TIM_ADVANCED_INSTANCE(TIMx) != RESET) + { + assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState)); + /* Reset the Output Compare IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS4; + /* Set the Output Idle state */ + tmpcr2 |= (OC_Config->OCIdleState << 6); + } + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR4 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Time Output Compare 4 configuration + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param sSlaveConfig: The slave configuration structure + * @retval None + */ +static void TIM_SlaveTimer_SetConfig(TIM_HandleTypeDef *htim, + TIM_SlaveConfigTypeDef * sSlaveConfig) +{ + uint32_t tmpsmcr = 0; + uint32_t tmpccmr1 = 0; + uint32_t tmpccer = 0; + + /* Get the TIMx SMCR register value */ + tmpsmcr = htim->Instance->SMCR; + + /* Reset the Trigger Selection Bits */ + tmpsmcr &= ~TIM_SMCR_TS; + /* Set the Input Trigger source */ + tmpsmcr |= sSlaveConfig->InputTrigger; + + /* Reset the slave mode Bits */ + tmpsmcr &= ~TIM_SMCR_SMS; + /* Set the slave mode */ + tmpsmcr |= sSlaveConfig->SlaveMode; + + /* Write to TIMx SMCR */ + htim->Instance->SMCR = tmpsmcr; + + /* Configure the trigger prescaler, filter, and polarity */ + switch (sSlaveConfig->InputTrigger) + { + case TIM_TS_ETRF: + { + /* Check the parameters */ + assert_param(IS_TIM_ETR_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRIGGERPRESCALER(sSlaveConfig->TriggerPrescaler)); + assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity)); + assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter)); + /* Configure the ETR Trigger source */ + TIM_ETR_SetConfig(htim->Instance, + sSlaveConfig->TriggerPrescaler, + sSlaveConfig->TriggerPolarity, + sSlaveConfig->TriggerFilter); + } + break; + + case TIM_TS_TI1F_ED: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter)); + + /* Disable the Channel 1: Reset the CC1E Bit */ + tmpccer = htim->Instance->CCER; + htim->Instance->CCER &= ~TIM_CCER_CC1E; + tmpccmr1 = htim->Instance->CCMR1; + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC1F; + tmpccmr1 |= ((sSlaveConfig->TriggerFilter) << 4); + + /* Write to TIMx CCMR1 and CCER registers */ + htim->Instance->CCMR1 = tmpccmr1; + htim->Instance->CCER = tmpccer; + + } + break; + + case TIM_TS_TI1FP1: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity)); + assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter)); + + /* Configure TI1 Filter and Polarity */ + TIM_TI1_ConfigInputStage(htim->Instance, + sSlaveConfig->TriggerPolarity, + sSlaveConfig->TriggerFilter); + } + break; + + case TIM_TS_TI2FP2: + { + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity)); + assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter)); + + /* Configure TI2 Filter and Polarity */ + TIM_TI2_ConfigInputStage(htim->Instance, + sSlaveConfig->TriggerPolarity, + sSlaveConfig->TriggerFilter); + } + break; + + case TIM_TS_ITR0: + { + /* Check the parameter */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + } + break; + + case TIM_TS_ITR1: + { + /* Check the parameter */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + } + break; + + case TIM_TS_ITR2: + { + /* Check the parameter */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + } + break; + + case TIM_TS_ITR3: + { + /* Check the parameter */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + } + break; + + default: + break; + } +} + + +/** + * @brief Configure the Polarity and Filter for TI1. + * @param TIMx to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TIM_TI1_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1 = 0; + uint32_t tmpccer = 0; + + /* Disable the Channel 1: Reset the CC1E Bit */ + tmpccer = TIMx->CCER; + TIMx->CCER &= ~TIM_CCER_CC1E; + tmpccmr1 = TIMx->CCMR1; + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC1F; + tmpccmr1 |= (TIM_ICFilter << 4); + + /* Select the Polarity and set the CC1E Bit */ + tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP); + tmpccer |= TIM_ICPolarity; + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI2 as Input. + * @param TIMx to select the TIM peripheral + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 2 is selected to be connected to IC2. + * @arg TIM_ICSelection_IndirectTI: TIM Input 2 is selected to be connected to IC1. + * @arg TIM_ICSelection_TRC: TIM Input 2 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI1FP2 + * (on channel1 path) is used as the input signal. Therefore CCMR1 must be + * protected against un-initialized filter and polarity values. + * @retval None + */ +static void TIM_TI2_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1 = 0; + uint32_t tmpccer = 0; + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= ~TIM_CCER_CC2E; + tmpccmr1 = TIMx->CCMR1; + tmpccer = TIMx->CCER; + + /* Select the Input */ + tmpccmr1 &= ~TIM_CCMR1_CC2S; + tmpccmr1 |= (TIM_ICSelection << 8); + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC2F; + tmpccmr1 |= ((TIM_ICFilter << 12) & TIM_CCMR1_IC2F); + + /* Select the Polarity and set the CC2E Bit */ + tmpccer &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP); + tmpccer |= ((TIM_ICPolarity << 4) & (TIM_CCER_CC2P | TIM_CCER_CC2NP)); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1 ; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the Polarity and Filter for TI2. + * @param TIMx to select the TIM peripheral. + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TIM_TI2_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1 = 0; + uint32_t tmpccer = 0; + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= ~TIM_CCER_CC2E; + tmpccmr1 = TIMx->CCMR1; + tmpccer = TIMx->CCER; + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC2F; + tmpccmr1 |= (TIM_ICFilter << 12); + + /* Select the Polarity and set the CC2E Bit */ + tmpccer &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP); + tmpccer |= (TIM_ICPolarity << 4); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1 ; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI3 as Input. + * @param TIMx to select the TIM peripheral + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 3 is selected to be connected to IC3. + * @arg TIM_ICSelection_IndirectTI: TIM Input 3 is selected to be connected to IC4. + * @arg TIM_ICSelection_TRC: TIM Input 3 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI4FP3 + * (on channel4 path) is used as the input signal. Therefore CCMR2 must be + * protected against un-initialized filter and polarity values. + * @retval None + */ +static void TIM_TI3_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr2 = 0; + uint32_t tmpccer = 0; + + /* Disable the Channel 3: Reset the CC3E Bit */ + TIMx->CCER &= ~TIM_CCER_CC3E; + tmpccmr2 = TIMx->CCMR2; + tmpccer = TIMx->CCER; + + /* Select the Input */ + tmpccmr2 &= ~TIM_CCMR2_CC3S; + tmpccmr2 |= TIM_ICSelection; + + /* Set the filter */ + tmpccmr2 &= ~TIM_CCMR2_IC3F; + tmpccmr2 |= ((TIM_ICFilter << 4) & TIM_CCMR2_IC3F); + + /* Select the Polarity and set the CC3E Bit */ + tmpccer &= ~(TIM_CCER_CC3P | TIM_CCER_CC3NP); + tmpccer |= ((TIM_ICPolarity << 8) & (TIM_CCER_CC3P | TIM_CCER_CC3NP)); + + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI4 as Input. + * @param TIMx to select the TIM peripheral + * @param TIM_ICPolarity : The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPolarity_Rising + * @arg TIM_ICPolarity_Falling + * @arg TIM_ICPolarity_BothEdge + * @param TIM_ICSelection: specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSelection_DirectTI: TIM Input 4 is selected to be connected to IC4. + * @arg TIM_ICSelection_IndirectTI: TIM Input 4 is selected to be connected to IC3. + * @arg TIM_ICSelection_TRC: TIM Input 4 is selected to be connected to TRC. + * @param TIM_ICFilter: Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI3FP4 + * (on channel3 path) is used as the input signal. Therefore CCMR2 must be + * protected against un-initialized filter and polarity values. + * @retval None + */ +static void TIM_TI4_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr2 = 0; + uint32_t tmpccer = 0; + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= ~TIM_CCER_CC4E; + tmpccmr2 = TIMx->CCMR2; + tmpccer = TIMx->CCER; + + /* Select the Input */ + tmpccmr2 &= ~TIM_CCMR2_CC4S; + tmpccmr2 |= (TIM_ICSelection << 8); + + /* Set the filter */ + tmpccmr2 &= ~TIM_CCMR2_IC4F; + tmpccmr2 |= ((TIM_ICFilter << 12) & TIM_CCMR2_IC4F); + + /* Select the Polarity and set the CC4E Bit */ + tmpccer &= ~(TIM_CCER_CC4P | TIM_CCER_CC4NP); + tmpccer |= ((TIM_ICPolarity << 12) & (TIM_CCER_CC4P | TIM_CCER_CC4NP)); + + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer ; +} + +/** + * @brief Selects the Input Trigger source + * @param TIMx to select the TIM peripheral + * @param TIM_ITRx: The Input Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal Trigger 0 + * @arg TIM_TS_ITR1: Internal Trigger 1 + * @arg TIM_TS_ITR2: Internal Trigger 2 + * @arg TIM_TS_ITR3: Internal Trigger 3 + * @arg TIM_TS_TI1F_ED: TI1 Edge Detector + * @arg TIM_TS_TI1FP1: Filtered Timer Input 1 + * @arg TIM_TS_TI2FP2: Filtered Timer Input 2 + * @arg TIM_TS_ETRF: External Trigger input + * @retval None + */ +static void TIM_ITRx_SetConfig(TIM_TypeDef *TIMx, uint16_t TIM_ITRx) +{ + uint32_t tmpsmcr = 0; + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + /* Reset the TS Bits */ + tmpsmcr &= ~TIM_SMCR_TS; + /* Set the Input Trigger source and the slave mode*/ + tmpsmcr |= TIM_ITRx | TIM_SLAVEMODE_EXTERNAL1; + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @brief Configures the TIMx External Trigger (ETR). + * @param TIMx to select the TIM peripheral + * @param TIM_ExtTRGPrescaler: The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPSC_DIV1: ETRP Prescaler OFF. + * @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2. + * @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4. + * @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity: The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active. + * @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active. + * @param ExtTRGFilter: External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +static void TIM_ETR_SetConfig(TIM_TypeDef* TIMx, uint32_t TIM_ExtTRGPrescaler, + uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter) +{ + uint32_t tmpsmcr = 0; + + tmpsmcr = TIMx->SMCR; + + /* Reset the ETR Bits */ + tmpsmcr &= ~(TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP); + + /* Set the Prescaler, the Filter value and the Polarity */ + tmpsmcr |= (uint32_t)(TIM_ExtTRGPrescaler | (TIM_ExtTRGPolarity | (ExtTRGFilter << 8))); + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @} + */ + +#endif /* HAL_TIM_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c new file mode 100644 index 0000000..9feb385 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c @@ -0,0 +1,1864 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_tim_ex.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief TIM HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Timer extension peripheral: + * + Time Hall Sensor Interface Initialization + * + Time Hall Sensor Interface Start + * + Time Complementary signal bread and dead time configuration + * + Time Master and Slave synchronization configuration + @verbatim + ============================================================================== + ##### TIMER Extended features ##### + ============================================================================== + [..] + The Timer Extension features include: + (#) Complementary outputs with programmable dead-time for : + (++) Input Capture + (++) Output Compare + (++) PWM generation (Edge and Center-aligned Mode) + (++) One-pulse mode output + (#) Synchronization circuit to control the timer with external signals and to + interconnect several timers together. + (#) Break input to put the timer output signals in reset state or in a known state. + (#) Supports incremental (quadrature) encoder and hall-sensor circuitry for + positioning purposes + + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Initialize the TIM low level resources by implementing the following functions + depending from feature used : + (++) Complementary Output Compare : HAL_TIM_OC_MspInit() + (++) Complementary PWM generation : HAL_TIM_PWM_MspInit() + (++) Complementary One-pulse mode output : HAL_TIM_OnePulse_MspInit() + (++) Hall Sensor output : HAL_TIM_HallSensor_MspInit() + + (#) Initialize the TIM low level resources : + (##) Enable the TIM interface clock using __TIMx_CLK_ENABLE(); + (##) TIM pins configuration + (+++) Enable the clock for the TIM GPIOs using the following function: + __GPIOx_CLK_ENABLE(); + (+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init(); + + (#) The external Clock can be configured, if needed (the default clock is the + internal clock from the APBx), using the following function: + HAL_TIM_ConfigClockSource, the clock configuration should be done before + any start function. + + (#) Configure the TIM in the desired functioning mode using one of the + initialization function of this driver: + (++) HAL_TIMEx_HallSensor_Init and HAL_TIMEx_ConfigCommutationEvent: to use the + Timer Hall Sensor Interface and the commutation event with the corresponding + Interrupt and DMA request if needed (Note that One Timer is used to interface + with the Hall sensor Interface and another Timer should be used to use + the commutation event). + + (#) Activate the TIM peripheral using one of the start functions: + (++) Complementary Output Compare : HAL_TIMEx_OCN_Start(), HAL_TIMEx_OCN_Start_DMA(), HAL_TIMEx_OC_Start_IT() + (++) Complementary PWM generation : HAL_TIMEx_PWMN_Start(), HAL_TIMEx_PWMN_Start_DMA(), HAL_TIMEx_PWMN_Start_IT() + (++) Complementary One-pulse mode output : HAL_TIMEx_OnePulseN_Start(), HAL_TIMEx_OnePulseN_Start_IT() + (++) Hall Sensor output : HAL_TIMEx_HallSensor_Start(), HAL_TIMEx_HallSensor_Start_DMA(), HAL_TIMEx_HallSensor_Start_IT(). + + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 TIMEx TIMEx + * @brief TIM HAL module driver + * @{ + */ + +#ifdef HAL_TIM_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @addtogroup TIMEx_Private_Functions + * @{ + */ +/* Private function prototypes -----------------------------------------------*/ +static void TIM_CCxNChannelCmd(TIM_TypeDef* TIMx, uint32_t Channel, uint32_t ChannelNState); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Functions TIM Exported Functions + * @{ + */ + +/** @defgroup TIMEx_Exported_Functions_Group1 Timer Hall Sensor functions + * @brief Timer Hall Sensor functions + * +@verbatim + ============================================================================== + ##### Timer Hall Sensor functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure TIM HAL Sensor. + (+) De-initialize TIM HAL Sensor. + (+) Start the Hall Sensor Interface. + (+) Stop the Hall Sensor Interface. + (+) Start the Hall Sensor Interface and enable interrupts. + (+) Stop the Hall Sensor Interface and disable interrupts. + (+) Start the Hall Sensor Interface and enable DMA transfers. + (+) Stop the Hall Sensor Interface and disable DMA transfers. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Hall Sensor Interface and create the associated handle. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param sConfig: TIM Hall Sensor configuration structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, TIM_HallSensor_InitTypeDef* sConfig) +{ + TIM_OC_InitTypeDef OC_Config; + + /* Check the TIM handle allocation */ + if(htim == NULL) + { + return HAL_ERROR; + } + + assert_param(IS_TIM_XOR_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_IC_POLARITY(sConfig->IC1Polarity)); + assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler)); + assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter)); + + /* Set the TIM state */ + htim->State= HAL_TIM_STATE_BUSY; + + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIMEx_HallSensor_MspInit(htim); + + /* Configure the Time base in the Encoder Mode */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Configure the Channel 1 as Input Channel to interface with the three Outputs of the Hall sensor */ + TIM_TI1_SetConfig(htim->Instance, sConfig->IC1Polarity, TIM_ICSELECTION_TRC, sConfig->IC1Filter); + + /* Reset the IC1PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC; + /* Set the IC1PSC value */ + htim->Instance->CCMR1 |= sConfig->IC1Prescaler; + + /* Enable the Hall sensor interface (XOR function of the three inputs) */ + htim->Instance->CR2 |= TIM_CR2_TI1S; + + /* Select the TIM_TS_TI1F_ED signal as Input trigger for the TIM */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= TIM_TS_TI1F_ED; + + /* Use the TIM_TS_TI1F_ED signal to reset the TIM counter each edge detection */ + htim->Instance->SMCR &= ~TIM_SMCR_SMS; + htim->Instance->SMCR |= TIM_SLAVEMODE_RESET; + + /* Program channel 2 in PWM 2 mode with the desired Commutation_Delay*/ + OC_Config.OCFastMode = TIM_OCFAST_DISABLE; + OC_Config.OCIdleState = TIM_OCIDLESTATE_RESET; + OC_Config.OCMode = TIM_OCMODE_PWM2; + OC_Config.OCNIdleState = TIM_OCNIDLESTATE_RESET; + OC_Config.OCNPolarity = TIM_OCNPOLARITY_HIGH; + OC_Config.OCPolarity = TIM_OCPOLARITY_HIGH; + OC_Config.Pulse = sConfig->Commutation_Delay; + + TIM_OC2_SetConfig(htim->Instance, &OC_Config); + + /* Select OC2REF as trigger output on TRGO: write the MMS bits in the TIMx_CR2 + register to 101 */ + htim->Instance->CR2 &= ~TIM_CR2_MMS; + htim->Instance->CR2 |= TIM_TRGO_OC2REF; + + /* Initialize the TIM state*/ + htim->State= HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM Hall Sensor interface + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_TIMEx_HallSensor_MspDeInit(htim); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Hall Sensor MSP. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIMEx_HallSensor_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Hall Sensor MSP. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIMEx_HallSensor_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Hall Sensor Interface. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_XOR_INSTANCE(htim->Instance)); + + /* Enable the Input Capture channels 1 + (in the Hall Sensor Interface the Three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Hall sensor Interface. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_XOR_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1, 2 and 3 + (in the Hall Sensor Interface the Three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Hall Sensor Interface in interrupt mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_XOR_INSTANCE(htim->Instance)); + + /* Enable the capture compare Interrupts 1 event */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + + /* Enable the Input Capture channels 1 + (in the Hall Sensor Interface the Three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Hall Sensor Interface in interrupt mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_XOR_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1 + (in the Hall Sensor Interface the Three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + /* Disable the capture compare Interrupts event */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Hall Sensor Interface in DMA mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param pData: The destination Buffer address. + * @param Length: The length of data to be transferred from TIM peripheral to memory. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length) +{ + /* Check the parameters */ + assert_param(IS_TIM_XOR_INSTANCE(htim->Instance)); + + if((htim->State == HAL_TIM_STATE_BUSY)) + { + return HAL_BUSY; + } + else if((htim->State == HAL_TIM_STATE_READY)) + { + if(((uint32_t)pData == 0 ) && (Length > 0)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + /* Enable the Input Capture channels 1 + (in the Hall Sensor Interface the Three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + + /* Set the DMA Input Capture 1 Callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream for Capture 1*/ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData, Length); + + /* Enable the capture compare 1 Interrupt */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Hall Sensor Interface in DMA mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_XOR_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1 + (in the Hall Sensor Interface the Three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + + /* Disable the capture compare Interrupts 1 event */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group2 Timer Complementary Output Compare functions + * @brief Timer Complementary Output Compare functions + * +@verbatim + ============================================================================== + ##### Timer Complementary Output Compare functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the Complementary Output Compare/PWM. + (+) Stop the Complementary Output Compare/PWM. + (+) Start the Complementary Output Compare/PWM and enable interrupts. + (+) Stop the Complementary Output Compare/PWM and disable interrupts. + (+) Start the Complementary Output Compare/PWM and enable DMA transfers. + (+) Stop the Complementary Output Compare/PWM and disable DMA transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Starts the TIM Output Compare signal generation on the complementary + * output. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Enable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Output Compare signal generation on the complementary + * output. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Disable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Output Compare signal generation in interrupt mode + * on the complementary output. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Output Compare interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Enable the TIM Output Compare interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Enable the TIM Output Compare interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Enable the TIM Output Compare interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + } + break; + + default: + break; + } + + /* Enable the TIM Break interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK); + + /* Enable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Output Compare signal generation in interrupt mode + * on the complementary output. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Output Compare interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Disable the TIM Output Compare interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Disable the TIM Output Compare interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Disable the TIM Output Compare interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + } + break; + + default: + break; + } + + /* Disable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the TIM Break interrupt (only if no more channel is active) */ + if((READ_REG(htim->Instance->CCER) & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == RESET) + { + __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK); + } + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Output Compare signal generation in DMA mode + * on the complementary output. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param pData: The source Buffer address. + * @param Length: The length of data to be transferred from memory to TIM peripheral + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + if((htim->State == HAL_TIM_STATE_BUSY)) + { + return HAL_BUSY; + } + else if((htim->State == HAL_TIM_STATE_READY)) + { + if(((uint32_t)pData == 0 ) && (Length > 0)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length); + + /* Enable the TIM Output Compare DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length); + + /* Enable the TIM Output Compare DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + } + break; + + case TIM_CHANNEL_3: +{ + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,Length); + + /* Enable the TIM Output Compare DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, Length); + + /* Enable the TIM Output Compare DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); + } + break; + + default: + break; + } + + /* Enable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Output Compare signal generation in DMA mode + * on the complementary output. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Output Compare DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Disable the TIM Output Compare DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Disable the TIM Output Compare DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Disable the TIM Output Compare interrupt */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); + } + break; + + default: + break; + } + + /* Disable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group3 Timer Complementary PWM functions + * @brief Timer Complementary PWM functions + * +@verbatim + ============================================================================== + ##### Timer Complementary PWM functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the Complementary PWM. + (+) Stop the Complementary PWM. + (+) Start the Complementary PWM and enable interrupts. + (+) Stop the Complementary PWM and disable interrupts. + (+) Start the Complementary PWM and enable DMA transfers. + (+) Stop the Complementary PWM and disable DMA transfers. + (+) Start the Complementary Input Capture measurement. + (+) Stop the Complementary Input Capture. + (+) Start the Complementary Input Capture and enable interrupts. + (+) Stop the Complementary Input Capture and disable interrupts. + (+) Start the Complementary Input Capture and enable DMA transfers. + (+) Stop the Complementary Input Capture and disable DMA transfers. + (+) Start the Complementary One Pulse generation. + (+) Stop the Complementary One Pulse. + (+) Start the Complementary One Pulse and enable interrupts. + (+) Stop the Complementary One Pulse and disable interrupts. + +@endverbatim + * @{ + */ + +/** + * @brief Starts the PWM signal generation on the complementary output. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Enable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the PWM signal generation on the complementary output. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Disable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the PWM signal generation in interrupt mode on the + * complementary output. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Enable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Enable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + } + break; + + default: + break; + } + + /* Enable the TIM Break interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK); + + /* Enable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the PWM signal generation in interrupt mode on the + * complementary output. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT (TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + } + break; + + default: + break; + } + + /* Disable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the TIM Break interrupt (only if no more channel is active) */ + if((READ_REG(htim->Instance->CCER) & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == RESET) + { + __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK); + } + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM PWM signal generation in DMA mode on the + * complementary output + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param pData: The source Buffer address. + * @param Length: The length of data to be transferred from memory to TIM peripheral + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + if((htim->State == HAL_TIM_STATE_BUSY)) + { + return HAL_BUSY; + } + else if((htim->State == HAL_TIM_STATE_READY)) + { + if(((uint32_t)pData == 0 ) && (Length > 0)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length); + + /* Enable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length); + + /* Enable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3,Length); + + /* Enable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Set the DMA Period elapsed callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, Length); + + /* Enable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); + } + break; + + default: + break; + } + + /* Enable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM PWM signal generation in DMA mode on the complementary + * output + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Channel: TIM Channel to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + } + break; + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + } + break; + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + } + break; + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); + } + break; + + default: + break; + } + + /* Disable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group4 Timer Complementary One Pulse functions + * @brief Timer Complementary One Pulse functions + * +@verbatim + ============================================================================== + ##### Timer Complementary One Pulse functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the Complementary One Pulse generation. + (+) Stop the Complementary One Pulse. + (+) Start the Complementary One Pulse and enable interrupts. + (+) Stop the Complementary One Pulse and disable interrupts. + +@endverbatim + * @{ + */ + +/** + * @brief Starts the TIM One Pulse signal generation on the complementary + * output. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param OutputChannel: TIM Channel to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel) + { + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); + + /* Enable the complementary One Pulse output */ + TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM One Pulse signal generation on the complementary + * output. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param OutputChannel: TIM Channel to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); + + /* Disable the complementary One Pulse output */ + TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM One Pulse signal generation in interrupt mode on the + * complementary channel. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param OutputChannel: TIM Channel to be enabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); + + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + + /* Enable the complementary One Pulse output */ + TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Return function status */ + return HAL_OK; + } + +/** + * @brief Stops the TIM One Pulse signal generation in interrupt mode on the + * complementary channel. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param OutputChannel: TIM Channel to be disabled. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); + + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + + /* Disable the complementary One Pulse output */ + TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Return function status */ + return HAL_OK; +} +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group5 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Configure The Input Output channels for OC, PWM, IC or One Pulse mode. + (+) Configure External Clock source. + (+) Configure Complementary channels, break features and dead time. + (+) Configure Master and the Slave synchronization. + (+) Configure the commutation event in case of use of the Hall sensor interface. + (+) Configure the DMA Burst Mode. + +@endverbatim + * @{ + */ +/** + * @brief Configure the TIM commutation event sequence. + * @note This function is mandatory to use the commutation event in order to + * update the configuration at each commutation detection on the TRGI input of the Timer, + * the typical use of this feature is with the use of another Timer(interface Timer) + * configured in Hall sensor interface, this interface Timer will generate the + * commutation at its TRGO output (connected to Timer used in this function) each time + * the TI1 of the Interface Timer detect a commutation at its input TI1. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param InputTrigger: the Internal trigger corresponding to the Timer Interfacing with the Hall sensor. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal trigger 0 selected + * @arg TIM_TS_ITR1: Internal trigger 1 selected + * @arg TIM_TS_ITR2: Internal trigger 2 selected + * @arg TIM_TS_ITR3: Internal trigger 3 selected + * @arg TIM_TS_NONE: No trigger is needed + * @param CommutationSource: the Commutation Event source. + * This parameter can be one of the following values: + * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer + * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_ADVANCED_INSTANCE(htim->Instance)); + assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger)); + + __HAL_LOCK(htim); + + if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) || + (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3)) + { + /* Select the Input trigger */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= InputTrigger; + } + + /* Select the Capture Compare preload feature */ + htim->Instance->CR2 |= TIM_CR2_CCPC; + /* Select the Commutation event source */ + htim->Instance->CR2 &= ~TIM_CR2_CCUS; + htim->Instance->CR2 |= CommutationSource; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configure the TIM commutation event sequence with interrupt. + * @note This function is mandatory to use the commutation event in order to + * update the configuration at each commutation detection on the TRGI input of the Timer, + * the typical use of this feature is with the use of another Timer(interface Timer) + * configured in Hall sensor interface, this interface Timer will generate the + * commutation at its TRGO output (connected to Timer used in this function) each time + * the TI1 of the Interface Timer detect a commutation at its input TI1. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param InputTrigger: the Internal trigger corresponding to the Timer Interfacing with the Hall sensor. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal trigger 0 selected + * @arg TIM_TS_ITR1: Internal trigger 1 selected + * @arg TIM_TS_ITR2: Internal trigger 2 selected + * @arg TIM_TS_ITR3: Internal trigger 3 selected + * @arg TIM_TS_NONE: No trigger is needed + * @param CommutationSource: the Commutation Event source. + * This parameter can be one of the following values: + * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer + * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_ADVANCED_INSTANCE(htim->Instance)); + assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger)); + + __HAL_LOCK(htim); + + if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) || + (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3)) + { + /* Select the Input trigger */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= InputTrigger; + } + + /* Select the Capture Compare preload feature */ + htim->Instance->CR2 |= TIM_CR2_CCPC; + /* Select the Commutation event source */ + htim->Instance->CR2 &= ~TIM_CR2_CCUS; + htim->Instance->CR2 |= CommutationSource; + + /* Enable the Commutation Interrupt Request */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_COM); + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configure the TIM commutation event sequence with DMA. + * @note This function is mandatory to use the commutation event in order to + * update the configuration at each commutation detection on the TRGI input of the Timer, + * the typical use of this feature is with the use of another Timer(interface Timer) + * configured in Hall sensor interface, this interface Timer will generate the + * commutation at its TRGO output (connected to Timer used in this function) each time + * the TI1 of the Interface Timer detect a commutation at its input TI1. + * @note: The user should configure the DMA in his own software, in This function only the COMDE bit is set + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param InputTrigger: the Internal trigger corresponding to the Timer Interfacing with the Hall sensor. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal trigger 0 selected + * @arg TIM_TS_ITR1: Internal trigger 1 selected + * @arg TIM_TS_ITR2: Internal trigger 2 selected + * @arg TIM_TS_ITR3: Internal trigger 3 selected + * @arg TIM_TS_NONE: No trigger is needed + * @param CommutationSource: the Commutation Event source. + * This parameter can be one of the following values: + * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer + * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutationEvent_DMA(TIM_HandleTypeDef *htim, uint32_t InputTrigger, uint32_t CommutationSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_ADVANCED_INSTANCE(htim->Instance)); + assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger)); + + __HAL_LOCK(htim); + + if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) || + (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3)) + { + /* Select the Input trigger */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= InputTrigger; + } + + /* Select the Capture Compare preload feature */ + htim->Instance->CR2 |= TIM_CR2_CCPC; + /* Select the Commutation event source */ + htim->Instance->CR2 &= ~TIM_CR2_CCUS; + htim->Instance->CR2 |= CommutationSource; + + /* Enable the Commutation DMA Request */ + /* Set the DMA Commutation Callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt; + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError; + + /* Enable the Commutation DMA Request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_COM); + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the TIM in master mode. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param sMasterConfig: pointer to a TIM_MasterConfigTypeDef structure that + * contains the selected trigger output (TRGO) and the Master/Slave + * mode. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim, TIM_MasterConfigTypeDef * sMasterConfig) +{ + /* Check the parameters */ + assert_param(IS_TIM_MASTER_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRGO_SOURCE(sMasterConfig->MasterOutputTrigger)); + assert_param(IS_TIM_MSM_STATE(sMasterConfig->MasterSlaveMode)); + + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Reset the MMS Bits */ + htim->Instance->CR2 &= ~TIM_CR2_MMS; + /* Select the TRGO source */ + htim->Instance->CR2 |= sMasterConfig->MasterOutputTrigger; + + /* Reset the MSM Bit */ + htim->Instance->SMCR &= ~TIM_SMCR_MSM; + /* Set or Reset the MSM Bit */ + htim->Instance->SMCR |= sMasterConfig->MasterSlaveMode; + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the Break feature, dead time, Lock level, OSSI/OSSR State + * and the AOE(automatic output enable). + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param sBreakDeadTimeConfig: pointer to a TIM_ConfigBreakDeadConfig_TypeDef structure that + * contains the BDTR Register configuration information for the TIM peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim, + TIM_BreakDeadTimeConfigTypeDef * sBreakDeadTimeConfig) +{ + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + assert_param(IS_TIM_OSSR_STATE(sBreakDeadTimeConfig->OffStateRunMode)); + assert_param(IS_TIM_OSSI_STATE(sBreakDeadTimeConfig->OffStateIDLEMode)); + assert_param(IS_TIM_LOCK_LEVEL(sBreakDeadTimeConfig->LockLevel)); + assert_param(IS_TIM_BREAK_STATE(sBreakDeadTimeConfig->BreakState)); + assert_param(IS_TIM_BREAK_POLARITY(sBreakDeadTimeConfig->BreakPolarity)); + assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(sBreakDeadTimeConfig->AutomaticOutput)); + assert_param(IS_TIM_DEADTIME(sBreakDeadTimeConfig->DeadTime)); + + /* Process Locked */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State, + the OSSI State, the dead time value and the Automatic Output Enable Bit */ + htim->Instance->BDTR = (uint32_t)sBreakDeadTimeConfig->OffStateRunMode | + sBreakDeadTimeConfig->OffStateIDLEMode | + sBreakDeadTimeConfig->LockLevel | + sBreakDeadTimeConfig->DeadTime | + sBreakDeadTimeConfig->BreakState | + sBreakDeadTimeConfig->BreakPolarity | + sBreakDeadTimeConfig->AutomaticOutput; + + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the TIM2, TIM5 and TIM11 Remapping input capabilities. + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @param Remap: specifies the TIM input remapping source. + * This parameter can be one of the following values: + * @arg TIM_TIM2_TIM8_TRGO: TIM2 ITR1 input is connected to TIM8 Trigger output(default) + * @arg TIM_TIM2_ETH_PTP: TIM2 ITR1 input is connected to ETH PTP trigger output. + * @arg TIM_TIM2_USBFS_SOF: TIM2 ITR1 input is connected to USB FS SOF. + * @arg TIM_TIM2_USBHS_SOF: TIM2 ITR1 input is connected to USB HS SOF. + * @arg TIM_TIM5_GPIO: TIM5 CH4 input is connected to dedicated Timer pin(default) + * @arg TIM_TIM5_LSI: TIM5 CH4 input is connected to LSI clock. + * @arg TIM_TIM5_LSE: TIM5 CH4 input is connected to LSE clock. + * @arg TIM_TIM5_RTC: TIM5 CH4 input is connected to RTC Output event. + * @arg TIM_TIM11_GPIO: TIM11 CH4 input is connected to dedicated Timer pin(default) + * @arg TIM_TIM11_HSE: TIM11 CH4 input is connected to HSE_RTC clock + * (HSE divided by a programmable prescaler) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap) +{ + __HAL_LOCK(htim); + + /* Check parameters */ + assert_param(IS_TIM_REMAP_INSTANCE(htim->Instance)); + assert_param(IS_TIM_REMAP(Remap)); + + /* Set the Timer remapping configuration */ + htim->Instance->OR = Remap; + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group6 Extension Callbacks functions + * @brief Extension Callbacks functions + * +@verbatim + ============================================================================== + ##### Extension Callbacks functions ##### + ============================================================================== + [..] + This section provides Extension TIM callback functions: + (+) Timer Commutation callback + (+) Timer Break callback + +@endverbatim + * @{ + */ + +/** + * @brief Hall commutation changed callback in non blocking mode + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIMEx_CommutationCallback(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIMEx_CommutationCallback could be implemented in the user file + */ +} + +/** + * @brief Hall Break detection callback in non blocking mode + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +__weak void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim) +{ + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_TIMEx_BreakCallback could be implemented in the user file + */ +} +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group7 Extension Peripheral State functions + * @brief Extension Peripheral State functions + * +@verbatim + ============================================================================== + ##### Extension Peripheral State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the TIM Hall Sensor interface state + * @param htim: pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @} + */ + +/** + * @brief TIM DMA Commutation callback. + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef* htim = ( TIM_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + htim->State= HAL_TIM_STATE_READY; + + HAL_TIMEx_CommutationCallback(htim); +} +/** + * @} + */ + +/** + * @brief Enables or disables the TIM Capture Compare Channel xN. + * @param TIMx to select the TIM peripheral + * @param Channel: specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_Channel_1: TIM Channel 1 + * @arg TIM_Channel_2: TIM Channel 2 + * @arg TIM_Channel_3: TIM Channel 3 + * @param ChannelNState: specifies the TIM Channel CCxNE bit new state. + * This parameter can be: TIM_CCxN_ENABLE or TIM_CCxN_Disable. + * @retval None + */ +static void TIM_CCxNChannelCmd(TIM_TypeDef* TIMx, uint32_t Channel, uint32_t ChannelNState) +{ + uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(TIMx)); + assert_param(IS_TIM_COMPLEMENTARY_CHANNELS(Channel)); + + tmp = TIM_CCER_CC1NE << Channel; + + /* Reset the CCxNE Bit */ + TIMx->CCER &= ~tmp; + + /* Set or reset the CCxNE Bit */ + TIMx->CCER |= (uint32_t)(ChannelNState << Channel); +} + +/** + * @} + */ + +#endif /* HAL_TIM_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c new file mode 100644 index 0000000..786b798 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c @@ -0,0 +1,1932 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_uart.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief UART HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Universal Asynchronous Receiver Transmitter (UART) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State and Errors functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The UART HAL driver can be used as follows: + + (#) Declare a UART_HandleTypeDef handle structure. + + (#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API: + (##) Enable the USARTx interface clock. + (##) UART pins configuration: + (+++) Enable the clock for the UART GPIOs. + (+++) Configure these UART pins as alternate function pull-up. + (##) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT() + and HAL_UART_Receive_IT() APIs): + (+++) Configure the USARTx interrupt priority. + (+++) Enable the NVIC USART IRQ handle. + (##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA() + and HAL_UART_Receive_DMA() APIs): + (+++) Declare a DMA handle structure for the Tx/Rx stream. + (+++) Enable the DMAx interface clock. + (+++) Configure the declared DMA handle structure with the required + Tx/Rx parameters. + (+++) Configure the DMA Tx/Rx Stream. + (+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle. + (+++) Configure the priority and enable the NVIC for the transfer complete + interrupt on the DMA Tx/Rx Stream. + + (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware + flow control and Mode(Receiver/Transmitter) in the Init structure. + + (#) For the UART asynchronous mode, initialize the UART registers by calling + the HAL_UART_Init() API. + + (#) For the UART Half duplex mode, initialize the UART registers by calling + the HAL_HalfDuplex_Init() API. + + (#) For the LIN mode, initialize the UART registers by calling the HAL_LIN_Init() API. + + (#) For the Multi-Processor mode, initialize the UART registers by calling + the HAL_MultiProcessor_Init() API. + + [..] + (@) The specific UART interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) will be managed using the macros + __HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit + and receive process. + + [..] + (@) These APIs (HAL_UART_Init() and HAL_HalfDuplex_Init()) configure also the + low level Hardware GPIO, CLOCK, CORTEX...etc) by calling the customized + HAL_UART_MspInit() API. + + [..] + Three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Send an amount of data in blocking mode using HAL_UART_Transmit() + (+) Receive an amount of data in blocking mode using HAL_UART_Receive() + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Send an amount of data in non blocking mode using HAL_UART_Transmit_IT() + (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_UART_TxCpltCallback + (+) Receive an amount of data in non blocking mode using HAL_UART_Receive_IT() + (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_UART_RxCpltCallback + (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_UART_ErrorCallback + + *** DMA mode IO operation *** + ============================== + [..] + (+) Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA() + (+) At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback + (+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_UART_TxCpltCallback + (+) Receive an amount of data in non blocking mode (DMA) using HAL_UART_Receive_DMA() + (+) At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback + (+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_UART_RxCpltCallback + (+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_UART_ErrorCallback + (+) Pause the DMA Transfer using HAL_UART_DMAPause() + (+) Resume the DMA Transfer using HAL_UART_DMAResume() + (+) Stop the DMA Transfer using HAL_UART_DMAStop() + + *** UART HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in UART HAL driver. + + (+) __HAL_UART_ENABLE: Enable the UART peripheral + (+) __HAL_UART_DISABLE: Disable the UART peripheral + (+) __HAL_UART_GET_FLAG : Check whether the specified UART flag is set or not + (+) __HAL_UART_CLEAR_FLAG : Clear the specified UART pending flag + (+) __HAL_UART_ENABLE_IT: Enable the specified UART interrupt + (+) __HAL_UART_DISABLE_IT: Disable the specified UART interrupt + (+) __HAL_UART_GET_IT_SOURCE: Check whether the specified UART interrupt has occurred or not + + [..] + (@) You can refer to the UART HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 UART UART + * @brief HAL UART module driver + * @{ + */ +#ifdef HAL_UART_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup UART_Private_Constants + * @{ + */ +#define UART_TIMEOUT_VALUE 22000 +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup UART_Private_Functions UART Private Functions + * @{ + */ +static void UART_SetConfig (UART_HandleTypeDef *huart); +static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart); +static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart); +static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart); +static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma); +static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma); +static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma); +static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma); +static void UART_DMAError(DMA_HandleTypeDef *hdma); +static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Timeout); +/** + * @} + */ + +/* Exported functions ---------------------------------------------------------*/ +/** @defgroup UART_Exported_Functions UART Exported Functions + * @{ + */ + +/** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim +=============================================================================== + ##### Initialization and Configuration functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the USARTx or the UARTy + in asynchronous mode. + (+) For the asynchronous mode only these parameters can be configured: + (++) Baud Rate + (++) Word Length + (++) Stop Bit + (++) Parity: If the parity is enabled, then the MSB bit of the data written + in the data register is transmitted but is changed by the parity bit. + Depending on the frame length defined by the M bit (8-bits or 9-bits), + please refer to Reference manual for possible UART frame formats. + (++) Hardware flow control + (++) Receiver/transmitter modes + (++) Over Sampling Method + [..] + The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init() and HAL_MultiProcessor_Init() APIs + follow respectively the UART asynchronous, UART Half duplex, LIN and Multi-Processor + configuration procedures (details for the procedures are available in reference manual (RM0329)). + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the UART mode according to the specified parameters in + * the UART_InitTypeDef and create the associated handle. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) +{ + /* Check the UART handle allocation */ + if(huart == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + if(huart->Init.HwFlowCtl != UART_HWCONTROL_NONE) + { + /* The hardware flow control is available only for USART1, USART2, USART3 and USART6 */ + assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance)); + assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl)); + } + else + { + assert_param(IS_UART_INSTANCE(huart->Instance)); + } + assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); + assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); + + if(huart->State == HAL_UART_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + huart->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_UART_MspInit(huart); + } + + huart->State = HAL_UART_STATE_BUSY; + + /* Disable the peripheral */ + __HAL_UART_DISABLE(huart); + + /* Set the UART Communication parameters */ + UART_SetConfig(huart); + + /* In asynchronous mode, the following bits must be kept cleared: + - LINEN and CLKEN bits in the USART_CR2 register, + - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/ + huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN); + huart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); + + /* Enable the peripheral */ + __HAL_UART_ENABLE(huart); + + /* Initialize the UART state */ + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->State= HAL_UART_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Initializes the half-duplex mode according to the specified + * parameters in the UART_InitTypeDef and create the associated handle. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart) +{ + /* Check the UART handle allocation */ + if(huart == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_UART_INSTANCE(huart->Instance)); + assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); + assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); + + if(huart->State == HAL_UART_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + huart->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_UART_MspInit(huart); + } + + huart->State = HAL_UART_STATE_BUSY; + + /* Disable the peripheral */ + __HAL_UART_DISABLE(huart); + + /* Set the UART Communication parameters */ + UART_SetConfig(huart); + + /* In half-duplex mode, the following bits must be kept cleared: + - LINEN and CLKEN bits in the USART_CR2 register, + - SCEN and IREN bits in the USART_CR3 register.*/ + huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN); + huart->Instance->CR3 &= ~(USART_CR3_IREN | USART_CR3_SCEN); + + /* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */ + huart->Instance->CR3 |= USART_CR3_HDSEL; + + /* Enable the peripheral */ + __HAL_UART_ENABLE(huart); + + /* Initialize the UART state*/ + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->State= HAL_UART_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Initializes the LIN mode according to the specified + * parameters in the UART_InitTypeDef and create the associated handle. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @param BreakDetectLength: Specifies the LIN break detection length. + * This parameter can be one of the following values: + * @arg UART_LINBREAKDETECTLENGTH_10B: 10-bit break detection + * @arg UART_LINBREAKDETECTLENGTH_11B: 11-bit break detection + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LIN_Init(UART_HandleTypeDef *huart, uint32_t BreakDetectLength) +{ + /* Check the UART handle allocation */ + if(huart == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_UART_INSTANCE(huart->Instance)); + assert_param(IS_UART_LIN_BREAK_DETECT_LENGTH(BreakDetectLength)); + assert_param(IS_UART_LIN_WORD_LENGTH(huart->Init.WordLength)); + assert_param(IS_UART_LIN_OVERSAMPLING(huart->Init.OverSampling)); + + if(huart->State == HAL_UART_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + huart->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_UART_MspInit(huart); + } + + huart->State = HAL_UART_STATE_BUSY; + + /* Disable the peripheral */ + __HAL_UART_DISABLE(huart); + + /* Set the UART Communication parameters */ + UART_SetConfig(huart); + + /* In LIN mode, the following bits must be kept cleared: + - LINEN and CLKEN bits in the USART_CR2 register, + - SCEN and IREN bits in the USART_CR3 register.*/ + huart->Instance->CR2 &= ~(USART_CR2_CLKEN); + huart->Instance->CR3 &= ~(USART_CR3_HDSEL | USART_CR3_IREN | USART_CR3_SCEN); + + /* Enable the LIN mode by setting the LINEN bit in the CR2 register */ + huart->Instance->CR2 |= USART_CR2_LINEN; + + /* Set the USART LIN Break detection length. */ + huart->Instance->CR2 &= ~(USART_CR2_LBDL); + huart->Instance->CR2 |= BreakDetectLength; + + /* Enable the peripheral */ + __HAL_UART_ENABLE(huart); + + /* Initialize the UART state*/ + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->State= HAL_UART_STATE_READY; + + return HAL_OK; +} + +/** + * @brief Initializes the Multi-Processor mode according to the specified + * parameters in the UART_InitTypeDef and create the associated handle. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @param Address: USART address + * @param WakeUpMethod: specifies the USART wake-up method. + * This parameter can be one of the following values: + * @arg UART_WAKEUPMETHOD_IDLELINE: Wake-up by an idle line detection + * @arg UART_WAKEUPMETHOD_ADDRESSMARK: Wake-up by an address mark + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod) +{ + /* Check the UART handle allocation */ + if(huart == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_UART_INSTANCE(huart->Instance)); + assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod)); + assert_param(IS_UART_ADDRESS(Address)); + assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); + assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); + + if(huart->State == HAL_UART_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + huart->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_UART_MspInit(huart); + } + + huart->State = HAL_UART_STATE_BUSY; + + /* Disable the peripheral */ + __HAL_UART_DISABLE(huart); + + /* Set the UART Communication parameters */ + UART_SetConfig(huart); + + /* In Multi-Processor mode, the following bits must be kept cleared: + - LINEN and CLKEN bits in the USART_CR2 register, + - SCEN, HDSEL and IREN bits in the USART_CR3 register */ + huart->Instance->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN); + huart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); + + /* Clear the USART address */ + huart->Instance->CR2 &= ~(USART_CR2_ADD); + /* Set the USART address node */ + huart->Instance->CR2 |= Address; + + /* Set the wake up method by setting the WAKE bit in the CR1 register */ + huart->Instance->CR1 &= ~(USART_CR1_WAKE); + huart->Instance->CR1 |= WakeUpMethod; + + /* Enable the peripheral */ + __HAL_UART_ENABLE(huart); + + /* Initialize the UART state */ + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->State= HAL_UART_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the UART peripheral. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart) +{ + /* Check the UART handle allocation */ + if(huart == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_UART_INSTANCE(huart->Instance)); + + huart->State = HAL_UART_STATE_BUSY; + + /* DeInit the low level hardware */ + HAL_UART_MspDeInit(huart); + + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->State = HAL_UART_STATE_RESET; + + /* Process Lock */ + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief UART MSP Init. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval None + */ + __weak void HAL_UART_MspInit(UART_HandleTypeDef *huart) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_UART_MspInit could be implemented in the user file + */ +} + +/** + * @brief UART MSP DeInit. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval None + */ + __weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_UART_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup UART_Exported_Functions_Group2 IO operation functions + * @brief UART Transmit and Receive functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to manage the UART asynchronous + and Half duplex data transfers. + + (#) There are two modes of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) Non blocking mode: The communication is performed using Interrupts + or DMA, these APIs return the HAL status. + The end of the data processing will be indicated through the + dedicated UART IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks + will be executed respectively at the end of the transmit or receive process. + The HAL_UART_ErrorCallback() user callback will be executed when + a communication error is detected. + + (#) Blocking mode APIs are: + (++) HAL_UART_Transmit() + (++) HAL_UART_Receive() + + (#) Non Blocking mode APIs with Interrupt are: + (++) HAL_UART_Transmit_IT() + (++) HAL_UART_Receive_IT() + (++) HAL_UART_IRQHandler() + + (#) Non Blocking mode functions with DMA are: + (++) HAL_UART_Transmit_DMA() + (++) HAL_UART_Receive_DMA() + + (#) A set of Transfer Complete Callbacks are provided in non blocking mode: + (++) HAL_UART_TxCpltCallback() + (++) HAL_UART_RxCpltCallback() + (++) HAL_UART_ErrorCallback() + + [..] + (@) In the Half duplex communication, it is forbidden to run the transmit + and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX + can't be useful. + +@endverbatim + * @{ + */ + +/** + * @brief Sends an amount of data in blocking mode. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint16_t* tmp; + uint32_t tmp1 = 0; + + tmp1 = huart->State; + if((tmp1 == HAL_UART_STATE_READY) || (tmp1 == HAL_UART_STATE_BUSY_RX)) + { + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->ErrorCode = HAL_UART_ERROR_NONE; + /* Check if a non-blocking receive process is ongoing or not */ + if(huart->State == HAL_UART_STATE_BUSY_RX) + { + huart->State = HAL_UART_STATE_BUSY_TX_RX; + } + else + { + huart->State = HAL_UART_STATE_BUSY_TX; + } + + huart->TxXferSize = Size; + huart->TxXferCount = Size; + while(huart->TxXferCount > 0) + { + huart->TxXferCount--; + if(huart->Init.WordLength == UART_WORDLENGTH_9B) + { + if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + tmp = (uint16_t*) pData; + huart->Instance->DR = (*tmp & (uint16_t)0x01FF); + if(huart->Init.Parity == UART_PARITY_NONE) + { + pData +=2; + } + else + { + pData +=1; + } + } + else + { + if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + huart->Instance->DR = (*pData++ & (uint8_t)0xFF); + } + } + + if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Check if a non-blocking receive process is ongoing or not */ + if(huart->State == HAL_UART_STATE_BUSY_TX_RX) + { + huart->State = HAL_UART_STATE_BUSY_RX; + } + else + { + huart->State = HAL_UART_STATE_READY; + } + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receives an amount of data in blocking mode. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be received + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint16_t* tmp; + uint32_t tmp1 = 0; + + tmp1 = huart->State; + if((tmp1 == HAL_UART_STATE_READY) || (tmp1 == HAL_UART_STATE_BUSY_TX)) + { + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->ErrorCode = HAL_UART_ERROR_NONE; + /* Check if a non-blocking transmit process is ongoing or not */ + if(huart->State == HAL_UART_STATE_BUSY_TX) + { + huart->State = HAL_UART_STATE_BUSY_TX_RX; + } + else + { + huart->State = HAL_UART_STATE_BUSY_RX; + } + + huart->RxXferSize = Size; + huart->RxXferCount = Size; + + /* Check the remain data to be received */ + while(huart->RxXferCount > 0) + { + huart->RxXferCount--; + if(huart->Init.WordLength == UART_WORDLENGTH_9B) + { + if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + tmp = (uint16_t*) pData ; + if(huart->Init.Parity == UART_PARITY_NONE) + { + *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF); + pData +=2; + } + else + { + *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF); + pData +=1; + } + + } + else + { + if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + if(huart->Init.Parity == UART_PARITY_NONE) + { + *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF); + } + else + { + *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F); + } + + } + } + + /* Check if a non-blocking transmit process is ongoing or not */ + if(huart->State == HAL_UART_STATE_BUSY_TX_RX) + { + huart->State = HAL_UART_STATE_BUSY_TX; + } + else + { + huart->State = HAL_UART_STATE_READY; + } + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sends an amount of data in non blocking mode. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +{ + uint32_t tmp = 0; + + tmp = huart->State; + if((tmp == HAL_UART_STATE_READY) || (tmp == HAL_UART_STATE_BUSY_RX)) + { + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->pTxBuffPtr = pData; + huart->TxXferSize = Size; + huart->TxXferCount = Size; + + huart->ErrorCode = HAL_UART_ERROR_NONE; + /* Check if a receive process is ongoing or not */ + if(huart->State == HAL_UART_STATE_BUSY_RX) + { + huart->State = HAL_UART_STATE_BUSY_TX_RX; + } + else + { + huart->State = HAL_UART_STATE_BUSY_TX; + } + + /* Enable the UART Parity Error Interrupt */ + __HAL_UART_ENABLE_IT(huart, UART_IT_PE); + + /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_UART_ENABLE_IT(huart, UART_IT_ERR); + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + /* Enable the UART Transmit data register empty Interrupt */ + __HAL_UART_ENABLE_IT(huart, UART_IT_TXE); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receives an amount of data in non blocking mode + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +{ + uint32_t tmp = 0; + + tmp = huart->State; + if((tmp == HAL_UART_STATE_READY) || (tmp == HAL_UART_STATE_BUSY_TX)) + { + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->pRxBuffPtr = pData; + huart->RxXferSize = Size; + huart->RxXferCount = Size; + + huart->ErrorCode = HAL_UART_ERROR_NONE; + /* Check if a transmit process is ongoing or not */ + if(huart->State == HAL_UART_STATE_BUSY_TX) + { + huart->State = HAL_UART_STATE_BUSY_TX_RX; + } + else + { + huart->State = HAL_UART_STATE_BUSY_RX; + } + + /* Enable the UART Parity Error Interrupt */ + __HAL_UART_ENABLE_IT(huart, UART_IT_PE); + + /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_UART_ENABLE_IT(huart, UART_IT_ERR); + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + /* Enable the UART Data Register not empty Interrupt */ + __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sends an amount of data in non blocking mode. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +{ + uint32_t *tmp; + uint32_t tmp1 = 0; + + tmp1 = huart->State; + if((tmp1 == HAL_UART_STATE_READY) || (tmp1 == HAL_UART_STATE_BUSY_RX)) + { + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->pTxBuffPtr = pData; + huart->TxXferSize = Size; + huart->TxXferCount = Size; + + huart->ErrorCode = HAL_UART_ERROR_NONE; + /* Check if a receive process is ongoing or not */ + if(huart->State == HAL_UART_STATE_BUSY_RX) + { + huart->State = HAL_UART_STATE_BUSY_TX_RX; + } + else + { + huart->State = HAL_UART_STATE_BUSY_TX; + } + + /* Set the UART DMA transfer complete callback */ + huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt; + + /* Set the UART DMA Half transfer complete callback */ + huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt; + + /* Set the DMA error callback */ + huart->hdmatx->XferErrorCallback = UART_DMAError; + + /* Enable the UART transmit DMA Stream */ + tmp = (uint32_t*)&pData; + HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->DR, Size); + + /* Clear the TC flag in the SR register by writing 0 to it */ + __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC); + + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the UART CR3 register */ + huart->Instance->CR3 |= USART_CR3_DMAT; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receives an amount of data in non blocking mode. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @param pData: Pointer to data buffer + * @param Size: Amount of data to be received + * @note When the UART parity is enabled (PCE = 1) the data received contain the parity bit. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +{ + uint32_t *tmp; + uint32_t tmp1 = 0; + + tmp1 = huart->State; + if((tmp1 == HAL_UART_STATE_READY) || (tmp1 == HAL_UART_STATE_BUSY_TX)) + { + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->pRxBuffPtr = pData; + huart->RxXferSize = Size; + + huart->ErrorCode = HAL_UART_ERROR_NONE; + /* Check if a transmit process is ongoing or not */ + if(huart->State == HAL_UART_STATE_BUSY_TX) + { + huart->State = HAL_UART_STATE_BUSY_TX_RX; + } + else + { + huart->State = HAL_UART_STATE_BUSY_RX; + } + + /* Set the UART DMA transfer complete callback */ + huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt; + + /* Set the UART DMA Half transfer complete callback */ + huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt; + + /* Set the DMA error callback */ + huart->hdmarx->XferErrorCallback = UART_DMAError; + + /* Enable the DMA Stream */ + tmp = (uint32_t*)&pData; + HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->DR, *(uint32_t*)tmp, Size); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the UART CR3 register */ + huart->Instance->CR3 |= USART_CR3_DMAR; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Pauses the DMA Transfer. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart) +{ + /* Process Locked */ + __HAL_LOCK(huart); + + if(huart->State == HAL_UART_STATE_BUSY_TX) + { + /* Disable the UART DMA Tx request */ + huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT); + } + else if(huart->State == HAL_UART_STATE_BUSY_RX) + { + /* Disable the UART DMA Rx request */ + huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR); + } + else if (huart->State == HAL_UART_STATE_BUSY_TX_RX) + { + /* Disable the UART DMA Tx & Rx requests */ + huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT); + huart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAR); + } + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief Resumes the DMA Transfer. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart) +{ + /* Process Locked */ + __HAL_LOCK(huart); + + if(huart->State == HAL_UART_STATE_BUSY_TX) + { + /* Enable the UART DMA Tx request */ + huart->Instance->CR3 |= USART_CR3_DMAT; + } + else if(huart->State == HAL_UART_STATE_BUSY_RX) + { + /* Clear the Overrun flag before resuming the Rx transfer*/ + __HAL_UART_CLEAR_OREFLAG(huart); + /* Enable the UART DMA Rx request */ + huart->Instance->CR3 |= USART_CR3_DMAR; + } + else if(huart->State == HAL_UART_STATE_BUSY_TX_RX) + { + /* Clear the Overrun flag before resuming the Rx transfer*/ + __HAL_UART_CLEAR_OREFLAG(huart); + /* Enable the UART DMA Tx & Rx request */ + huart->Instance->CR3 |= USART_CR3_DMAT; + huart->Instance->CR3 |= USART_CR3_DMAR; + } + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief Stops the DMA Transfer. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart) +{ + /* The Lock is not implemented on this API to allow the user application + to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback(): + when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated + and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback() + */ + + /* Disable the UART Tx/Rx DMA requests */ + huart->Instance->CR3 &= ~USART_CR3_DMAT; + huart->Instance->CR3 &= ~USART_CR3_DMAR; + + /* Abort the UART DMA tx Stream */ + if(huart->hdmatx != NULL) + { + HAL_DMA_Abort(huart->hdmatx); + } + /* Abort the UART DMA rx Stream */ + if(huart->hdmarx != NULL) + { + HAL_DMA_Abort(huart->hdmarx); + } + + huart->State = HAL_UART_STATE_READY; + + return HAL_OK; +} + +/** + * @brief This function handles UART interrupt request. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval None + */ +void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) +{ + uint32_t tmp1 = 0, tmp2 = 0; + + tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_PE); + tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE); + /* UART parity error interrupt occurred ------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_UART_CLEAR_PEFLAG(huart); + + huart->ErrorCode |= HAL_UART_ERROR_PE; + } + + tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_FE); + tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR); + /* UART frame error interrupt occurred -------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_UART_CLEAR_FEFLAG(huart); + + huart->ErrorCode |= HAL_UART_ERROR_FE; + } + + tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_NE); + tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR); + /* UART noise error interrupt occurred -------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_UART_CLEAR_NEFLAG(huart); + + huart->ErrorCode |= HAL_UART_ERROR_NE; + } + + tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE); + tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR); + /* UART Over-Run interrupt occurred ----------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_UART_CLEAR_OREFLAG(huart); + + huart->ErrorCode |= HAL_UART_ERROR_ORE; + } + + tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE); + tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE); + /* UART in mode Receiver ---------------------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + UART_Receive_IT(huart); + } + + tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_TXE); + tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE); + /* UART in mode Transmitter ------------------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + UART_Transmit_IT(huart); + } + + tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_TC); + tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC); + /* UART in mode Transmitter end --------------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + UART_EndTransmit_IT(huart); + } + + if(huart->ErrorCode != HAL_UART_ERROR_NONE) + { + /* Set the UART state ready to be able to start again the process */ + huart->State = HAL_UART_STATE_READY; + + HAL_UART_ErrorCallback(huart); + } +} + +/** + * @brief Tx Transfer completed callbacks. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval None + */ + __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_UART_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Tx Half Transfer completed callbacks. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval None + */ + __weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_UART_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callbacks. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval None + */ +__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_UART_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Half Transfer completed callbacks. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval None + */ +__weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_UART_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief UART error callbacks. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval None + */ + __weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_UART_ErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions + * @brief UART control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control the UART: + (+) HAL_LIN_SendBreak() API can be helpful to transmit the break character. + (+) HAL_MultiProcessor_EnterMuteMode() API can be helpful to enter the UART in mute mode. + (+) HAL_MultiProcessor_ExitMuteMode() API can be helpful to exit the UART mute mode by software. + +@endverbatim + * @{ + */ + +/** + * @brief Transmits break characters. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_LIN_SendBreak(UART_HandleTypeDef *huart) +{ + /* Check the parameters */ + assert_param(IS_UART_INSTANCE(huart->Instance)); + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->State = HAL_UART_STATE_BUSY; + + /* Send break characters */ + huart->Instance->CR1 |= USART_CR1_SBK; + + huart->State = HAL_UART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief Enters the UART in mute mode. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart) +{ + /* Check the parameters */ + assert_param(IS_UART_INSTANCE(huart->Instance)); + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->State = HAL_UART_STATE_BUSY; + + /* Enable the USART mute mode by setting the RWU bit in the CR1 register */ + huart->Instance->CR1 |= USART_CR1_RWU; + + huart->State = HAL_UART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief Exits the UART mute mode: wake up software. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart) +{ + /* Check the parameters */ + assert_param(IS_UART_INSTANCE(huart->Instance)); + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->State = HAL_UART_STATE_BUSY; + + /* Disable the USART mute mode by clearing the RWU bit in the CR1 register */ + huart->Instance->CR1 &= (uint32_t)~((uint32_t)USART_CR1_RWU); + + huart->State = HAL_UART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief Enables the UART transmitter and disables the UART receiver. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart) +{ + uint32_t tmpreg = 0x00; + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->State = HAL_UART_STATE_BUSY; + + /*-------------------------- USART CR1 Configuration -----------------------*/ + tmpreg = huart->Instance->CR1; + + /* Clear TE and RE bits */ + tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE)); + + /* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */ + tmpreg |= (uint32_t)USART_CR1_TE; + + /* Write to USART CR1 */ + huart->Instance->CR1 = (uint32_t)tmpreg; + + huart->State = HAL_UART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @brief Enables the UART receiver and disables the UART transmitter. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart) +{ + uint32_t tmpreg = 0x00; + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->State = HAL_UART_STATE_BUSY; + + /*-------------------------- USART CR1 Configuration -----------------------*/ + tmpreg = huart->Instance->CR1; + + /* Clear TE and RE bits */ + tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE)); + + /* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */ + tmpreg |= (uint32_t)USART_CR1_RE; + + /* Write to USART CR1 */ + huart->Instance->CR1 = (uint32_t)tmpreg; + + huart->State = HAL_UART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Errors functions + * @brief UART State and Errors functions + * +@verbatim + ============================================================================== + ##### Peripheral State and Errors functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to return the State of + UART communication process, return Peripheral Errors occurred during communication + process + (+) HAL_UART_GetState() API can be helpful to check in run-time the state of the UART peripheral. + (+) HAL_UART_GetError() check in run-time errors that could be occurred during communication. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the UART state. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL state + */ +HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart) +{ + return huart->State; +} + +/** +* @brief Return the UART error code +* @param huart : pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART. +* @retval UART Error Code +*/ +uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart) +{ + return huart->ErrorCode; +} + +/** + * @} + */ + +/** + * @brief DMA UART transmit process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + /* DMA Normal mode*/ + if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) + { + huart->TxXferCount = 0; + + /* Disable the DMA transfer for transmit request by setting the DMAT bit + in the UART CR3 register */ + huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAT); + + /* Enable the UART Transmit Complete Interrupt */ + __HAL_UART_ENABLE_IT(huart, UART_IT_TC); + } + /* DMA Circular mode */ + else + { + HAL_UART_TxCpltCallback(huart); + } +} + +/** + * @brief DMA UART transmit process half complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + HAL_UART_TxHalfCpltCallback(huart); +} + +/** + * @brief DMA UART receive process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + /* DMA Normal mode*/ + if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) + { + huart->RxXferCount = 0; + + /* Disable the DMA transfer for the receiver request by setting the DMAR bit + in the UART CR3 register */ + huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAR); + + /* Check if a transmit process is ongoing or not */ + if(huart->State == HAL_UART_STATE_BUSY_TX_RX) + { + huart->State = HAL_UART_STATE_BUSY_TX; + } + else + { + huart->State = HAL_UART_STATE_READY; + } + } + HAL_UART_RxCpltCallback(huart); +} + +/** + * @brief DMA UART receive process half complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = (UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + HAL_UART_RxHalfCpltCallback(huart); +} + +/** + * @brief DMA UART communication error callback. + * @param hdma: DMA handle + * @retval None + */ +static void UART_DMAError(DMA_HandleTypeDef *hdma) +{ + UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + huart->RxXferCount = 0; + huart->TxXferCount = 0; + huart->State= HAL_UART_STATE_READY; + huart->ErrorCode |= HAL_UART_ERROR_DMA; + HAL_UART_ErrorCallback(huart); +} + +/** + * @brief This function handles UART Communication Timeout. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @param Flag: specifies the UART flag to check. + * @param Status: The new Flag status (SET or RESET). + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until flag is set */ + if(Status == RESET) + { + while(__HAL_UART_GET_FLAG(huart, Flag) == RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ + __HAL_UART_DISABLE_IT(huart, UART_IT_TXE); + __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE); + __HAL_UART_DISABLE_IT(huart, UART_IT_PE); + __HAL_UART_DISABLE_IT(huart, UART_IT_ERR); + + huart->State= HAL_UART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_TIMEOUT; + } + } + } + } + else + { + while(__HAL_UART_GET_FLAG(huart, Flag) != RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ + __HAL_UART_DISABLE_IT(huart, UART_IT_TXE); + __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE); + __HAL_UART_DISABLE_IT(huart, UART_IT_PE); + __HAL_UART_DISABLE_IT(huart, UART_IT_ERR); + + huart->State= HAL_UART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + return HAL_TIMEOUT; + } + } + } + } + return HAL_OK; +} + +/** + * @brief Sends an amount of data in non blocking mode. + * @param huart: Pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart) +{ + uint16_t* tmp; + uint32_t tmp1 = 0; + + tmp1 = huart->State; + if((tmp1 == HAL_UART_STATE_BUSY_TX) || (tmp1 == HAL_UART_STATE_BUSY_TX_RX)) + { + if(huart->Init.WordLength == UART_WORDLENGTH_9B) + { + tmp = (uint16_t*) huart->pTxBuffPtr; + huart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF); + if(huart->Init.Parity == UART_PARITY_NONE) + { + huart->pTxBuffPtr += 2; + } + else + { + huart->pTxBuffPtr += 1; + } + } + else + { + huart->Instance->DR = (uint8_t)(*huart->pTxBuffPtr++ & (uint8_t)0x00FF); + } + + if(--huart->TxXferCount == 0) + { + /* Disable the UART Transmit Complete Interrupt */ + __HAL_UART_DISABLE_IT(huart, UART_IT_TXE); + + /* Enable the UART Transmit Complete Interrupt */ + __HAL_UART_ENABLE_IT(huart, UART_IT_TC); + } + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + + +/** + * @brief Wraps up transmission in non blocking mode. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart) +{ + /* Disable the UART Transmit Complete Interrupt */ + __HAL_UART_DISABLE_IT(huart, UART_IT_TC); + + /* Check if a receive process is ongoing or not */ + if(huart->State == HAL_UART_STATE_BUSY_TX_RX) + { + huart->State = HAL_UART_STATE_BUSY_RX; + } + else + { + /* Disable the UART Parity Error Interrupt */ + __HAL_UART_DISABLE_IT(huart, UART_IT_PE); + + /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_UART_DISABLE_IT(huart, UART_IT_ERR); + + huart->State = HAL_UART_STATE_READY; + } + + HAL_UART_TxCpltCallback(huart); + + return HAL_OK; +} + +/** + * @brief Receives an amount of data in non blocking mode + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval HAL status + */ +static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) +{ + uint16_t* tmp; + uint32_t tmp1 = 0; + + tmp1 = huart->State; + if((tmp1 == HAL_UART_STATE_BUSY_RX) || (tmp1 == HAL_UART_STATE_BUSY_TX_RX)) + { + if(huart->Init.WordLength == UART_WORDLENGTH_9B) + { + tmp = (uint16_t*) huart->pRxBuffPtr; + if(huart->Init.Parity == UART_PARITY_NONE) + { + *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF); + huart->pRxBuffPtr += 2; + } + else + { + *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF); + huart->pRxBuffPtr += 1; + } + } + else + { + if(huart->Init.Parity == UART_PARITY_NONE) + { + *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF); + } + else + { + *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F); + } + } + + if(--huart->RxXferCount == 0) + { + __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE); + + /* Check if a transmit process is ongoing or not */ + if(huart->State == HAL_UART_STATE_BUSY_TX_RX) + { + huart->State = HAL_UART_STATE_BUSY_TX; + } + else + { + /* Disable the UART Parity Error Interrupt */ + __HAL_UART_DISABLE_IT(huart, UART_IT_PE); + + /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_UART_DISABLE_IT(huart, UART_IT_ERR); + + huart->State = HAL_UART_STATE_READY; + } + HAL_UART_RxCpltCallback(huart); + + return HAL_OK; + } + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Configures the UART peripheral. + * @param huart: pointer to a UART_HandleTypeDef structure that contains + * the configuration information for the specified UART module. + * @retval None + */ +static void UART_SetConfig(UART_HandleTypeDef *huart) +{ + uint32_t tmpreg = 0x00; + + /* Check the parameters */ + assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate)); + assert_param(IS_UART_STOPBITS(huart->Init.StopBits)); + assert_param(IS_UART_PARITY(huart->Init.Parity)); + assert_param(IS_UART_MODE(huart->Init.Mode)); + + /*-------------------------- USART CR2 Configuration -----------------------*/ + tmpreg = huart->Instance->CR2; + + /* Clear STOP[13:12] bits */ + tmpreg &= (uint32_t)~((uint32_t)USART_CR2_STOP); + + /* Configure the UART Stop Bits: Set STOP[13:12] bits according to huart->Init.StopBits value */ + tmpreg |= (uint32_t)huart->Init.StopBits; + + /* Write to USART CR2 */ + huart->Instance->CR2 = (uint32_t)tmpreg; + + /*-------------------------- USART CR1 Configuration -----------------------*/ + tmpreg = huart->Instance->CR1; + + /* Clear M, PCE, PS, TE and RE bits */ + tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \ + USART_CR1_RE | USART_CR1_OVER8)); + + /* Configure the UART Word Length, Parity and mode: + Set the M bits according to huart->Init.WordLength value + Set PCE and PS bits according to huart->Init.Parity value + Set TE and RE bits according to huart->Init.Mode value + Set OVER8 bit according to huart->Init.OverSampling value */ + tmpreg |= (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling; + + /* Write to USART CR1 */ + huart->Instance->CR1 = (uint32_t)tmpreg; + + /*-------------------------- USART CR3 Configuration -----------------------*/ + tmpreg = huart->Instance->CR3; + + /* Clear CTSE and RTSE bits */ + tmpreg &= (uint32_t)~((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE)); + + /* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */ + tmpreg |= huart->Init.HwFlowCtl; + + /* Write to USART CR3 */ + huart->Instance->CR3 = (uint32_t)tmpreg; + + /* Check the Over Sampling */ + if(huart->Init.OverSampling == UART_OVERSAMPLING_8) + { + /*-------------------------- USART BRR Configuration ---------------------*/ + if((huart->Instance == USART1) || (huart->Instance == USART6)) + { + huart->Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate); + } + else + { + huart->Instance->BRR = UART_BRR_SAMPLING8(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate); + } + } + else + { + /*-------------------------- USART BRR Configuration ---------------------*/ + if((huart->Instance == USART1) || (huart->Instance == USART6)) + { + huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK2Freq(), huart->Init.BaudRate); + } + else + { + huart->Instance->BRR = UART_BRR_SAMPLING16(HAL_RCC_GetPCLK1Freq(), huart->Init.BaudRate); + } + } +} + +/** + * @} + */ + +#endif /* HAL_UART_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_usart.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_usart.c new file mode 100644 index 0000000..6eb31b1 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_usart.c @@ -0,0 +1,1857 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_usart.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief USART HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Universal Synchronous Asynchronous Receiver Transmitter (USART) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The USART HAL driver can be used as follows: + + (#) Declare a USART_HandleTypeDef handle structure. + (#) Initialize the USART low level resources by implementing the HAL_USART_MspInit () API: + (##) Enable the USARTx interface clock. + (##) USART pins configuration: + (+++) Enable the clock for the USART GPIOs. + (+++) Configure these USART pins as alternate function pull-up. + (##) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(), + HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs): + (+++) Configure the USARTx interrupt priority. + (+++) Enable the NVIC USART IRQ handle. + (##) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA() + HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs): + (+++) Declare a DMA handle structure for the Tx/Rx stream. + (+++) Enable the DMAx interface clock. + (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. + (+++) Configure the DMA Tx/Rx Stream. + (+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle. + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream. + + (#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware + flow control and Mode(Receiver/Transmitter) in the husart Init structure. + + (#) Initialize the USART registers by calling the HAL_USART_Init() API: + (++) These APIs configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) + by calling the customized HAL_USART_MspInit(&husart) API. + + -@@- The specific USART interrupts (Transmission complete interrupt, + RXNE interrupt and Error Interrupts) will be managed using the macros + __HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process. + + (#) Three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Send an amount of data in blocking mode using HAL_USART_Transmit() + (+) Receive an amount of data in blocking mode using HAL_USART_Receive() + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Send an amount of data in non blocking mode using HAL_USART_Transmit_IT() + (+) At transmission end of transfer HAL_USART_TxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_USART_TxCpltCallback + (+) Receive an amount of data in non blocking mode using HAL_USART_Receive_IT() + (+) At reception end of transfer HAL_USART_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_UART_RxCpltCallback + (+) In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_USART_ErrorCallback + + *** DMA mode IO operation *** + ============================== + [..] + (+) Send an amount of data in non blocking mode (DMA) using HAL_USART_Transmit_DMA() + (+) At transmission end of half transfer HAL_USART_TxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_USART_TxHalfCpltCallback + (+) At transmission end of transfer HAL_USART_TxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_USART_TxCpltCallback + (+) Receive an amount of data in non blocking mode (DMA) using HAL_USART_Receive_DMA() + (+) At reception end of half transfer HAL_USART_RxHalfCpltCallback is executed and user can + add his own code by customization of function pointer HAL_USART_RxHalfCpltCallback + (+) At reception end of transfer HAL_USART_RxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_USART_RxCpltCallback + (+) In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_USART_ErrorCallback + (+) Pause the DMA Transfer using HAL_USART_DMAPause() + (+) Resume the DMA Transfer using HAL_USART_DMAResume() + (+) Stop the DMA Transfer using HAL_USART_DMAStop() + + *** USART HAL driver macros list *** + ============================================= + [..] + Below the list of most used macros in USART HAL driver. + + (+) __HAL_USART_ENABLE: Enable the USART peripheral + (+) __HAL_USART_DISABLE: Disable the USART peripheral + (+) __HAL_USART_GET_FLAG : Check whether the specified USART flag is set or not + (+) __HAL_USART_CLEAR_FLAG : Clear the specified USART pending flag + (+) __HAL_USART_ENABLE_IT: Enable the specified USART interrupt + (+) __HAL_USART_DISABLE_IT: Disable the specified USART interrupt + + [..] + (@) You can refer to the USART HAL driver header file for more useful macros + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 USART USART + * @brief HAL USART Synchronous module driver + * @{ + */ +#ifdef HAL_USART_MODULE_ENABLED +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup USART_Private_Constants + * @{ + */ +#define DUMMY_DATA 0xFFFF +#define USART_TIMEOUT_VALUE 22000 +/** + * @} + */ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup USART_Private_Functions + * @{ + */ +static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart); +static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart); +static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart); +static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart); +static void USART_SetConfig (USART_HandleTypeDef *husart); +static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma); +static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma); +static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma); +static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma); +static void USART_DMAError(DMA_HandleTypeDef *hdma); +static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup USART_Exported_Functions USART Exported Functions + * @{ + */ + +/** @defgroup USART_Exported_Functions_Group1 USART Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and Configuration functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to initialize the USART + in asynchronous and in synchronous modes. + (+) For the asynchronous mode only these parameters can be configured: + (++) Baud Rate + (++) Word Length + (++) Stop Bit + (++) Parity: If the parity is enabled, then the MSB bit of the data written + in the data register is transmitted but is changed by the parity bit. + Depending on the frame length defined by the M bit (8-bits or 9-bits), + please refer to Reference manual for possible USART frame formats. + (++) USART polarity + (++) USART phase + (++) USART LastBit + (++) Receiver/transmitter modes + + [..] + The HAL_USART_Init() function follows the USART synchronous configuration + procedure (details for the procedure are available in reference manual (RM0329)). + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the USART mode according to the specified + * parameters in the USART_InitTypeDef and create the associated handle. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart) +{ + /* Check the USART handle allocation */ + if(husart == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_USART_INSTANCE(husart->Instance)); + + if(husart->State == HAL_USART_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + husart->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_USART_MspInit(husart); + } + + husart->State = HAL_USART_STATE_BUSY; + + /* Set the USART Communication parameters */ + USART_SetConfig(husart); + + /* In USART mode, the following bits must be kept cleared: + - LINEN bit in the USART_CR2 register + - HDSEL, SCEN and IREN bits in the USART_CR3 register */ + husart->Instance->CR2 &= ~USART_CR2_LINEN; + husart->Instance->CR3 &= ~(USART_CR3_IREN | USART_CR3_SCEN | USART_CR3_HDSEL); + + /* Enable the Peripheral */ + __HAL_USART_ENABLE(husart); + + /* Initialize the USART state */ + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State= HAL_USART_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the USART peripheral. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart) +{ + /* Check the USART handle allocation */ + if(husart == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_USART_INSTANCE(husart->Instance)); + + husart->State = HAL_USART_STATE_BUSY; + + /* Disable the Peripheral */ + __HAL_USART_DISABLE(husart); + + /* DeInit the low level hardware */ + HAL_USART_MspDeInit(husart); + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(husart); + + return HAL_OK; +} + +/** + * @brief USART MSP Init. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval None + */ + __weak void HAL_USART_MspInit(USART_HandleTypeDef *husart) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_USART_MspInit could be implemented in the user file + */ +} + +/** + * @brief USART MSP DeInit. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval None + */ + __weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_USART_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup USART_Exported_Functions_Group2 IO operation functions + * @brief USART Transmit and Receive functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to manage the USART synchronous + data transfers. + + [..] + The USART supports master mode only: it cannot receive or send data related to an input + clock (SCLK is always an output). + + (#) There are two modes of transfer: + (++) Blocking mode: The communication is performed in polling mode. + The HAL status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode: The communication is performed using Interrupts + or DMA, These API's return the HAL status. + The end of the data processing will be indicated through the + dedicated USART IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback() + user callbacks + will be executed respectively at the end of the transmit or Receive process + The HAL_USART_ErrorCallback() user callback will be executed when a communication + error is detected + + (#) Blocking mode APIs are : + (++) HAL_USART_Transmit() in simplex mode + (++) HAL_USART_Receive() in full duplex receive only + (++) HAL_USART_TransmitReceive() in full duplex mode + + (#) Non Blocking mode APIs with Interrupt are : + (++) HAL_USART_Transmit_IT()in simplex mode + (++) HAL_USART_Receive_IT() in full duplex receive only + (++) HAL_USART_TransmitReceive_IT() in full duplex mode + (++) HAL_USART_IRQHandler() + + (#) Non Blocking mode functions with DMA are : + (++) HAL_USART_Transmit_DMA()in simplex mode + (++) HAL_USART_Receive_DMA() in full duplex receive only + (++) HAL_USART_TransmitReceie_DMA() in full duplex mode + (++) HAL_USART_DMAPause() + (++) HAL_USART_DMAResume() + (++) HAL_USART_DMAStop() + + (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) HAL_USART_TxHalfCpltCallback() + (++) HAL_USART_TxCpltCallback() + (++) HAL_USART_RxHalfCpltCallback() + (++) HAL_USART_RxCpltCallback() + (++) HAL_USART_ErrorCallback() + (++) HAL_USART_TxRxCpltCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Simplex Send an amount of data in blocking mode. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @param pTxData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout) +{ + uint16_t* tmp; + + if(husart->State == HAL_USART_STATE_READY) + { + if((pTxData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(husart); + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_TX; + + husart->TxXferSize = Size; + husart->TxXferCount = Size; + while(husart->TxXferCount > 0) + { + husart->TxXferCount--; + if(husart->Init.WordLength == USART_WORDLENGTH_9B) + { + /* Wait for TC flag in order to write data in DR */ + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + tmp = (uint16_t*) pTxData; + husart->Instance->DR = (*tmp & (uint16_t)0x01FF); + if(husart->Init.Parity == USART_PARITY_NONE) + { + pTxData += 2; + } + else + { + pTxData += 1; + } + } + else + { + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + husart->Instance->DR = (*pTxData++ & (uint8_t)0xFF); + } + } + + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + husart->State = HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Full-Duplex Receive an amount of data in blocking mode. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @param pRxData: Pointer to data buffer + * @param Size: Amount of data to be received + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout) +{ + uint16_t* tmp; + + if(husart->State == HAL_USART_STATE_READY) + { + if((pRxData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(husart); + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_RX; + + husart->RxXferSize = Size; + husart->RxXferCount = Size; + /* Check the remain data to be received */ + while(husart->RxXferCount > 0) + { + husart->RxXferCount--; + if(husart->Init.WordLength == USART_WORDLENGTH_9B) + { + /* Wait until TXE flag is set to send dummy byte in order to generate the clock for the slave to send data */ + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + /* Send dummy byte in order to generate clock */ + husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x01FF); + + /* Wait for RXNE Flag */ + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + tmp = (uint16_t*) pRxData ; + if(husart->Init.Parity == USART_PARITY_NONE) + { + *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF); + pRxData +=2; + } + else + { + *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF); + pRxData +=1; + } + } + else + { + /* Wait until TXE flag is set to send dummy byte in order to generate the clock for the slave to send data */ + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send Dummy Byte in order to generate clock */ + husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x00FF); + + /* Wait until RXNE flag is set to receive the byte */ + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + if(husart->Init.Parity == USART_PARITY_NONE) + { + /* Receive data */ + *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF); + } + else + { + /* Receive data */ + *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F); + } + + } + } + + husart->State = HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Full-Duplex Send receive an amount of data in full-duplex mode (blocking mode). + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @param pTxData: Pointer to data transmitted buffer + * @param pRxData: Pointer to data received buffer + * @param Size: Amount of data to be sent + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout) +{ + uint16_t* tmp; + + if(husart->State == HAL_USART_STATE_READY) + { + if((pTxData == NULL) || (pRxData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(husart); + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_RX; + + husart->RxXferSize = Size; + husart->TxXferSize = Size; + husart->TxXferCount = Size; + husart->RxXferCount = Size; + + /* Check the remain data to be received */ + while(husart->TxXferCount > 0) + { + husart->TxXferCount--; + husart->RxXferCount--; + if(husart->Init.WordLength == USART_WORDLENGTH_9B) + { + /* Wait for TC flag in order to write data in DR */ + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + tmp = (uint16_t*) pTxData; + husart->Instance->DR = (*tmp & (uint16_t)0x01FF); + if(husart->Init.Parity == USART_PARITY_NONE) + { + pTxData += 2; + } + else + { + pTxData += 1; + } + + /* Wait for RXNE Flag */ + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + tmp = (uint16_t*) pRxData ; + if(husart->Init.Parity == USART_PARITY_NONE) + { + *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF); + pRxData += 2; + } + else + { + *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF); + pRxData += 1; + } + } + else + { + /* Wait for TC flag in order to write data in DR */ + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + husart->Instance->DR = (*pTxData++ & (uint8_t)0x00FF); + + /* Wait for RXNE Flag */ + if(USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, Timeout) != HAL_OK) + { + return HAL_TIMEOUT; + } + if(husart->Init.Parity == USART_PARITY_NONE) + { + /* Receive data */ + *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF); + } + else + { + /* Receive data */ + *pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F); + } + } + } + + husart->State = HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Simplex Send an amount of data in non-blocking mode. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @param pTxData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + * @note The USART errors are not managed to avoid the overrun error. + */ +HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size) +{ + if(husart->State == HAL_USART_STATE_READY) + { + if((pTxData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(husart); + + husart->pTxBuffPtr = pTxData; + husart->TxXferSize = Size; + husart->TxXferCount = Size; + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_TX; + + /* The USART Error Interrupts: (Frame error, Noise error, Overrun error) + are not managed by the USART transmit process to avoid the overrun interrupt + when the USART mode is configured for transmit and receive "USART_MODE_TX_RX" + to benefit for the frame error and noise interrupts the USART mode should be + configured only for transmit "USART_MODE_TX" + The __HAL_USART_ENABLE_IT(husart, USART_IT_ERR) can be used to enable the Frame error, + Noise error interrupt */ + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + /* Enable the USART Transmit Data Register Empty Interrupt */ + __HAL_USART_ENABLE_IT(husart, USART_IT_TXE); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Simplex Receive an amount of data in non-blocking mode. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @param pRxData: Pointer to data buffer + * @param Size: Amount of data to be received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size) +{ + if(husart->State == HAL_USART_STATE_READY) + { + if((pRxData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(husart); + + husart->pRxBuffPtr = pRxData; + husart->RxXferSize = Size; + husart->RxXferCount = Size; + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_RX; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + /* Enable the USART Data Register not empty Interrupt */ + __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE); + + /* Enable the USART Parity Error Interrupt */ + __HAL_USART_ENABLE_IT(husart, USART_IT_PE); + + /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_USART_ENABLE_IT(husart, USART_IT_ERR); + + /* Send dummy byte in order to generate the clock for the slave to send data */ + husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x01FF); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking). + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @param pTxData: Pointer to data transmitted buffer + * @param pRxData: Pointer to data received buffer + * @param Size: Amount of data to be received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size) +{ + if(husart->State == HAL_USART_STATE_READY) + { + if((pTxData == NULL) || (pRxData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(husart); + + husart->pRxBuffPtr = pRxData; + husart->RxXferSize = Size; + husart->RxXferCount = Size; + husart->pTxBuffPtr = pTxData; + husart->TxXferSize = Size; + husart->TxXferCount = Size; + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_TX_RX; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + /* Enable the USART Data Register not empty Interrupt */ + __HAL_USART_ENABLE_IT(husart, USART_IT_RXNE); + + /* Enable the USART Parity Error Interrupt */ + __HAL_USART_ENABLE_IT(husart, USART_IT_PE); + + /* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_USART_ENABLE_IT(husart, USART_IT_ERR); + + /* Enable the USART Transmit Data Register Empty Interrupt */ + __HAL_USART_ENABLE_IT(husart, USART_IT_TXE); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Simplex Send an amount of data in non-blocking mode. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @param pTxData: Pointer to data buffer + * @param Size: Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size) +{ + uint32_t *tmp; + + if(husart->State == HAL_USART_STATE_READY) + { + if((pTxData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(husart); + + husart->pTxBuffPtr = pTxData; + husart->TxXferSize = Size; + husart->TxXferCount = Size; + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_TX; + + /* Set the USART DMA transfer complete callback */ + husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt; + + /* Set the USART DMA Half transfer complete callback */ + husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt; + + /* Set the DMA error callback */ + husart->hdmatx->XferErrorCallback = USART_DMAError; + + /* Enable the USART transmit DMA Stream */ + tmp = (uint32_t*)&pTxData; + HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size); + + /* Clear the TC flag in the SR register by writing 0 to it */ + __HAL_USART_CLEAR_FLAG(husart, USART_FLAG_TC); + + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the USART CR3 register */ + husart->Instance->CR3 |= USART_CR3_DMAT; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Full-Duplex Receive an amount of data in non-blocking mode. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @param pRxData: Pointer to data buffer + * @param Size: Amount of data to be received + * @retval HAL status + * @note The USART DMA transmit stream must be configured in order to generate the clock for the slave. + * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit. + */ +HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size) +{ + uint32_t *tmp; + + if(husart->State == HAL_USART_STATE_READY) + { + if((pRxData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(husart); + + husart->pRxBuffPtr = pRxData; + husart->RxXferSize = Size; + husart->pTxBuffPtr = pRxData; + husart->TxXferSize = Size; + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_RX; + + /* Set the USART DMA Rx transfer complete callback */ + husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt; + + /* Set the USART DMA Half transfer complete callback */ + husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt; + + /* Set the USART DMA Rx transfer error callback */ + husart->hdmarx->XferErrorCallback = USART_DMAError; + + /* Enable the USART receive DMA Stream */ + tmp = (uint32_t*)&pRxData; + HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->DR, *(uint32_t*)tmp, Size); + + /* Enable the USART transmit DMA Stream: the transmit stream is used in order + to generate in the non-blocking mode the clock to the slave device, + this mode isn't a simplex receive mode but a full-duplex receive one */ + HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size); + + /* Clear the Overrun flag just before enabling the DMA Rx request: mandatory for the second transfer + when using the USART in circular mode */ + __HAL_USART_CLEAR_OREFLAG(husart); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the USART CR3 register */ + husart->Instance->CR3 |= USART_CR3_DMAR; + + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the USART CR3 register */ + husart->Instance->CR3 |= USART_CR3_DMAT; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Full-Duplex Transmit Receive an amount of data in non-blocking mode. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @param pTxData: Pointer to data transmitted buffer + * @param pRxData: Pointer to data received buffer + * @param Size: Amount of data to be received + * @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size) +{ + uint32_t *tmp; + + if(husart->State == HAL_USART_STATE_READY) + { + if((pTxData == NULL) || (pRxData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + /* Process Locked */ + __HAL_LOCK(husart); + + husart->pRxBuffPtr = pRxData; + husart->RxXferSize = Size; + husart->pTxBuffPtr = pTxData; + husart->TxXferSize = Size; + + husart->ErrorCode = HAL_USART_ERROR_NONE; + husart->State = HAL_USART_STATE_BUSY_TX_RX; + + /* Set the USART DMA Rx transfer complete callback */ + husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt; + + /* Set the USART DMA Half transfer complete callback */ + husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt; + + /* Set the USART DMA Tx transfer complete callback */ + husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt; + + /* Set the USART DMA Half transfer complete callback */ + husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt; + + /* Set the USART DMA Tx transfer error callback */ + husart->hdmatx->XferErrorCallback = USART_DMAError; + + /* Set the USART DMA Rx transfer error callback */ + husart->hdmarx->XferErrorCallback = USART_DMAError; + + /* Enable the USART receive DMA Stream */ + tmp = (uint32_t*)&pRxData; + HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->DR, *(uint32_t*)tmp, Size); + + /* Enable the USART transmit DMA Stream */ + tmp = (uint32_t*)&pTxData; + HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t*)tmp, (uint32_t)&husart->Instance->DR, Size); + + /* Clear the TC flag in the SR register by writing 0 to it */ + __HAL_USART_CLEAR_FLAG(husart, USART_FLAG_TC); + + /* Clear the Overrun flag: mandatory for the second transfer in circular mode */ + __HAL_USART_CLEAR_OREFLAG(husart); + + /* Enable the DMA transfer for the receiver request by setting the DMAR bit + in the USART CR3 register */ + husart->Instance->CR3 |= USART_CR3_DMAR; + + /* Enable the DMA transfer for transmit request by setting the DMAT bit + in the USART CR3 register */ + husart->Instance->CR3 |= USART_CR3_DMAT; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Pauses the DMA Transfer. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart) +{ + /* Process Locked */ + __HAL_LOCK(husart); + + /* Disable the USART DMA Tx request */ + husart->Instance->CR3 &= (uint32_t)(~USART_CR3_DMAT); + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; +} + +/** + * @brief Resumes the DMA Transfer. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart) +{ + /* Process Locked */ + __HAL_LOCK(husart); + + /* Enable the USART DMA Tx request */ + husart->Instance->CR3 |= USART_CR3_DMAT; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_OK; +} + +/** + * @brief Stops the DMA Transfer. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart) +{ + /* The Lock is not implemented on this API to allow the user application + to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback(): + when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated + and the correspond call back is executed HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback() + */ + + /* Abort the USART DMA Tx Stream */ + if(husart->hdmatx != NULL) + { + HAL_DMA_Abort(husart->hdmatx); + } + /* Abort the USART DMA Rx Stream */ + if(husart->hdmarx != NULL) + { + HAL_DMA_Abort(husart->hdmarx); + } + + /* Disable the USART Tx/Rx DMA requests */ + husart->Instance->CR3 &= ~USART_CR3_DMAT; + husart->Instance->CR3 &= ~USART_CR3_DMAR; + + husart->State = HAL_USART_STATE_READY; + + return HAL_OK; +} + +/** + * @brief This function handles USART interrupt request. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval None + */ +void HAL_USART_IRQHandler(USART_HandleTypeDef *husart) +{ + uint32_t tmp1 = 0, tmp2 = 0; + + tmp1 = __HAL_USART_GET_FLAG(husart, USART_FLAG_PE); + tmp2 = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_PE); + /* USART parity error interrupt occurred -----------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_USART_CLEAR_PEFLAG(husart); + husart->ErrorCode |= HAL_USART_ERROR_PE; + } + + tmp1 = __HAL_USART_GET_FLAG(husart, USART_FLAG_FE); + tmp2 = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR); + /* USART frame error interrupt occurred ------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_USART_CLEAR_FEFLAG(husart); + husart->ErrorCode |= HAL_USART_ERROR_FE; + } + + tmp1 = __HAL_USART_GET_FLAG(husart, USART_FLAG_NE); + tmp2 = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR); + /* USART noise error interrupt occurred ------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_USART_CLEAR_NEFLAG(husart); + husart->ErrorCode |= HAL_USART_ERROR_NE; + } + + tmp1 = __HAL_USART_GET_FLAG(husart, USART_FLAG_ORE); + tmp2 = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_ERR); + /* USART Over-Run interrupt occurred ---------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + __HAL_USART_CLEAR_OREFLAG(husart); + husart->ErrorCode |= HAL_USART_ERROR_ORE; + } + + if(husart->ErrorCode != HAL_USART_ERROR_NONE) + { + /* Set the USART state ready to be able to start again the process */ + husart->State = HAL_USART_STATE_READY; + + HAL_USART_ErrorCallback(husart); + } + + tmp1 = __HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE); + tmp2 = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_RXNE); + /* USART in mode Receiver --------------------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + if(husart->State == HAL_USART_STATE_BUSY_RX) + { + USART_Receive_IT(husart); + } + else + { + USART_TransmitReceive_IT(husart); + } + } + + tmp1 = __HAL_USART_GET_FLAG(husart, USART_FLAG_TXE); + tmp2 = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_TXE); + /* USART in mode Transmitter -----------------------------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + if(husart->State == HAL_USART_STATE_BUSY_TX) + { + USART_Transmit_IT(husart); + } + else + { + USART_TransmitReceive_IT(husart); + } + } + + tmp1 = __HAL_USART_GET_FLAG(husart, USART_FLAG_TC); + tmp2 = __HAL_USART_GET_IT_SOURCE(husart, USART_IT_TC); + /* USART in mode Transmitter (transmission end) ----------------------------*/ + if((tmp1 != RESET) && (tmp2 != RESET)) + { + USART_EndTransmit_IT(husart); + } +} + +/** + * @brief Tx Transfer completed callbacks. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval None + */ + __weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_USART_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Tx Half Transfer completed callbacks. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval None + */ + __weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_USART_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Transfer completed callbacks. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval None + */ +__weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_USART_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Rx Half Transfer completed callbacks. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval None + */ +__weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_USART_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Tx/Rx Transfers completed callback for the non-blocking process. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval None + */ +__weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_USART_TxCpltCallback could be implemented in the user file + */ +} + +/** + * @brief USART error callbacks. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval None + */ + __weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_USART_ErrorCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup USART_Exported_Functions_Group3 Peripheral State and Errors functions + * @brief USART State and Errors functions + * +@verbatim + ============================================================================== + ##### Peripheral State and Errors functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to return the State of + USART communication + process, return Peripheral Errors occurred during communication process + (+) HAL_USART_GetState() API can be helpful to check in run-time the state + of the USART peripheral. + (+) HAL_USART_GetError() check in run-time errors that could be occurred during + communication. +@endverbatim + * @{ + */ + +/** + * @brief Returns the USART state. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval HAL state + */ +HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart) +{ + return husart->State; +} + +/** + * @brief Return the USART error code + * @param husart : pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART. + * @retval USART Error Code + */ +uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart) +{ + return husart->ErrorCode; +} + +/** + * @} + */ + + +/** + * @brief DMA USART transmit process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma) +{ + USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + /* DMA Normal mode */ + if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) + { + husart->TxXferCount = 0; + if(husart->State == HAL_USART_STATE_BUSY_TX) + { + /* Disable the DMA transfer for transmit request by resetting the DMAT bit + in the USART CR3 register */ + CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT); + + /* Enable the USART Transmit Complete Interrupt */ + __HAL_USART_ENABLE_IT(husart, USART_IT_TC); + } + } + /* DMA Circular mode */ + else + { + if(husart->State == HAL_USART_STATE_BUSY_TX) + { + HAL_USART_TxCpltCallback(husart); + } + } +} + +/** + * @brief DMA USART transmit process half complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma) +{ + USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + HAL_USART_TxHalfCpltCallback(husart); +} + +/** + * @brief DMA USART receive process complete callback. + * @param hdma: DMA handle + * @retval None + */ +static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma) +{ + USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + /* DMA Normal mode */ + if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) + { + husart->RxXferCount = 0; + if(husart->State == HAL_USART_STATE_BUSY_RX) + { + /* Disable the DMA transfer for the Transmit/receiver requests by setting the DMAT/DMAR bit + in the USART CR3 register */ + husart->Instance->CR3 &= ~(USART_CR3_DMAR); + + husart->State= HAL_USART_STATE_READY; + HAL_USART_RxCpltCallback(husart); + } + /* The USART state is HAL_USART_STATE_BUSY_TX_RX */ + else + { + /* Disable the DMA transfer for the Transmit/receiver requests by setting the DMAT/DMAR bit + in the USART CR3 register */ + husart->Instance->CR3 &= ~(USART_CR3_DMAR); + husart->Instance->CR3 &= ~(USART_CR3_DMAT); + + husart->State= HAL_USART_STATE_READY; + HAL_USART_TxRxCpltCallback(husart); + } + } + /* DMA circular mode */ + else + { + if(husart->State == HAL_USART_STATE_BUSY_RX) + { + HAL_USART_RxCpltCallback(husart); + } + /* The USART state is HAL_USART_STATE_BUSY_TX_RX */ + else + { + HAL_USART_TxRxCpltCallback(husart); + } + } +} + +/** + * @brief DMA USART receive process half complete callback + * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * the configuration information for the specified DMA module. + * @retval None + */ +static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma) +{ + USART_HandleTypeDef* husart = (USART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + HAL_USART_RxHalfCpltCallback(husart); +} + +/** + * @brief DMA USART communication error callback. + * @param hdma: DMA handle + * @retval None + */ +static void USART_DMAError(DMA_HandleTypeDef *hdma) +{ + USART_HandleTypeDef* husart = ( USART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + husart->RxXferCount = 0; + husart->TxXferCount = 0; + husart->ErrorCode |= HAL_USART_ERROR_DMA; + husart->State= HAL_USART_STATE_READY; + + HAL_USART_ErrorCallback(husart); +} + +/** + * @brief This function handles USART Communication Timeout. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @param Flag: specifies the USART flag to check. + * @param Status: The new Flag status (SET or RESET). + * @param Timeout: Timeout duration + * @retval HAL status + */ +static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until flag is set */ + if(Status == RESET) + { + while(__HAL_USART_GET_FLAG(husart, Flag) == RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ + __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); + __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE); + __HAL_USART_DISABLE_IT(husart, USART_IT_PE); + __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); + + husart->State= HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_TIMEOUT; + } + } + } + } + else + { + while(__HAL_USART_GET_FLAG(husart, Flag) != RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ + __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); + __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE); + __HAL_USART_DISABLE_IT(husart, USART_IT_PE); + __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); + + husart->State= HAL_USART_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(husart); + + return HAL_TIMEOUT; + } + } + } + } + return HAL_OK; +} + + +/** + * @brief Simplex Send an amount of data in non-blocking mode. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval HAL status + * @note The USART errors are not managed to avoid the overrun error. + */ +static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart) +{ + uint16_t* tmp; + + if(husart->State == HAL_USART_STATE_BUSY_TX) + { + if(husart->Init.WordLength == USART_WORDLENGTH_9B) + { + tmp = (uint16_t*) husart->pTxBuffPtr; + husart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF); + if(husart->Init.Parity == USART_PARITY_NONE) + { + husart->pTxBuffPtr += 2; + } + else + { + husart->pTxBuffPtr += 1; + } + } + else + { + husart->Instance->DR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0x00FF); + } + + if(--husart->TxXferCount == 0) + { + /* Disable the USART Transmit data register empty Interrupt */ + __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); + + /* Enable the USART Transmit Complete Interrupt */ + __HAL_USART_ENABLE_IT(husart, USART_IT_TC); + } + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Wraps up transmission in non blocking mode. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval HAL status + */ +static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart) +{ + /* Disable the USART Transmit Complete Interrupt */ + __HAL_USART_DISABLE_IT(husart, USART_IT_TC); + + /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); + + husart->State = HAL_USART_STATE_READY; + + HAL_USART_TxCpltCallback(husart); + + return HAL_OK; +} + +/** + * @brief Simplex Receive an amount of data in non-blocking mode. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval HAL status + */ +static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart) +{ + uint16_t* tmp; + if(husart->State == HAL_USART_STATE_BUSY_RX) + { + if(husart->Init.WordLength == USART_WORDLENGTH_9B) + { + tmp = (uint16_t*) husart->pRxBuffPtr; + if(husart->Init.Parity == USART_PARITY_NONE) + { + *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF); + husart->pRxBuffPtr += 2; + } + else + { + *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF); + husart->pRxBuffPtr += 1; + } + if(--husart->RxXferCount != 0x00) + { + /* Send dummy byte in order to generate the clock for the slave to send the next data */ + husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x01FF); + } + } + else + { + if(husart->Init.Parity == USART_PARITY_NONE) + { + *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF); + } + else + { + *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F); + } + + if(--husart->RxXferCount != 0x00) + { + /* Send dummy byte in order to generate the clock for the slave to send the next data */ + husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x00FF); + } + } + + if(husart->RxXferCount == 0) + { + /* Disable the USART RXNE Interrupt */ + __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE); + + /* Disable the USART Parity Error Interrupt */ + __HAL_USART_DISABLE_IT(husart, USART_IT_PE); + + /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); + + husart->State = HAL_USART_STATE_READY; + HAL_USART_RxCpltCallback(husart); + + return HAL_OK; + } + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking). + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval HAL status + */ +static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart) +{ + uint16_t* tmp; + + if(husart->State == HAL_USART_STATE_BUSY_TX_RX) + { + if(husart->TxXferCount != 0x00) + { + if(__HAL_USART_GET_FLAG(husart, USART_FLAG_TXE) != RESET) + { + if(husart->Init.WordLength == USART_WORDLENGTH_9B) + { + tmp = (uint16_t*) husart->pTxBuffPtr; + husart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF); + if(husart->Init.Parity == USART_PARITY_NONE) + { + husart->pTxBuffPtr += 2; + } + else + { + husart->pTxBuffPtr += 1; + } + } + else + { + husart->Instance->DR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0x00FF); + } + husart->TxXferCount--; + + /* Check the latest data transmitted */ + if(husart->TxXferCount == 0) + { + __HAL_USART_DISABLE_IT(husart, USART_IT_TXE); + } + } + } + + if(husart->RxXferCount != 0x00) + { + if(__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET) + { + if(husart->Init.WordLength == USART_WORDLENGTH_9B) + { + tmp = (uint16_t*) husart->pRxBuffPtr; + if(husart->Init.Parity == USART_PARITY_NONE) + { + *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF); + husart->pRxBuffPtr += 2; + } + else + { + *tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF); + husart->pRxBuffPtr += 1; + } + } + else + { + if(husart->Init.Parity == USART_PARITY_NONE) + { + *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF); + } + else + { + *husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F); + } + } + husart->RxXferCount--; + } + } + + /* Check the latest data received */ + if(husart->RxXferCount == 0) + { + __HAL_USART_DISABLE_IT(husart, USART_IT_RXNE); + + /* Disable the USART Parity Error Interrupt */ + __HAL_USART_DISABLE_IT(husart, USART_IT_PE); + + /* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */ + __HAL_USART_DISABLE_IT(husart, USART_IT_ERR); + + husart->State = HAL_USART_STATE_READY; + + HAL_USART_TxRxCpltCallback(husart); + + return HAL_OK; + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Configures the USART peripheral. + * @param husart: pointer to a USART_HandleTypeDef structure that contains + * the configuration information for the specified USART module. + * @retval None + */ +static void USART_SetConfig(USART_HandleTypeDef *husart) +{ + uint32_t tmpreg = 0x00; + + /* Check the parameters */ + assert_param(IS_USART_INSTANCE(husart->Instance)); + assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity)); + assert_param(IS_USART_PHASE(husart->Init.CLKPhase)); + assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit)); + assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate)); + assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength)); + assert_param(IS_USART_STOPBITS(husart->Init.StopBits)); + assert_param(IS_USART_PARITY(husart->Init.Parity)); + assert_param(IS_USART_MODE(husart->Init.Mode)); + + /* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the + receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */ + husart->Instance->CR1 &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE)); + + /*---------------------------- USART CR2 Configuration ---------------------*/ + tmpreg = husart->Instance->CR2; + /* Clear CLKEN, CPOL, CPHA and LBCL bits */ + tmpreg &= (uint32_t)~((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP)); + /* Configure the USART Clock, CPOL, CPHA and LastBit -----------------------*/ + /* Set CPOL bit according to husart->Init.CLKPolarity value */ + /* Set CPHA bit according to husart->Init.CLKPhase value */ + /* Set LBCL bit according to husart->Init.CLKLastBit value */ + /* Set Stop Bits: Set STOP[13:12] bits according to husart->Init.StopBits value */ + tmpreg |= (uint32_t)(USART_CLOCK_ENABLE| husart->Init.CLKPolarity | + husart->Init.CLKPhase| husart->Init.CLKLastBit | husart->Init.StopBits); + /* Write to USART CR2 */ + husart->Instance->CR2 = (uint32_t)tmpreg; + + /*-------------------------- USART CR1 Configuration -----------------------*/ + tmpreg = husart->Instance->CR1; + + /* Clear M, PCE, PS, TE, RE and OVER8 bits */ + tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \ + USART_CR1_RE | USART_CR1_OVER8)); + + /* Configure the USART Word Length, Parity and mode: + Set the M bits according to husart->Init.WordLength value + Set PCE and PS bits according to husart->Init.Parity value + Set TE and RE bits according to husart->Init.Mode value + Force OVER8 bit to 1 in order to reach the max USART frequencies */ + tmpreg |= (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8; + + /* Write to USART CR1 */ + husart->Instance->CR1 = (uint32_t)tmpreg; + + /*-------------------------- USART CR3 Configuration -----------------------*/ + /* Clear CTSE and RTSE bits */ + husart->Instance->CR3 &= (uint32_t)~((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE)); + + /*-------------------------- USART BRR Configuration -----------------------*/ + if((husart->Instance == USART1) || (husart->Instance == USART6)) + { + husart->Instance->BRR = USART_BRR(HAL_RCC_GetPCLK2Freq(), husart->Init.BaudRate); + } + else + { + husart->Instance->BRR = USART_BRR(HAL_RCC_GetPCLK1Freq(), husart->Init.BaudRate); + } +} + +/** + * @} + */ + +#endif /* HAL_USART_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_wwdg.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_wwdg.c new file mode 100644 index 0000000..01a6186 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_wwdg.c @@ -0,0 +1,454 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_wwdg.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief WWDG HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Window Watchdog (WWDG) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State functions + @verbatim + ============================================================================== + ##### WWDG specific features ##### + ============================================================================== + [..] + Once enabled the WWDG generates a system reset on expiry of a programmed + time period, unless the program refreshes the counter (downcounter) + before reaching 0x3F value (i.e. a reset is generated when the counter + value rolls over from 0x40 to 0x3F). + + (+) An MCU reset is also generated if the counter value is refreshed + before the counter has reached the refresh window value. This + implies that the counter must be refreshed in a limited window. + (+) Once enabled the WWDG cannot be disabled except by a system reset. + (+) WWDGRST flag in RCC_CSR register can be used to inform when a WWDG + reset occurs. + (+) The WWDG counter input clock is derived from the APB clock divided + by a programmable prescaler. + (+) WWDG clock (Hz) = PCLK1 / (4096 * Prescaler) + (+) WWDG timeout (mS) = 1000 * Counter / WWDG clock + (+) WWDG Counter refresh is allowed between the following limits : + (++) min time (mS) = 1000 * (Counter – Window) / WWDG clock + (++) max time (mS) = 1000 * (Counter – 0x40) / WWDG clock + + (+) Min-max timeout value at 50 MHz(PCLK1): 81.9 us / 41.9 ms + + + ##### How to use this driver ##### + ============================================================================== + [..] + (+) Enable WWDG APB1 clock using __HAL_RCC_WWDG_CLK_ENABLE(). + (+) Set the WWDG prescaler, refresh window and counter value + using HAL_WWDG_Init() function. + (+) Start the WWDG using HAL_WWDG_Start() function. + When the WWDG is enabled the counter value should be configured to + a value greater than 0x40 to prevent generating an immediate reset. + (+) Optionally you can enable the Early Wakeup Interrupt (EWI) which is + generated when the counter reaches 0x40, and then start the WWDG using + HAL_WWDG_Start_IT(). At EWI HAL_WWDG_WakeupCallback is executed and user can + add his own code by customization of function pointer HAL_WWDG_WakeupCallback + Once enabled, EWI interrupt cannot be disabled except by a system reset. + (+) Then the application program must refresh the WWDG counter at regular + intervals during normal operation to prevent an MCU reset, using + HAL_WWDG_Refresh() function. This operation must occur only when + the counter is lower than the refresh window value already programmed. + + *** WWDG HAL driver macros list *** + ================================== + [..] + Below the list of most used macros in WWDG HAL driver. + + (+) __HAL_WWDG_ENABLE: Enable the WWDG peripheral + (+) __HAL_WWDG_GET_FLAG: Get the selected WWDG's flag status + (+) __HAL_WWDG_CLEAR_FLAG: Clear the WWDG's pending flags + (+) __HAL_WWDG_ENABLE_IT: Enables the WWDG early wake-up interrupt + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 WWDG WWDG + * @brief WWDG HAL module driver. + * @{ + */ + +#ifdef HAL_WWDG_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup WWDG_Exported_Functions WWDG Exported Functions + * @{ + */ + +/** @defgroup WWDG_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 WWDG according to the specified parameters + in the WWDG_InitTypeDef and create the associated handle + (+) DeInitialize the WWDG peripheral + (+) Initialize the WWDG MSP + (+) DeInitialize the WWDG MSP + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the WWDG according to the specified + * parameters in the WWDG_InitTypeDef and creates the associated handle. + * @param hwwdg: pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg) +{ + /* Check the WWDG handle allocation */ + if(hwwdg == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_WWDG_ALL_INSTANCE(hwwdg->Instance)); + assert_param(IS_WWDG_PRESCALER(hwwdg->Init.Prescaler)); + assert_param(IS_WWDG_WINDOW(hwwdg->Init.Window)); + assert_param(IS_WWDG_COUNTER(hwwdg->Init.Counter)); + + if(hwwdg->State == HAL_WWDG_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hwwdg->Lock = HAL_UNLOCKED; + /* Init the low level hardware */ + HAL_WWDG_MspInit(hwwdg); + } + + /* Change WWDG peripheral state */ + hwwdg->State = HAL_WWDG_STATE_BUSY; + + /* Set WWDG Prescaler and Window */ + MODIFY_REG(hwwdg->Instance->CFR, (WWDG_CFR_WDGTB | WWDG_CFR_W), (hwwdg->Init.Prescaler | hwwdg->Init.Window)); + /* Set WWDG Counter */ + MODIFY_REG(hwwdg->Instance->CR, WWDG_CR_T, hwwdg->Init.Counter); + + /* Change WWDG peripheral state */ + hwwdg->State = HAL_WWDG_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief DeInitializes the WWDG peripheral. + * @param hwwdg: pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_WWDG_DeInit(WWDG_HandleTypeDef *hwwdg) +{ + /* Check the WWDG handle allocation */ + if(hwwdg == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_WWDG_ALL_INSTANCE(hwwdg->Instance)); + + /* Change WWDG peripheral state */ + hwwdg->State = HAL_WWDG_STATE_BUSY; + + /* DeInit the low level hardware */ + HAL_WWDG_MspDeInit(hwwdg); + + /* Reset WWDG Control register */ + hwwdg->Instance->CR = (uint32_t)0x0000007F; + + /* Reset WWDG Configuration register */ + hwwdg->Instance->CFR = (uint32_t)0x0000007F; + + /* Reset WWDG Status register */ + hwwdg->Instance->SR = 0; + + /* Change WWDG peripheral state */ + hwwdg->State = HAL_WWDG_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(hwwdg); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Initializes the WWDG MSP. + * @param hwwdg: pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. + * @retval None + */ +__weak void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_WWDG_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes the WWDG MSP. + * @param hwwdg: pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. + * @retval None + */ +__weak void HAL_WWDG_MspDeInit(WWDG_HandleTypeDef *hwwdg) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_WWDG_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup WWDG_Exported_Functions_Group2 IO operation functions + * @brief IO operation functions + * +@verbatim + ============================================================================== + ##### IO operation functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the WWDG. + (+) Refresh the WWDG. + (+) Handle WWDG interrupt request. + +@endverbatim + * @{ + */ + +/** + * @brief Starts the WWDG. + * @param hwwdg: pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_WWDG_Start(WWDG_HandleTypeDef *hwwdg) +{ + /* Process Locked */ + __HAL_LOCK(hwwdg); + + /* Change WWDG peripheral state */ + hwwdg->State = HAL_WWDG_STATE_BUSY; + + /* Enable the peripheral */ + __HAL_WWDG_ENABLE(hwwdg); + + /* Change WWDG peripheral state */ + hwwdg->State = HAL_WWDG_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hwwdg); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the WWDG with interrupt enabled. + * @param hwwdg: pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_WWDG_Start_IT(WWDG_HandleTypeDef *hwwdg) +{ + /* Process Locked */ + __HAL_LOCK(hwwdg); + + /* Change WWDG peripheral state */ + hwwdg->State = HAL_WWDG_STATE_BUSY; + + /* Enable the Early Wakeup Interrupt */ + __HAL_WWDG_ENABLE_IT(hwwdg, WWDG_IT_EWI); + + /* Enable the peripheral */ + __HAL_WWDG_ENABLE(hwwdg); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Refreshes the WWDG. + * @param hwwdg: pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. + * @param Counter: value of counter to put in WWDG counter + * @retval HAL status + */ +HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg, uint32_t Counter) +{ + /* Process Locked */ + __HAL_LOCK(hwwdg); + + /* Change WWDG peripheral state */ + hwwdg->State = HAL_WWDG_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_WWDG_COUNTER(Counter)); + + /* Write to WWDG CR the WWDG Counter value to refresh with */ + MODIFY_REG(hwwdg->Instance->CR, (uint32_t)WWDG_CR_T, Counter); + + /* Change WWDG peripheral state */ + hwwdg->State = HAL_WWDG_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hwwdg); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Handles WWDG interrupt request. + * @note The Early Wakeup Interrupt (EWI) can be used if specific safety operations + * or data logging must be performed before the actual reset is generated. + * The EWI interrupt is enabled using __HAL_WWDG_ENABLE_IT() macro. + * When the downcounter reaches the value 0x40, and EWI interrupt is + * generated and the corresponding Interrupt Service Routine (ISR) can + * be used to trigger specific actions (such as communications or data + * logging), before resetting the device. + * @param hwwdg: pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. + * @retval None + */ +void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg) +{ + /* Check if Early Wakeup Interrupt is enable */ + if(__HAL_WWDG_GET_IT_SOURCE(hwwdg, WWDG_IT_EWI) != RESET) + { + /* Check if WWDG Early Wakeup Interrupt occurred */ + if(__HAL_WWDG_GET_FLAG(hwwdg, WWDG_FLAG_EWIF) != RESET) + { + /* Early Wakeup callback */ + HAL_WWDG_WakeupCallback(hwwdg); + + /* Change WWDG peripheral state */ + hwwdg->State = HAL_WWDG_STATE_READY; + + /* Clear the WWDG Early Wakeup flag */ + __HAL_WWDG_CLEAR_FLAG(hwwdg, WWDG_FLAG_EWIF); + + /* Process Unlocked */ + __HAL_UNLOCK(hwwdg); + } + } +} + +/** + * @brief Early Wakeup WWDG callback. + * @param hwwdg: pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. + * @retval None + */ +__weak void HAL_WWDG_WakeupCallback(WWDG_HandleTypeDef* hwwdg) +{ + /* NOTE: This function Should not be modified, when the callback is needed, + the HAL_WWDG_WakeupCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup WWDG_Exported_Functions_Group3 Peripheral State functions + * @brief Peripheral State functions. + * +@verbatim + ============================================================================== + ##### Peripheral State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Returns the WWDG state. + * @param hwwdg: pointer to a WWDG_HandleTypeDef structure that contains + * the configuration information for the specified WWDG module. + * @retval HAL state + */ +HAL_WWDG_StateTypeDef HAL_WWDG_GetState(WWDG_HandleTypeDef *hwwdg) +{ + return hwwdg->State; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_WWDG_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c new file mode 100644 index 0000000..ef1055d --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c @@ -0,0 +1,1733 @@ +/** + ****************************************************************************** + * @file stm32f4xx_ll_fmc.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief FMC Low Layer HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the Flexible Memory Controller (FMC) peripheral memories: + * + Initialization/de-initialization functions + * + Peripheral Control functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### FMC peripheral features ##### + ============================================================================== + [..] The Flexible memory controller (FMC) includes three memory controllers: + (+) The NOR/PSRAM memory controller + (+) The NAND/PC Card memory controller + (+) The Synchronous DRAM (SDRAM) controller + + [..] The FMC functional block makes the interface with synchronous and asynchronous static + memories, SDRAM memories, and 16-bit PC memory cards. Its main purposes are: + (+) to translate AHB transactions into the appropriate external device protocol + (+) to meet the access time requirements of the external memory devices + + [..] All external memories share the addresses, data and control signals with the controller. + Each external device is accessed by means of a unique Chip Select. The FMC performs + only one access at a time to an external device. + The main features of the FMC controller are the following: + (+) Interface with static-memory mapped devices including: + (++) Static random access memory (SRAM) + (++) Read-only memory (ROM) + (++) NOR Flash memory/OneNAND Flash memory + (++) PSRAM (4 memory banks) + (++) 16-bit PC Card compatible devices + (++) Two banks of NAND Flash memory with ECC hardware to check up to 8 Kbytes of + data + (+) Interface with synchronous DRAM (SDRAM) memories + (+) Independent Chip Select control for each memory bank + (+) Independent configuration for each memory bank + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 FMC_LL FMC Low Layer + * @brief FMC driver modules + * @{ + */ + +#if defined (HAL_SRAM_MODULE_ENABLED) || defined(HAL_NOR_MODULE_ENABLED) || defined(HAL_NAND_MODULE_ENABLED) || defined(HAL_PCCARD_MODULE_ENABLED) || defined(HAL_SDRAM_MODULE_ENABLED) + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F446xx) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup FMC_LL_Private_Functions + * @{ + */ + +/** @addtogroup FMC_LL_NORSRAM + * @brief NORSRAM Controller functions + * + @verbatim + ============================================================================== + ##### How to use NORSRAM device driver ##### + ============================================================================== + + [..] + This driver contains a set of APIs to interface with the FMC NORSRAM banks in order + to run the NORSRAM external devices. + + (+) FMC NORSRAM bank reset using the function FMC_NORSRAM_DeInit() + (+) FMC NORSRAM bank control configuration using the function FMC_NORSRAM_Init() + (+) FMC NORSRAM bank timing configuration using the function FMC_NORSRAM_Timing_Init() + (+) FMC NORSRAM bank extended timing configuration using the function + FMC_NORSRAM_Extended_Timing_Init() + (+) FMC NORSRAM bank enable/disable write operation using the functions + FMC_NORSRAM_WriteOperation_Enable()/FMC_NORSRAM_WriteOperation_Disable() + + +@endverbatim + * @{ + */ + +/** @addtogroup FMC_LL_NORSRAM_Private_Functions_Group1 + * @brief Initialization and Configuration functions + * + @verbatim + ============================================================================== + ##### Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the FMC NORSRAM interface + (+) De-initialize the FMC NORSRAM interface + (+) Configure the FMC clock and associated GPIOs + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the FMC_NORSRAM device according to the specified + * control parameters in the FMC_NORSRAM_InitTypeDef + * @param Device: Pointer to NORSRAM device instance + * @param Init: Pointer to NORSRAM Initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_InitTypeDef* Init) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_NORSRAM_BANK(Init->NSBank)); + assert_param(IS_FMC_MUX(Init->DataAddressMux)); + assert_param(IS_FMC_MEMORY(Init->MemoryType)); + assert_param(IS_FMC_NORSRAM_MEMORY_WIDTH(Init->MemoryDataWidth)); + assert_param(IS_FMC_BURSTMODE(Init->BurstAccessMode)); + assert_param(IS_FMC_WAIT_POLARITY(Init->WaitSignalPolarity)); +#if !defined (STM32F446xx) + assert_param(IS_FMC_WRAP_MODE(Init->WrapMode)); +#endif /* !defined (STM32F446xx) */ + assert_param(IS_FMC_WAIT_SIGNAL_ACTIVE(Init->WaitSignalActive)); + assert_param(IS_FMC_WRITE_OPERATION(Init->WriteOperation)); + assert_param(IS_FMC_WAITE_SIGNAL(Init->WaitSignal)); + assert_param(IS_FMC_EXTENDED_MODE(Init->ExtendedMode)); + assert_param(IS_FMC_ASYNWAIT(Init->AsynchronousWait)); + assert_param(IS_FMC_WRITE_BURST(Init->WriteBurst)); + assert_param(IS_FMC_CONTINOUS_CLOCK(Init->ContinuousClock)); +#if defined (STM32F446xx) + assert_param(IS_FMC_WRITE_FIFO(Init->WriteFifo)); + assert_param(IS_FMC_PAGESIZE(Init->PageSize)); +#endif /* defined (STM32F446xx) */ + + /* Get the BTCR register value */ + tmpr = Device->BTCR[Init->NSBank]; + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + /* Clear MBKEN, MUXEN, MTYP, MWID, FACCEN, BURSTEN, WAITPOL, WRAPMOD, WAITCFG, WREN, + WAITEN, EXTMOD, ASYNCWAIT, CBURSTRW and CCLKEN bits */ + tmpr &= ((uint32_t)~(FMC_BCR1_MBKEN | FMC_BCR1_MUXEN | FMC_BCR1_MTYP | \ + FMC_BCR1_MWID | FMC_BCR1_FACCEN | FMC_BCR1_BURSTEN | \ + FMC_BCR1_WAITPOL | FMC_BCR1_WRAPMOD | FMC_BCR1_WAITCFG | \ + FMC_BCR1_WREN | FMC_BCR1_WAITEN | FMC_BCR1_EXTMOD | \ + FMC_BCR1_ASYNCWAIT | FMC_BCR1_CBURSTRW | FMC_BCR1_CCLKEN)); + + /* Set NORSRAM device control parameters */ + tmpr |= (uint32_t)(Init->DataAddressMux |\ + Init->MemoryType |\ + Init->MemoryDataWidth |\ + Init->BurstAccessMode |\ + Init->WaitSignalPolarity |\ + Init->WrapMode |\ + Init->WaitSignalActive |\ + Init->WriteOperation |\ + Init->WaitSignal |\ + Init->ExtendedMode |\ + Init->AsynchronousWait |\ + Init->WriteBurst |\ + Init->ContinuousClock); +#else /* defined(STM32F446xx) */ + /* Clear MBKEN, MUXEN, MTYP, MWID, FACCEN, BURSTEN, WAITPOL, CPSIZE, WAITCFG, WREN, + WAITEN, EXTMOD, ASYNCWAIT, CBURSTRW, CCLKEN and WFDIS bits */ + tmpr &= ((uint32_t)~(FMC_BCR1_MBKEN | FMC_BCR1_MUXEN | FMC_BCR1_MTYP | \ + FMC_BCR1_MWID | FMC_BCR1_FACCEN | FMC_BCR1_BURSTEN | \ + FMC_BCR1_WAITPOL | FMC_BCR1_WAITCFG | FMC_BCR1_CPSIZE | \ + FMC_BCR1_WREN | FMC_BCR1_WAITEN | FMC_BCR1_EXTMOD | \ + FMC_BCR1_ASYNCWAIT | FMC_BCR1_CBURSTRW | FMC_BCR1_CCLKEN | \ + FMC_BCR1_WFDIS)); + + /* Set NORSRAM device control parameters */ + tmpr |= (uint32_t)(Init->DataAddressMux |\ + Init->MemoryType |\ + Init->MemoryDataWidth |\ + Init->BurstAccessMode |\ + Init->WaitSignalPolarity |\ + Init->WaitSignalActive |\ + Init->WriteOperation |\ + Init->WaitSignal |\ + Init->ExtendedMode |\ + Init->AsynchronousWait |\ + Init->WriteBurst |\ + Init->ContinuousClock |\ + Init->PageSize |\ + Init->WriteFifo); +#endif /* defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) */ + + if(Init->MemoryType == FMC_MEMORY_TYPE_NOR) + { + tmpr |= (uint32_t)FMC_NORSRAM_FLASH_ACCESS_ENABLE; + } + + Device->BTCR[Init->NSBank] = tmpr; + + /* Configure synchronous mode when Continuous clock is enabled for bank2..4 */ + if((Init->ContinuousClock == FMC_CONTINUOUS_CLOCK_SYNC_ASYNC) && (Init->NSBank != FMC_NORSRAM_BANK1)) + { + Init->BurstAccessMode = FMC_BURST_ACCESS_MODE_ENABLE; + Device->BTCR[FMC_NORSRAM_BANK1] |= (uint32_t)(Init->BurstAccessMode |\ + Init->ContinuousClock); + } + +#if defined(STM32F446xx) + if(Init->NSBank != FMC_NORSRAM_BANK1) + { + Device->BTCR[FMC_NORSRAM_BANK1] |= (uint32_t)(Init->WriteFifo); + } +#endif /* defined(STM32F446xx) */ + + return HAL_OK; +} + +/** + * @brief DeInitialize the FMC_NORSRAM peripheral + * @param Device: Pointer to NORSRAM device instance + * @param ExDevice: Pointer to NORSRAM extended mode device instance + * @param Bank: NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(ExDevice)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Disable the FMC_NORSRAM device */ + __FMC_NORSRAM_DISABLE(Device, Bank); + + /* De-initialize the FMC_NORSRAM device */ + /* FMC_NORSRAM_BANK1 */ + if(Bank == FMC_NORSRAM_BANK1) + { + Device->BTCR[Bank] = 0x000030DB; + } + /* FMC_NORSRAM_BANK2, FMC_NORSRAM_BANK3 or FMC_NORSRAM_BANK4 */ + else + { + Device->BTCR[Bank] = 0x000030D2; + } + + Device->BTCR[Bank + 1] = 0x0FFFFFFF; + ExDevice->BWTR[Bank] = 0x0FFFFFFF; + + return HAL_OK; +} + +/** + * @brief Initialize the FMC_NORSRAM Timing according to the specified + * parameters in the FMC_NORSRAM_TimingTypeDef + * @param Device: Pointer to NORSRAM device instance + * @param Timing: Pointer to NORSRAM Timing structure + * @param Bank: NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime)); + assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime)); + assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime)); + assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration)); + assert_param(IS_FMC_CLK_DIV(Timing->CLKDivision)); + assert_param(IS_FMC_DATA_LATENCY(Timing->DataLatency)); + assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Get the BTCR register value */ + tmpr = Device->BTCR[Bank + 1]; + + /* Clear ADDSET, ADDHLD, DATAST, BUSTURN, CLKDIV, DATLAT and ACCMOD bits */ + tmpr &= ((uint32_t)~(FMC_BTR1_ADDSET | FMC_BTR1_ADDHLD | FMC_BTR1_DATAST | \ + FMC_BTR1_BUSTURN | FMC_BTR1_CLKDIV | FMC_BTR1_DATLAT | \ + FMC_BTR1_ACCMOD)); + + /* Set FMC_NORSRAM device timing parameters */ + tmpr |= (uint32_t)(Timing->AddressSetupTime |\ + ((Timing->AddressHoldTime) << 4) |\ + ((Timing->DataSetupTime) << 8) |\ + ((Timing->BusTurnAroundDuration) << 16) |\ + (((Timing->CLKDivision)-1) << 20) |\ + (((Timing->DataLatency)-2) << 24) |\ + (Timing->AccessMode)); + + Device->BTCR[Bank + 1] = tmpr; + + /* Configure Clock division value (in NORSRAM bank 1) when continuous clock is enabled */ + if(HAL_IS_BIT_SET(Device->BTCR[FMC_NORSRAM_BANK1], FMC_BCR1_CCLKEN)) + { + tmpr = (uint32_t)(Device->BTCR[FMC_NORSRAM_BANK1 + 1] & ~(((uint32_t)0x0F) << 20)); + tmpr |= (uint32_t)(((Timing->CLKDivision)-1) << 20); + Device->BTCR[FMC_NORSRAM_BANK1 + 1] = tmpr; + } + + return HAL_OK; +} + +/** + * @brief Initialize the FMC_NORSRAM Extended mode Timing according to the specified + * parameters in the FMC_NORSRAM_TimingTypeDef + * @param Device: Pointer to NORSRAM device instance + * @param Timing: Pointer to NORSRAM Timing structure + * @param Bank: NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef *Device, FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, uint32_t ExtendedMode) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_EXTENDED_MODE(ExtendedMode)); + + /* Set NORSRAM device timing register for write configuration, if extended mode is used */ + if(ExtendedMode == FMC_EXTENDED_MODE_ENABLE) + { + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(Device)); + assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime)); + assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime)); + assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime)); + assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration)); +#if !defined(STM32F446xx) + assert_param(IS_FMC_CLK_DIV(Timing->CLKDivision)); + assert_param(IS_FMC_DATA_LATENCY(Timing->DataLatency)); +#endif /* !defined(STM32F446xx) */ + assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Get the BWTR register value */ + tmpr = Device->BWTR[Bank]; + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) + /* Clear ADDSET, ADDHLD, DATAST, BUSTURN, CLKDIV, DATLAT and ACCMOD bits */ + tmpr &= ((uint32_t)~(FMC_BWTR1_ADDSET | FMC_BWTR1_ADDHLD | FMC_BWTR1_DATAST | \ + FMC_BWTR1_BUSTURN | FMC_BWTR1_CLKDIV | FMC_BWTR1_DATLAT | \ + FMC_BWTR1_ACCMOD)); + + tmpr |= (uint32_t)(Timing->AddressSetupTime |\ + ((Timing->AddressHoldTime) << 4) |\ + ((Timing->DataSetupTime) << 8) |\ + ((Timing->BusTurnAroundDuration) << 16) |\ + (((Timing->CLKDivision)-1) << 20) |\ + (((Timing->DataLatency)-2) << 24) |\ + (Timing->AccessMode)); +#else /* defined(STM32F446xx) */ + /* Clear ADDSET, ADDHLD, DATAST, BUSTURN and ACCMOD bits */ + tmpr &= ((uint32_t)~(FMC_BWTR1_ADDSET | FMC_BWTR1_ADDHLD | FMC_BWTR1_DATAST | \ + FMC_BWTR1_BUSTURN | FMC_BWTR1_ACCMOD)); + + tmpr |= (uint32_t)(Timing->AddressSetupTime |\ + ((Timing->AddressHoldTime) << 4) |\ + ((Timing->DataSetupTime) << 8) |\ + ((Timing->BusTurnAroundDuration) << 16) |\ + (Timing->AccessMode)); +#endif /* defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) */ + + Device->BWTR[Bank] = tmpr; + } + else + { + Device->BWTR[Bank] = 0x0FFFFFFF; + } + + return HAL_OK; +} +/** + * @} + */ + +/** @addtogroup FMC_LL_NORSRAM_Private_Functions_Group2 + * @brief management functions + * +@verbatim + ============================================================================== + ##### FMC_NORSRAM Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the FMC NORSRAM interface. + +@endverbatim + * @{ + */ +/** + * @brief Enables dynamically FMC_NORSRAM write operation. + * @param Device: Pointer to NORSRAM device instance + * @param Bank: NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Enable write operation */ + Device->BTCR[Bank] |= FMC_WRITE_OPERATION_ENABLE; + + return HAL_OK; +} + +/** + * @brief Disables dynamically FMC_NORSRAM write operation. + * @param Device: Pointer to NORSRAM device instance + * @param Bank: NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Disable write operation */ + Device->BTCR[Bank] &= ~FMC_WRITE_OPERATION_ENABLE; + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup FMC_LL_NAND + * @brief NAND Controller functions + * + @verbatim + ============================================================================== + ##### How to use NAND device driver ##### + ============================================================================== + [..] + This driver contains a set of APIs to interface with the FMC NAND banks in order + to run the NAND external devices. + + (+) FMC NAND bank reset using the function FMC_NAND_DeInit() + (+) FMC NAND bank control configuration using the function FMC_NAND_Init() + (+) FMC NAND bank common space timing configuration using the function + FMC_NAND_CommonSpace_Timing_Init() + (+) FMC NAND bank attribute space timing configuration using the function + FMC_NAND_AttributeSpace_Timing_Init() + (+) FMC NAND bank enable/disable ECC correction feature using the functions + FMC_NAND_ECC_Enable()/FMC_NAND_ECC_Disable() + (+) FMC NAND bank get ECC correction code using the function FMC_NAND_GetECC() + +@endverbatim + * @{ + */ + +#if defined(STM32F446xx) +/** @defgroup HAL_FMC_NAND_Group1 Initialization/de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the FMC NAND interface + (+) De-initialize the FMC NAND interface + (+) Configure the FMC clock and associated GPIOs + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the FMC_NAND device according to the specified + * control parameters in the FMC_NAND_HandleTypeDef + * @param Device: Pointer to NAND device instance + * @param Init: Pointer to NAND Initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_Init(FMC_NAND_TypeDef *Device, FMC_NAND_InitTypeDef *Init) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Init->NandBank)); + assert_param(IS_FMC_WAIT_FEATURE(Init->Waitfeature)); + assert_param(IS_FMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth)); + assert_param(IS_FMC_ECC_STATE(Init->EccComputation)); + assert_param(IS_FMC_ECCPAGE_SIZE(Init->ECCPageSize)); + assert_param(IS_FMC_TCLR_TIME(Init->TCLRSetupTime)); + assert_param(IS_FMC_TAR_TIME(Init->TARSetupTime)); + + /* Get the NAND bank register value */ + tmpr = Device->PCR; + + /* Clear PWAITEN, PBKEN, PTYP, PWID, ECCEN, TCLR, TAR and ECCPS bits */ + tmpr &= ((uint32_t)~(FMC_PCR_PWAITEN | FMC_PCR_PBKEN | FMC_PCR_PTYP | \ + FMC_PCR_PWID | FMC_PCR_ECCEN | FMC_PCR_TCLR | \ + FMC_PCR_TAR | FMC_PCR_ECCPS)); + + /* Set NAND device control parameters */ + tmpr |= (uint32_t)(Init->Waitfeature |\ + FMC_PCR_MEMORY_TYPE_NAND |\ + Init->MemoryDataWidth |\ + Init->EccComputation |\ + Init->ECCPageSize |\ + ((Init->TCLRSetupTime) << 9) |\ + ((Init->TARSetupTime) << 13)); + + /* NAND bank registers configuration */ + Device->PCR = tmpr; + + return HAL_OK; +} + +/** + * @brief Initializes the FMC_NAND Common space Timing according to the specified + * parameters in the FMC_NAND_PCC_TimingTypeDef + * @param Device: Pointer to NAND device instance + * @param Timing: Pointer to NAND timing structure + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Get the NAND bank 2 register value */ + tmpr = Device->PMEM; + + + /* Clear MEMSETx, MEMWAITx, MEMHOLDx and MEMHIZx bits */ + tmpr &= ((uint32_t)~(FMC_PMEM_MEMSET2 | FMC_PMEM_MEMWAIT2 | FMC_PMEM_MEMHOLD2 | \ + FMC_PMEM_MEMHIZ2)); + + /* Set FMC_NAND device timing parameters */ + tmpr |= (uint32_t)(Timing->SetupTime |\ + ((Timing->WaitSetupTime) << 8) |\ + ((Timing->HoldSetupTime) << 16) |\ + ((Timing->HiZSetupTime) << 24) + ); + + /* NAND bank registers configuration */ + Device->PMEM = tmpr; + + return HAL_OK; +} + +/** + * @brief Initializes the FMC_NAND Attribute space Timing according to the specified + * parameters in the FMC_NAND_PCC_TimingTypeDef + * @param Device: Pointer to NAND device instance + * @param Timing: Pointer to NAND timing structure + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Get the NAND bank register value */ + tmpr = Device->PATT; + + /* Clear ATTSETx, ATTWAITx, ATTHOLDx and ATTHIZx bits */ + tmpr &= ((uint32_t)~(FMC_PATT_ATTSET2 | FMC_PATT_ATTWAIT2 | FMC_PATT_ATTHOLD2 | \ + FMC_PATT_ATTHIZ2)); + + /* Set FMC_NAND device timing parameters */ + tmpr |= (uint32_t)(Timing->SetupTime |\ + ((Timing->WaitSetupTime) << 8) |\ + ((Timing->HoldSetupTime) << 16) |\ + ((Timing->HiZSetupTime) << 24)); + + /* NAND bank registers configuration */ + Device->PATT = tmpr; + + return HAL_OK; +} + + +/** + * @brief DeInitializes the FMC_NAND device + * @param Device: Pointer to NAND device instance + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_DeInit(FMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Disable the NAND Bank */ + __FMC_NAND_DISABLE(Device, Bank); + + /* De-initialize the NAND Bank */ + /* Set the FMC_NAND_BANK registers to their reset values */ + Device->PCR = 0x00000018; + Device->SR = 0x00000040; + Device->PMEM = 0xFCFCFCFC; + Device->PATT = 0xFCFCFCFC; + + return HAL_OK; +} + +/** + * @} + */ + + +/** @defgroup HAL_FMC_NAND_Group2 Control functions + * @brief management functions + * +@verbatim + ============================================================================== + ##### FMC_NAND Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the FMC NAND interface. + +@endverbatim + * @{ + */ + + +/** + * @brief Enables dynamically FMC_NAND ECC feature. + * @param Device: Pointer to NAND device instance + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_ECC_Enable(FMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Enable ECC feature */ + Device->PCR |= FMC_PCR_ECCEN; + + return HAL_OK; +} + + +/** + * @brief Disables dynamically FMC_NAND ECC feature. + * @param Device: Pointer to NAND device instance + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_ECC_Disable(FMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Disable ECC feature */ + Device->PCR &= ~FMC_PCR_ECCEN; + + return HAL_OK; +} + +/** + * @brief Disables dynamically FMC_NAND ECC feature. + * @param Device: Pointer to NAND device instance + * @param ECCval: Pointer to ECC value + * @param Bank: NAND bank number + * @param Timeout: Timeout wait value + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_GetECC(FMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until FIFO is empty */ + while(__FMC_NAND_GET_FLAG(Device, Bank, FMC_FLAG_FEMPT) == RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + return HAL_TIMEOUT; + } + } + } + + /* Get the ECCR register value */ + *ECCval = (uint32_t)Device->ECCR; + + return HAL_OK; +} + +/** + * @} + */ + +#else /* defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) */ +/** @defgroup HAL_FMC_NAND_Group1 Initialization/de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the FMC NAND interface + (+) De-initialize the FMC NAND interface + (+) Configure the FMC clock and associated GPIOs + +@endverbatim + * @{ + */ +/** + * @brief Initializes the FMC_NAND device according to the specified + * control parameters in the FMC_NAND_HandleTypeDef + * @param Device: Pointer to NAND device instance + * @param Init: Pointer to NAND Initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_Init(FMC_NAND_TypeDef *Device, FMC_NAND_InitTypeDef *Init) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Init->NandBank)); + assert_param(IS_FMC_WAIT_FEATURE(Init->Waitfeature)); + assert_param(IS_FMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth)); + assert_param(IS_FMC_ECC_STATE(Init->EccComputation)); + assert_param(IS_FMC_ECCPAGE_SIZE(Init->ECCPageSize)); + assert_param(IS_FMC_TCLR_TIME(Init->TCLRSetupTime)); + assert_param(IS_FMC_TAR_TIME(Init->TARSetupTime)); + + if(Init->NandBank == FMC_NAND_BANK2) + { + /* Get the NAND bank 2 register value */ + tmpr = Device->PCR2; + } + else + { + /* Get the NAND bank 3 register value */ + tmpr = Device->PCR3; + } + + /* Clear PWAITEN, PBKEN, PTYP, PWID, ECCEN, TCLR, TAR and ECCPS bits */ + tmpr &= ((uint32_t)~(FMC_PCR2_PWAITEN | FMC_PCR2_PBKEN | FMC_PCR2_PTYP | \ + FMC_PCR2_PWID | FMC_PCR2_ECCEN | FMC_PCR2_TCLR | \ + FMC_PCR2_TAR | FMC_PCR2_ECCPS)); + + /* Set NAND device control parameters */ + tmpr |= (uint32_t)(Init->Waitfeature |\ + FMC_PCR_MEMORY_TYPE_NAND |\ + Init->MemoryDataWidth |\ + Init->EccComputation |\ + Init->ECCPageSize |\ + ((Init->TCLRSetupTime) << 9) |\ + ((Init->TARSetupTime) << 13)); + + if(Init->NandBank == FMC_NAND_BANK2) + { + /* NAND bank 2 registers configuration */ + Device->PCR2 = tmpr; + } + else + { + /* NAND bank 3 registers configuration */ + Device->PCR3 = tmpr; + } + + return HAL_OK; + +} + +/** + * @brief Initializes the FMC_NAND Common space Timing according to the specified + * parameters in the FMC_NAND_PCC_TimingTypeDef + * @param Device: Pointer to NAND device instance + * @param Timing: Pointer to NAND timing structure + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + if(Bank == FMC_NAND_BANK2) + { + /* Get the NAND bank 2 register value */ + tmpr = Device->PMEM2; + } + else + { + /* Get the NAND bank 3 register value */ + tmpr = Device->PMEM3; + } + + /* Clear MEMSETx, MEMWAITx, MEMHOLDx and MEMHIZx bits */ + tmpr &= ((uint32_t)~(FMC_PMEM2_MEMSET2 | FMC_PMEM2_MEMWAIT2 | FMC_PMEM2_MEMHOLD2 | \ + FMC_PMEM2_MEMHIZ2)); + + /* Set FMC_NAND device timing parameters */ + tmpr |= (uint32_t)(Timing->SetupTime |\ + ((Timing->WaitSetupTime) << 8) |\ + ((Timing->HoldSetupTime) << 16) |\ + ((Timing->HiZSetupTime) << 24) + ); + + if(Bank == FMC_NAND_BANK2) + { + /* NAND bank 2 registers configuration */ + Device->PMEM2 = tmpr; + } + else + { + /* NAND bank 3 registers configuration */ + Device->PMEM3 = tmpr; + } + + return HAL_OK; +} + +/** + * @brief Initializes the FMC_NAND Attribute space Timing according to the specified + * parameters in the FMC_NAND_PCC_TimingTypeDef + * @param Device: Pointer to NAND device instance + * @param Timing: Pointer to NAND timing structure + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + if(Bank == FMC_NAND_BANK2) + { + /* Get the NAND bank 2 register value */ + tmpr = Device->PATT2; + } + else + { + /* Get the NAND bank 3 register value */ + tmpr = Device->PATT3; + } + + /* Clear ATTSETx, ATTWAITx, ATTHOLDx and ATTHIZx bits */ + tmpr &= ((uint32_t)~(FMC_PATT2_ATTSET2 | FMC_PATT2_ATTWAIT2 | FMC_PATT2_ATTHOLD2 | \ + FMC_PATT2_ATTHIZ2)); + + /* Set FMC_NAND device timing parameters */ + tmpr |= (uint32_t)(Timing->SetupTime |\ + ((Timing->WaitSetupTime) << 8) |\ + ((Timing->HoldSetupTime) << 16) |\ + ((Timing->HiZSetupTime) << 24)); + + if(Bank == FMC_NAND_BANK2) + { + /* NAND bank 2 registers configuration */ + Device->PATT2 = tmpr; + } + else + { + /* NAND bank 3 registers configuration */ + Device->PATT3 = tmpr; + } + + return HAL_OK; +} + +/** + * @brief DeInitializes the FMC_NAND device + * @param Device: Pointer to NAND device instance + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_DeInit(FMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Disable the NAND Bank */ + __FMC_NAND_DISABLE(Device, Bank); + + /* De-initialize the NAND Bank */ + if(Bank == FMC_NAND_BANK2) + { + /* Set the FMC_NAND_BANK2 registers to their reset values */ + Device->PCR2 = 0x00000018; + Device->SR2 = 0x00000040; + Device->PMEM2 = 0xFCFCFCFC; + Device->PATT2 = 0xFCFCFCFC; + } + /* FMC_Bank3_NAND */ + else + { + /* Set the FMC_NAND_BANK3 registers to their reset values */ + Device->PCR3 = 0x00000018; + Device->SR3 = 0x00000040; + Device->PMEM3 = 0xFCFCFCFC; + Device->PATT3 = 0xFCFCFCFC; + } + + return HAL_OK; +} + +/** + * @} + */ + +/** @addtogroup FMC_LL_NAND_Private_Functions_Group2 + * @brief management functions + * +@verbatim + ============================================================================== + ##### FMC_NAND Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the FMC NAND interface. + +@endverbatim + * @{ + */ +/** + * @brief Enables dynamically FMC_NAND ECC feature. + * @param Device: Pointer to NAND device instance + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_ECC_Enable(FMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Enable ECC feature */ + if(Bank == FMC_NAND_BANK2) + { + Device->PCR2 |= FMC_PCR2_ECCEN; + } + else + { + Device->PCR3 |= FMC_PCR3_ECCEN; + } + + return HAL_OK; +} + +/** + * @brief Disables dynamically FMC_NAND ECC feature. + * @param Device: Pointer to NAND device instance + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_ECC_Disable(FMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Disable ECC feature */ + if(Bank == FMC_NAND_BANK2) + { + Device->PCR2 &= ~FMC_PCR2_ECCEN; + } + else + { + Device->PCR3 &= ~FMC_PCR3_ECCEN; + } + + return HAL_OK; +} + +/** + * @brief Disables dynamically FMC_NAND ECC feature. + * @param Device: Pointer to NAND device instance + * @param ECCval: Pointer to ECC value + * @param Bank: NAND bank number + * @param Timeout: Timeout wait value + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_GetECC(FMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until FIFO is empty */ + while(__FMC_NAND_GET_FLAG(Device, Bank, FMC_FLAG_FEMPT) == RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + return HAL_TIMEOUT; + } + } + } + + if(Bank == FMC_NAND_BANK2) + { + /* Get the ECCR2 register value */ + *ECCval = (uint32_t)Device->ECCR2; + } + else + { + /* Get the ECCR3 register value */ + *ECCval = (uint32_t)Device->ECCR3; + } + + return HAL_OK; +} + +/** + * @} + */ + +#endif /* defined(STM32F446xx) */ +/** + * @} + */ + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) +/** @addtogroup FMC_LL_PCCARD + * @brief PCCARD Controller functions + * + @verbatim + ============================================================================== + ##### How to use PCCARD device driver ##### + ============================================================================== + [..] + This driver contains a set of APIs to interface with the FMC PCCARD bank in order + to run the PCCARD/compact flash external devices. + + (+) FMC PCCARD bank reset using the function FMC_PCCARD_DeInit() + (+) FMC PCCARD bank control configuration using the function FMC_PCCARD_Init() + (+) FMC PCCARD bank common space timing configuration using the function + FMC_PCCARD_CommonSpace_Timing_Init() + (+) FMC PCCARD bank attribute space timing configuration using the function + FMC_PCCARD_AttributeSpace_Timing_Init() + (+) FMC PCCARD bank IO space timing configuration using the function + FMC_PCCARD_IOSpace_Timing_Init() +@endverbatim + * @{ + */ + +/** @addtogroup FMC_LL_PCCARD_Private_Functions_Group1 + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the FMC PCCARD interface + (+) De-initialize the FMC PCCARD interface + (+) Configure the FMC clock and associated GPIOs + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the FMC_PCCARD device according to the specified + * control parameters in the FMC_PCCARD_HandleTypeDef + * @param Device: Pointer to PCCARD device instance + * @param Init: Pointer to PCCARD Initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef FMC_PCCARD_Init(FMC_PCCARD_TypeDef *Device, FMC_PCCARD_InitTypeDef *Init) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_PCCARD_DEVICE(Device)); + assert_param(IS_FMC_WAIT_FEATURE(Init->Waitfeature)); + assert_param(IS_FMC_TCLR_TIME(Init->TCLRSetupTime)); + assert_param(IS_FMC_TAR_TIME(Init->TARSetupTime)); + + /* Get PCCARD control register value */ + tmpr = Device->PCR4; + + /* Clear TAR, TCLR, PWAITEN and PWID bits */ + tmpr &= ((uint32_t)~(FMC_PCR4_TAR | FMC_PCR4_TCLR | FMC_PCR4_PWAITEN | \ + FMC_PCR4_PWID)); + + /* Set FMC_PCCARD device control parameters */ + tmpr |= (uint32_t)(Init->Waitfeature |\ + FMC_NAND_PCC_MEM_BUS_WIDTH_16 |\ + (Init->TCLRSetupTime << 9) |\ + (Init->TARSetupTime << 13)); + + Device->PCR4 = tmpr; + + return HAL_OK; +} + +/** + * @brief Initializes the FMC_PCCARD Common space Timing according to the specified + * parameters in the FMC_NAND_PCC_TimingTypeDef + * @param Device: Pointer to PCCARD device instance + * @param Timing: Pointer to PCCARD timing structure + * @retval HAL status + */ +HAL_StatusTypeDef FMC_PCCARD_CommonSpace_Timing_Init(FMC_PCCARD_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_PCCARD_DEVICE(Device)); + assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime)); + + /* Get PCCARD common space timing register value */ + tmpr = Device->PMEM4; + + /* Clear MEMSETx, MEMWAITx, MEMHOLDx and MEMHIZx bits */ + tmpr &= ((uint32_t)~(FMC_PMEM4_MEMSET4 | FMC_PMEM4_MEMWAIT4 | FMC_PMEM4_MEMHOLD4 | \ + FMC_PMEM4_MEMHIZ4)); + /* Set PCCARD timing parameters */ + tmpr |= (uint32_t)(Timing->SetupTime |\ + ((Timing->WaitSetupTime) << 8) |\ + ((Timing->HoldSetupTime) << 16) |\ + ((Timing->HiZSetupTime) << 24)); + + Device->PMEM4 = tmpr; + + return HAL_OK; +} + +/** + * @brief Initializes the FMC_PCCARD Attribute space Timing according to the specified + * parameters in the FMC_NAND_PCC_TimingTypeDef + * @param Device: Pointer to PCCARD device instance + * @param Timing: Pointer to PCCARD timing structure + * @retval HAL status + */ +HAL_StatusTypeDef FMC_PCCARD_AttributeSpace_Timing_Init(FMC_PCCARD_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_PCCARD_DEVICE(Device)); + assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime)); + + /* Get PCCARD timing parameters */ + tmpr = Device->PATT4; + + /* Clear ATTSETx, ATTWAITx, ATTHOLDx and ATTHIZx bits */ + tmpr &= ((uint32_t)~(FMC_PATT4_ATTSET4 | FMC_PATT4_ATTWAIT4 | FMC_PATT4_ATTHOLD4 | \ + FMC_PATT4_ATTHIZ4)); + + /* Set PCCARD timing parameters */ + tmpr |= (uint32_t)(Timing->SetupTime |\ + ((Timing->WaitSetupTime) << 8) |\ + ((Timing->HoldSetupTime) << 16) |\ + ((Timing->HiZSetupTime) << 24)); + Device->PATT4 = tmpr; + + return HAL_OK; +} + +/** + * @brief Initializes the FMC_PCCARD IO space Timing according to the specified + * parameters in the FMC_NAND_PCC_TimingTypeDef + * @param Device: Pointer to PCCARD device instance + * @param Timing: Pointer to PCCARD timing structure + * @retval HAL status + */ +HAL_StatusTypeDef FMC_PCCARD_IOSpace_Timing_Init(FMC_PCCARD_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_PCCARD_DEVICE(Device)); + assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime)); + + /* Get FMC_PCCARD device timing parameters */ + tmpr = Device->PIO4; + + /* Clear IOSET4, IOWAIT4, IOHOLD4 and IOHIZ4 bits */ + tmpr &= ((uint32_t)~(FMC_PIO4_IOSET4 | FMC_PIO4_IOWAIT4 | FMC_PIO4_IOHOLD4 | \ + FMC_PIO4_IOHIZ4)); + + /* Set FMC_PCCARD device timing parameters */ + tmpr |= (uint32_t)(Timing->SetupTime |\ + ((Timing->WaitSetupTime) << 8) |\ + ((Timing->HoldSetupTime) << 16) |\ + ((Timing->HiZSetupTime) << 24)); + + Device->PIO4 = tmpr; + + return HAL_OK; +} + +/** + * @brief DeInitializes the FMC_PCCARD device + * @param Device: Pointer to PCCARD device instance + * @retval HAL status + */ +HAL_StatusTypeDef FMC_PCCARD_DeInit(FMC_PCCARD_TypeDef *Device) +{ + /* Check the parameters */ + assert_param(IS_FMC_PCCARD_DEVICE(Device)); + + /* Disable the FMC_PCCARD device */ + __FMC_PCCARD_DISABLE(Device); + + /* De-initialize the FMC_PCCARD device */ + Device->PCR4 = 0x00000018; + Device->SR4 = 0x00000000; + Device->PMEM4 = 0xFCFCFCFC; + Device->PATT4 = 0xFCFCFCFC; + Device->PIO4 = 0xFCFCFCFC; + + return HAL_OK; +} + +/** + * @} + */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ + + +/** @addtogroup FMC_LL_SDRAM + * @brief SDRAM Controller functions + * + @verbatim + ============================================================================== + ##### How to use SDRAM device driver ##### + ============================================================================== + [..] + This driver contains a set of APIs to interface with the FMC SDRAM banks in order + to run the SDRAM external devices. + + (+) FMC SDRAM bank reset using the function FMC_SDRAM_DeInit() + (+) FMC SDRAM bank control configuration using the function FMC_SDRAM_Init() + (+) FMC SDRAM bank timing configuration using the function FMC_SDRAM_Timing_Init() + (+) FMC SDRAM bank enable/disable write operation using the functions + FMC_SDRAM_WriteOperation_Enable()/FMC_SDRAM_WriteOperation_Disable() + (+) FMC SDRAM bank send command using the function FMC_SDRAM_SendCommand() + +@endverbatim + * @{ + */ + +/** @addtogroup FMC_LL_SDRAM_Private_Functions_Group1 + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the FMC SDRAM interface + (+) De-initialize the FMC SDRAM interface + (+) Configure the FMC clock and associated GPIOs + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the FMC_SDRAM device according to the specified + * control parameters in the FMC_SDRAM_InitTypeDef + * @param Device: Pointer to SDRAM device instance + * @param Init: Pointer to SDRAM Initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef FMC_SDRAM_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_InitTypeDef *Init) +{ + uint32_t tmpr1 = 0; + uint32_t tmpr2 = 0; + + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Init->SDBank)); + assert_param(IS_FMC_COLUMNBITS_NUMBER(Init->ColumnBitsNumber)); + assert_param(IS_FMC_ROWBITS_NUMBER(Init->RowBitsNumber)); + assert_param(IS_FMC_SDMEMORY_WIDTH(Init->MemoryDataWidth)); + assert_param(IS_FMC_INTERNALBANK_NUMBER(Init->InternalBankNumber)); + assert_param(IS_FMC_CAS_LATENCY(Init->CASLatency)); + assert_param(IS_FMC_WRITE_PROTECTION(Init->WriteProtection)); + assert_param(IS_FMC_SDCLOCK_PERIOD(Init->SDClockPeriod)); + assert_param(IS_FMC_READ_BURST(Init->ReadBurst)); + assert_param(IS_FMC_READPIPE_DELAY(Init->ReadPipeDelay)); + + /* Set SDRAM bank configuration parameters */ + if (Init->SDBank != FMC_SDRAM_BANK2) + { + tmpr1 = Device->SDCR[FMC_SDRAM_BANK1]; + + /* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */ + tmpr1 &= ((uint32_t)~(FMC_SDCR1_NC | FMC_SDCR1_NR | FMC_SDCR1_MWID | \ + FMC_SDCR1_NB | FMC_SDCR1_CAS | FMC_SDCR1_WP | \ + FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE)); + + + tmpr1 |= (uint32_t)(Init->ColumnBitsNumber |\ + Init->RowBitsNumber |\ + Init->MemoryDataWidth |\ + Init->InternalBankNumber |\ + Init->CASLatency |\ + Init->WriteProtection |\ + Init->SDClockPeriod |\ + Init->ReadBurst |\ + Init->ReadPipeDelay + ); + Device->SDCR[FMC_SDRAM_BANK1] = tmpr1; + } + else /* FMC_Bank2_SDRAM */ + { + tmpr1 = Device->SDCR[FMC_SDRAM_BANK1]; + + /* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */ + tmpr1 &= ((uint32_t)~(FMC_SDCR1_NC | FMC_SDCR1_NR | FMC_SDCR1_MWID | \ + FMC_SDCR1_NB | FMC_SDCR1_CAS | FMC_SDCR1_WP | \ + FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE)); + + tmpr1 |= (uint32_t)(Init->SDClockPeriod |\ + Init->ReadBurst |\ + Init->ReadPipeDelay); + + tmpr2 = Device->SDCR[FMC_SDRAM_BANK2]; + + /* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */ + tmpr2 &= ((uint32_t)~(FMC_SDCR1_NC | FMC_SDCR1_NR | FMC_SDCR1_MWID | \ + FMC_SDCR1_NB | FMC_SDCR1_CAS | FMC_SDCR1_WP | \ + FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE)); + + tmpr2 |= (uint32_t)(Init->ColumnBitsNumber |\ + Init->RowBitsNumber |\ + Init->MemoryDataWidth |\ + Init->InternalBankNumber |\ + Init->CASLatency |\ + Init->WriteProtection); + + Device->SDCR[FMC_SDRAM_BANK1] = tmpr1; + Device->SDCR[FMC_SDRAM_BANK2] = tmpr2; + } + + return HAL_OK; +} + +/** + * @brief Initializes the FMC_SDRAM device timing according to the specified + * parameters in the FMC_SDRAM_TimingTypeDef + * @param Device: Pointer to SDRAM device instance + * @param Timing: Pointer to SDRAM Timing structure + * @param Bank: SDRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_SDRAM_Timing_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpr1 = 0; + uint32_t tmpr2 = 0; + + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_LOADTOACTIVE_DELAY(Timing->LoadToActiveDelay)); + assert_param(IS_FMC_EXITSELFREFRESH_DELAY(Timing->ExitSelfRefreshDelay)); + assert_param(IS_FMC_SELFREFRESH_TIME(Timing->SelfRefreshTime)); + assert_param(IS_FMC_ROWCYCLE_DELAY(Timing->RowCycleDelay)); + assert_param(IS_FMC_WRITE_RECOVERY_TIME(Timing->WriteRecoveryTime)); + assert_param(IS_FMC_RP_DELAY(Timing->RPDelay)); + assert_param(IS_FMC_RCD_DELAY(Timing->RCDDelay)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* Set SDRAM device timing parameters */ + if (Bank != FMC_SDRAM_BANK2) + { + tmpr1 = Device->SDTR[FMC_SDRAM_BANK1]; + + /* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */ + tmpr1 &= ((uint32_t)~(FMC_SDTR1_TMRD | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS | \ + FMC_SDTR1_TRC | FMC_SDTR1_TWR | FMC_SDTR1_TRP | \ + FMC_SDTR1_TRCD)); + + tmpr1 |= (uint32_t)(((Timing->LoadToActiveDelay)-1) |\ + (((Timing->ExitSelfRefreshDelay)-1) << 4) |\ + (((Timing->SelfRefreshTime)-1) << 8) |\ + (((Timing->RowCycleDelay)-1) << 12) |\ + (((Timing->WriteRecoveryTime)-1) <<16) |\ + (((Timing->RPDelay)-1) << 20) |\ + (((Timing->RCDDelay)-1) << 24)); + Device->SDTR[FMC_SDRAM_BANK1] = tmpr1; + } + else /* FMC_Bank2_SDRAM */ + { + tmpr1 = Device->SDTR[FMC_SDRAM_BANK2]; + + /* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */ + tmpr1 &= ((uint32_t)~(FMC_SDTR1_TMRD | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS | \ + FMC_SDTR1_TRC | FMC_SDTR1_TWR | FMC_SDTR1_TRP | \ + FMC_SDTR1_TRCD)); + + tmpr1 |= (uint32_t)(((Timing->LoadToActiveDelay)-1) |\ + (((Timing->ExitSelfRefreshDelay)-1) << 4) |\ + (((Timing->SelfRefreshTime)-1) << 8) |\ + (((Timing->WriteRecoveryTime)-1) <<16) |\ + (((Timing->RCDDelay)-1) << 24)); + + tmpr2 = Device->SDTR[FMC_SDRAM_BANK1]; + + /* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */ + tmpr2 &= ((uint32_t)~(FMC_SDTR1_TMRD | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS | \ + FMC_SDTR1_TRC | FMC_SDTR1_TWR | FMC_SDTR1_TRP | \ + FMC_SDTR1_TRCD)); + tmpr2 |= (uint32_t)((((Timing->RowCycleDelay)-1) << 12) |\ + (((Timing->RPDelay)-1) << 20)); + + Device->SDTR[FMC_SDRAM_BANK2] = tmpr1; + Device->SDTR[FMC_SDRAM_BANK1] = tmpr2; + } + + return HAL_OK; +} + +/** + * @brief DeInitializes the FMC_SDRAM peripheral + * @param Device: Pointer to SDRAM device instance + * @retval HAL status + */ +HAL_StatusTypeDef FMC_SDRAM_DeInit(FMC_SDRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* De-initialize the SDRAM device */ + Device->SDCR[Bank] = 0x000002D0; + Device->SDTR[Bank] = 0x0FFFFFFF; + Device->SDCMR = 0x00000000; + Device->SDRTR = 0x00000000; + Device->SDSR = 0x00000000; + + return HAL_OK; +} + +/** + * @} + */ + +/** @addtogroup FMC_LL_SDRAMPrivate_Functions_Group2 + * @brief management functions + * +@verbatim + ============================================================================== + ##### FMC_SDRAM Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the FMC SDRAM interface. + +@endverbatim + * @{ + */ +/** + * @brief Enables dynamically FMC_SDRAM write protection. + * @param Device: Pointer to SDRAM device instance + * @param Bank: SDRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_SDRAM_WriteProtection_Enable(FMC_SDRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* Enable write protection */ + Device->SDCR[Bank] |= FMC_SDRAM_WRITE_PROTECTION_ENABLE; + + return HAL_OK; +} + +/** + * @brief Disables dynamically FMC_SDRAM write protection. + * @param hsdram: FMC_SDRAM handle + * @retval HAL status + */ +HAL_StatusTypeDef FMC_SDRAM_WriteProtection_Disable(FMC_SDRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* Disable write protection */ + Device->SDCR[Bank] &= ~FMC_SDRAM_WRITE_PROTECTION_ENABLE; + + return HAL_OK; +} + +/** + * @brief Send Command to the FMC SDRAM bank + * @param Device: Pointer to SDRAM device instance + * @param Command: Pointer to SDRAM command structure + * @param Timing: Pointer to SDRAM Timing structure + * @param Timeout: Timeout wait value + * @retval HAL state + */ +HAL_StatusTypeDef FMC_SDRAM_SendCommand(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_CommandTypeDef *Command, uint32_t Timeout) +{ + __IO uint32_t tmpr = 0; + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_COMMAND_MODE(Command->CommandMode)); + assert_param(IS_FMC_COMMAND_TARGET(Command->CommandTarget)); + assert_param(IS_FMC_AUTOREFRESH_NUMBER(Command->AutoRefreshNumber)); + assert_param(IS_FMC_MODE_REGISTER(Command->ModeRegisterDefinition)); + + /* Set command register */ + tmpr = (uint32_t)((Command->CommandMode) |\ + (Command->CommandTarget) |\ + (((Command->AutoRefreshNumber)-1) << 5) |\ + ((Command->ModeRegisterDefinition) << 9) + ); + + Device->SDCMR = tmpr; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until command is send */ + while(HAL_IS_BIT_SET(Device->SDSR, FMC_SDSR_BUSY)) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + return HAL_TIMEOUT; + } + } + } + + return HAL_OK; +} + +/** + * @brief Program the SDRAM Memory Refresh rate. + * @param Device: Pointer to SDRAM device instance + * @param RefreshRate: The SDRAM refresh rate value. + * @retval HAL state + */ +HAL_StatusTypeDef FMC_SDRAM_ProgramRefreshRate(FMC_SDRAM_TypeDef *Device, uint32_t RefreshRate) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_REFRESH_RATE(RefreshRate)); + + /* Set the refresh rate in command register */ + Device->SDRTR |= (RefreshRate<<1); + + return HAL_OK; +} + +/** + * @brief Set the Number of consecutive SDRAM Memory auto Refresh commands. + * @param Device: Pointer to SDRAM device instance + * @param AutoRefreshNumber: Specifies the auto Refresh number. + * @retval None + */ +HAL_StatusTypeDef FMC_SDRAM_SetAutoRefreshNumber(FMC_SDRAM_TypeDef *Device, uint32_t AutoRefreshNumber) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_AUTOREFRESH_NUMBER(AutoRefreshNumber)); + + /* Set the Auto-refresh number in command register */ + Device->SDCMR |= (AutoRefreshNumber << 5); + + return HAL_OK; +} + +/** + * @brief Returns the indicated FMC SDRAM bank mode status. + * @param Device: Pointer to SDRAM device instance + * @param Bank: Defines the FMC SDRAM bank. This parameter can be + * FMC_Bank1_SDRAM or FMC_Bank2_SDRAM. + * @retval The FMC SDRAM bank mode status, could be on of the following values: + * FMC_SDRAM_NORMAL_MODE, FMC_SDRAM_SELF_REFRESH_MODE or + * FMC_SDRAM_POWER_DOWN_MODE. + */ +uint32_t FMC_SDRAM_GetModeStatus(FMC_SDRAM_TypeDef *Device, uint32_t Bank) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* Get the corresponding bank mode */ + if(Bank == FMC_SDRAM_BANK1) + { + tmpreg = (uint32_t)(Device->SDSR & FMC_SDSR_MODES1); + } + else + { + tmpreg = ((uint32_t)(Device->SDSR & FMC_SDSR_MODES2) >> 2); + } + + /* Return the mode status */ + return tmpreg; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx */ +#endif /* HAL_SRAM_MODULE_ENABLED || HAL_NOR_MODULE_ENABLED || HAL_NAND_MODULE_ENABLED || HAL_PCCARD_MODULE_ENABLED || HAL_SDRAM_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c new file mode 100644 index 0000000..005d5e1 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c @@ -0,0 +1,955 @@ +/** + ****************************************************************************** + * @file stm32f4xx_ll_fsmc.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief FSMC Low Layer HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the Flexible Static Memory Controller (FSMC) peripheral memories: + * + Initialization/de-initialization functions + * + Peripheral Control functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### FSMC peripheral features ##### + ============================================================================== + [..] The Flexible static memory controller (FSMC) includes two memory controllers: + (+) The NOR/PSRAM memory controller + (+) The NAND/PC Card memory controller + + [..] The FSMC functional block makes the interface with synchronous and asynchronous static + memories, SDRAM memories, and 16-bit PC memory cards. Its main purposes are: + (+) to translate AHB transactions into the appropriate external device protocol. + (+) to meet the access time requirements of the external memory devices. + + [..] All external memories share the addresses, data and control signals with the controller. + Each external device is accessed by means of a unique Chip Select. The FSMC performs + only one access at a time to an external device. + The main features of the FSMC controller are the following: + (+) Interface with static-memory mapped devices including: + (++) Static random access memory (SRAM). + (++) Read-only memory (ROM). + (++) NOR Flash memory/OneNAND Flash memory. + (++) PSRAM (4 memory banks). + (++) 16-bit PC Card compatible devices. + (++) Two banks of NAND Flash memory with ECC hardware to check up to 8 Kbytes of + data. + (+) Independent Chip Select control for each memory bank. + (+) Independent configuration for each memory bank. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 FSMC_LL FSMC Low Layer + * @brief FSMC driver modules + * @{ + */ + +#if defined (HAL_SRAM_MODULE_ENABLED) || defined(HAL_NOR_MODULE_ENABLED) || defined(HAL_NAND_MODULE_ENABLED) || defined(HAL_PCCARD_MODULE_ENABLED) +#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup FSMC_LL_Private_Functions + * @{ + */ + +/** @addtogroup FSMC_LL_NORSRAM + * @brief NORSRAM Controller functions + * + @verbatim + ============================================================================== + ##### How to use NORSRAM device driver ##### + ============================================================================== + + [..] + This driver contains a set of APIs to interface with the FSMC NORSRAM banks in order + to run the NORSRAM external devices. + + (+) FSMC NORSRAM bank reset using the function FSMC_NORSRAM_DeInit() + (+) FSMC NORSRAM bank control configuration using the function FSMC_NORSRAM_Init() + (+) FSMC NORSRAM bank timing configuration using the function FSMC_NORSRAM_Timing_Init() + (+) FSMC NORSRAM bank extended timing configuration using the function + FSMC_NORSRAM_Extended_Timing_Init() + (+) FSMC NORSRAM bank enable/disable write operation using the functions + FSMC_NORSRAM_WriteOperation_Enable()/FSMC_NORSRAM_WriteOperation_Disable() + +@endverbatim + * @{ + */ + +/** @addtogroup FSMC_LL_NORSRAM_Private_Functions_Group1 + * @brief Initialization and Configuration functions + * + @verbatim + ============================================================================== + ##### Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the FSMC NORSRAM interface + (+) De-initialize the FSMC NORSRAM interface + (+) Configure the FSMC clock and associated GPIOs + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the FSMC_NORSRAM device according to the specified + * control parameters in the FSMC_NORSRAM_InitTypeDef + * @param Device: Pointer to NORSRAM device instance + * @param Init: Pointer to NORSRAM Initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_NORSRAM_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_InitTypeDef* Init) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FSMC_NORSRAM_BANK(Init->NSBank)); + assert_param(IS_FSMC_MUX(Init->DataAddressMux)); + assert_param(IS_FSMC_MEMORY(Init->MemoryType)); + assert_param(IS_FSMC_NORSRAM_MEMORY_WIDTH(Init->MemoryDataWidth)); + assert_param(IS_FSMC_BURSTMODE(Init->BurstAccessMode)); + assert_param(IS_FSMC_WAIT_POLARITY(Init->WaitSignalPolarity)); + assert_param(IS_FSMC_WRAP_MODE(Init->WrapMode)); + assert_param(IS_FSMC_WAIT_SIGNAL_ACTIVE(Init->WaitSignalActive)); + assert_param(IS_FSMC_WRITE_OPERATION(Init->WriteOperation)); + assert_param(IS_FSMC_WAITE_SIGNAL(Init->WaitSignal)); + assert_param(IS_FSMC_EXTENDED_MODE(Init->ExtendedMode)); + assert_param(IS_FSMC_ASYNWAIT(Init->AsynchronousWait)); + assert_param(IS_FSMC_WRITE_BURST(Init->WriteBurst)); + + /* Get the BTCR register value */ + tmpr = Device->BTCR[Init->NSBank]; + + /* Clear MBKEN, MUXEN, MTYP, MWID, FACCEN, BURSTEN, WAITPOL, WRAPMOD, WAITCFG, WREN, + WAITEN, EXTMOD, ASYNCWAIT, CBURSTRW and CCLKEN bits */ + tmpr &= ((uint32_t)~(FSMC_BCR1_MBKEN | FSMC_BCR1_MUXEN | FSMC_BCR1_MTYP | \ + FSMC_BCR1_MWID | FSMC_BCR1_FACCEN | FSMC_BCR1_BURSTEN | \ + FSMC_BCR1_WAITPOL | FSMC_BCR1_WRAPMOD | FSMC_BCR1_WAITCFG | \ + FSMC_BCR1_WREN | FSMC_BCR1_WAITEN | FSMC_BCR1_EXTMOD | \ + FSMC_BCR1_ASYNCWAIT | FSMC_BCR1_CBURSTRW)); + /* Set NORSRAM device control parameters */ + tmpr |= (uint32_t)(Init->DataAddressMux |\ + Init->MemoryType |\ + Init->MemoryDataWidth |\ + Init->BurstAccessMode |\ + Init->WaitSignalPolarity |\ + Init->WrapMode |\ + Init->WaitSignalActive |\ + Init->WriteOperation |\ + Init->WaitSignal |\ + Init->ExtendedMode |\ + Init->AsynchronousWait |\ + Init->WriteBurst + ); + + if(Init->MemoryType == FSMC_MEMORY_TYPE_NOR) + { + tmpr |= (uint32_t)FSMC_NORSRAM_FLASH_ACCESS_ENABLE; + } + + Device->BTCR[Init->NSBank] = tmpr; + + return HAL_OK; +} + +/** + * @brief DeInitialize the FSMC_NORSRAM peripheral + * @param Device: Pointer to NORSRAM device instance + * @param ExDevice: Pointer to NORSRAM extended mode device instance + * @param Bank: NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_NORSRAM_DeInit(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FSMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FSMC_NORSRAM_EXTENDED_DEVICE(ExDevice)); + + /* Disable the FSMC_NORSRAM device */ + __FSMC_NORSRAM_DISABLE(Device, Bank); + + /* De-initialize the FSMC_NORSRAM device */ + /* FSMC_NORSRAM_BANK1 */ + if(Bank == FSMC_NORSRAM_BANK1) + { + Device->BTCR[Bank] = 0x000030DB; + } + /* FSMC_NORSRAM_BANK2, FSMC_NORSRAM_BANK3 or FSMC_NORSRAM_BANK4 */ + else + { + Device->BTCR[Bank] = 0x000030D2; + } + + Device->BTCR[Bank + 1] = 0x0FFFFFFF; + ExDevice->BWTR[Bank] = 0x0FFFFFFF; + + return HAL_OK; +} + + +/** + * @brief Initialize the FSMC_NORSRAM Timing according to the specified + * parameters in the FSMC_NORSRAM_TimingTypeDef + * @param Device: Pointer to NORSRAM device instance + * @param Timing: Pointer to NORSRAM Timing structure + * @param Bank: NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_NORSRAM_Timing_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FSMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime)); + assert_param(IS_FSMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime)); + assert_param(IS_FSMC_DATASETUP_TIME(Timing->DataSetupTime)); + assert_param(IS_FSMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration)); + assert_param(IS_FSMC_CLK_DIV(Timing->CLKDivision)); + assert_param(IS_FSMC_DATA_LATENCY(Timing->DataLatency)); + assert_param(IS_FSMC_ACCESS_MODE(Timing->AccessMode)); + + /* Get the BTCR register value */ + tmpr = Device->BTCR[Bank + 1]; + + /* Clear ADDSET, ADDHLD, DATAST, BUSTURN, CLKDIV, DATLAT and ACCMOD bits */ + tmpr &= ((uint32_t)~(FSMC_BTR1_ADDSET | FSMC_BTR1_ADDHLD | FSMC_BTR1_DATAST | \ + FSMC_BTR1_BUSTURN | FSMC_BTR1_CLKDIV | FSMC_BTR1_DATLAT | \ + FSMC_BTR1_ACCMOD)); + + /* Set FSMC_NORSRAM device timing parameters */ + tmpr |= (uint32_t)(Timing->AddressSetupTime |\ + ((Timing->AddressHoldTime) << 4) |\ + ((Timing->DataSetupTime) << 8) |\ + ((Timing->BusTurnAroundDuration) << 16) |\ + (((Timing->CLKDivision)-1) << 20) |\ + (((Timing->DataLatency)-2) << 24) |\ + (Timing->AccessMode)); + + Device->BTCR[Bank + 1] = tmpr; + + return HAL_OK; +} + +/** + * @brief Initialize the FSMC_NORSRAM Extended mode Timing according to the specified + * parameters in the FSMC_NORSRAM_TimingTypeDef + * @param Device: Pointer to NORSRAM device instance + * @param Timing: Pointer to NORSRAM Timing structure + * @param Bank: NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_NORSRAM_Extended_Timing_Init(FSMC_NORSRAM_EXTENDED_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, uint32_t ExtendedMode) +{ + uint32_t tmpr = 0; + + /* Set NORSRAM device timing register for write configuration, if extended mode is used */ + if(ExtendedMode == FSMC_EXTENDED_MODE_ENABLE) + { + /* Check the parameters */ + assert_param(IS_FSMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime)); + assert_param(IS_FSMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime)); + assert_param(IS_FSMC_DATASETUP_TIME(Timing->DataSetupTime)); + assert_param(IS_FSMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration)); + assert_param(IS_FSMC_CLK_DIV(Timing->CLKDivision)); + assert_param(IS_FSMC_DATA_LATENCY(Timing->DataLatency)); + assert_param(IS_FSMC_ACCESS_MODE(Timing->AccessMode)); + + /* Get the BWTR register value */ + tmpr = Device->BWTR[Bank]; + + /* Clear ADDSET, ADDHLD, DATAST, BUSTURN, CLKDIV, DATLAT and ACCMOD bits */ + tmpr &= ((uint32_t)~(FSMC_BWTR1_ADDSET | FSMC_BWTR1_ADDHLD | FSMC_BWTR1_DATAST | \ + FSMC_BWTR1_BUSTURN | FSMC_BWTR1_CLKDIV | FSMC_BWTR1_DATLAT | \ + FSMC_BWTR1_ACCMOD)); + + tmpr |= (uint32_t)(Timing->AddressSetupTime |\ + ((Timing->AddressHoldTime) << 4) |\ + ((Timing->DataSetupTime) << 8) |\ + ((Timing->BusTurnAroundDuration) << 16) |\ + (((Timing->CLKDivision)-1) << 20) |\ + (((Timing->DataLatency)-2) << 24) |\ + (Timing->AccessMode)); + + Device->BWTR[Bank] = tmpr; + } + else + { + Device->BWTR[Bank] = 0x0FFFFFFF; + } + + return HAL_OK; +} +/** + * @} + */ + +/** @addtogroup FSMC_LL_NORSRAM_Private_Functions_Group2 + * @brief management functions + * +@verbatim + ============================================================================== + ##### FSMC_NORSRAM Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the FSMC NORSRAM interface. + +@endverbatim + * @{ + */ + +/** + * @brief Enables dynamically FSMC_NORSRAM write operation. + * @param Device: Pointer to NORSRAM device instance + * @param Bank: NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Enable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank) +{ + /* Enable write operation */ + Device->BTCR[Bank] |= FSMC_WRITE_OPERATION_ENABLE; + + return HAL_OK; +} + +/** + * @brief Disables dynamically FSMC_NORSRAM write operation. + * @param Device: Pointer to NORSRAM device instance + * @param Bank: NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_NORSRAM_WriteOperation_Disable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank) +{ + /* Disable write operation */ + Device->BTCR[Bank] &= ~FSMC_WRITE_OPERATION_ENABLE; + + return HAL_OK; +} +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup FSMC_LL_NAND + * @brief NAND Controller functions + * + @verbatim + ============================================================================== + ##### How to use NAND device driver ##### + ============================================================================== + [..] + This driver contains a set of APIs to interface with the FSMC NAND banks in order + to run the NAND external devices. + + (+) FSMC NAND bank reset using the function FSMC_NAND_DeInit() + (+) FSMC NAND bank control configuration using the function FSMC_NAND_Init() + (+) FSMC NAND bank common space timing configuration using the function + FSMC_NAND_CommonSpace_Timing_Init() + (+) FSMC NAND bank attribute space timing configuration using the function + FSMC_NAND_AttributeSpace_Timing_Init() + (+) FSMC NAND bank enable/disable ECC correction feature using the functions + FSMC_NAND_ECC_Enable()/FSMC_NAND_ECC_Disable() + (+) FSMC NAND bank get ECC correction code using the function FSMC_NAND_GetECC() + +@endverbatim + * @{ + */ + +/** @addtogroup FSMC_LL_NAND_Private_Functions_Group1 + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the FSMC NAND interface + (+) De-initialize the FSMC NAND interface + (+) Configure the FSMC clock and associated GPIOs + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the FSMC_NAND device according to the specified + * control parameters in the FSMC_NAND_HandleTypeDef + * @param Device: Pointer to NAND device instance + * @param Init: Pointer to NAND Initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_NAND_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_InitTypeDef *Init) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FSMC_NAND_BANK(Init->NandBank)); + assert_param(IS_FSMC_WAIT_FEATURE(Init->Waitfeature)); + assert_param(IS_FSMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth)); + assert_param(IS_FSMC_ECC_STATE(Init->EccComputation)); + assert_param(IS_FSMC_ECCPAGE_SIZE(Init->ECCPageSize)); + assert_param(IS_FSMC_TCLR_TIME(Init->TCLRSetupTime)); + assert_param(IS_FSMC_TAR_TIME(Init->TARSetupTime)); + + if(Init->NandBank == FSMC_NAND_BANK2) + { + /* Get the NAND bank 2 register value */ + tmpr = Device->PCR2; + } + else + { + /* Get the NAND bank 3 register value */ + tmpr = Device->PCR3; + } + + /* Clear PWAITEN, PBKEN, PTYP, PWID, ECCEN, TCLR, TAR and ECCPS bits */ + tmpr &= ((uint32_t)~(FSMC_PCR2_PWAITEN | FSMC_PCR2_PBKEN | FSMC_PCR2_PTYP | \ + FSMC_PCR2_PWID | FSMC_PCR2_ECCEN | FSMC_PCR2_TCLR | \ + FSMC_PCR2_TAR | FSMC_PCR2_ECCPS)); + + /* Set NAND device control parameters */ + tmpr |= (uint32_t)(Init->Waitfeature |\ + FSMC_PCR_MEMORY_TYPE_NAND |\ + Init->MemoryDataWidth |\ + Init->EccComputation |\ + Init->ECCPageSize |\ + ((Init->TCLRSetupTime) << 9) |\ + ((Init->TARSetupTime) << 13)); + + if(Init->NandBank == FSMC_NAND_BANK2) + { + /* NAND bank 2 registers configuration */ + Device->PCR2 = tmpr; + } + else + { + /* NAND bank 3 registers configuration */ + Device->PCR3 = tmpr; + } + + return HAL_OK; +} + +/** + * @brief Initializes the FSMC_NAND Common space Timing according to the specified + * parameters in the FSMC_NAND_PCC_TimingTypeDef + * @param Device: Pointer to NAND device instance + * @param Timing: Pointer to NAND timing structure + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_NAND_CommonSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime)); + + if(Bank == FSMC_NAND_BANK2) + { + /* Get the NAND bank 2 register value */ + tmpr = Device->PMEM2; + } + else + { + /* Get the NAND bank 3 register value */ + tmpr = Device->PMEM3; + } + + /* Clear MEMSETx, MEMWAITx, MEMHOLDx and MEMHIZx bits */ + tmpr &= ((uint32_t)~(FSMC_PMEM2_MEMSET2 | FSMC_PMEM2_MEMWAIT2 | FSMC_PMEM2_MEMHOLD2 | \ + FSMC_PMEM2_MEMHIZ2)); + + /* Set FSMC_NAND device timing parameters */ + tmpr |= (uint32_t)(Timing->SetupTime |\ + ((Timing->WaitSetupTime) << 8) |\ + ((Timing->HoldSetupTime) << 16) |\ + ((Timing->HiZSetupTime) << 24) + ); + + if(Bank == FSMC_NAND_BANK2) + { + /* NAND bank 2 registers configuration */ + Device->PMEM2 = tmpr; + } + else + { + /* NAND bank 3 registers configuration */ + Device->PMEM3 = tmpr; + } + + return HAL_OK; +} + +/** + * @brief Initializes the FSMC_NAND Attribute space Timing according to the specified + * parameters in the FSMC_NAND_PCC_TimingTypeDef + * @param Device: Pointer to NAND device instance + * @param Timing: Pointer to NAND timing structure + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_NAND_AttributeSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime)); + + if(Bank == FSMC_NAND_BANK2) + { + /* Get the NAND bank 2 register value */ + tmpr = Device->PATT2; + } + else + { + /* Get the NAND bank 3 register value */ + tmpr = Device->PATT3; + } + + /* Clear ATTSETx, ATTWAITx, ATTHOLDx and ATTHIZx bits */ + tmpr &= ((uint32_t)~(FSMC_PATT2_ATTSET2 | FSMC_PATT2_ATTWAIT2 | FSMC_PATT2_ATTHOLD2 | \ + FSMC_PATT2_ATTHIZ2)); + + /* Set FSMC_NAND device timing parameters */ + tmpr |= (uint32_t)(Timing->SetupTime |\ + ((Timing->WaitSetupTime) << 8) |\ + ((Timing->HoldSetupTime) << 16) |\ + ((Timing->HiZSetupTime) << 24) + ); + + if(Bank == FSMC_NAND_BANK2) + { + /* NAND bank 2 registers configuration */ + Device->PATT2 = tmpr; + } + else + { + /* NAND bank 3 registers configuration */ + Device->PATT3 = tmpr; + } + + return HAL_OK; +} + +/** + * @brief DeInitializes the FSMC_NAND device + * @param Device: Pointer to NAND device instance + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_NAND_DeInit(FSMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Disable the NAND Bank */ + __FSMC_NAND_DISABLE(Device, Bank); + + /* De-initialize the NAND Bank */ + if(Bank == FSMC_NAND_BANK2) + { + /* Set the FSMC_NAND_BANK2 registers to their reset values */ + Device->PCR2 = 0x00000018; + Device->SR2 = 0x00000040; + Device->PMEM2 = 0xFCFCFCFC; + Device->PATT2 = 0xFCFCFCFC; + } + /* FSMC_Bank3_NAND */ + else + { + /* Set the FSMC_NAND_BANK3 registers to their reset values */ + Device->PCR3 = 0x00000018; + Device->SR3 = 0x00000040; + Device->PMEM3 = 0xFCFCFCFC; + Device->PATT3 = 0xFCFCFCFC; + } + + return HAL_OK; +} +/** + * @} + */ + +/** @addtogroup FSMC_LL_NAND_Private_Functions_Group2 + * @brief management functions + * +@verbatim + ============================================================================== + ##### FSMC_NAND Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the FSMC NAND interface. + +@endverbatim + * @{ + */ + +/** + * @brief Enables dynamically FSMC_NAND ECC feature. + * @param Device: Pointer to NAND device instance + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_NAND_ECC_Enable(FSMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Enable ECC feature */ + if(Bank == FSMC_NAND_BANK2) + { + Device->PCR2 |= FSMC_PCR2_ECCEN; + } + else + { + Device->PCR3 |= FSMC_PCR3_ECCEN; + } + + return HAL_OK; +} + +/** + * @brief Disables dynamically FSMC_NAND ECC feature. + * @param Device: Pointer to NAND device instance + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_NAND_ECC_Disable(FSMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Disable ECC feature */ + if(Bank == FSMC_NAND_BANK2) + { + Device->PCR2 &= ~FSMC_PCR2_ECCEN; + } + else + { + Device->PCR3 &= ~FSMC_PCR3_ECCEN; + } + + return HAL_OK; +} + +/** + * @brief Disables dynamically FSMC_NAND ECC feature. + * @param Device: Pointer to NAND device instance + * @param ECCval: Pointer to ECC value + * @param Bank: NAND bank number + * @param Timeout: Timeout wait value + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_NAND_GetECC(FSMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_FSMC_NAND_DEVICE(Device)); + assert_param(IS_FSMC_NAND_BANK(Bank)); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until FIFO is empty */ + while(__FSMC_NAND_GET_FLAG(Device, Bank, FSMC_FLAG_FEMPT) == RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + return HAL_TIMEOUT; + } + } + } + + if(Bank == FSMC_NAND_BANK2) + { + /* Get the ECCR2 register value */ + *ECCval = (uint32_t)Device->ECCR2; + } + else + { + /* Get the ECCR3 register value */ + *ECCval = (uint32_t)Device->ECCR3; + } + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @addtogroup FSMC_LL_PCCARD + * @brief PCCARD Controller functions + * + @verbatim + ============================================================================== + ##### How to use PCCARD device driver ##### + ============================================================================== + [..] + This driver contains a set of APIs to interface with the FSMC PCCARD bank in order + to run the PCCARD/compact flash external devices. + + (+) FSMC PCCARD bank reset using the function FSMC_PCCARD_DeInit() + (+) FSMC PCCARD bank control configuration using the function FSMC_PCCARD_Init() + (+) FSMC PCCARD bank common space timing configuration using the function + FSMC_PCCARD_CommonSpace_Timing_Init() + (+) FSMC PCCARD bank attribute space timing configuration using the function + FSMC_PCCARD_AttributeSpace_Timing_Init() + (+) FSMC PCCARD bank IO space timing configuration using the function + FSMC_PCCARD_IOSpace_Timing_Init() + +@endverbatim + * @{ + */ + +/** @addtogroup FSMC_LL_PCCARD_Private_Functions_Group1 + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the FSMC PCCARD interface + (+) De-initialize the FSMC PCCARD interface + (+) Configure the FSMC clock and associated GPIOs + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the FSMC_PCCARD device according to the specified + * control parameters in the FSMC_PCCARD_HandleTypeDef + * @param Device: Pointer to PCCARD device instance + * @param Init: Pointer to PCCARD Initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_PCCARD_Init(FSMC_PCCARD_TypeDef *Device, FSMC_PCCARD_InitTypeDef *Init) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FSMC_WAIT_FEATURE(Init->Waitfeature)); + assert_param(IS_FSMC_TCLR_TIME(Init->TCLRSetupTime)); + assert_param(IS_FSMC_TAR_TIME(Init->TARSetupTime)); + + /* Get PCCARD control register value */ + tmpr = Device->PCR4; + + /* Clear TAR, TCLR, PWAITEN and PWID bits */ + tmpr &= ((uint32_t)~(FSMC_PCR4_TAR | FSMC_PCR4_TCLR | FSMC_PCR4_PWAITEN | \ + FSMC_PCR4_PWID)); + + /* Set FSMC_PCCARD device control parameters */ + tmpr |= (uint32_t)(Init->Waitfeature |\ + FSMC_NAND_PCC_MEM_BUS_WIDTH_16 |\ + (Init->TCLRSetupTime << 9) |\ + (Init->TARSetupTime << 13)); + + Device->PCR4 = tmpr; + + return HAL_OK; +} + +/** + * @brief Initializes the FSMC_PCCARD Common space Timing according to the specified + * parameters in the FSMC_NAND_PCC_TimingTypeDef + * @param Device: Pointer to PCCARD device instance + * @param Timing: Pointer to PCCARD timing structure + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_PCCARD_CommonSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime)); + + /* Get PCCARD common space timing register value */ + tmpr = Device->PMEM4; + + /* Clear MEMSETx, MEMWAITx, MEMHOLDx and MEMHIZx bits */ + tmpr &= ((uint32_t)~(FSMC_PMEM4_MEMSET4 | FSMC_PMEM4_MEMWAIT4 | FSMC_PMEM4_MEMHOLD4 | \ + FSMC_PMEM4_MEMHIZ4)); + /* Set PCCARD timing parameters */ + tmpr |= (uint32_t)((Timing->SetupTime |\ + ((Timing->WaitSetupTime) << 8) |\ + (Timing->HoldSetupTime) << 16) |\ + ((Timing->HiZSetupTime) << 24)); + + Device->PMEM4 = tmpr; + + return HAL_OK; +} + +/** + * @brief Initializes the FSMC_PCCARD Attribute space Timing according to the specified + * parameters in the FSMC_NAND_PCC_TimingTypeDef + * @param Device: Pointer to PCCARD device instance + * @param Timing: Pointer to PCCARD timing structure + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_PCCARD_AttributeSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime)); + + /* Get PCCARD timing parameters */ + tmpr = Device->PATT4; + + /* Clear ATTSETx, ATTWAITx, ATTHOLDx and ATTHIZx bits */ + tmpr &= ((uint32_t)~(FSMC_PATT4_ATTSET4 | FSMC_PATT4_ATTWAIT4 | FSMC_PATT4_ATTHOLD4 | \ + FSMC_PATT4_ATTHIZ4)); + + /* Set PCCARD timing parameters */ + tmpr |= (uint32_t)(Timing->SetupTime |\ + ((Timing->WaitSetupTime) << 8) |\ + ((Timing->HoldSetupTime) << 16) |\ + ((Timing->HiZSetupTime) << 24)); + Device->PATT4 = tmpr; + + return HAL_OK; +} + +/** + * @brief Initializes the FSMC_PCCARD IO space Timing according to the specified + * parameters in the FSMC_NAND_PCC_TimingTypeDef + * @param Device: Pointer to PCCARD device instance + * @param Timing: Pointer to PCCARD timing structure + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_PCCARD_IOSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FSMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FSMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FSMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FSMC_HIZ_TIME(Timing->HiZSetupTime)); + + /* Get FSMC_PCCARD device timing parameters */ + tmpr = Device->PIO4; + + /* Clear IOSET4, IOWAIT4, IOHOLD4 and IOHIZ4 bits */ + tmpr &= ((uint32_t)~(FSMC_PIO4_IOSET4 | FSMC_PIO4_IOWAIT4 | FSMC_PIO4_IOHOLD4 | \ + FSMC_PIO4_IOHIZ4)); + + /* Set FSMC_PCCARD device timing parameters */ + tmpr |= (uint32_t)(Timing->SetupTime |\ + ((Timing->WaitSetupTime) << 8) |\ + ((Timing->HoldSetupTime) << 16) |\ + ((Timing->HiZSetupTime) << 24)); + + Device->PIO4 = tmpr; + + return HAL_OK; +} + +/** + * @brief DeInitializes the FSMC_PCCARD device + * @param Device: Pointer to PCCARD device instance + * @retval HAL status + */ +HAL_StatusTypeDef FSMC_PCCARD_DeInit(FSMC_PCCARD_TypeDef *Device) +{ + /* Disable the FSMC_PCCARD device */ + __FSMC_PCCARD_DISABLE(Device); + + /* De-initialize the FSMC_PCCARD device */ + Device->PCR4 = 0x00000018; + Device->SR4 = 0x00000000; + Device->PMEM4 = 0xFCFCFCFC; + Device->PATT4 = 0xFCFCFCFC; + Device->PIO4 = 0xFCFCFCFC; + + return HAL_OK; +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */ +#endif /* HAL_SRAM_MODULE_ENABLED || HAL_NOR_MODULE_ENABLED || HAL_NAND_MODULE_ENABLED || HAL_PCCARD_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c new file mode 100644 index 0000000..fb61e41 --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c @@ -0,0 +1,505 @@ +/** + ****************************************************************************** + * @file stm32f4xx_ll_sdmmc.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief SDMMC Low Layer HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the SDMMC peripheral: + * + Initialization/de-initialization functions + * + I/O operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### SDMMC peripheral features ##### + ============================================================================== + [..] The SD/SDIO MMC card host interface (SDIO) provides an interface between the APB2 + peripheral bus and MultiMedia cards (MMCs), SD memory cards, SDIO cards and CE-ATA + devices. + + [..] The SDIO features include the following: + (+) Full compliance with MultiMedia Card System Specification Version 4.2. Card support + for three different databus modes: 1-bit (default), 4-bit and 8-bit + (+) Full compatibility with previous versions of MultiMedia Cards (forward compatibility) + (+) Full compliance with SD Memory Card Specifications Version 2.0 + (+) Full compliance with SD I/O Card Specification Version 2.0: card support for two + different data bus modes: 1-bit (default) and 4-bit + (+) Full support of the CE-ATA features (full compliance with CE-ATA digital protocol + Rev1.1) + (+) Data transfer up to 48 MHz for the 8 bit mode + (+) Data and command output enable signals to control external bidirectional drivers. + + + ##### How to use this driver ##### + ============================================================================== + [..] + This driver is a considered as a driver of service for external devices drivers + that interfaces with the SDIO peripheral. + According to the device used (SD card/ MMC card / SDIO card ...), a set of APIs + is used in the device's driver to perform SDIO operations and functionalities. + + This driver is almost transparent for the final user, it is only used to implement other + functionalities of the external device. + + [..] + (+) The SDIO clock (SDIOCLK = 48 MHz) is coming from a specific output of PLL + (PLL48CLK). Before start working with SDIO peripheral make sure that the + PLL is well configured. + The SDIO peripheral uses two clock signals: + (++) SDIO adapter clock (SDIOCLK = 48 MHz) + (++) APB2 bus clock (PCLK2) + + -@@- PCLK2 and SDIO_CK clock frequencies must respect the following condition: + Frequency(PCLK2) >= (3 / 8 x Frequency(SDIO_CK)) + + (+) Enable/Disable peripheral clock using RCC peripheral macros related to SDIO + peripheral. + + (+) Enable the Power ON State using the SDIO_PowerState_ON(SDIOx) + function and disable it using the function SDIO_PowerState_OFF(SDIOx). + + (+) Enable/Disable the clock using the __SDIO_ENABLE()/__SDIO_DISABLE() macros. + + (+) Enable/Disable the peripheral interrupts using the macros __SDIO_ENABLE_IT(hsdio, IT) + and __SDIO_DISABLE_IT(hsdio, IT) if you need to use interrupt mode. + + (+) When using the DMA mode + (++) Configure the DMA in the MSP layer of the external device + (++) Active the needed channel Request + (++) Enable the DMA using __SDIO_DMA_ENABLE() macro or Disable it using the macro + __SDIO_DMA_DISABLE(). + + (+) To control the CPSM (Command Path State Machine) and send + commands to the card use the SDIO_SendCommand(SDIOx), + SDIO_GetCommandResponse() and SDIO_GetResponse() functions. First, user has + to fill the command structure (pointer to SDIO_CmdInitTypeDef) according + to the selected command to be sent. + The parameters that should be filled are: + (++) Command Argument + (++) Command Index + (++) Command Response type + (++) Command Wait + (++) CPSM Status (Enable or Disable). + + -@@- To check if the command is well received, read the SDIO_CMDRESP + register using the SDIO_GetCommandResponse(). + The SDIO responses registers (SDIO_RESP1 to SDIO_RESP2), use the + SDIO_GetResponse() function. + + (+) To control the DPSM (Data Path State Machine) and send/receive + data to/from the card use the SDIO_DataConfig(), SDIO_GetDataCounter(), + SDIO_ReadFIFO(), DIO_WriteFIFO() and SDIO_GetFIFOCount() functions. + + *** Read Operations *** + ======================= + [..] + (#) First, user has to fill the data structure (pointer to + SDIO_DataInitTypeDef) according to the selected data type to be received. + The parameters that should be filled are: + (++) Data Timeout + (++) Data Length + (++) Data Block size + (++) Data Transfer direction: should be from card (To SDIO) + (++) Data Transfer mode + (++) DPSM Status (Enable or Disable) + + (#) Configure the SDIO resources to receive the data from the card + according to selected transfer mode (Refer to Step 8, 9 and 10). + + (#) Send the selected Read command (refer to step 11). + + (#) Use the SDIO flags/interrupts to check the transfer status. + + *** Write Operations *** + ======================== + [..] + (#) First, user has to fill the data structure (pointer to + SDIO_DataInitTypeDef) according to the selected data type to be received. + The parameters that should be filled are: + (++) Data Timeout + (++) Data Length + (++) Data Block size + (++) Data Transfer direction: should be to card (To CARD) + (++) Data Transfer mode + (++) DPSM Status (Enable or Disable) + + (#) Configure the SDIO resources to send the data to the card according to + selected transfer mode. + + (#) Send the selected Write command. + + (#) Use the SDIO flags/interrupts to check the transfer status. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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 SDMMC_LL SDMMC Low Layer + * @brief Low layer module for SD and MMC driver + * @{ + */ + +#if defined (HAL_SD_MODULE_ENABLED) || defined(HAL_MMC_MODULE_ENABLED) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup SDMMC_LL_Exported_Functions SDMMC_LL Exported Functions + * @{ + */ + +/** @defgroup HAL_SDMMC_LL_Group1 Initialization/de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization/de-initialization functions ##### + =============================================================================== + [..] This section provides functions allowing to: + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the SDIO according to the specified + * parameters in the SDIO_InitTypeDef and create the associated handle. + * @param SDIOx: Pointer to SDIO register base + * @param Init: SDIO initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef SDIO_Init(SDIO_TypeDef *SDIOx, SDIO_InitTypeDef Init) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_SDIO_ALL_INSTANCE(SDIOx)); + assert_param(IS_SDIO_CLOCK_EDGE(Init.ClockEdge)); + assert_param(IS_SDIO_CLOCK_BYPASS(Init.ClockBypass)); + assert_param(IS_SDIO_CLOCK_POWER_SAVE(Init.ClockPowerSave)); + assert_param(IS_SDIO_BUS_WIDE(Init.BusWide)); + assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(Init.HardwareFlowControl)); + assert_param(IS_SDIO_CLKDIV(Init.ClockDiv)); + + /* Set SDIO configuration parameters */ + tmpreg |= (Init.ClockEdge |\ + Init.ClockBypass |\ + Init.ClockPowerSave |\ + Init.BusWide |\ + Init.HardwareFlowControl |\ + Init.ClockDiv + ); + + /* Write to SDIO CLKCR */ + MODIFY_REG(SDIOx->CLKCR, CLKCR_CLEAR_MASK, tmpreg); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup HAL_SDMMC_LL_Group2 I/O operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### I/O operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the SDIO data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Read data (word) from Rx FIFO in blocking mode (polling) + * @param SDIOx: Pointer to SDIO register base + * @retval HAL status + */ +uint32_t SDIO_ReadFIFO(SDIO_TypeDef *SDIOx) +{ + /* Read data from Rx FIFO */ + return (SDIOx->FIFO); +} + +/** + * @brief Write data (word) to Tx FIFO in blocking mode (polling) + * @param SDIOx: Pointer to SDIO register base + * @param pWriteData: pointer to data to write + * @retval HAL status + */ +HAL_StatusTypeDef SDIO_WriteFIFO(SDIO_TypeDef *SDIOx, uint32_t *pWriteData) +{ + /* Write data to FIFO */ + SDIOx->FIFO = *pWriteData; + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup HAL_SDMMC_LL_Group3 Peripheral Control functions + * @brief management functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the SDIO data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Set SDIO Power state to ON. + * @param SDIOx: Pointer to SDIO register base + * @retval HAL status + */ +HAL_StatusTypeDef SDIO_PowerState_ON(SDIO_TypeDef *SDIOx) +{ + /* Set power state to ON */ + SDIOx->POWER = SDIO_POWER_PWRCTRL; + + return HAL_OK; +} + +/** + * @brief Set SDIO Power state to OFF. + * @param SDIOx: Pointer to SDIO register base + * @retval HAL status + */ +HAL_StatusTypeDef SDIO_PowerState_OFF(SDIO_TypeDef *SDIOx) +{ + /* Set power state to OFF */ + SDIOx->POWER = (uint32_t)0x00000000; + + return HAL_OK; +} + +/** + * @brief Get SDIO Power state. + * @param SDIOx: Pointer to SDIO register base + * @retval Power status of the controller. The returned value can be one of the + * following values: + * - 0x00: Power OFF + * - 0x02: Power UP + * - 0x03: Power ON + */ +uint32_t SDIO_GetPowerState(SDIO_TypeDef *SDIOx) +{ + return (SDIOx->POWER & SDIO_POWER_PWRCTRL); +} + +/** + * @brief Configure the SDIO command path according to the specified parameters in + * SDIO_CmdInitTypeDef structure and send the command + * @param SDIOx: Pointer to SDIO register base + * @param SDIO_CmdInitStruct: pointer to a SDIO_CmdInitTypeDef structure that contains + * the configuration information for the SDIO command + * @retval HAL status + */ +HAL_StatusTypeDef SDIO_SendCommand(SDIO_TypeDef *SDIOx, SDIO_CmdInitTypeDef *SDIO_CmdInitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_SDIO_CMD_INDEX(SDIO_CmdInitStruct->CmdIndex)); + assert_param(IS_SDIO_RESPONSE(SDIO_CmdInitStruct->Response)); + assert_param(IS_SDIO_WAIT(SDIO_CmdInitStruct->WaitForInterrupt)); + assert_param(IS_SDIO_CPSM(SDIO_CmdInitStruct->CPSM)); + + /* Set the SDIO Argument value */ + SDIOx->ARG = SDIO_CmdInitStruct->Argument; + + /* Set SDIO command parameters */ + tmpreg |= (uint32_t)(SDIO_CmdInitStruct->CmdIndex |\ + SDIO_CmdInitStruct->Response |\ + SDIO_CmdInitStruct->WaitForInterrupt |\ + SDIO_CmdInitStruct->CPSM); + + /* Write to SDIO CMD register */ + MODIFY_REG(SDIOx->CMD, CMD_CLEAR_MASK, tmpreg); + + return HAL_OK; +} + +/** + * @brief Return the command index of last command for which response received + * @param SDIOx: Pointer to SDIO register base + * @retval Command index of the last command response received + */ +uint8_t SDIO_GetCommandResponse(SDIO_TypeDef *SDIOx) +{ + return (uint8_t)(SDIOx->RESPCMD); +} + + +/** + * @brief Return the response received from the card for the last command + * @param SDIO_RESP: Specifies the SDIO response register. + * This parameter can be one of the following values: + * @arg SDIO_RESP1: Response Register 1 + * @arg SDIO_RESP2: Response Register 2 + * @arg SDIO_RESP3: Response Register 3 + * @arg SDIO_RESP4: Response Register 4 + * @retval The Corresponding response register value + */ +uint32_t SDIO_GetResponse(uint32_t SDIO_RESP) +{ + __IO uint32_t tmp = 0; + + /* Check the parameters */ + assert_param(IS_SDIO_RESP(SDIO_RESP)); + + /* Get the response */ + tmp = SDIO_RESP_ADDR + SDIO_RESP; + + return (*(__IO uint32_t *) tmp); +} + +/** + * @brief Configure the SDIO data path according to the specified + * parameters in the SDIO_DataInitTypeDef. + * @param SDIOx: Pointer to SDIO register base + * @param SDIO_DataInitStruct : pointer to a SDIO_DataInitTypeDef structure + * that contains the configuration information for the SDIO command. + * @retval HAL status + */ +HAL_StatusTypeDef SDIO_DataConfig(SDIO_TypeDef *SDIOx, SDIO_DataInitTypeDef* SDIO_DataInitStruct) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_SDIO_DATA_LENGTH(SDIO_DataInitStruct->DataLength)); + assert_param(IS_SDIO_BLOCK_SIZE(SDIO_DataInitStruct->DataBlockSize)); + assert_param(IS_SDIO_TRANSFER_DIR(SDIO_DataInitStruct->TransferDir)); + assert_param(IS_SDIO_TRANSFER_MODE(SDIO_DataInitStruct->TransferMode)); + assert_param(IS_SDIO_DPSM(SDIO_DataInitStruct->DPSM)); + + /* Set the SDIO Data Timeout value */ + SDIOx->DTIMER = SDIO_DataInitStruct->DataTimeOut; + + /* Set the SDIO DataLength value */ + SDIOx->DLEN = SDIO_DataInitStruct->DataLength; + + /* Set the SDIO data configuration parameters */ + tmpreg |= (uint32_t)(SDIO_DataInitStruct->DataBlockSize |\ + SDIO_DataInitStruct->TransferDir |\ + SDIO_DataInitStruct->TransferMode |\ + SDIO_DataInitStruct->DPSM); + + /* Write to SDIO DCTRL */ + MODIFY_REG(SDIOx->DCTRL, DCTRL_CLEAR_MASK, tmpreg); + + return HAL_OK; + +} + +/** + * @brief Returns number of remaining data bytes to be transferred. + * @param SDIOx: Pointer to SDIO register base + * @retval Number of remaining data bytes to be transferred + */ +uint32_t SDIO_GetDataCounter(SDIO_TypeDef *SDIOx) +{ + return (SDIOx->DCOUNT); +} + +/** + * @brief Get the FIFO data + * @param SDIOx: Pointer to SDIO register base + * @retval Data received + */ +uint32_t SDIO_GetFIFOCount(SDIO_TypeDef *SDIOx) +{ + return (SDIOx->FIFO); +} + + +/** + * @brief Sets one of the two options of inserting read wait interval. + * @param SDIO_ReadWaitMode: SD I/O Read Wait operation mode. + * This parameter can be: + * @arg SDIO_READ_WAIT_MODE_CLK: Read Wait control by stopping SDIOCLK + * @arg SDIO_READ_WAIT_MODE_DATA2: Read Wait control using SDIO_DATA2 + * @retval None + */ +HAL_StatusTypeDef SDIO_SetSDIOReadWaitMode(uint32_t SDIO_ReadWaitMode) +{ + /* Check the parameters */ + assert_param(IS_SDIO_READWAIT_MODE(SDIO_ReadWaitMode)); + + *(__IO uint32_t *)DCTRL_RWMOD_BB = SDIO_ReadWaitMode; + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +#endif /* (HAL_SD_MODULE_ENABLED) || (HAL_MMC_MODULE_ENABLED) */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c new file mode 100644 index 0000000..5577d3e --- /dev/null +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.c @@ -0,0 +1,1753 @@ +/** + ****************************************************************************** + * @file stm32f4xx_ll_usb.c + * @author MCD Application Team + * @version V1.3.2 + * @date 26-June-2015 + * @brief USB Low Layer HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Initialization/de-initialization functions + * + I/O operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure. + + (#) Call USB_CoreInit() API to initialize the USB Core peripheral. + + (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes. + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2015 STMicroelectronics

+ * + * 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. + * + ****************************************************************************** + * + * Modifications by Robert Fisk + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/** @addtogroup STM32F4xx_LL_USB_DRIVER + * @{ + */ + +#if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx); + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup LL_USB_Exported_Functions USB Low Layer Exported Functions + * @{ + */ + +/** @defgroup LL_USB_Group1 Initialization/de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization/de-initialization functions ##### + =============================================================================== + [..] This section provides functions allowing to: + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the USB Core + * @param USBx: USB Instance + * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains + * the configuration information for the specified USBx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg) +{ + if (cfg.phy_itface == USB_OTG_ULPI_PHY) + { + + USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN); + + /* Init The ULPI Interface */ + USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL); + + /* Select vbus source */ + USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); + if(cfg.use_external_vbus == 1) + { + USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD; + } + /* Reset after a PHY select */ + USB_CoreReset(USBx); + } + else /* FS interface (embedded Phy) */ + { + /* Select FS Embedded PHY */ + USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; + + /* Reset after a PHY select and set Host mode */ + USB_CoreReset(USBx); + + /* Deactivate the power down*/ + USBx->GCCFG = USB_OTG_GCCFG_PWRDWN; + } + + if(cfg.dma_enable == ENABLE) + { + USBx->GAHBCFG |= (USB_OTG_GAHBCFG_HBSTLEN_1 | USB_OTG_GAHBCFG_HBSTLEN_2); + USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN; + } + + return HAL_OK; +} + +/** + * @brief USB_EnableGlobalInt + * Enables the controller's Global Int in the AHB Config reg + * @param USBx : Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx) +{ + USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT; + return HAL_OK; +} + + +/** + * @brief USB_DisableGlobalInt + * Disable the controller's Global Int in the AHB Config reg + * @param USBx : Selected device + * @retval HAL status +*/ +HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx) +{ + USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT; + return HAL_OK; +} + +/** + * @brief USB_SetCurrentMode : Set functional mode + * @param USBx : Selected device + * @param mode : current core mode + * This parameter can be one of these values: + * @arg USB_OTG_DEVICE_MODE: Peripheral mode + * @arg USB_OTG_HOST_MODE: Host mode + * @arg USB_OTG_DRD_MODE: Dual Role Device mode + * @retval HAL status + */ +HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx , USB_OTG_ModeTypeDef mode) +{ + USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD); + + if ( mode == USB_OTG_HOST_MODE) + { + USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD; + } + else if ( mode == USB_OTG_DEVICE_MODE) + { + USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; + } + HAL_Delay(50); + + return HAL_OK; +} + +/** + * @brief USB_DevInit : Initializes the USB_OTG controller registers + * for device mode + * @param USBx : Selected device + * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains + * the configuration information for the specified USBx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef USB_DevInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg) +{ + uint32_t i = 0; + + /*Activate VBUS Sensing B */ +#if defined(STM32F446xx) + USBx->GCCFG |= USB_OTG_GCCFG_VBDEN; + + if (cfg.vbus_sensing_enable == 0) + { + /* Deactivate VBUS Sensing B */ + USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN; + + /* B-peripheral session valid override enable*/ + USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; + USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; + } +#else + USBx->GCCFG |= USB_OTG_GCCFG_VBUSBSEN; + + if (cfg.vbus_sensing_enable == 0) + { + USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; + } +#endif /* STM32F446xx */ + + /* Restart the Phy Clock */ + USBx_PCGCCTL = 0; + + /* Device mode configuration */ + USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80; + + if(cfg.phy_itface == USB_OTG_ULPI_PHY) + { + if(cfg.speed == USB_OTG_SPEED_HIGH) + { + /* Set High speed phy */ + USB_SetDevSpeed (USBx , USB_OTG_SPEED_HIGH); + } + else + { + /* set High speed phy in Full speed mode */ + USB_SetDevSpeed (USBx , USB_OTG_SPEED_HIGH_IN_FULL); + } + } + else + { + /* Set Full speed phy */ + USB_SetDevSpeed (USBx , USB_OTG_SPEED_FULL); + } + + /* Flush the FIFOs */ + USB_FlushTxFifo(USBx , 0x10); /* all Tx FIFOs */ + USB_FlushRxFifo(USBx); + + /* Clear all pending Device Interrupts */ + USBx_DEVICE->DIEPMSK = 0; + USBx_DEVICE->DOEPMSK = 0; + USBx_DEVICE->DAINT = 0xFFFFFFFF; + USBx_DEVICE->DAINTMSK = 0; + + for (i = 0; i < cfg.dev_endpoints; i++) + { + if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA) + { + USBx_INEP(i)->DIEPCTL = (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK); + } + else + { + USBx_INEP(i)->DIEPCTL = 0; + } + + USBx_INEP(i)->DIEPTSIZ = 0; + USBx_INEP(i)->DIEPINT = 0xFF; + } + + for (i = 0; i < cfg.dev_endpoints; i++) + { + if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) + { + USBx_OUTEP(i)->DOEPCTL = (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK); + } + else + { + USBx_OUTEP(i)->DOEPCTL = 0; + } + + USBx_OUTEP(i)->DOEPTSIZ = 0; + USBx_OUTEP(i)->DOEPINT = 0xFF; + } + + USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM); + + if (cfg.dma_enable == 1) + { + /*Set threshold parameters */ + USBx_DEVICE->DTHRCTL = (USB_OTG_DTHRCTL_TXTHRLEN_6 | USB_OTG_DTHRCTL_RXTHRLEN_6); + USBx_DEVICE->DTHRCTL |= (USB_OTG_DTHRCTL_RXTHREN | USB_OTG_DTHRCTL_ISOTHREN | USB_OTG_DTHRCTL_NONISOTHREN); + + i= USBx_DEVICE->DTHRCTL; + } + + /* Disable all interrupts. */ + USBx->GINTMSK = 0; + + /* Clear any pending interrupts */ + USBx->GINTSTS = 0xBFFFFFFF; + + /* Enable the common interrupts */ + if (cfg.dma_enable == DISABLE) + { + USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; + } + + /* Enable interrupts matching to the Device mode ONLY */ + USBx->GINTMSK |= (USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |\ + USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |\ + USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM|\ + USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM); + + if(cfg.Sof_enable) + { + USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM; + } + + if (cfg.vbus_sensing_enable == ENABLE) + { + USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT); + } + + return HAL_OK; +} + + +/** + * @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO + * @param USBx : Selected device + * @param num : FIFO number + * This parameter can be a value from 1 to 15 + 16 means Flush all Tx FIFOs + * @retval HAL status + */ +HAL_StatusTypeDef USB_FlushTxFifo (USB_OTG_GlobalTypeDef *USBx, uint32_t num ) +{ + uint32_t count = 0; + + USBx->GRSTCTL = ( USB_OTG_GRSTCTL_TXFFLSH |(uint32_t)( num << 6)); + + do + { + if (++count > 200000) + { + return HAL_TIMEOUT; + } + } + while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH); + + return HAL_OK; +} + + +/** + * @brief USB_FlushRxFifo : Flush Rx FIFO + * @param USBx : Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx) +{ + uint32_t count = 0; + + USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH; + + do + { + if (++count > 200000) + { + return HAL_TIMEOUT; + } + } + while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH); + + return HAL_OK; +} + +/** + * @brief USB_SetDevSpeed :Initializes the DevSpd field of DCFG register + * depending the PHY type and the enumeration speed of the device. + * @param USBx : Selected device + * @param speed : device speed + * This parameter can be one of these values: + * @arg USB_OTG_SPEED_HIGH: High speed mode + * @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full Speed mode + * @arg USB_OTG_SPEED_FULL: Full speed mode + * @arg USB_OTG_SPEED_LOW: Low speed mode + * @retval Hal status + */ +HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx , uint8_t speed) +{ + USBx_DEVICE->DCFG |= speed; + return HAL_OK; +} + +/** + * @brief USB_GetDevSpeed :Return the Dev Speed + * @param USBx : Selected device + * @retval speed : device speed + * This parameter can be one of these values: + * @arg USB_OTG_SPEED_HIGH: High speed mode + * @arg USB_OTG_SPEED_FULL: Full speed mode + * @arg USB_OTG_SPEED_LOW: Low speed mode + */ +uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx) +{ + uint8_t speed = 0; + + if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ) + { + speed = USB_OTG_SPEED_HIGH; + } + else if (((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ)|| + ((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_48MHZ)) + { + speed = USB_OTG_SPEED_FULL; + } + else if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ) + { + speed = USB_OTG_SPEED_LOW; + } + + return speed; +} + +/** + * @brief Activate and configure an endpoint + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep) +{ + if (ep->is_in == 1) + { + USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))); + + if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0) + { + USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\ + ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP)); + } + + } + else + { + USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16); + + if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0) + { + USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\ + (USB_OTG_DIEPCTL_SD0PID_SEVNFRM)| (USB_OTG_DOEPCTL_USBAEP)); + } + } + return HAL_OK; +} +/** + * @brief Activate and configure a dedicated endpoint + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep) +{ + static __IO uint32_t debug = 0; + + /* Read DEPCTLn register */ + if (ep->is_in == 1) + { + if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0) + { + USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\ + ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP)); + } + + + debug |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\ + ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP)); + + USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))); + } + else + { + if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0) + { + USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\ + ((ep->num) << 22 ) | (USB_OTG_DOEPCTL_USBAEP)); + + debug = (uint32_t)(((uint32_t )USBx) + USB_OTG_OUT_ENDPOINT_BASE + (0)*USB_OTG_EP_REG_SIZE); + debug = (uint32_t )&USBx_OUTEP(ep->num)->DOEPCTL; + debug |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\ + ((ep->num) << 22 ) | (USB_OTG_DOEPCTL_USBAEP)); + } + + USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16); + } + + return HAL_OK; +} +/** + * @brief De-activate and de-initialize an endpoint + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep) +{ + /* Read DEPCTLn register */ + if (ep->is_in == 1) + { + USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)))); + USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)))); + USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP; + } + else + { + USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16)); + USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16)); + USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP; + } + return HAL_OK; +} + +/** + * @brief De-activate and de-initialize a dedicated endpoint + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep) +{ + /* Read DEPCTLn register */ + if (ep->is_in == 1) + { + USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP; + USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)))); + } + else + { + USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP; + USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16)); + } + return HAL_OK; +} + +/** + * @brief USB_EPStartXfer : setup and starts a transfer over an EP + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @param dma: USB dma enabled or disabled + * This parameter can be one of these values: + * 0 : DMA feature not used + * 1 : DMA feature used + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma) +{ + uint16_t pktcnt = 0; + + /* IN endpoint */ + if (ep->is_in == 1) + { + /* Zero Length Packet? */ + if (ep->xfer_len == 0) + { + USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); + USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ; + USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); + } + else + { + /* Program the transfer size and packet count + * as follows: xfersize = N * maxpacket + + * short_packet pktcnt = N + (short_packet + * exist ? 1 : 0) + */ + USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); + USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); + USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket) << 19)) ; + USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len); + + if (ep->type == EP_TYPE_ISOC) + { + USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT); + USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1 << 29)); + } + } + + if (dma == 1) + { + USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr); + } + else + { + if (ep->type != EP_TYPE_ISOC) + { + /* Enable the Tx FIFO Empty Interrupt for this EP */ + if (ep->xfer_len > 0) + { + USBx_DEVICE->DIEPEMPMSK |= 1 << ep->num; + } + } + } + + if (ep->type == EP_TYPE_ISOC) + { + if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0) + { + USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM; + } + else + { + USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; + } + } + + /* EP enable, IN data in FIFO */ + USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA); + + if (ep->type == EP_TYPE_ISOC) + { + USB_WritePacket(USBx, ep->xfer_buff, ep->num, ep->xfer_len, dma); + } + } + else /* OUT endpoint */ + { + /* Program the transfer size and packet count as follows: + * pktcnt = N + * xfersize = N * maxpacket + */ + USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ); + USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT); + + if (ep->xfer_len == 0) + { + USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket); + USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) ; + } + else + { + pktcnt = (ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket; + USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19)); ; + USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt)); + } + + if (dma == 1) + { + USBx_OUTEP(ep->num)->DOEPDMA = (uint32_t)ep->xfer_buff; + } + + if (ep->type == EP_TYPE_ISOC) + { + if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0) + { + USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM; + } + else + { + USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; + } + } + /* EP enable */ + USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA); + } + return HAL_OK; +} + +/** + * @brief USB_EP0StartXfer : setup and starts a transfer over the EP 0 + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @param dma: USB dma enabled or disabled + * This parameter can be one of these values: + * 0 : DMA feature not used + * 1 : DMA feature used + * @retval HAL status + */ +HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma) +{ + /* IN endpoint */ + if (ep->is_in == 1) + { + /* Zero Length Packet? */ + if (ep->xfer_len == 0) + { + USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); + USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ; + USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); + } + else + { + /* Program the transfer size and packet count + * as follows: xfersize = N * maxpacket + + * short_packet pktcnt = N + (short_packet + * exist ? 1 : 0) + */ + USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); + USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); + + if(ep->xfer_len > ep->maxpacket) + { + ep->xfer_len = ep->maxpacket; + } + USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ; + USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len); + + } + + if (dma == 1) + { + USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr); + } + else + { + /* Enable the Tx FIFO Empty Interrupt for this EP */ + if (ep->xfer_len > 0) + { + USBx_DEVICE->DIEPEMPMSK |= 1 << (ep->num); + } + } + + /* EP enable, IN data in FIFO */ + USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA); + } + else /* OUT endpoint */ + { + /* Program the transfer size and packet count as follows: + * pktcnt = N + * xfersize = N * maxpacket + */ + USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ); + USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT); + + if (ep->xfer_len > 0) + { + ep->xfer_len = ep->maxpacket; + } + + USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)); + USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket)); + + + if (dma == 1) + { + USBx_OUTEP(ep->num)->DOEPDMA = (uint32_t)(ep->xfer_buff); + } + + /* EP enable */ + USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA); + } + return HAL_OK; +} + +/** + * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated + * with the EP/channel + * @param USBx : Selected device + * @param src : pointer to source buffer + * @param ch_ep_num : endpoint or host channel number + * @param len : Number of bytes to write + * @param dma: USB dma enabled or disabled + * This parameter can be one of these values: + * 0 : DMA feature not used + * 1 : DMA feature used + * @retval HAL status + */ +HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma) +{ + uint32_t count32b= 0 , i= 0; + + if (dma == 0) + { + count32b = (len + 3) / 4; + for (i = 0; i < count32b; i++, src += 4) + { + USBx_DFIFO(ch_ep_num) = *((__packed uint32_t *)src); + } + } + return HAL_OK; +} + +/** + * @brief USB_ReadPacket : read a packet from the Tx FIFO associated + * with the EP/channel + * @param USBx : Selected device + * @param src : source pointer + * @param ch_ep_num : endpoint or host channel number + * @param len : Number of bytes to read + * @param dma: USB dma enabled or disabled + * This parameter can be one of these values: + * 0 : DMA feature not used + * 1 : DMA feature used + * @retval pointer to destination buffer + */ +void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len) +{ + uint32_t i=0; + uint32_t count32b = (len + 3) / 4; + + for ( i = 0; i < count32b; i++, dest += 4 ) + { + *(__packed uint32_t *)dest = USBx_DFIFO(0); + + } + return ((void *)dest); +} + +/** + * @brief USB_EPSetStall : set a stall condition over an EP + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep) +{ + if (ep->is_in == 1) + { + if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == 0) + { + USBx_INEP(ep->num)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS); + } + USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_STALL; + } + else + { + if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == 0) + { + USBx_OUTEP(ep->num)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS); + } + USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_STALL; + } + return HAL_OK; +} + + +/** + * @brief USB_EPClearStall : Clear a stall condition over an EP + * @param USBx : Selected device + * @param ep: pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep) +{ + if (ep->is_in == 1) + { + USBx_INEP(ep->num)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL; + if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK) + { + USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */ + } + } + else + { + USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL; + if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK) + { + USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */ + } + } + return HAL_OK; +} + +/** + * @brief USB_StopDevice : Stop the usb device mode + * @param USBx : Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx) +{ + uint32_t i; + + /* Clear Pending interrupt */ + for (i = 0; i < 15 ; i++) + { + USBx_INEP(i)->DIEPINT = 0xFF; + USBx_OUTEP(i)->DOEPINT = 0xFF; + } + USBx_DEVICE->DAINT = 0xFFFFFFFF; + + /* Clear interrupt masks */ + USBx_DEVICE->DIEPMSK = 0; + USBx_DEVICE->DOEPMSK = 0; + USBx_DEVICE->DAINTMSK = 0; + + /* Flush the FIFO */ + USB_FlushRxFifo(USBx); + USB_FlushTxFifo(USBx , 0x10 ); + + return HAL_OK; +} + +/** + * @brief USB_SetDevAddress : Stop the usb device mode + * @param USBx : Selected device + * @param address : new device address to be assigned + * This parameter can be a value from 0 to 255 + * @retval HAL status + */ +HAL_StatusTypeDef USB_SetDevAddress (USB_OTG_GlobalTypeDef *USBx, uint8_t address) +{ + USBx_DEVICE->DCFG &= ~ (USB_OTG_DCFG_DAD); + USBx_DEVICE->DCFG |= (address << 4) & USB_OTG_DCFG_DAD ; + + return HAL_OK; +} + +/** + * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down + * @param USBx : Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_DevConnect (USB_OTG_GlobalTypeDef *USBx) +{ + USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS ; + HAL_Delay(3); + + return HAL_OK; +} + +/** + * @brief USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down + * @param USBx : Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_DevDisconnect (USB_OTG_GlobalTypeDef *USBx) +{ + USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS ; + HAL_Delay(3); + + return HAL_OK; +} + +/** + * @brief USB_ReadInterrupts: return the global USB interrupt status + * @param USBx : Selected device + * @retval HAL status + */ +uint32_t USB_ReadInterrupts (USB_OTG_GlobalTypeDef *USBx) +{ + uint32_t v = 0; + + v = USBx->GINTSTS; + v &= USBx->GINTMSK; + return v; +} + +/** + * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status + * @param USBx : Selected device + * @retval HAL status + */ +uint32_t USB_ReadDevAllOutEpInterrupt (USB_OTG_GlobalTypeDef *USBx) +{ + uint32_t v; + v = USBx_DEVICE->DAINT; + v &= USBx_DEVICE->DAINTMSK; + return ((v & 0xffff0000) >> 16); +} + +/** + * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status + * @param USBx : Selected device + * @retval HAL status + */ +uint32_t USB_ReadDevAllInEpInterrupt (USB_OTG_GlobalTypeDef *USBx) +{ + uint32_t v; + v = USBx_DEVICE->DAINT; + v &= USBx_DEVICE->DAINTMSK; + return ((v & 0xFFFF)); +} + +/** + * @brief Returns Device OUT EP Interrupt register + * @param USBx : Selected device + * @param epnum : endpoint number + * This parameter can be a value from 0 to 15 + * @retval Device OUT EP Interrupt register + */ +uint32_t USB_ReadDevOutEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum) +{ + uint32_t v; + v = USBx_OUTEP(epnum)->DOEPINT; + v &= USBx_DEVICE->DOEPMSK; + return v; +} + +/** + * @brief Returns Device IN EP Interrupt register + * @param USBx : Selected device + * @param epnum : endpoint number + * This parameter can be a value from 0 to 15 + * @retval Device IN EP Interrupt register + */ +uint32_t USB_ReadDevInEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum) +{ + uint32_t v, msk, emp; + + msk = USBx_DEVICE->DIEPMSK; + emp = USBx_DEVICE->DIEPEMPMSK; + msk |= ((emp >> epnum) & 0x1) << 7; + v = USBx_INEP(epnum)->DIEPINT & msk; + return v; +} + +/** + * @brief USB_ClearInterrupts: clear a USB interrupt + * @param USBx : Selected device + * @param interrupt : interrupt flag + * @retval None + */ +void USB_ClearInterrupts (USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt) +{ + USBx->GINTSTS |= interrupt; +} + +/** + * @brief Returns USB core mode + * @param USBx : Selected device + * @retval return core mode : Host or Device + * This parameter can be one of these values: + * 0 : Host + * 1 : Device + */ +uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx) +{ + return ((USBx->GINTSTS ) & 0x1); +} + + +/** + * @brief Activate EP0 for Setup transactions + * @param USBx : Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_ActivateSetup (USB_OTG_GlobalTypeDef *USBx) +{ + /* Set the MPS of the IN EP based on the enumeration speed */ + USBx_INEP(0)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ; + + if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ) + { + USBx_INEP(0)->DIEPCTL |= 3; + } + USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK; + + return HAL_OK; +} + + +/** + * @brief Prepare the EP0 to start the first control setup + * @param USBx : Selected device + * @param dma: USB dma enabled or disabled + * This parameter can be one of these values: + * 0 : DMA feature not used + * 1 : DMA feature used + * @param psetup : pointer to setup packet + * @retval HAL status + */ +HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t dma, uint8_t *psetup) +{ + USBx_OUTEP(0)->DOEPTSIZ = 0; + USBx_OUTEP(0)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) ; + USBx_OUTEP(0)->DOEPTSIZ |= (3 * 8); + USBx_OUTEP(0)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT; + + if (dma == 1) + { + USBx_OUTEP(0)->DOEPDMA = (uint32_t)psetup; + /* EP enable */ + USBx_OUTEP(0)->DOEPCTL = 0x80008000; + } + + return HAL_OK; +} + + +/** + * @brief Reset the USB Core (needed after USB clock settings change) + * @param USBx : Selected device + * @retval HAL status + */ +static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx) +{ + uint32_t count = 0; + + /* Wait for AHB master IDLE state. */ + do + { + if (++count > 200000) + { + return HAL_TIMEOUT; + } + } + while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0); + + /* Core Soft Reset */ + count = 0; + USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; + + do + { + if (++count > 200000) + { + return HAL_TIMEOUT; + } + } + while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST); + + return HAL_OK; +} + + +/** + * @brief USB_HostInit : Initializes the USB OTG controller registers + * for Host mode + * @param USBx : Selected device + * @param cfg : pointer to a USB_OTG_CfgTypeDef structure that contains + * the configuration information for the specified USBx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg) +{ + uint32_t i; + + /* Restart the Phy Clock */ + USBx_PCGCCTL = 0; + + /* Activate VBUS Sensing B */ +#if defined(STM32F446xx) + USBx->GCCFG |= USB_OTG_GCCFG_VBDEN; +#else + USBx->GCCFG &=~ (USB_OTG_GCCFG_VBUSASEN); + USBx->GCCFG &=~ (USB_OTG_GCCFG_VBUSBSEN); + USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; +#endif /* STM32F446xx */ + + /* Disable the FS/LS support mode only */ + if((cfg.speed == USB_OTG_SPEED_FULL)&& + (USBx != USB_OTG_FS)) + { + USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS; + } + else + { + USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS); + } + + /* Make sure the FIFOs are flushed. */ + USB_FlushTxFifo(USBx, 0x10 ); /* all Tx FIFOs */ + USB_FlushRxFifo(USBx); + + /* Clear all pending HC Interrupts */ + for (i = 0; i < cfg.Host_channels; i++) + { + USBx_HC(i)->HCINT = 0xFFFFFFFF; + USBx_HC(i)->HCINTMSK = 0; + } + + /* Enable VBUS driving */ + USB_DriveVbus(USBx, 1); + + HAL_Delay(200); + + /* Disable all interrupts. */ + USBx->GINTMSK = 0; + + /* Clear any pending interrupts */ + USBx->GINTSTS = 0xFFFFFFFF; + + if(USBx == USB_OTG_FS) + { + /* set Rx FIFO size */ + USBx->GRXFSIZ = (uint32_t )0x80; + USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x60 << 16)& USB_OTG_NPTXFD) | 0x80); + USBx->HPTXFSIZ = (uint32_t )(((0x40 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0); + } + else + { + /* set Rx FIFO size */ + USBx->GRXFSIZ = (uint32_t )0x200; + USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x100 << 16)& USB_OTG_NPTXFD) | 0x200); + USBx->HPTXFSIZ = (uint32_t )(((0xE0 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0x300); + } + + /* Enable the common interrupts */ + if (cfg.dma_enable == DISABLE) + { + USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; + } + + /* Enable interrupts matching to the Host mode ONLY */ + USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM |\ + USB_OTG_GINTMSK_SOFM |USB_OTG_GINTSTS_DISCINT|\ + USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM); + + return HAL_OK; +} + +/** + * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the + * HCFG register on the PHY type and set the right frame interval + * @param USBx : Selected device + * @param freq : clock frequency + * This parameter can be one of these values: + * HCFG_48_MHZ : Full Speed 48 MHz Clock + * HCFG_6_MHZ : Low Speed 6 MHz Clock + * @retval HAL status + */ +HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx , uint8_t freq) +{ + USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS); + USBx_HOST->HCFG |= (freq & USB_OTG_HCFG_FSLSPCS); + + if (freq == HCFG_48_MHZ) + { + USBx_HOST->HFIR = (uint32_t)48000; + } + else if (freq == HCFG_6_MHZ) + { + USBx_HOST->HFIR = (uint32_t)6000; + } + return HAL_OK; +} + +/** +* @brief USB_OTG_ResetPort : Reset Host Port + * @param USBx : Selected device + * @retval HAL status + * @note (1)The application must wait at least 10 ms + * before clearing the reset bit. + */ +HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx) +{ + __IO uint32_t hprt0; + + hprt0 = USBx_HPRT0; + + hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ + USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); + + USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0); + HAL_Delay (10); /* See Note #1 */ + USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0); + return HAL_OK; +} + +/** + * @brief USB_DriveVbus : activate or de-activate vbus + * @param state : VBUS state + * This parameter can be one of these values: + * 0 : VBUS Active + * 1 : VBUS Inactive + * @retval HAL status +*/ +HAL_StatusTypeDef USB_DriveVbus (USB_OTG_GlobalTypeDef *USBx, uint8_t state) +{ + __IO uint32_t hprt0; + + hprt0 = USBx_HPRT0; + hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ + USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); + + if (((hprt0 & USB_OTG_HPRT_PPWR) == 0 ) && (state == 1 )) + { + USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0); + } + if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0 )) + { + USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0); + } + return HAL_OK; +} + +/** + * @brief Return Host Core speed + * @param USBx : Selected device + * @retval speed : Host speed + * This parameter can be one of these values: + * @arg USB_OTG_SPEED_HIGH: High speed mode + * @arg USB_OTG_SPEED_FULL: Full speed mode + * @arg USB_OTG_SPEED_LOW: Low speed mode + */ +uint32_t USB_GetHostSpeed (USB_OTG_GlobalTypeDef *USBx) +{ + __IO uint32_t hprt0; + + hprt0 = USBx_HPRT0; + return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17); +} + +/** + * @brief Return Host Current Frame number + * @param USBx : Selected device + * @retval current frame number +*/ +uint32_t USB_GetCurrentFrame (USB_OTG_GlobalTypeDef *USBx) +{ + return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM); +} + +/** + * @brief Initialize a host channel + * @param USBx : Selected device + * @param ch_num : Channel number + * This parameter can be a value from 1 to 15 + * @param epnum : Endpoint number + * This parameter can be a value from 1 to 15 + * @param dev_address : Current device address + * This parameter can be a value from 0 to 255 + * @param speed : Current device speed + * This parameter can be one of these values: + * @arg USB_OTG_SPEED_HIGH: High speed mode + * @arg USB_OTG_SPEED_FULL: Full speed mode + * @arg USB_OTG_SPEED_LOW: Low speed mode + * @param ep_type : Endpoint Type + * This parameter can be one of these values: + * @arg EP_TYPE_CTRL: Control type + * @arg EP_TYPE_ISOC: Isochronous type + * @arg EP_TYPE_BULK: Bulk type + * @arg EP_TYPE_INTR: Interrupt type + * @param mps : Max Packet Size + * This parameter can be a value from 0 to32K + * @retval HAL state + */ +HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, + uint8_t ch_num, + uint8_t epnum, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps) +{ + + /* Clear old interrupt conditions for this host channel. */ + USBx_HC(ch_num)->HCINT = 0xFFFFFFFF; + + /* Enable channel interrupts required for this transfer. */ + switch (ep_type) + { + case EP_TYPE_CTRL: + case EP_TYPE_BULK: + + USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\ + USB_OTG_HCINTMSK_STALLM |\ + USB_OTG_HCINTMSK_TXERRM |\ + USB_OTG_HCINTMSK_DTERRM |\ + USB_OTG_HCINTMSK_AHBERR |\ + USB_OTG_HCINTMSK_NAKM ; + + if (epnum & 0x80) + { + USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM; + } + else + { + if(USBx != USB_OTG_FS) + { + USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM); + } + } + break; + + case EP_TYPE_INTR: + + USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\ + USB_OTG_HCINTMSK_STALLM |\ + USB_OTG_HCINTMSK_TXERRM |\ + USB_OTG_HCINTMSK_DTERRM |\ + USB_OTG_HCINTMSK_NAKM |\ + USB_OTG_HCINTMSK_AHBERR |\ + USB_OTG_HCINTMSK_FRMORM ; + + if (epnum & 0x80) + { + USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM; + } + + break; + case EP_TYPE_ISOC: + + USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\ + USB_OTG_HCINTMSK_ACKM |\ + USB_OTG_HCINTMSK_AHBERR |\ + USB_OTG_HCINTMSK_FRMORM ; + + if (epnum & 0x80) + { + USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM); + } + break; + } + + /* Enable the top level host channel interrupt. */ + USBx_HOST->HAINTMSK |= (1 << ch_num); + + /* Make sure host channel interrupts are enabled. */ + USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM; + + /* Program the HCCHAR register */ + USBx_HC(ch_num)->HCCHAR = (((dev_address << 22) & USB_OTG_HCCHAR_DAD) |\ + (((epnum & 0x7F)<< 11) & USB_OTG_HCCHAR_EPNUM)|\ + ((((epnum & 0x80) == 0x80)<< 15) & USB_OTG_HCCHAR_EPDIR)|\ + (((speed == HPRT0_PRTSPD_LOW_SPEED)<< 17) & USB_OTG_HCCHAR_LSDEV)|\ + ((ep_type << 18) & USB_OTG_HCCHAR_EPTYP)|\ + (mps & USB_OTG_HCCHAR_MPSIZ)); + + if (ep_type == EP_TYPE_INTR) + { + USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ; + } + + return HAL_OK; +} + +/** + * @brief Start a transfer over a host channel + * @param USBx : Selected device + * @param hc : pointer to host channel structure + * @param dma: USB dma enabled or disabled + * This parameter can be one of these values: + * 0 : DMA feature not used + * 1 : DMA feature used + * @retval HAL state + */ +//#if defined (__CC_ARM) /*!< ARM Compiler */ +//#pragma O0 +//#elif defined (__GNUC__) /*!< GNU Compiler */ +//#pragma GCC optimize ("O0") +//#endif /* __CC_ARM */ +HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma) +{ + uint8_t is_oddframe = 0; + uint16_t num_packets = 0; + uint16_t max_hc_pkt_count = 256; + uint32_t tmpreg = 0; + + if((USBx != USB_OTG_FS) && (hc->speed == USB_OTG_SPEED_HIGH)) + { + if((dma == 0) && (hc->do_ping == 1)) + { + USB_DoPing(USBx, hc->ch_num); + return HAL_OK; + } + else if(dma == 1) + { + USBx_HC(hc->ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM); + hc->do_ping = 0; + } + } + + /* Compute the expected number of packets associated to the transfer */ + if (hc->xfer_len > 0) + { + num_packets = (hc->xfer_len + hc->max_packet - 1) / hc->max_packet; + + if (num_packets > max_hc_pkt_count) + { + num_packets = max_hc_pkt_count; + hc->xfer_len = num_packets * hc->max_packet; + } + } + else + { + num_packets = 1; + } + hc->packet_count = (uint8_t)num_packets; + + if (hc->ep_is_in) + { + hc->xfer_len = num_packets * hc->max_packet; + } + + /* Initialize the HCTSIZn register */ + USBx_HC(hc->ch_num)->HCTSIZ = (((hc->xfer_len) & USB_OTG_HCTSIZ_XFRSIZ)) |\ + ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\ + (((hc->data_pid) << 29) & USB_OTG_HCTSIZ_DPID); + + if (dma) + { + /* xfer_buff MUST be 32-bits aligned */ + USBx_HC(hc->ch_num)->HCDMA = (uint32_t)hc->xfer_buff; + } + + is_oddframe = (USBx_HOST->HFNUM & 0x01) ? 0 : 1; + USBx_HC(hc->ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM; + USBx_HC(hc->ch_num)->HCCHAR |= (is_oddframe << 29); + + /* Set host channel enable */ + tmpreg = USBx_HC(hc->ch_num)->HCCHAR; + tmpreg &= ~USB_OTG_HCCHAR_CHDIS; + tmpreg |= USB_OTG_HCCHAR_CHENA; + USBx_HC(hc->ch_num)->HCCHAR = tmpreg; + + if (dma == 0) /* Slave mode */ + { + if((hc->ep_is_in == 0) && (hc->xfer_len > 0)) + { + + switch(hc->ep_type) + { + /* Non periodic transfer */ + case EP_TYPE_CTRL: + case EP_TYPE_BULK: + + if (USB_HC_WriteEmptyTxFifo(USBx, hc, 0) == HAL_BUSY) + { + while (1); +//If transaction doesn't fit in fifo, enable interrupt like so: +// USB_UNMASK_INTERRUPT(USBx, USB_OTG_GINTMSK_NPTXFEM); + } + break; + + /* Periodic transfer */ + case EP_TYPE_INTR: + case EP_TYPE_ISOC: + + if (USB_HC_WriteEmptyTxFifo(USBx, hc, 1) == HAL_BUSY) + { + while (1); +//If transaction doesn't fit in fifo, enable interrupt like so: +// USB_UNMASK_INTERRUPT(USBx, USB_OTG_GINTMSK_PTXFEM); + } + break; + + default: + break; + } + } + } + + return HAL_OK; +} + + + + +HAL_StatusTypeDef USB_HC_WriteEmptyTxFifo(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t periodic) +{ + int32_t len; + uint32_t len32b; + + + while (1) + { + len = hc->xfer_len - hc->xfer_count; + if (len > hc->max_packet) + { + len = hc->max_packet; + } + if (len <= 0) + { + return HAL_OK; //transfer complete + } + + len32b = (len + 3) / 4; + if (periodic == 0) + { + if ((len32b > (USBx->HNPTXSTS & 0xFFFF)) || + (((USBx->HNPTXSTS >> HxTXSTS_xTXQSAV_SHIFT) & HxTXSTS_xTXQSAV_MASK) == 0)) + { + return HAL_BUSY; //fifo is full + } + } + else + { + if ((len32b > (USBx_HOST->HPTXSTS & 0xFFFF)) || + (((USBx_HOST->HPTXSTS >> HxTXSTS_xTXQSAV_SHIFT) & HxTXSTS_xTXQSAV_MASK) == 0)) + { + return HAL_BUSY; //fifo is full + } + } + + /* Write packet into the Tx FIFO. */ + USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, len, 0); + + hc->xfer_count += len; + hc->xfer_buff += len; + } +} + + +/** + * @brief Read all host channel interrupts status + * @param USBx : Selected device + * @retval HAL state + */ +uint32_t USB_HC_ReadInterrupt (USB_OTG_GlobalTypeDef *USBx) +{ + return ((USBx_HOST->HAINT) & 0xFFFF); +} + +/** + * @brief Halt a host channel + * @param USBx : Selected device + * @param hc_num : Host Channel number + * This parameter can be a value from 1 to 15 + * @retval HAL state + */ +HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num) +{ + uint32_t count = 0; + + /* Check for space in the request queue to issue the halt. */ + if (((USBx_HC(hc_num)->HCCHAR) & (HCCHAR_CTRL << 18)) || ((USBx_HC(hc_num)->HCCHAR) & (HCCHAR_BULK << 18))) + { + USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS; + + if ((USBx->HNPTXSTS & 0xFFFF) == 0) + { + USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA; + USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA; + USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR; + do + { + if (++count > 1000) + { + break; + } + } + while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA); + } + else + { + USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA; + } + } + else + { + USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS; + + if ((USBx_HOST->HPTXSTS & 0xFFFF) == 0) + { + USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA; + USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA; + USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR; + do + { + if (++count > 1000) + { + break; + } + } + while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA); + } + else + { + USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA; + } + } + + return HAL_OK; +} + +/** + * @brief Initiate Do Ping protocol + * @param USBx : Selected device + * @param hc_num : Host Channel number + * This parameter can be a value from 1 to 15 + * @retval HAL state + */ +HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx , uint8_t ch_num) +{ + uint8_t num_packets = 1; + uint32_t tmpreg = 0; + + USBx_HC(ch_num)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\ + USB_OTG_HCTSIZ_DOPING; + + /* Set host channel enable */ + tmpreg = USBx_HC(ch_num)->HCCHAR; + tmpreg &= ~USB_OTG_HCCHAR_CHDIS; + tmpreg |= USB_OTG_HCCHAR_CHENA; + USBx_HC(ch_num)->HCCHAR = tmpreg; + + return HAL_OK; +} + +/** + * @brief Stop Host Core + * @param USBx : Selected device + * @retval HAL state + */ +HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx) +{ + uint8_t i; + uint32_t count = 0; + uint32_t value; + + USB_DisableGlobalInt(USBx); + + /* Flush FIFO */ + USB_FlushTxFifo(USBx, 0x10); + USB_FlushRxFifo(USBx); + + /* Flush out any leftover queued requests. */ + for (i = 0; i <= 15; i++) + { + + value = USBx_HC(i)->HCCHAR ; + value |= USB_OTG_HCCHAR_CHDIS; + value &= ~USB_OTG_HCCHAR_CHENA; + value &= ~USB_OTG_HCCHAR_EPDIR; + USBx_HC(i)->HCCHAR = value; + } + + /* Halt all channels to put them into a known state. */ + for (i = 0; i <= 15; i++) + { + value = USBx_HC(i)->HCCHAR ; + + value |= USB_OTG_HCCHAR_CHDIS; + value |= USB_OTG_HCCHAR_CHENA; + value &= ~USB_OTG_HCCHAR_EPDIR; + + USBx_HC(i)->HCCHAR = value; + do + { + if (++count > 1000) + { + break; + } + } + while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA); + } + + /* Clear any pending Host interrupts */ + USBx_HOST->HAINT = 0xFFFFFFFF; + USBx->GINTSTS = 0xFFFFFFFF; + USB_EnableGlobalInt(USBx); + return HAL_OK; +} +/** + * @} + */ + +#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/