core_uart.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  1. /*
  2. * Copyright (c) 2022 OpenLuat & AirM2M
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. * this software and associated documentation files (the "Software"), to deal in
  6. * the Software without restriction, including without limitation the rights to
  7. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  8. * the Software, and to permit persons to whom the Software is furnished to do so,
  9. * subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in all
  12. * copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  16. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  17. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  18. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. */
  21. #include "user.h"
  22. //const UART_TypeDef* hwUart[UART_MAX] = {UART0, UART1, UART2, UART3};
  23. //const int IrqUart[UART_MAX] = {UART0_IRQn, UART1_IRQn, UART2_IRQn, UART3_IRQn};
  24. //static CBFuncEx_t UartCB[UART_MAX];
  25. //static Buffer_Struct prvUartTxBuffer[UART_MAX];
  26. #define RX_BUF_LOW (1024)
  27. #define RX_BUF_INIT (2048)
  28. #define RX_BUF_HIGH (4096)
  29. #define RX_BUF_BAND (3)
  30. #define TX_BUF_INIT (2048)
  31. //#define __RX_USE_DMA__
  32. typedef struct
  33. {
  34. const UART_TypeDef *RegBase;
  35. const int IrqLine;
  36. const uint16_t DMATxChannel;
  37. const uint16_t DMARxChannel;
  38. CBFuncEx_t Callback;
  39. Buffer_Struct TxBuf;
  40. #ifdef __BUILD_OS__
  41. Buffer_Struct TxCacheBuf; // 缓存下次发送的数据
  42. #endif
  43. Buffer_Struct RxBuf;
  44. #ifdef __RX_USE_DMA__
  45. Buffer_Struct RxDMABuf[RX_BUF_BAND];
  46. #endif
  47. uint32_t LastError;
  48. #ifdef __RX_USE_DMA__
  49. uint8_t RxDMASn;
  50. #endif
  51. uint8_t RxCacheMode;
  52. uint8_t DMATxStream;
  53. uint8_t DMARxStream;
  54. }Uart_ResourceStruct;
  55. static Uart_ResourceStruct prvUart[UART_MAX] = {
  56. {
  57. UART0,
  58. UART0_IRQn,
  59. SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART0_TX,
  60. SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART0_RX,
  61. },
  62. {
  63. UART1,
  64. UART1_IRQn,
  65. SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART1_TX,
  66. SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART1_RX,
  67. },
  68. {
  69. UART2,
  70. UART2_IRQn,
  71. SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART2_TX,
  72. SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART2_RX,
  73. },
  74. {
  75. UART3,
  76. UART3_IRQn,
  77. SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART3_TX,
  78. SYSCTRL_PHER_CTRL_DMA_CHx_IF_UART3_RX,
  79. },
  80. };
  81. static int32_t prvUart_DummyCB(void *pData, void *pParam)
  82. {
  83. return 0;
  84. }
  85. static void prvUart_IrqHandle(int32_t IrqLine, void *pData);
  86. static void prvUart_RxDMADone(uint8_t UartID)
  87. {
  88. #ifdef __BUILD_OS__
  89. #ifdef __RX_USE_DMA__
  90. uint32_t Length, LastRxSn;
  91. LastRxSn = prvUart[UartID].RxDMASn;
  92. DMA_StopStream(prvUart[UartID].DMARxStream);
  93. Length = DMA_GetDataLength(prvUart[UartID].DMARxStream, &prvUart[UartID].RxDMABuf[LastRxSn].Data);
  94. Length += Uart_FifoRead(UartID, &prvUart[UartID].RxDMABuf[LastRxSn].Data[Length]);
  95. prvUart[UartID].RxDMASn = (prvUart[UartID].RxDMASn + 1)%RX_BUF_BAND;
  96. Uart_DMARx(UartID, prvUart[UartID].DMARxStream, prvUart[UartID].RxDMABuf[prvUart[UartID].RxDMASn].Data, RX_BUF_LOW);
  97. if ((prvUart[UartID].RxBuf.Pos + Length) < prvUart[UartID].RxBuf.MaxLen)
  98. {
  99. }
  100. else
  101. {
  102. OS_ReSizeBuffer(&prvUart[UartID].RxBuf, prvUart[UartID].RxBuf.MaxLen * 2);
  103. }
  104. OS_BufferWrite(&prvUart[UartID].RxBuf, prvUart[UartID].RxDMABuf[LastRxSn].Data, Length);
  105. #endif
  106. #endif
  107. }
  108. static int32_t prvUart_DMAIrqCB(void *pData, void *pParam)
  109. {
  110. uint8_t UartID = (uint32_t)pData;
  111. UART_TypeDef* Uart = (UART_TypeDef*)prvUart[UartID].RegBase;
  112. if (prvUart[UartID].RxCacheMode)
  113. {
  114. prvUart_RxDMADone(UartID);
  115. }
  116. else
  117. {
  118. prvUart[UartID].Callback(pData, pParam);
  119. }
  120. }
  121. static void prvUart_FIFOInit(UART_TypeDef *UARTx, UART_FIFOInitTypeDef *UART_FIFOInitStruct)
  122. {
  123. /************************** FIFO Tx Interrupt Config ******************************/
  124. if (DISABLE != UART_FIFOInitStruct->FIFO_TX_TriggerIntEnable)
  125. {
  126. UARTx->OFFSET_4.IER |= UART_IER_PTIME;
  127. }
  128. else
  129. {
  130. UARTx->OFFSET_4.IER &= ~UART_IER_PTIME;
  131. }
  132. /************************** FIFO Config ******************************/
  133. /* FCR Write Only So Here we Use FCR Shadow Register SDMAM(WR) */
  134. if (UARTx->SFE | UART_SFE_SFE)
  135. {
  136. UARTx->SFE &= ~UART_SFE_SFE;
  137. }
  138. if (UART_FIFO_DMA_Mode_0 == UART_FIFOInitStruct->FIFO_DMA_Mode)
  139. {
  140. UARTx->SDMAM &= ~UART_SDMAM_SDMAM;
  141. }
  142. else if(UART_FIFO_DMA_Mode_1 == UART_FIFOInitStruct->FIFO_DMA_Mode)
  143. {
  144. UARTx->SDMAM |= UART_SDMAM_SDMAM;
  145. }
  146. /* FCR Write Only So Here we Use FCR Shadow Register SRT and STET(WR) */
  147. UARTx->SRT = UART_FIFOInitStruct->FIFO_RX_Trigger;
  148. UARTx->STET = UART_FIFOInitStruct->FIFO_TX_Trigger;
  149. if (DISABLE != UART_FIFOInitStruct->FIFO_Enable)
  150. {
  151. UARTx->SFE |= UART_SFE_SFE;
  152. }
  153. else
  154. {
  155. UARTx->SFE &= ~UART_SFE_SFE;
  156. }
  157. }
  158. void Uart_GlobalInit(void)
  159. {
  160. int i, j;
  161. for(i = 0; i < UART_MAX; i++)
  162. {
  163. memset(&prvUart[i].RxBuf, 0, sizeof(Buffer_Struct));
  164. #ifdef __RX_USE_DMA__
  165. for(j = 0; j < RX_BUF_BAND; j++)
  166. {
  167. memset(&prvUart[i].RxDMABuf[j], 0, sizeof(Buffer_Struct));
  168. }
  169. #endif
  170. prvUart[i].RxCacheMode = 0;
  171. }
  172. }
  173. void Uart_BaseInit(uint8_t UartID, uint32_t BaudRate, uint8_t IsRxCacheEnable, uint8_t DataBits, uint8_t Parity, uint8_t StopBits, CBFuncEx_t CB)
  174. {
  175. uint32_t tmpBaudRateDiv, LCR;
  176. UART_FIFOInitTypeDef UART_FIFOInitStruct;
  177. UART_TypeDef* Uart = prvUart[UartID].RegBase;
  178. SYSCTRL->SOFT_RST1 = (1 << UartID);
  179. while(SYSCTRL->SOFT_RST1 & (1 << UartID)){;}
  180. UART_FIFOInitStruct.FIFO_Enable = ENABLE;
  181. UART_FIFOInitStruct.FIFO_DMA_Mode = UART_FIFO_DMA_Mode_1;
  182. UART_FIFOInitStruct.FIFO_RX_Trigger = UART_FIFO_RX_Trigger_1_2_Full;
  183. UART_FIFOInitStruct.FIFO_TX_Trigger = UART_FIFO_TX_Trigger_1_4_Full;
  184. UART_FIFOInitStruct.FIFO_TX_TriggerIntEnable = ENABLE;
  185. ISR_SetHandler(prvUart[UartID].IrqLine, prvUart_IrqHandle, (void *)UartID);
  186. #ifdef __BUILD_OS__
  187. ISR_SetPriority(prvUart[UartID].IrqLine, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 2);
  188. #else
  189. ISR_SetPriority(prvUart[UartID].IrqLine, 5);
  190. #endif
  191. if (CB)
  192. {
  193. prvUart[UartID].Callback = CB;
  194. }
  195. else
  196. {
  197. prvUart[UartID].Callback = prvUart_DummyCB;
  198. }
  199. // UART_Init(Uart, &UART_InitStruct);
  200. Uart->LCR |= UART_LCR_DLAB;
  201. // baud rate = (serial clock freq) / (16 * divisor).
  202. tmpBaudRateDiv = (SystemCoreClock >> 6) / BaudRate;
  203. Uart->OFFSET_0.DLL = (tmpBaudRateDiv & 0x00FF);
  204. Uart->OFFSET_4.DLH = ((tmpBaudRateDiv >> 8) & 0x00FF);
  205. /* LCR = 0 */
  206. Uart->LCR &= ~UART_LCR_DLAB;
  207. LCR = UART_WordLength_5b + DataBits - UART_DATA_BIT5;
  208. switch(Parity)
  209. {
  210. case UART_STOP_BIT1:
  211. LCR |= UART_StopBits_1;
  212. break;
  213. case UART_STOP_BIT1_5:
  214. LCR |= UART_StopBits_1_5;
  215. break;
  216. case UART_STOP_BIT2:
  217. LCR |= UART_StopBits_2;
  218. break;
  219. }
  220. switch(Parity)
  221. {
  222. case UART_PARITY_NONE:
  223. LCR |= UART_Parity_No;
  224. break;
  225. case UART_PARITY_ODD:
  226. LCR |= UART_Parity_Odd;
  227. break;
  228. case UART_PARITY_EVEN:
  229. LCR |= UART_Parity_Even;
  230. break;
  231. }
  232. Uart->LCR = LCR;
  233. prvUart_FIFOInit(Uart, &UART_FIFOInitStruct);
  234. ISR_OnOff(prvUart[UartID].IrqLine, 0);
  235. Uart->SFE |= UART_SFE_SFE;
  236. Uart->OFFSET_4.IER = UART_IER_ELSI;
  237. prvUart[UartID].RxCacheMode = IsRxCacheEnable;
  238. #ifdef __BUILD_OS__
  239. if (IsRxCacheEnable)
  240. {
  241. OS_ReInitBuffer(&prvUart[UartID].RxBuf, RX_BUF_INIT);
  242. #ifdef __RX_USE_DMA__
  243. for(i = 0; i < RX_BUF_BAND; i++)
  244. {
  245. OS_ReInitBuffer(&prvUart[UartID].RxDMABuf[i], RX_BUF_LOW + 32);
  246. }
  247. Uart_DMARxInit(UartID, UART_ID0_RX_DMA_STREAM + UartID, 0);
  248. Uart_DMARx(UartID, UART_ID0_RX_DMA_STREAM + UartID, prvUart[UartID].RxDMABuf[prvUart[UartID].RxDMASn].Data, RX_BUF_LOW);
  249. #endif
  250. }
  251. else
  252. {
  253. OS_DeInitBuffer(&prvUart[UartID].RxBuf);
  254. OS_ReInitBuffer(&prvUart[UartID].TxCacheBuf, TX_BUF_INIT);
  255. OS_DeInitBuffer(&prvUart[UartID].TxBuf);
  256. #ifdef __RX_USE_DMA__
  257. for(i = 0; i < RX_BUF_BAND; i++)
  258. {
  259. OS_DeInitBuffer(&prvUart[UartID].RxDMABuf[i]);
  260. }
  261. #endif
  262. }
  263. #endif
  264. }
  265. void Uart_SetCb(uint8_t UartID, CBFuncEx_t CB)
  266. {
  267. if (CB)
  268. {
  269. prvUart[UartID].Callback = CB;
  270. }
  271. else
  272. {
  273. prvUart[UartID].Callback = prvUart_DummyCB;
  274. }
  275. }
  276. void Uart_DeInit(uint8_t UartID)
  277. {
  278. UART_TypeDef* Uart = (UART_TypeDef*)prvUart[UartID].RegBase;
  279. Uart->OFFSET_4.IER = 0;
  280. Uart_BufferTxStop(UartID);
  281. ISR_OnOff(prvUart[UartID].IrqLine, 0);
  282. ISR_Clear(prvUart[UartID].IrqLine);
  283. /* LCR = 1 */
  284. Uart->LCR |= UART_LCR_DLAB;
  285. Uart->OFFSET_0.DLL = 0;
  286. Uart->OFFSET_4.DLH = 0;
  287. /* LCR = 0 */
  288. Uart->LCR &= ~UART_LCR_DLAB;
  289. }
  290. int Uart_DMATxInit(uint8_t UartID, uint8_t Stream, uint32_t Channel)
  291. {
  292. DMA_InitTypeDef DMA_InitStruct;
  293. UART_TypeDef* Uart = (UART_TypeDef*)prvUart[UartID].RegBase;
  294. DMA_BaseConfig(&DMA_InitStruct);
  295. DMA_InitStruct.DMA_Peripheral = prvUart[UartID].DMATxChannel;
  296. DMA_InitStruct.DMA_PeripheralBurstSize = DMA_BurstSize_8;
  297. DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&Uart->OFFSET_0.THR;
  298. DMA_InitStruct.DMA_Priority = DMA_Priority_3;
  299. DMA_InitStruct.DMA_MemoryBurstSize = DMA_BurstSize_8;
  300. prvUart[UartID].DMATxStream = Stream;
  301. return DMA_ConfigStream(Stream, &DMA_InitStruct);
  302. }
  303. int Uart_DMARxInit(uint8_t UartID, uint8_t Stream, uint32_t Channel)
  304. {
  305. DMA_InitTypeDef DMA_InitStruct;
  306. UART_TypeDef* Uart = (UART_TypeDef*)prvUart[UartID].RegBase;
  307. DMA_BaseConfig(&DMA_InitStruct);
  308. DMA_InitStruct.DMA_Peripheral = prvUart[UartID].DMARxChannel;
  309. DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&Uart->OFFSET_0.RBR;
  310. DMA_InitStruct.DMA_Priority = DMA_Priority_3;
  311. prvUart[UartID].DMARxStream = Stream;
  312. return DMA_ConfigStream(Stream, &DMA_InitStruct);
  313. }
  314. void Uart_BlockTx(uint8_t UartID, uint8_t *Data, uint32_t Len)
  315. {
  316. uint32_t i = 0;
  317. UART_TypeDef* Uart = (UART_TypeDef*)prvUart[UartID].RegBase;
  318. Uart->OFFSET_4.IER &= ~(UART_IER_PTIME|UART_IER_ETBEI);
  319. while(i < Len)
  320. {
  321. while (Uart->USR & UART_STATUS_TX_FIFO_NOT_FULL)
  322. {
  323. Uart->OFFSET_0.THR = Data[i];
  324. i++;
  325. }
  326. }
  327. }
  328. void Uart_NoBlockTx(uint8_t UartID, uint8_t Data)
  329. {
  330. uint32_t i = 0;
  331. UART_TypeDef* Uart = (UART_TypeDef*)prvUart[UartID].RegBase;
  332. while (!(Uart->USR & UART_STATUS_TX_FIFO_NOT_FULL))
  333. {
  334. }
  335. Uart->OFFSET_0.THR = Data;
  336. }
  337. void Uart_EnableRxIrq(uint8_t UartID)
  338. {
  339. UART_TypeDef* Uart = (UART_TypeDef*)prvUart[UartID].RegBase;
  340. Uart->SRT = UART_FIFO_RX_Trigger_1_2_Full;
  341. Uart->OFFSET_4.IER |= UART_IT_RX_RECVD|UART_IER_ELSI;
  342. ISR_OnOff(prvUart[UartID].IrqLine, 1);
  343. }
  344. void Uart_EnableTxDoneIrq(uint8_t UartID)
  345. {
  346. }
  347. void Uart_DMATx(uint8_t UartID, uint8_t Stream, const uint8_t *Data, uint32_t Len)
  348. {
  349. UART_TypeDef* Uart = (UART_TypeDef*)prvUart[UartID].RegBase;
  350. Uart->OFFSET_4.IER &= ~(UART_IER_PTIME|UART_IER_ETBEI);
  351. DMA_ClearStreamFlag(Stream);
  352. DMA_ForceStartStream(Stream, Data, Len, prvUart_DMAIrqCB, (uint32_t)UartID, 1);
  353. Uart->OFFSET_4.IER |= UART_IER_PTIME|UART_IER_ETBEI;
  354. ISR_OnOff(prvUart[UartID].IrqLine, 1);
  355. }
  356. void Uart_DMARx(uint8_t UartID, uint8_t Stream, uint8_t *Data, uint32_t Len)
  357. {
  358. UART_TypeDef* Uart = (UART_TypeDef*)prvUart[UartID].RegBase;
  359. Uart->OFFSET_4.IER |= UART_IT_RX_RECVD;
  360. Uart->SRT = UART_FIFO_RX_Trigger_1_4_Full;
  361. ISR_OnOff(prvUart[UartID].IrqLine, 1);
  362. DMA_ClearStreamFlag(Stream);
  363. DMA_ForceStartStream(Stream, Data, Len, prvUart_DMAIrqCB, (uint32_t)UartID, 1);
  364. }
  365. int32_t Uart_BufferTx(uint8_t UartID, const uint8_t *Data, uint32_t Len)
  366. {
  367. UART_TypeDef* Uart = (UART_TypeDef*)prvUart[UartID].RegBase;
  368. ISR_OnOff(prvUart[UartID].IrqLine, 0);
  369. #ifdef __BUILD_OS__
  370. if (Data && Len)
  371. {
  372. OS_BufferWrite(&prvUart[UartID].TxCacheBuf, Data, Len);
  373. }
  374. #endif
  375. if (prvUart[UartID].TxBuf.Data || prvUart[UartID].TxBuf.MaxLen)
  376. {
  377. ISR_OnOff(prvUart[UartID].IrqLine, 1);
  378. return 0;
  379. }
  380. Uart->OFFSET_4.IER &= ~(UART_IER_PTIME|UART_IER_ETBEI);
  381. #ifdef __BUILD_OS__
  382. // 把缓存的Tx指针交给发送的Tx指针,缓存的Tx指针重新建立一个
  383. Buffer_StaticInit(&prvUart[UartID].TxBuf, prvUart[UartID].TxCacheBuf.Data, prvUart[UartID].TxCacheBuf.Pos);
  384. #else
  385. Buffer_StaticInit(&prvUart[UartID].TxBuf, Data, Len);
  386. #endif
  387. while ((prvUart[UartID].TxBuf.Pos < prvUart[UartID].TxBuf.MaxLen) && (Uart->USR & UART_STATUS_TX_FIFO_NOT_FULL))
  388. {
  389. Uart->OFFSET_0.THR = prvUart[UartID].TxBuf.Data[prvUart[UartID].TxBuf.Pos];
  390. prvUart[UartID].TxBuf.Pos++;
  391. }
  392. if (prvUart[UartID].TxBuf.Pos >= prvUart[UartID].TxBuf.MaxLen)
  393. {
  394. // 只有少量数据,只靠FIFO就能填充满,就不需要重新分配内存
  395. memset(&prvUart[UartID].TxBuf, 0, sizeof(prvUart[UartID].TxBuf));
  396. #ifdef __BUILD_OS__
  397. prvUart[UartID].TxCacheBuf.Pos = 0;
  398. #endif
  399. ISR_OnOff(prvUart[UartID].IrqLine, 1);
  400. Uart->OFFSET_4.IER |= UART_IER_ETBEI|UART_IER_ELSI;
  401. return 0;
  402. }
  403. else
  404. {
  405. // 数据多,暂时发不完,就需要为缓存重新分配内存
  406. #ifdef __BUILD_OS__
  407. OS_InitBuffer(&prvUart[UartID].TxCacheBuf, TX_BUF_INIT);
  408. #endif
  409. ISR_OnOff(prvUart[UartID].IrqLine, 1);
  410. Uart->OFFSET_4.IER |= UART_IER_PTIME|UART_IER_ETBEI|UART_IER_ELSI;
  411. return 1;
  412. }
  413. }
  414. #ifdef __BUILD_OS__
  415. void Uart_BufferTxStop(uint8_t UartID)
  416. {
  417. UART_TypeDef* Uart = (UART_TypeDef*)prvUart[UartID].RegBase;
  418. Uart->OFFSET_4.IER &= ~(UART_IER_PTIME|UART_IER_ETBEI);
  419. ISR_OnOff(prvUart[UartID].IrqLine, 0);
  420. OS_DeInitBuffer(&prvUart[UartID].TxBuf);
  421. prvUart[UartID].TxCacheBuf.Pos = 0;
  422. ISR_OnOff(prvUart[UartID].IrqLine, 1);
  423. }
  424. #endif
  425. static uint32_t prvUart_FifoRead(uint8_t UartID, uint8_t *Data, uint8_t Len)
  426. {
  427. uint32_t i = 0;
  428. UART_TypeDef* Uart = (UART_TypeDef*)prvUart[UartID].RegBase;
  429. while (Uart->USR & UART_STATUS_RX_FIFO_NOT_EMPTY && (--Len))
  430. {
  431. Data[i] = Uart->OFFSET_0.RBR;
  432. i++;
  433. }
  434. return i;
  435. }
  436. uint32_t Uart_FifoRead(uint8_t UartID, uint8_t *Data)
  437. {
  438. uint32_t i = 0;
  439. UART_TypeDef* Uart = (UART_TypeDef*)prvUart[UartID].RegBase;
  440. while (Uart->USR & UART_STATUS_RX_FIFO_NOT_EMPTY)
  441. {
  442. Data[i] = Uart->OFFSET_0.RBR;
  443. i++;
  444. }
  445. return i;
  446. }
  447. void Uart_RxBufferCB(uint8_t UartID, CBFuncEx_t CB)
  448. {
  449. #ifdef __BUILD_OS__
  450. uint32_t ReadLen;
  451. if (!prvUart[UartID].RxCacheMode)
  452. {
  453. return ;
  454. }
  455. ISR_OnOff(prvUart[UartID].IrqLine, 0);
  456. if (!CB(prvUart[UartID].RxBuf.Data, (void *)prvUart[UartID].RxBuf.Pos))
  457. {
  458. prvUart[UartID].RxBuf.Pos = 0;
  459. if (prvUart[UartID].RxBuf.MaxLen > RX_BUF_HIGH)
  460. {
  461. OS_ReInitBuffer(&prvUart[UartID].RxBuf, RX_BUF_INIT);
  462. }
  463. }
  464. ISR_OnOff(prvUart[UartID].IrqLine, 1);
  465. #endif
  466. }
  467. uint32_t Uart_RxBufferRead(uint8_t UartID, uint8_t *Data, uint32_t Len)
  468. {
  469. #ifdef __BUILD_OS__
  470. uint32_t ReadLen;
  471. if (!prvUart[UartID].RxCacheMode)
  472. {
  473. return 0;
  474. }
  475. ISR_OnOff(prvUart[UartID].IrqLine, 0);
  476. if (!Len)
  477. {
  478. ReadLen = prvUart[UartID].RxBuf.Pos;
  479. ISR_OnOff(prvUart[UartID].IrqLine, 1);
  480. return ReadLen;
  481. }
  482. ReadLen = (prvUart[UartID].RxBuf.Pos < Len)?prvUart[UartID].RxBuf.Pos:Len;
  483. memcpy(Data, prvUart[UartID].RxBuf.Data, ReadLen);
  484. OS_BufferRemove(&prvUart[UartID].RxBuf, ReadLen);
  485. if (!prvUart[UartID].RxBuf.Pos && prvUart[UartID].RxBuf.MaxLen > RX_BUF_HIGH)
  486. {
  487. OS_ReInitBuffer(&prvUart[UartID].RxBuf, RX_BUF_INIT);
  488. }
  489. ISR_OnOff(prvUart[UartID].IrqLine, 1);
  490. return ReadLen;
  491. #else
  492. return 0;
  493. #endif
  494. }
  495. void Uart_RxBufferClear(uint8_t UartID)
  496. {
  497. uint32_t ReadLen;
  498. if (!prvUart[UartID].RxCacheMode)
  499. {
  500. return ;
  501. }
  502. ISR_OnOff(prvUart[UartID].IrqLine, 0);
  503. prvUart[UartID].RxBuf.Pos = 0;
  504. ISR_OnOff(prvUart[UartID].IrqLine, 1);
  505. }
  506. #ifdef __BUILD_OS__
  507. static void prvUart_Tx(uint8_t UartID, UART_TypeDef* Uart)
  508. {
  509. if (prvUart[UartID].TxBuf.Data)
  510. {
  511. while ((prvUart[UartID].TxBuf.Pos < prvUart[UartID].TxBuf.MaxLen) && (Uart->USR & UART_STATUS_TX_FIFO_NOT_FULL))
  512. {
  513. Uart->OFFSET_0.THR = prvUart[UartID].TxBuf.Data[prvUart[UartID].TxBuf.Pos];
  514. prvUart[UartID].TxBuf.Pos++;
  515. }
  516. if (prvUart[UartID].TxBuf.Pos >= prvUart[UartID].TxBuf.MaxLen)
  517. {
  518. #ifdef __BUILD_OS__
  519. OS_DeInitBuffer(&prvUart[UartID].TxBuf);
  520. Uart_BufferTx(UartID, NULL, 0);
  521. #else
  522. memset(&prvUart[UartID].TxBuf, 0, sizeof(prvUart[UartID].TxBuf));
  523. #endif
  524. }
  525. }
  526. #ifdef __BUILD_OS__
  527. else if (prvUart[UartID].TxCacheBuf.Pos)
  528. {
  529. Uart_BufferTx(UartID, NULL, 0);
  530. }
  531. if (!prvUart[UartID].TxBuf.Data && !prvUart[UartID].TxCacheBuf.Pos)
  532. #else
  533. if (!prvUart[UartID].TxBuf.Data)
  534. #endif
  535. {
  536. if (Uart->OFFSET_4.IER & UART_IER_PTIME)
  537. {
  538. Uart->OFFSET_4.IER &= ~UART_IER_PTIME;
  539. prvUart[UartID].Callback((uint32_t)UartID, (void *)UART_CB_TX_BUFFER_DONE);
  540. }
  541. else
  542. {
  543. Uart->OFFSET_4.IER &= ~UART_IER_ETBEI;
  544. prvUart[UartID].Callback((uint32_t)UartID, (void *)UART_CB_TX_ALL_DONE);
  545. }
  546. }
  547. }
  548. #endif
  549. static void prvUart_IrqHandle(int32_t IrqLine, void *pData)
  550. {
  551. uint8_t UartID = (uint32_t)pData;
  552. UART_TypeDef* Uart = (UART_TypeDef*)prvUart[UartID].RegBase;
  553. uint32_t reg_value, read_len;
  554. switch(Uart->OFFSET_8.IIR & 0x0f)
  555. {
  556. case UART_IT_ID_RX_RECVD:
  557. {
  558. // Uart->SRT = UART_FIFO_RX_Trigger_1_2_Full;
  559. #ifdef __BUILD_OS__
  560. if (prvUart[UartID].RxCacheMode)
  561. {
  562. if ((prvUart[UartID].RxBuf.Pos + 32) < prvUart[UartID].RxBuf.MaxLen)
  563. {
  564. prvUart[UartID].RxBuf.Pos += prvUart_FifoRead(UartID, &prvUart[UartID].RxBuf.Data[prvUart[UartID].RxBuf.Pos], 7);
  565. }
  566. else
  567. {
  568. OS_ReSizeBuffer(&prvUart[UartID].RxBuf, prvUart[UartID].RxBuf.MaxLen * 2);
  569. prvUart[UartID].RxBuf.Pos += prvUart_FifoRead(UartID, &prvUart[UartID].RxBuf.Data[prvUart[UartID].RxBuf.Pos], 7);
  570. }
  571. break;
  572. }
  573. #endif
  574. prvUart[UartID].Callback((uint32_t)UartID, (void *)UART_CB_RX_NEW);
  575. }
  576. break;
  577. case UART_IT_ID_TX_EMPTY:
  578. {
  579. #ifdef __BUILD_OS__
  580. prvUart_Tx(UartID, Uart);
  581. #endif
  582. }
  583. break;
  584. case UART_IT_ID_MODEM_STATUS:
  585. {
  586. reg_value = Uart->MSR;
  587. }
  588. break;
  589. case UART_IT_ID_LINE_STATUS:
  590. {
  591. reg_value = Uart->LSR;
  592. if (reg_value & UART_LSR_TEMT)
  593. {
  594. #ifdef __BUILD_OS__
  595. prvUart_Tx(UartID, Uart);
  596. #endif
  597. }
  598. if (reg_value & (UART_LSR_PFE|UART_LSR_BI|UART_LSR_FE|UART_LSR_PE|UART_LSR_OE))
  599. {
  600. prvUart[UartID].LastError = reg_value;
  601. prvUart[UartID].Callback((uint32_t)UartID, (void *)UART_CB_ERROR);
  602. }
  603. }
  604. break;
  605. case UART_IT_ID_BUSY_DETECT:
  606. {
  607. reg_value = Uart->USR;
  608. }
  609. break;
  610. case UART_IT_ID_CHAR_TIMEOUT:
  611. #ifdef __BUILD_OS__
  612. #ifdef __RX_USE_DMA__
  613. if (prvUart[UartID].RxCacheMode)
  614. {
  615. prvUart_RxDMADone(UartID);
  616. }
  617. #else
  618. if (prvUart[UartID].RxCacheMode)
  619. {
  620. if ((prvUart[UartID].RxBuf.Pos + 32) < prvUart[UartID].RxBuf.MaxLen)
  621. {
  622. prvUart[UartID].RxBuf.Pos += prvUart_FifoRead(UartID, &prvUart[UartID].RxBuf.Data[prvUart[UartID].RxBuf.Pos], 32);
  623. }
  624. else
  625. {
  626. OS_ReSizeBuffer(&prvUart[UartID].RxBuf, prvUart[UartID].RxBuf.MaxLen * 2);
  627. prvUart[UartID].RxBuf.Pos += prvUart_FifoRead(UartID, &prvUart[UartID].RxBuf.Data[prvUart[UartID].RxBuf.Pos], 32);
  628. }
  629. }
  630. #endif
  631. #endif
  632. prvUart[UartID].Callback((uint32_t)UartID, (void *)UART_CB_RX_TIMEOUT);
  633. break;
  634. default:
  635. break;
  636. }
  637. }
  638. void Uart_PrintReg(uint8_t UartID)
  639. {
  640. UART_TypeDef* Uart = (UART_TypeDef*)prvUart[UartID].RegBase;
  641. DBG("%x, %x, %x", Uart->LCR, Uart->OFFSET_4.IER, Uart->SRT);
  642. }
  643. void Uart_ChangeBR(uint8_t UartID, uint32_t BaudRate)
  644. {
  645. UART_TypeDef* Uart = prvUart[UartID].RegBase;
  646. Uart->LCR |= UART_LCR_DLAB;
  647. // baud rate = (serial clock freq) / (16 * divisor).
  648. uint32_t tmpBaudRateDiv = (SystemCoreClock >> 6) / BaudRate;
  649. Uart->OFFSET_0.DLL = (tmpBaudRateDiv & 0x00FF);
  650. Uart->OFFSET_4.DLH = ((tmpBaudRateDiv >> 8) & 0x00FF);
  651. /* LCR = 0 */
  652. Uart->LCR &= ~UART_LCR_DLAB;
  653. }
  654. uint32_t Uart_GetLastError(uint8_t UartID)
  655. {
  656. return prvUart[UartID].LastError;
  657. }