/** **************************************************************************************************** * @file fm33lg0xx_fl_uart.c * @author FMSH Application Team * @brief Src file of UART FL Module **************************************************************************************************** * @attention * * Copyright (c) [2020] [Fudan Microelectronics] * THIS SOFTWARE is licensed under the Mulan PSL v1. * can use this software according to the terms and conditions of the Mulan PSL v1. * You may obtain a copy of Mulan PSL v1 at: * http://license.coscl.org.cn/MulanPSL * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR * PURPOSE. * See the Mulan PSL v1 for more details. * **************************************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "fm33lg0xx_fl.h" /** @addtogroup FM33LG0XX_FL_Driver * @{ */ /** @addtogroup UART * @{ */ #ifdef FL_UART_DRIVER_ENABLED /* Private macros ------------------------------------------------------------*/ /** @addtogroup UART_FL_Private_Macros * @{ */ #define IS_UART_INSTANCE(INSTANCE) (((INSTANCE) == UART0)||\ ((INSTANCE) == UART1)||\ ((INSTANCE) == UART3)||\ ((INSTANCE) == UART4)||\ ((INSTANCE) == UART5)) #define IS_FL_UART_CLKSRC(__VALUE__) (((__VALUE__) == FL_CMU_UART0_CLK_SOURCE_APBCLK)||\ ((__VALUE__) == FL_CMU_UART0_CLK_SOURCE_RCHF)||\ ((__VALUE__) == FL_CMU_UART0_CLK_SOURCE_SYSCLK)||\ ((__VALUE__) == FL_CMU_UART0_CLK_SOURCE_XTHF)||\ ((__VALUE__) == FL_CMU_UART1_CLK_SOURCE_APBCLK)||\ ((__VALUE__) == FL_CMU_UART1_CLK_SOURCE_RCHF)||\ ((__VALUE__) == FL_CMU_UART1_CLK_SOURCE_SYSCLK)||\ ((__VALUE__) == FL_CMU_UART1_CLK_SOURCE_XTHF)) #define IS_FL_UART_DATAWIDTH(__VALUE__) (((__VALUE__) == FL_UART_DATA_WIDTH_6B)||\ ((__VALUE__) == FL_UART_DATA_WIDTH_7B)||\ ((__VALUE__) == FL_UART_DATA_WIDTH_8B)||\ ((__VALUE__) == FL_UART_DATA_WIDTH_9B)) #define IS_FL_UART_STOPBITS(__VALUE__) (((__VALUE__) == FL_UART_STOP_BIT_WIDTH_1B)||\ ((__VALUE__) == FL_UART_STOP_BIT_WIDTH_2B)) #define IS_FL_UART_PARITY(__VALUE__) (((__VALUE__) == FL_UART_PARITY_NONE)||\ ((__VALUE__) == FL_UART_PARITY_EVEN)||\ ((__VALUE__) == FL_UART_PARITY_ODD)) #define IS_FL_UART_DIRECTION(__VALUE__) (((__VALUE__) == FL_UART_DIRECTION_NONE)||\ ((__VALUE__) == FL_UART_DIRECTION_RX)||\ ((__VALUE__) == FL_UART_DIRECTION_TX)||\ ((__VALUE__) == FL_UART_DIRECTION_TX_RX)) #define IS_FL_UART_INFRA_MODULATION(__VALUE__) (((__VALUE__) == FL_DISABLE)||\ ((__VALUE__) == FL_ENABLE)) #define IS_FL_UART_INFRARED_POLARITY(__VALUE__) (((__VALUE__) == FL_UART_INFRARED_POLARITY_NORMAL)||\ ((__VALUE__) == FL_UART_INFRARED_POLARITY_INVERT)) #define IS_FL_UART_INFRARED_MODULATION_DUTY(__VALUE__) (((__VALUE__) <= 100)) /** * @} */ /* Exported functions --------------------------------------------------------*/ /** @addtogroup UART_FL_EF_Init * @{ */ /** * @brief 复位UART 外设寄存器值为复位值 * @param 外设入口地址 * @retval 返回错误状态,可能值: * -FL_PASS 外设寄存器值恢复复位值 * -FL_FAIL 复位未成功 */ FL_ErrorStatus FL_UART_DeInit(UART_Type *UARTx) { FL_ErrorStatus status = FL_PASS; /* 参数入口合法性 */ assert_param(IS_UART_INSTANCE(UARTx)); /* 外设复位使能 */ FL_RMU_EnablePeripheralReset(RMU); if(UARTx == UART0) { /*复位UART*/ FL_RMU_EnableResetAPBPeripheral(RMU, FL_RMU_RSTAPB_UART0); FL_RMU_DisableResetAPBPeripheral(RMU, FL_RMU_RSTAPB_UART0); /* 外设总线时钟关闭 */ FL_CMU_DisableGroup3BusClock(FL_CMU_GROUP3_BUSCLK_UART0); /* 外设工作时钟关闭 */ FL_CMU_DisableGroup3OperationClock(FL_CMU_GROUP3_OPCLK_UART0); } else if(UARTx == UART1) { /*复位UART*/ FL_RMU_EnableResetAPBPeripheral(RMU, FL_RMU_RSTAPB_UART1); FL_RMU_DisableResetAPBPeripheral(RMU, FL_RMU_RSTAPB_UART1); /* 外设总线时钟关闭 */ FL_CMU_DisableGroup3BusClock(FL_CMU_GROUP3_BUSCLK_UART1); /* 外设工作时钟关闭 */ FL_CMU_DisableGroup3OperationClock(FL_CMU_GROUP3_OPCLK_UART1); } else if(UARTx == UART3) { /*复位UART*/ FL_RMU_EnableResetAPBPeripheral(RMU, FL_RMU_RSTAPB_UART3); FL_RMU_DisableResetAPBPeripheral(RMU, FL_RMU_RSTAPB_UART3); /* UART3、4、5为单时钟,关闭总线时钟 */ FL_CMU_DisableGroup3BusClock(FL_CMU_GROUP3_BUSCLK_UART3); } else if(UARTx == UART4) { /*复位UART*/ FL_RMU_EnableResetAPBPeripheral(RMU, FL_RMU_RSTAPB_UART4); FL_RMU_DisableResetAPBPeripheral(RMU, FL_RMU_RSTAPB_UART4); /* 总线、工作时钟关闭 */ FL_CMU_DisableGroup3BusClock(FL_CMU_GROUP3_BUSCLK_UART4); } else if(UARTx == UART5) { /*复位UART*/ FL_RMU_EnableResetAPBPeripheral(RMU, FL_RMU_RSTAPB_UART5); FL_RMU_DisableResetAPBPeripheral(RMU, FL_RMU_RSTAPB_UART5); /* 总线(工作)时钟关闭 */ FL_CMU_DisableGroup3BusClock(FL_CMU_GROUP3_BUSCLK_UART5); } else { status = FL_FAIL; } /* 锁定外设复位功能 */ FL_RMU_DisablePeripheralReset(RMU); return (status); } /** * @brief 根据需要配置UART * * @param UARTx 外设入口地址 * @param UART_InitStruct指向一个FL_UART_InitTypeDef类型的结构体,它包含外设UART的配置信息 * * @retval ErrorStatus枚举值 * -FL_FAIL 配置过程发生错误 * -FL_PASS UART配置成功 */ FL_ErrorStatus FL_UART_Init(UART_Type *UARTx, FL_UART_InitTypeDef *initStruct) { FL_ErrorStatus status = FL_FAIL; uint32_t Fclk = 0, BaudRate = 0; /* 参数合法性检查 */ assert_param(IS_UART_INSTANCE(UARTx)); assert_param(IS_FL_UART_CLKSRC(initStruct->clockSrc)); assert_param(IS_FL_UART_DATAWIDTH(initStruct->dataWidth)); assert_param(IS_FL_UART_PARITY(initStruct->parity)); assert_param(IS_FL_UART_STOPBITS(initStruct->stopBits)); assert_param(IS_FL_UART_DIRECTION(initStruct->transferDirection)); if(UARTx == UART0) { /*时钟源选择*/ FL_CMU_SetUART0ClockSource(initStruct->clockSrc); /* 根据不同的时钟源计算baudrate 寄存器值,并配置 */ switch(initStruct->clockSrc) { case FL_CMU_UART0_CLK_SOURCE_APBCLK: Fclk = FL_CMU_GetAPBClockFreq(); break; case FL_CMU_UART0_CLK_SOURCE_RCHF: Fclk = FL_CMU_GetRCHFClockFreq(); break; case FL_CMU_UART0_CLK_SOURCE_SYSCLK: Fclk = FL_CMU_GetSystemClockFreq(); break; case FL_CMU_UART0_CLK_SOURCE_XTHF: Fclk = XTHFClock; break; default: Fclk = FL_CMU_GetAPBClockFreq(); break; } BaudRate = Fclk / initStruct->baudRate - 1; } if(UARTx == UART1) { /*时钟源选择*/ FL_CMU_SetUART1ClockSource(initStruct->clockSrc); /* 根据不同的时钟源计算baudrate 寄存器值,并配置 */ switch(initStruct->clockSrc) { case FL_CMU_UART1_CLK_SOURCE_APBCLK: Fclk = FL_CMU_GetAPBClockFreq(); break; case FL_CMU_UART1_CLK_SOURCE_RCHF: Fclk = FL_CMU_GetRCHFClockFreq(); break; case FL_CMU_UART1_CLK_SOURCE_SYSCLK : Fclk = FL_CMU_GetSystemClockFreq(); break; case FL_CMU_UART1_CLK_SOURCE_XTHF: Fclk = XTHFClock; break; default: Fclk = FL_CMU_GetAPBClockFreq(); break; } BaudRate = Fclk / initStruct->baudRate - 1; } if(UARTx == UART0) { FL_CMU_EnableGroup3BusClock(FL_CMU_GROUP3_BUSCLK_UART0); FL_CMU_EnableGroup3OperationClock(FL_CMU_GROUP3_OPCLK_UART0); } else if(UARTx == UART1) { FL_CMU_EnableGroup3BusClock(FL_CMU_GROUP3_BUSCLK_UART1); FL_CMU_EnableGroup3OperationClock(FL_CMU_GROUP3_OPCLK_UART1); } else if(UARTx == UART3) { FL_CMU_EnableGroup3BusClock(FL_CMU_GROUP3_BUSCLK_UART3); Fclk = FL_CMU_GetAPBClockFreq(); BaudRate = Fclk / initStruct->baudRate - 1; } else if(UARTx == UART4) { FL_CMU_EnableGroup3BusClock(FL_CMU_GROUP3_BUSCLK_UART4); Fclk = FL_CMU_GetAPBClockFreq(); BaudRate = Fclk / initStruct->baudRate - 1; } else if(UARTx == UART5) { FL_CMU_EnableGroup3BusClock(FL_CMU_GROUP3_BUSCLK_UART5); Fclk = FL_CMU_GetAPBClockFreq(); BaudRate = Fclk / initStruct->baudRate - 1; } /*发送接收控制*/ if(initStruct->transferDirection & FL_UART_DIRECTION_TX) { FL_UART_EnableTX(UARTx); } if(initStruct->transferDirection & FL_UART_DIRECTION_RX) { FL_UART_EnableRX(UARTx); } /*配置波特率*/ FL_UART_WriteBaudRate(UARTx, BaudRate); /*配置停止位长度*/ FL_UART_SetStopBitsWidth(UARTx, initStruct->stopBits); /*数据长度*/ FL_UART_SetDataWidth(UARTx, initStruct->dataWidth); /*配置奇偶校验*/ FL_UART_SetParity(UARTx, initStruct->parity); status = FL_PASS; return status; } /** * @brief 根据需要配置红外调制寄存器 * * @param UARTx 外设入口地址 * * @param initStruct指向FL_UART_InitTypeDef类型的结构体,包含UART外设信息 * * @retval ErrorStatus枚举值 * -FL_FAIL 配置过程出现错误 * -FL_PASS UART配置成功 */ FL_ErrorStatus FL_UART_InfraRed_Init(UART_Type *UARTx, FL_UART_InfraRed_InitTypeDef *initStruct) { FL_ErrorStatus status = FL_FAIL; uint32_t tempTZBRG = 0, tempTH = 0; /* 参数合法性检查 */ assert_param(IS_UART_INSTANCE(UARTx)); assert_param(IS_FL_UART_INFRARED_POLARITY(initStruct->polarity)); assert_param(IS_FL_UART_INFRARED_MODULATION_DUTY(initStruct->modulationDuty)); /*红外发送总线时钟使能*/ FL_CMU_EnableGroup3BusClock(FL_CMU_GROUP3_BUSCLK_UARTIR); /*红外发送使能*/ FL_UART_EnableIRModulation(UARTx); /*红外调制极性*/ FL_UART_SetIRPolarity(UART, initStruct->polarity); /*红外调制频率*/ tempTZBRG = (uint32_t)((FL_CMU_GetAPBClockFreq() * 1.0) / initStruct->modulationFrequency - 1); /* 调制占空比 */ if((tempTZBRG >> 4) != 0) { tempTH = (uint32_t)(((float)initStruct->modulationDuty / 100.0f) * ((float)(tempTZBRG + 1) / (float)(tempTZBRG >> 4)) + 0.5f); } else { tempTH = (uint32_t)(((float)initStruct->modulationDuty / 100.0f) * (float)(tempTZBRG + 1) + 0.5f); } /* 占空比限位到小于95%,否则结果会有问题 */ tempTH = ((float)((tempTZBRG >> 4) * tempTH) / (float)(tempTZBRG + 1)) < 0.95f ? tempTH : tempTH - 1; /* 占空比和调制频率配置 */ FL_UART_WriteIRModulationDuty(UART, tempTH); FL_UART_WriteIRModulationFrequency(UART, tempTZBRG); status = FL_PASS; return status; } /** * @brief UART_InitStruct 为默认配置 * @param UART_InitStruct 指向需要将值设置为默认配置 的结构体@ref FL_UART_InitTypeDef structure 结构体 * * @retval None */ void FL_UART_InfraRed_StructInit(FL_UART_InfraRed_InitTypeDef *initStruct) { initStruct->polarity = FL_UART_INFRARED_POLARITY_NORMAL; initStruct->modulationDuty = 50; initStruct->modulationFrequency = 38000; } /** * @brief UART_InitStruct 为默认配置 * @param UART_InitStruct 指向需要将值设置为默认配置 的结构体@ref FL_UART_InitTypeDef structure 结构体 * 结构体 * @retval None */ void FL_UART_StructInit(FL_UART_InitTypeDef *initStruct) { initStruct->baudRate = 115200; initStruct->dataWidth = FL_UART_DATA_WIDTH_8B; initStruct->stopBits = FL_UART_STOP_BIT_WIDTH_1B; initStruct->parity = FL_UART_PARITY_EVEN ; initStruct->transferDirection = FL_UART_DIRECTION_TX_RX; initStruct->clockSrc = 0; } /** * @} */ #endif /* FL_UART_DRIVER_ENABLED */ /** * @} */ /** * @} */ /*************************(C) COPYRIGHT Fudan Microelectronics **** END OF FILE*************************/