fm33lc0xx_fl_uart.c 13 KB

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