/* This file combines several STM32F4 HAL Functions into one file. This was done for space reasons, to avoid having several MB of HAL functions that most people will not use. In addition this HAL is slightly less demanding (no interrupts), but less robust as doesn't implement the timeouts. The original HAL files are COPYRIGHT STMicroelectronics, as shown below: */ /* * COPYRIGHT(c) 2017 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. * ****************************************************************************** */ #include "stm32f2_hal.h" #include "stm32f2_hal_lowlevel.h" #include "stm32f2xx_hal_rcc.h" #include "stm32f2xx_hal_gpio.h" #include "stm32f2xx_hal_dma.h" #include "stm32f2xx_hal_uart.h" #include "stm32f2xx_hal_flash.h" #define assert_param(expr) ((void)0U) uint32_t HAL_GetTick(void) { static uint32_t tick; return tick++;; } #define RCC_CFGR_HPRE_BITNUMBER POSITION_VAL(RCC_CFGR_HPRE) #define CLOCKSWITCH_TIMEOUT_VALUE ((uint32_t)5000U) /* 5 s */ const uint8_t APBAHBPrescTable[16] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; #define UART_CR1_FIELDS ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | \ USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8)) /*!< UART or USART CR1 fields of parameters set by UART_SetConfig API */ uint32_t HAL_RCC_GetSysClockFreq(void) { return 7372800U; } uint32_t HAL_RCC_GetPCLK1Freq(void) { return 7372800U; } HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) { uint32_t tickstart = 0U; /* 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 { /* 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 enable */ tickstart = HAL_GetTick(); while((PWR->CR & PWR_CR_DBP) == RESET) { if((HAL_GetTick() - tickstart ) > RCC_DBP_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 ) > 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 >> 1U) - 1U) << 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; } HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency) { uint32_t tickstart = 0U; /* 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 number of wait states because of higher 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) { /* 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 { while(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI) { if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE) { return HAL_TIMEOUT; } } } } /* Decreasing the number of wait states because of lower 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; } } /*-------------------------- 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) << 3U)); } /* Update the SystemCoreClock global variable */ //SystemCoreClock = HAL_RCC_GetSysClockFreq() >> APBAHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> POSITION_VAL(RCC_CFGR_HPRE)]; /* Configure the source of time base considering new system clocks settings*/ //HAL_InitTick (TICK_INT_PRIORITY); return HAL_OK; } /** * @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()>> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2)>> POSITION_VAL(RCC_CFGR_PPRE2)]); return 7372800; } #define GPIO_MODE ((uint32_t)0x00000003U) #define EXTI_MODE ((uint32_t)0x10000000U) #define GPIO_MODE_IT ((uint32_t)0x00010000U) #define GPIO_MODE_EVT ((uint32_t)0x00020000U) #define RISING_EDGE ((uint32_t)0x00100000U) #define FALLING_EDGE ((uint32_t)0x00200000U) #define GPIO_OUTPUT_TYPE ((uint32_t)0x00000010U) #define GPIO_NUMBER ((uint32_t)16U) #define __HAL_RCC_GPIOA_CLK_ENABLE() do { \ __IO uint32_t tmpreg = 0x00U; \ 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) void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) { uint32_t position; uint32_t ioposition = 0x00U; uint32_t iocurrent = 0x00U; uint32_t temp = 0x00U; /* 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 = 0U; position < GPIO_NUMBER; position++) { /* Get the IO position */ ioposition = ((uint32_t)0x01U) << 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 >> 3U]; temp &= ~((uint32_t)0xFU << ((uint32_t)(position & (uint32_t)0x07U) * 4U)) ; temp |= ((uint32_t)(GPIO_Init->Alternate) << (((uint32_t)position & (uint32_t)0x07U) * 4U)); GPIOx->AFR[position >> 3U] = temp; } /* Configure IO Direction mode (Input, Output, Alternate or Analog) */ temp = GPIOx->MODER; temp &= ~(GPIO_MODER_MODER0 << (position * 2U)); temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2U)); 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 * 2U)); temp |= (GPIO_Init->Speed << (position * 2U)); GPIOx->OSPEEDR = temp; /* Configure the IO Output Type */ temp = GPIOx->OTYPER; temp &= ~(GPIO_OTYPER_OT_0 << position) ; temp |= (((GPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4U) << position); GPIOx->OTYPER = temp; } /* Activate the Pull-up or Pull down resistor for the current IO */ temp = GPIOx->PUPDR; temp &= ~(GPIO_PUPDR_PUPDR0 << (position * 2U)); temp |= ((GPIO_Init->Pull) << (position * 2U)); 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 >> 2U]; temp &= ~(((uint32_t)0x0FU) << (4U * (position & 0x03))); temp |= ((uint32_t)(GPIO_GET_INDEX(GPIOx)) << (4U * (position & 0x03U))); SYSCFG->EXTICR[position >> 2U] = 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; } } } } 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 << 16U; } } static void UART_SetConfig(UART_HandleTypeDef *huart) { uint32_t tmpreg = 0x00U; /* 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 */ WRITE_REG(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 */ WRITE_REG(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 */ WRITE_REG(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); } } } 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->gState == HAL_UART_STATE_RESET) { /* Allocate lock resource and initialize it */ huart->Lock = HAL_UNLOCKED; /* Init the low level hardware */ //HAL_UART_MspInit(huart); } huart->gState = 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.*/ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); CLEAR_BIT(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->gState= HAL_UART_STATE_READY; huart->RxState= HAL_UART_STATE_READY; return HAL_OK; } static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout) { /* Wait until flag is set */ while((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status) { /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) { /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */ CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE)); CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); huart->gState = HAL_UART_STATE_READY; huart->RxState = HAL_UART_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(huart); return HAL_TIMEOUT; } } } return HAL_OK; } HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) { uint16_t* tmp; uint32_t tickstart = 0U; /* Check that a Tx process is not already ongoing */ if(huart->gState == HAL_UART_STATE_READY) { if((pData == NULL ) || (Size == 0U)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(huart); huart->ErrorCode = HAL_UART_ERROR_NONE; huart->gState = HAL_UART_STATE_BUSY_TX; /* Init tickstart for timeout managment */ tickstart = HAL_GetTick(); huart->TxXferSize = Size; huart->TxXferCount = Size; while(huart->TxXferCount > 0U) { huart->TxXferCount--; if(huart->Init.WordLength == UART_WORDLENGTH_9B) { if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) { return HAL_TIMEOUT; } tmp = (uint16_t*) pData; huart->Instance->DR = (*tmp & (uint16_t)0x01FFU); if(huart->Init.Parity == UART_PARITY_NONE) { pData +=2; } else { pData +=1; } } else { if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK) { return HAL_TIMEOUT; } huart->Instance->DR = (*pData++ & (uint8_t)0xFFU); } } if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK) { return HAL_TIMEOUT; } /* At end of Tx process, restore huart->gState to Ready */ huart->gState = HAL_UART_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(huart); return HAL_OK; } else { return HAL_BUSY; } } HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout) { uint16_t* tmp; uint32_t tickstart = 0U; /* Check that a Rx process is not already ongoing */ if(huart->RxState == HAL_UART_STATE_READY) { if((pData == NULL ) || (Size == 0U)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(huart); huart->ErrorCode = HAL_UART_ERROR_NONE; huart->RxState = HAL_UART_STATE_BUSY_RX; /* Init tickstart for timeout managment */ tickstart = HAL_GetTick(); huart->RxXferSize = Size; huart->RxXferCount = Size; /* Check the remain data to be received */ while(huart->RxXferCount > 0U) { huart->RxXferCount--; if(huart->Init.WordLength == UART_WORDLENGTH_9B) { if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, 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)0x01FFU); pData +=2; } else { *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FFU); pData +=1; } } else { if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK) { return HAL_TIMEOUT; } if(huart->Init.Parity == UART_PARITY_NONE) { *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FFU); } else { *pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007FU); } } } /* At end of Rx process, restore huart->RxState to Ready */ huart->RxState = HAL_UART_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(huart); return HAL_OK; } else { return HAL_BUSY; } }