yc_uart.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. /*
  2. * Copyright (c) 2006-2020, YICHIP Development Team
  3. * @file yc_uart.c
  4. * @brief source file for setting uart
  5. *
  6. * Change Logs:
  7. * Date Author Version Notes
  8. * 2020-11-06 wushengyan V1.0.0 the first version
  9. */
  10. #include "yc_uart.h"
  11. #define uart_DMA_buf_len 1024
  12. const UART_TypeDef * const UARTs[] = {MUART0, MUART1, MUART2, MUART3};
  13. uint8_t uart0_DMA_buf[uart_DMA_buf_len] = {0};
  14. uint8_t uart1_DMA_buf[uart_DMA_buf_len] = {0};
  15. uint8_t uart2_DMA_buf[uart_DMA_buf_len] = {0};
  16. uint8_t uart3_DMA_buf[uart_DMA_buf_len] = {0};
  17. #define RX_ENABLE BIT0
  18. #define UART_DMA_ENABLE BIT31
  19. #define TX_INTR_ENABLE BIT31
  20. #define Set_RxITNum_Mask 0xff00
  21. #define Statu_RxNum_Mask (uint32_t)0xffff0000
  22. /**
  23. * @method UART_Buffer_Select
  24. * @brief select UART buffer
  25. * @param UARTx: Select the UART peripheral.
  26. * This parameter can be one of the following values:
  27. * MUART0, MUART1, MUART2 or MUART3.
  28. * @retval NULL
  29. */
  30. static uint8_t *UART_Buffer_Select(UART_TypeDef *UARTx)
  31. {
  32. _ASSERT(IS_UART(UARTx));
  33. uint8_t *buffers[] = {uart0_DMA_buf, uart1_DMA_buf, uart2_DMA_buf, uart3_DMA_buf};
  34. for (int i = 0; i < sizeof(UARTs) / sizeof(UARTs[0]); i++)
  35. {
  36. if ((void *)UARTs[i] == (void *)UARTx)
  37. {
  38. return buffers[i];
  39. }
  40. }
  41. return NULL;
  42. }
  43. /**
  44. * @method UART_DeInit
  45. * @brief DeInit UART
  46. * @param UARTx: Select the UART peripheral.
  47. * This parameter can be one of the following values:
  48. * MUART0, MUART1, MUART2 or MUART3.
  49. * @retval None
  50. */
  51. void UART_DeInit(UART_TypeDef *UARTx)
  52. {
  53. _ASSERT(IS_UART(UARTx));
  54. UARTx->CTRL.reg = 0;
  55. UARTx->RX_INT_LEN.reg = 0;
  56. }
  57. /**
  58. * @method UART_Init
  59. * @brief Initializes the UARTx peripheral according to
  60. * the specified parameters.
  61. * @param UARTx: Select the UART peripheral.
  62. * This parameter can be one of the following values:
  63. * MUART0, MUART1, MUART2 or MUART3.
  64. * @param UART_InitStruct: pointer to a UART_InitTypeDef structure that
  65. * contains the configuration information.
  66. */
  67. void UART_Init(UART_TypeDef *UARTx, UART_InitTypeDef *UART_InitStruct)
  68. {
  69. DMA_TypeDef *DMAx = NULL;
  70. uint8_t *uartx_DMA_buf = NULL;
  71. uint32_t temp_baudrate = 0;
  72. _ASSERT(IS_UART(UARTx));
  73. _ASSERT(IS_UART_RX_MODE(UART_InitStruct->RxMode));
  74. _ASSERT(IS_UART_PARITY(UART_InitStruct->Parity));
  75. _ASSERT(IS_UART_WORD_LENGTH(UART_InitStruct->DataBits));
  76. _ASSERT(IS_UART_STOPBITS(UART_InitStruct->StopBits));
  77. _ASSERT(IS_UART_FLOW_CTRL(UART_InitStruct->FlowCtrl));
  78. _ASSERT(IS_UART_SMART_CARD(UART_InitStruct->SmartCard));
  79. _ASSERT(IS_UART_COMM_MODE(UART_InitStruct->CommMode));
  80. _ASSERT(IS_UART_BAUDRATE(UART_InitStruct->BaudRate));
  81. DMAx = (DMA_TypeDef *)((uint32_t)UARTx - sizeof(DMA_TypeDef));
  82. uartx_DMA_buf = UART_Buffer_Select(UARTx);
  83. temp_baudrate = (48000000 / UART_InitStruct->BaudRate);
  84. UART_DeInit(UARTx);
  85. DMAx->DEST_ADDR.reg = (uint32_t)uartx_DMA_buf;
  86. DMAx->LEN_LOW.bit.RX_LEN_L = uart_DMA_buf_len;
  87. DMAx->CTRL.bit.LOOPBACK = 1;
  88. DMAx->CTRL.bit.RESET = 1;
  89. DMAx->CTRL.bit.RESET = 0;
  90. UARTx->CTRL.bit.RX_EN = UART_InitStruct->RxMode;
  91. UARTx->CTRL.bit.PARITY = UART_InitStruct->Parity;
  92. UARTx->CTRL.bit.DATA_BITS = UART_InitStruct->DataBits;
  93. UARTx->CTRL.bit.STOP_BITS = UART_InitStruct->StopBits;
  94. UARTx->CTRL.bit.FLOW_CTRL = UART_InitStruct->FlowCtrl;
  95. UARTx->CTRL.bit.SMART_CARD = UART_InitStruct->SmartCard;
  96. UARTx->CTRL.bit.HDX_EN = UART_InitStruct->CommMode;
  97. UARTx->CTRL.bit.RESET_BAUD = ENABLE;
  98. UARTx->BAUD.bit.BAUD_RATE = temp_baudrate;
  99. }
  100. /**
  101. * @method UART_StructInit
  102. * @brief Fills each USART_InitStruct member with its default value.
  103. * @param USART_InitStruct: pointer to a USART_InitTypeDef structure
  104. * which will be initialized.
  105. * @retval None
  106. */
  107. void UART_StructInit(UART_InitTypeDef *UART_InitStruct)
  108. {
  109. UART_InitStruct->BaudRate = 9600;
  110. UART_InitStruct->RxMode = MODE_RX_ENABLE;
  111. UART_InitStruct->Parity = YC_PARITY_NONE;
  112. UART_InitStruct->DataBits = DATABITS_8B;
  113. UART_InitStruct->StopBits = STOPBITS_1;
  114. UART_InitStruct->FlowCtrl = FLOWCTRL_NONE;
  115. UART_InitStruct->SmartCard = SMARTCARD_DISABLE;
  116. UART_InitStruct->CommMode = MODE_DUPLEX;
  117. }
  118. /**
  119. * @method UART_ITConfig
  120. * @brief Enable or disable the specified UART interrupt.
  121. * @param UARTx: Select the UART peripheral.
  122. * This parameter can be one of the following values:
  123. * MUART0, MUART1, MUART2 or MUART3.
  124. * @param UART_IT: specifies the UART interrupt sources
  125. * This parameter can be one of the following values:
  126. * @arg UART_IT_TX:interrupt trigger after send data completed.
  127. * @arg UART_IT_RX:interrupt trigger when received data.
  128. * @param NewState: new state of the specified UART interrupt
  129. * This parameter can be ENABLE or DISABLE
  130. */
  131. void UART_ITConfig(UART_TypeDef *UARTx, uint32_t UART_IT, FunctionalState NewState)
  132. {
  133. _ASSERT(IS_UART(UARTx));
  134. _ASSERT(IS_UART_IT(UART_IT));
  135. if (UART_IT == UART_IT_TX)
  136. {
  137. UARTx->BAUD.bit.TX_INT_EN = NewState;
  138. }
  139. else if (UART_IT == UART_IT_RX)
  140. {
  141. UARTx->RX_INT_LEN.bit.VAL = NewState;
  142. }
  143. }
  144. /**
  145. * @method UART_SendData
  146. * @brief UART Send One Data
  147. * @param UARTx: Select the UART peripheral.
  148. * This parameter can be one of the following values:
  149. * MUART0, MUART1, MUART2 or MUART3.
  150. * @retval None
  151. */
  152. void UART_SendData(UART_TypeDef *UARTx, uint8_t Data)
  153. {
  154. _ASSERT(IS_UART(UARTx));
  155. volatile uint8_t buf[1];
  156. buf[0] = Data;
  157. DMA_TypeDef *DMAx = (DMA_TypeDef *)((uint32_t)UARTx - sizeof(DMA_TypeDef));
  158. DMAx->SRC_ADDR.reg = (uint32_t)buf;
  159. DMAx->LEN_LOW.bit.TX_LEN_L = 1;
  160. DMAx->CTRL.bit.START = 1;
  161. while (DMAx->STATUS.bit.DONE != 1);
  162. }
  163. /**
  164. * @method UART_SendBuf
  165. * @brief Transmits datas via UART DMA, the function will return after datas is sent.
  166. * @param USARTx: Select the USART or the UART peripheral.
  167. * This parameter can be one of the following values:
  168. * MUART0, MUART1, MUART2 or MUART3.
  169. * @param buf: pointer to a buf that contains the data you want transmit.
  170. * @param len: the buf length
  171. * @retval None
  172. */
  173. void UART_SendBuf(UART_TypeDef *UARTx, uint8_t *buf, uint32_t len)
  174. {
  175. _ASSERT(IS_UART(UARTx));
  176. _ASSERT(NULL != buf);
  177. _ASSERT(len < 0xfffff);
  178. DMA_TypeDef *DMAx = (DMA_TypeDef *)((uint32_t)UARTx - sizeof(DMA_TypeDef));
  179. DMAx->SRC_ADDR.reg = (uint32_t)buf;
  180. DMAx->LEN_LOW.bit.TX_LEN_L = len & 0xffff;
  181. DMAx->CTRL.bit.TX_LEN_H = len >> 16;
  182. DMAx->CTRL.bit.START = 1;
  183. while (DMAx->STATUS.bit.DONE != 1);
  184. }
  185. /**
  186. * @method UART_ReceiveData
  187. * @brief Receive single data through the USARTx peripheral.
  188. * @param USARTx: Select the USART or the UART peripheral.
  189. * This parameter can be one of the following values:
  190. * MUART0, MUART1, MUART2 or MUART3.
  191. * @retval An one byte received data.
  192. */
  193. uint8_t UART_ReceiveData(UART_TypeDef *UARTx)
  194. {
  195. _ASSERT(IS_UART(UARTx));
  196. return UARTx->RX_DATA.bit.VAL;
  197. }
  198. /**
  199. * @method UART_ReceiveBuf
  200. * @brief Receives datas through the UART DMA.
  201. * @param USARTx: Select the USART or the UART peripheral.
  202. * This parameter can be one of the following values:
  203. * MUART0, MUART1, MUART2 or MUART3.
  204. * @param buf: pointer to a buf that contains the data you want receive.
  205. * @param len: the buf length, which size should be less than 20 bit (len < 0xfffff)
  206. * @retval The length of received data before return.
  207. */
  208. uint32_t UART_ReceiveBuf(UART_TypeDef *UARTx, uint8_t *buf, uint32_t len)
  209. {
  210. _ASSERT(IS_UART(UARTx));
  211. _ASSERT(NULL != buf);
  212. _ASSERT(len < 0xfffff);
  213. uint32_t rcv_len = 0;
  214. while ((UART_ReceiveDataLen(UARTx) > 0) && (rcv_len < len))
  215. {
  216. buf[rcv_len++] = UARTx->RX_DATA.bit.VAL;
  217. }
  218. return rcv_len;
  219. }
  220. /**
  221. * @method UART_AutoFlowCtrlCmd
  222. * @brief ENABLE or DISABLE UARTx auto flow control
  223. * @param USARTx: Select the USART or the UART peripheral.
  224. * This parameter can be one of the following values:
  225. * MUART0, MUART1, MUART2 or MUART3.
  226. * @param NewState: ENABLE or DISABLE auto flow control
  227. * @retval None
  228. */
  229. void UART_AutoFlowCtrlCmd(UART_TypeDef *UARTx, FunctionalState NewState)
  230. {
  231. _ASSERT(IS_UART(UARTx));
  232. UARTx->CTRL.bit.FLOW_CTRL = NewState;
  233. }
  234. /**
  235. * @method UART_GetITIdentity
  236. * @brief Get IT Identity
  237. * @param UARTx: Select the UART peripheral.
  238. * This parameter can be one of the following values:
  239. * MUART0, MUART1, MUART2 or MUART3.
  240. * @retval IT Identity
  241. */
  242. uint8_t UART_GetITIdentity(UART_TypeDef *UARTx)
  243. {
  244. _ASSERT(IS_UART(UARTx));
  245. //return (0 || (UARTx->BAUD.bit.TX_INT_EN) || (UARTx->RX_INT_LEN.bit.VAL));
  246. if((UARTx->RX_INT_LEN.reg > 0)&& (UARTx->STATUS.bit.RX_ITEMS_L >=UARTx->RX_INT_LEN.reg))
  247. {
  248. return UART_IT_RX;
  249. }
  250. else if(UARTx->BAUD.bit.TX_INT_EN)
  251. {
  252. return UART_IT_TX;
  253. }
  254. return 0;
  255. }
  256. /**
  257. * @method UART_IsRXFIFOFull
  258. * @brief Check if the Rx fifo is full or not.
  259. * @param UARTx: Select the UART peripheral.
  260. * This parameter can be one of the following values:
  261. * MUART0, MUART1, MUART2 or MUART3.
  262. * @retval TRUE: Rx fifo is full.
  263. * FALSE: Rx fifo is not full
  264. */
  265. Boolean UART_IsRXFIFOFull(UART_TypeDef *UARTx)
  266. {
  267. _ASSERT(IS_UART(UARTx));
  268. return (Boolean)(UARTx->STATUS.bit.RX_FULL);
  269. }
  270. /**
  271. * @method UART_IsRXFIFONotEmpty
  272. * @brief Check if the Rx fifo is empty or not.
  273. * @param UARTx: Select the UART peripheral.
  274. * This parameter can be one of the following values:
  275. * MUART0, MUART1, MUART2 or MUART3.
  276. * @retval TRUE: Rx fifo is not empty.
  277. * FALSE: Rx fifo is empty
  278. */
  279. Boolean UART_IsRXFIFONotEmpty(UART_TypeDef *UARTx)
  280. {
  281. _ASSERT(IS_UART(UARTx));
  282. return (Boolean)(!(UARTx->STATUS.bit.RX_EMPTY));
  283. }
  284. /**
  285. * @method UART_IsBusy
  286. * @brief Check if the UARTx is busy or not.
  287. * @param UARTx: Select the UART peripheral.
  288. * This parameter can be one of the following values:
  289. * MUART0, MUART1, MUART2 or MUART3.
  290. * @retval TRUE: UARTx is busy.
  291. * FALSE: UARTx is not busy.
  292. */
  293. Boolean UART_IsBusy(UART_TypeDef *UARTx)
  294. {
  295. _ASSERT(IS_UART(UARTx));
  296. return (Boolean)(!(UARTx->STATUS.bit.RX_EMPTY));
  297. }
  298. /**
  299. * @method UART_SetITTimeout
  300. * @brief Sets the interruption time for serial port timeout.
  301. * @param USARTx: Select the USART or the UART peripheral.
  302. * This parameter can be one of the following values:
  303. * MUART0, MUART1, MUART2 or MUART3.
  304. * @param timeout: 0x00~0xff
  305. * @retval None
  306. */
  307. void UART_SetITTimeout(UART_TypeDef *UARTx, uint16_t timeout)
  308. {
  309. _ASSERT(IS_UART(UARTx));
  310. UARTx->TIMEOUT_INT.reg = timeout;
  311. }
  312. /**
  313. * @method UART_SetRxITNum
  314. * @brief Set the number of uart receive data intterupt trigger
  315. * @param UARTx: Select the UART peripheral.
  316. * This parameter can be one of the following values:
  317. * MUART0, MUART1, MUART2 or MUART3.
  318. * @param Bcnt: if the number of receive datas greater than Bcnt,interrupt trigger
  319. * @retval None
  320. */
  321. void UART_SetRxITNum(UART_TypeDef *UARTx, uint8_t Bcnt)
  322. {
  323. _ASSERT(IS_UART(UARTx));
  324. UARTx->RX_INT_LEN.reg = Bcnt;
  325. }
  326. /**
  327. * @method UART_ReceiveDataLen
  328. * @brief Return the length of received data
  329. * @param UARTx: Select the UART peripheral.
  330. * This parameter can be one of the following values:
  331. * MUART0, MUART1, MUART2 or MUART3.
  332. * @retval Data len
  333. */
  334. uint32_t UART_ReceiveDataLen(UART_TypeDef *UARTx)
  335. {
  336. _ASSERT(IS_UART(UARTx));
  337. return (UARTx->STATUS.bit.RX_ITEMS_H << 16) + UARTx->STATUS.bit.RX_ITEMS_L;
  338. }
  339. /************************ (C) COPYRIGHT Yichip Microelectronics *****END OF FILE****/