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