1 /**
2 ****************************************************************************************************
3 * @file fm33lc0xx_fl_uart.c
4 * @author FMSH Application Team
5 * @brief Src file of UART FL Module
6 ****************************************************************************************************
7 * @attention
8 *
9 * Copyright (c) [2021] [Fudan Microelectronics]
10 * THIS SOFTWARE is licensed under Mulan PSL v2.
11 * You can use this software according to the terms and conditions of the Mulan PSL v2.
12 * You may obtain a copy of Mulan PSL v2 at:
13 * http://license.coscl.org.cn/MulanPSL2
14 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
15 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
16 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
17 * See the Mulan PSL v2 for more details.
18 *
19 ****************************************************************************************************
20 */
21
22
23 /* Includes ------------------------------------------------------------------*/
24 #include "fm33lc0xx_fl.h"
25
26 /** @addtogroup FM33LC0XX_FL_Driver
27 * @{
28 */
29
30 /** @addtogroup UART
31 * @{
32 */
33
34 #ifdef FL_UART_DRIVER_ENABLED
35
36 /* Private macros ------------------------------------------------------------*/
37 /** @addtogroup UART_FL_Private_Macros
38 * @{
39 */
40
41
42 #define IS_UART_INSTANCE(INSTANCE) (((INSTANCE) == UART0)||\
43 ((INSTANCE) == UART1)||\
44 ((INSTANCE) == UART4)||\
45 ((INSTANCE) == UART5))
46
47 #define IS_FL_UART_CLKSRC(__VALUE__) (((__VALUE__) == FL_RCC_UART1_CLK_SOURCE_APB1CLK)||\
48 ((__VALUE__) == FL_RCC_UART1_CLK_SOURCE_RCHF)||\
49 ((__VALUE__) == FL_RCC_UART1_CLK_SOURCE_SYSCLK)||\
50 ((__VALUE__) == FL_RCC_UART1_CLK_SOURCE_RCMF_PSC)||\
51 ((__VALUE__) == FL_RCC_UART0_CLK_SOURCE_APB1CLK)||\
52 ((__VALUE__) == FL_RCC_UART0_CLK_SOURCE_RCHF)||\
53 ((__VALUE__) == FL_RCC_UART0_CLK_SOURCE_SYSCLK)||\
54 ((__VALUE__) == FL_RCC_UART0_CLK_SOURCE_RCMF_PSC))
55
56
57 #define IS_FL_UART_DATAWIDTH(__VALUE__) (((__VALUE__) == FL_UART_DATA_WIDTH_7B)||\
58 ((__VALUE__) == FL_UART_DATA_WIDTH_8B)||\
59 ((__VALUE__) == FL_UART_DATA_WIDTH_9B)||\
60 ((__VALUE__) == FL_UART_DATA_WIDTH_6B))
61
62 #define IS_FL_UART_STOPBITS(__VALUE__) (((__VALUE__) == FL_UART_STOP_BIT_WIDTH_1B)||\
63 ((__VALUE__) == FL_UART_STOP_BIT_WIDTH_2B))
64
65 #define IS_FL_UART_PARITY(__VALUE__) (((__VALUE__) == FL_UART_PARITY_NONE)||\
66 ((__VALUE__) == FL_UART_PARITY_EVEN)||\
67 ((__VALUE__) == FL_UART_PARITY_ODD))
68
69 #define IS_FL_UART_DIRECTION(__VALUE__) (((__VALUE__) == FL_UART_DIRECTION_NONE)||\
70 ((__VALUE__) == FL_UART_DIRECTION_RX)||\
71 ((__VALUE__) == FL_UART_DIRECTION_TX)||\
72 ((__VALUE__) == FL_UART_DIRECTION_TX_RX))
73
74 #define IS_FL_UART_INFRA_MODULATION(__VALUE__) (((__VALUE__) == FL_DISABLE)||\
75 ((__VALUE__) == FL_ENABLE))
76
77
78 #define IS_FL_UART_INFRARED_POLARITY(__VALUE__) (((__VALUE__) == FL_UART_INFRARED_POLARITY_NORMAL)||\
79 ((__VALUE__) == FL_UART_INFRARED_POLARITY_INVERT))
80
81 #define IS_FL_UART_INFRARED_MODULATION_DUTY(__VALUE__) (((__VALUE__) <= 100))
82
83
84 /**
85 * @}
86 */
87
88 /** @addtogroup UART_FL_EF_Init
89 * @{
90 */
91
92 /**
93 * @brief 复位UART外设
94 * @param UARTx 外设入口地址
95 * @retval 错误状态,可能值:
96 * -FL_PASS 外设寄存器值恢复复位值
97 * -FL_FAIL 复位未成功
98 */
FL_UART_DeInit(UART_Type * UARTx)99 FL_ErrorStatus FL_UART_DeInit(UART_Type *UARTx)
100 {
101 FL_ErrorStatus status = FL_PASS;
102 /* 参数入口合法性 */
103 assert_param(IS_UART_INSTANCE(UARTx));
104 /* 外设复位使能 */
105 FL_RCC_EnablePeripheralReset();
106 if(UARTx == UART0)
107 {
108 /*复位UART*/
109 FL_RCC_EnableResetAPB2Peripheral(FL_RCC_RSTAPB_UART0);
110 FL_RCC_DisableResetAPB2Peripheral(FL_RCC_RSTAPB_UART0);
111 /* 外设总线时钟关闭 */
112 FL_RCC_DisableGroup3BusClock(FL_RCC_GROUP3_BUSCLK_UART0);
113 /* 外设操作时钟关闭 */
114 FL_RCC_DisableGroup1OperationClock(FL_RCC_GROUP1_OPCLK_UART0);
115 }
116 else
117 if(UARTx == UART1)
118 {
119 /*复位UART*/
120 FL_RCC_EnableResetAPB2Peripheral(FL_RCC_RSTAPB_UART1);
121 FL_RCC_DisableResetAPB2Peripheral(FL_RCC_RSTAPB_UART1);
122 /* 外设总线时钟关闭 */
123 FL_RCC_DisableGroup3BusClock(FL_RCC_GROUP3_BUSCLK_UART1);
124 /* 外设操作时钟关闭 */
125 FL_RCC_DisableGroup1OperationClock(FL_RCC_GROUP1_OPCLK_UART1);
126 }
127 else
128 if(UARTx == UART4)
129 {
130 /*复位UART*/
131 FL_RCC_EnableResetAPB1Peripheral(FL_RCC_RSTAPB_UART4);
132 FL_RCC_DisableResetAPB1Peripheral(FL_RCC_RSTAPB_UART4);
133 /* 外设总线时钟关闭 */
134 FL_RCC_DisableGroup3BusClock(FL_RCC_GROUP3_BUSCLK_UART4);
135 }
136 else
137 if(UARTx == UART5)
138 {
139 /*复位UART*/
140 FL_RCC_EnableResetAPB1Peripheral(FL_RCC_RSTAPB_UART5);
141 FL_RCC_DisableResetAPB1Peripheral(FL_RCC_RSTAPB_UART5);
142 /* 外设总线时钟关闭 */
143 FL_RCC_DisableGroup3BusClock(FL_RCC_GROUP3_BUSCLK_UART5);
144 }
145 else
146 {
147 status = FL_FAIL;
148 }
149 /* 锁定外设复位功能 */
150 FL_RCC_DisablePeripheralReset();
151 return (status);
152 }
153
154 /**
155 * @brief 配置UART
156 *
157 * @param UARTx 外设入口地址
158 * @param initStruct 指向 @ref FL_UART_InitTypeDef 结构体的指针
159 *
160 * @retval 错误状态,可能值:
161 * -FL_PASS 配置成功
162 * -FL_FAIL 配置过程发生错误
163 */
FL_UART_Init(UART_Type * UARTx,FL_UART_InitTypeDef * initStruct)164 FL_ErrorStatus FL_UART_Init(UART_Type *UARTx, FL_UART_InitTypeDef *initStruct)
165 {
166 FL_ErrorStatus status = FL_FAIL;
167 uint32_t Fclk = 0, baudRate = 0;
168 /* 参数合法性检查 */
169 assert_param(IS_UART_INSTANCE(UARTx));
170 assert_param(IS_FL_UART_CLKSRC(initStruct->clockSrc));
171 assert_param(IS_FL_UART_DATAWIDTH(initStruct->dataWidth));
172 assert_param(IS_FL_UART_PARITY(initStruct->parity));
173 assert_param(IS_FL_UART_STOPBITS(initStruct->stopBits));
174 assert_param(IS_FL_UART_DIRECTION(initStruct->transferDirection));
175 if(UARTx == UART0)
176 {
177 /*时钟源选择*/
178 FL_RCC_SetUART0ClockSource(initStruct->clockSrc);
179 /* 根据不同的时钟源计算baudrate 寄存器值,并配置 */
180 switch(initStruct->clockSrc)
181 {
182 case FL_RCC_UART0_CLK_SOURCE_APB1CLK:
183 Fclk = FL_RCC_GetAPB1ClockFreq();
184 break;
185 case FL_RCC_UART0_CLK_SOURCE_RCHF:
186 Fclk = FL_RCC_GetRCHFClockFreq();
187 break;
188 case FL_RCC_UART0_CLK_SOURCE_SYSCLK:
189 Fclk = FL_RCC_GetSystemClockFreq();
190 break;
191 case FL_RCC_UART0_CLK_SOURCE_RCMF_PSC:
192 Fclk = FL_RCC_GetRCMFClockFreq();
193 break;
194 }
195 baudRate = Fclk / initStruct->baudRate - 1;
196 }
197 if(UARTx == UART1)
198 {
199 /*时钟源选择*/
200 FL_RCC_SetUART1ClockSource(initStruct->clockSrc);
201 /* 根据不同的时钟源计算baudrate 寄存器值,并配置 */
202 switch(initStruct->clockSrc)
203 {
204 case FL_RCC_UART1_CLK_SOURCE_APB1CLK:
205 Fclk = FL_RCC_GetAPB1ClockFreq();
206 break;
207 case FL_RCC_UART1_CLK_SOURCE_RCHF:
208 Fclk = FL_RCC_GetRCHFClockFreq();
209 break;
210 case FL_RCC_UART1_CLK_SOURCE_SYSCLK:
211 Fclk = FL_RCC_GetSystemClockFreq();
212 break;
213 case FL_RCC_UART1_CLK_SOURCE_RCMF_PSC:
214 Fclk = FL_RCC_GetRCMFClockFreq();
215 break;
216 }
217 baudRate = Fclk / initStruct->baudRate - 1;
218 }
219 if(UARTx == UART0)
220 {
221 /*总线时钟使能*/
222 FL_RCC_EnableGroup3BusClock(FL_RCC_GROUP3_BUSCLK_UART0);
223 /*操作时钟使能*/
224 FL_RCC_EnableGroup1OperationClock(FL_RCC_GROUP1_OPCLK_UART0);
225 }
226 else
227 if(UARTx == UART1)
228 {
229 /*总线时钟使能*/
230 FL_RCC_EnableGroup3BusClock(FL_RCC_GROUP3_BUSCLK_UART1);
231 /*操作时钟使能*/
232 FL_RCC_EnableGroup1OperationClock(FL_RCC_GROUP1_OPCLK_UART1);
233 }
234 else
235 if(UARTx == UART4)
236 {
237 /*总线时钟使能*/
238 FL_RCC_EnableGroup3BusClock(FL_RCC_GROUP3_BUSCLK_UART4);
239 Fclk = FL_RCC_GetAPB2ClockFreq();
240 baudRate = Fclk / initStruct->baudRate - 1;
241 }
242 else
243 if(UARTx == UART5)
244 {
245 FL_RCC_EnableGroup3BusClock(FL_RCC_GROUP3_BUSCLK_UART5);
246 Fclk = FL_RCC_GetAPB2ClockFreq();
247 baudRate = Fclk / initStruct->baudRate - 1;
248 }
249 /*发送接收控制*/
250 if(initStruct->transferDirection & FL_UART_DIRECTION_TX)
251 {
252 FL_UART_EnableTX(UARTx);
253 }
254 if(initStruct->transferDirection & FL_UART_DIRECTION_RX)
255 {
256 FL_UART_EnableRX(UARTx);
257 }
258 /*配置波特率*/
259 FL_UART_WriteBaudRate(UARTx, baudRate);
260 /*配置停止位长度*/
261 FL_UART_SetStopBitsWidth(UARTx, initStruct->stopBits);
262 /*数据长度*/
263 FL_UART_SetDataWidth(UARTx, initStruct->dataWidth);
264 /*配置奇偶校验*/
265 FL_UART_SetParity(UARTx, initStruct->parity);
266 status = FL_PASS;
267 return status;
268 }
269
270 /**
271 * @brief 配置UART红外调制
272 *
273 * @param UARTx 外设入口地址
274 *
275 * @param initStruct 指向 @ref FL_UART_InfraRed_InitTypeDef 结构体的指针
276 *
277 * @retval 错误状态,可能值:
278 * -FL_PASS 配置成功
279 * -FL_FAIL 配置过程发生错误
280 */
FL_UART_InfraRed_Init(UART_Type * UARTx,FL_UART_InfraRed_InitTypeDef * initStruct)281 FL_ErrorStatus FL_UART_InfraRed_Init(UART_Type *UARTx, FL_UART_InfraRed_InitTypeDef *initStruct)
282 {
283 FL_ErrorStatus status = FL_FAIL;
284 uint32_t tempTZBRG = 0, tempTH = 0;
285 /* 参数合法性检查 */
286 assert_param(IS_UART_INSTANCE(UARTx));
287 assert_param(IS_FL_UART_INFRARED_POLARITY(initStruct->polarity));
288 assert_param(IS_FL_UART_INFRARED_MODULATION_DUTY(initStruct->modulationDuty));
289 FL_RCC_EnableGroup3BusClock(FL_RCC_GROUP3_BUSCLK_UARTIR);
290 /*红外发送使能*/
291 FL_UART_EnableIRModulation(UARTx);
292 /*红外调制极性*/
293 FL_UART_SetIRPolarity(UART, initStruct->polarity);
294 /*红外调制频率*/
295 tempTZBRG = (uint32_t)((FL_RCC_GetAPB1ClockFreq() * 1.0) / initStruct->modulationFrequency - 1);
296 /* 调制占空比 */
297 if((tempTZBRG >> 4) != 0)
298 {
299 tempTH = (uint32_t)(((float)initStruct->modulationDuty / 100.0) * ((float)(tempTZBRG + 1) / (float)(tempTZBRG >> 4)) + 0.5);
300 }
301 else
302 {
303 tempTH = (uint32_t)(((float)initStruct->modulationDuty / 100.0) * (float)(tempTZBRG + 1) + 0.5);
304 }
305 /* 占空比限位到小于95%,否则结果会有问题 */
306 tempTH = ((float)((tempTZBRG >> 4) * tempTH) / (float)(tempTZBRG + 1)) < 0.95f ? tempTH : tempTH - 1;
307 /* 占空比和调制频率配置 */
308 FL_UART_WriteIRModulationDuty(UART, tempTH);
309 FL_UART_WriteIRModulationFrequency(UART, tempTZBRG);
310 status = FL_PASS;
311 return status;
312 }
313
314 /**
315 * @brief 将 @ref FL_UART_InfraRed_InitTypeDef 结构体初始化为默认配置
316 * @param initStruct 指向 @ref FL_UART_InfraRed_InitTypeDef 结构体的指针
317 *
318 * @retval None
319 */
FL_UART_InfraRed_StructInit(FL_UART_InfraRed_InitTypeDef * initStruct)320 void FL_UART_InfraRed_StructInit(FL_UART_InfraRed_InitTypeDef *initStruct)
321 {
322 initStruct->polarity = FL_UART_INFRARED_POLARITY_NORMAL;
323 initStruct->modulationDuty = 50;
324 initStruct->modulationFrequency = 38000;
325 }
326
327 /**
328 * @brief 将 @ref FL_UART_InitTypeDef 结构体初始化为默认配置
329 * @param initStruct 指向 @ref FL_UART_InitTypeDef 结构体的指针
330 *
331 * @retval None
332 */
FL_UART_StructInit(FL_UART_InitTypeDef * initStruct)333 void FL_UART_StructInit(FL_UART_InitTypeDef *initStruct)
334 {
335 initStruct->baudRate = 115200;
336 initStruct->dataWidth = FL_UART_DATA_WIDTH_8B;
337 initStruct->stopBits = FL_UART_STOP_BIT_WIDTH_1B;
338 initStruct->parity = FL_UART_PARITY_EVEN ;
339 initStruct->transferDirection = FL_UART_DIRECTION_TX_RX;
340 initStruct->clockSrc = 0;
341 }
342
343 /**
344 * @}
345 */
346
347 #endif /* FL_UART_DRIVER_ENABLED */
348
349 /**
350 * @}
351 */
352
353 /**
354 * @}
355 */
356
357 /********************** (C) COPYRIGHT Fudan Microelectronics **** END OF FILE ***********************/
358