hv_drv_Uart.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126
  1. /**
  2. * @file hv_drv_Uart.c
  3. * @brief uart driver layer file.
  4. *
  5. * @author HiView SoC Software Team
  6. * @version 1.0.0
  7. * @date 2023-06-14
  8. * @copyright Copyright(c),2023-6, Hiview Software. All rights reserved.
  9. * </table>
  10. */
  11. #include "hv_vos_Comm.h"
  12. #include "hv_cal_Dma.h"
  13. #include "hv_chip_Config.h"
  14. #include "hv_comm_Define.h"
  15. #include "hv_drv_Uart.h"
  16. #include "hv_comm_Assert.h"
  17. #define UART_LCR_MASK 0xE0
  18. #define UART_PARITY_MASK 0x03
  19. #define UART_PARITY_EVEN_MASK 0x18
  20. #define UART_PARITY_ODD_MASK 0x08
  21. #define UART_PARITY_NONE_MASK 0x00
  22. #define UART_DATALEN_MASK 0x03
  23. #define UART_STOP_POS 2U
  24. #define UART_STOP_MASK (0x01UL << UART_STOP_POS)
  25. /*!< Received Data Available */
  26. #define UART_RECV_INT_EN 0x01
  27. /*!< Transmit Holding Register Empty Interrupt */
  28. #define UART_TRANEMPTY_INT_EN 0x02
  29. /*!< Receiver Line Status Interrupt */
  30. #define UART_RECVSTATUS_INT_EN 0x04
  31. /*!< Modem Status */
  32. #define UART_MODEMSTATUS_INT_EN 0x08
  33. #define UART_FIFO_MASK 0x06
  34. /* Interrupt Type */
  35. #define UART_INT_MODEM_STATUS 0x00
  36. #define UART_INT_NO_INTERRUPT_PENDING 0x01
  37. #define UART_INT_THR_EMPTY 0x02
  38. #define UART_INT_RECEIVED_DATA_AVAILABLE 0x04
  39. #define UART_INT_RECEIVER_LINE_STATUS 0x06
  40. #define UART_INT_BUSY_DETECT 0x07
  41. #define UART_INT_CHARACTER_TIMEOUT 0x0c
  42. struct _UartSelf
  43. {
  44. UartInitParam stInitParam;
  45. UINT32 uiBaseOffset;
  46. /*!< Pointer to UART Tx transfer Buffer */
  47. const UCHAR8 *pucTxBuffPtr;
  48. /*!< UART Tx Transfer size */
  49. USHORT16 usTxXferSize;
  50. /*!< UART Tx Transfer Counter */
  51. USHORT16 usTxXferCount;
  52. /*!< Pointer to UART Rx transfer Buffer */
  53. UCHAR8 *pucRxBuffPtr;
  54. /*!< UART Rx Transfer size */
  55. USHORT16 usRxXferSize;
  56. /*!< UART Rx Transfer Counter */
  57. USHORT16 usRxXferCount;
  58. /*!< UART Tx DMA Handle parameters */
  59. DmaSelf *pstHdmaTx;
  60. /*!< UART Rx DMA Handle parameters */
  61. DmaSelf *pstHdmaRx;
  62. /*!< UART communication state */
  63. UartStateType enState;
  64. /*!< UART Error code */
  65. UINT32 errorCode;
  66. /*!< UART Binary Semaphore */
  67. HV_VOS_SEMAPHORE_S* pstUartBinarySema;
  68. };
  69. static UartSelf s_astUart[UART_PORT_MAX];
  70. #define UART_BUFF_SIZE 32
  71. static UCHAR8 g_aucUartRxBuf[UART_BUFF_SIZE] = {0};
  72. static UCHAR8 g_ucUartBufIndex = 0;
  73. static Status Uart_IntReceive(UartSelf *pstSelf)
  74. {
  75. UINT32 uiValue = 0;
  76. rs_cpu_sys_uart0_dlh_ier ier = {0};
  77. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR);
  78. uiValue = cpu_sys_uart0_lsr(uiValue)->reg_DR;
  79. while (uiValue & 0x1)
  80. {
  81. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_THR_DLL);
  82. if (pstSelf->stInitParam.bNewInterface == HV_TRUE)
  83. {
  84. g_aucUartRxBuf[(g_ucUartBufIndex++)%UART_BUFF_SIZE] = uiValue;
  85. }
  86. else
  87. {
  88. *pstSelf->pucRxBuffPtr++ = (UCHAR8)uiValue;
  89. if (--pstSelf->usRxXferCount == 0)
  90. {
  91. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER);
  92. /* Disable Received Data Available Interrupt */
  93. ier.reg_DLH_IER = cpu_sys_uart0_dlh_ier(uiValue)->reg_DLH_IER & ~UART_RECV_INT_EN;
  94. HV_W32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER, ier);
  95. if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
  96. {
  97. pstSelf->enState = UART_STATE_BUSY_TX;
  98. }
  99. else
  100. {
  101. pstSelf->enState = UART_STATE_READY;
  102. }
  103. if (pstSelf->stInitParam.fCallback)
  104. {
  105. pstSelf->stInitParam.fCallback(UART_INT_RX_COMPLETE, pstSelf->stInitParam.pCallbackArg, 0);
  106. }
  107. return HV_SUCCESS;
  108. }
  109. }
  110. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR);
  111. uiValue = cpu_sys_uart0_lsr(uiValue)->reg_DR;
  112. }
  113. if (pstSelf->stInitParam.bNewInterface == HV_TRUE)
  114. {
  115. pstSelf->stInitParam.fCallback(UART_INT_RX_COMPLETE, g_aucUartRxBuf, g_ucUartBufIndex);
  116. g_ucUartBufIndex = 0;
  117. }
  118. return HV_SUCCESS;
  119. }
  120. static Status Uart_IntTransmit(UartSelf *pstSelf)
  121. {
  122. UINT32 uiValue = 0;
  123. rs_cpu_sys_uart0_dlh_ier ier = {0};
  124. if (pstSelf->usTxXferCount == 0)
  125. {
  126. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER);
  127. /* Disable Transmit Holding Register Empty Interrupt */
  128. ier.reg_DLH_IER = cpu_sys_uart0_dlh_ier(uiValue)->reg_DLH_IER & ~UART_TRANEMPTY_INT_EN;
  129. HV_W32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER, ier);
  130. if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
  131. {
  132. pstSelf->enState = UART_STATE_BUSY_RX;
  133. }
  134. else
  135. {
  136. pstSelf->enState = UART_STATE_READY;
  137. }
  138. if (pstSelf->stInitParam.fCallback)
  139. {
  140. pstSelf->stInitParam.fCallback(UART_INT_TX_COMPLETE, pstSelf->stInitParam.pCallbackArg, 0);
  141. }
  142. return HV_SUCCESS;
  143. }
  144. do
  145. {
  146. HV_W32(pstSelf->uiBaseOffset + CPU_SYS_UART0_THR_DLL, *pstSelf->pucTxBuffPtr);
  147. pstSelf->pucTxBuffPtr += 1;
  148. if (--pstSelf->usTxXferCount == 0)
  149. {
  150. return HV_SUCCESS;
  151. }
  152. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_USR);
  153. uiValue = cpu_sys_uart0_usr(uiValue)->reg_TFNF;
  154. }
  155. while (pstSelf->stInitParam.bFifoEnable && (uiValue & 0x1));
  156. return HV_SUCCESS;
  157. }
  158. static Status Uart_DmaRxCpltCallback(DmaSelf* pstArg)
  159. {
  160. UartSelf *pstSelf = (UartSelf *)Hv_Cal_Dma_GetParent(pstArg);
  161. if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
  162. {
  163. pstSelf->enState = UART_STATE_BUSY_TX;
  164. }
  165. else
  166. {
  167. pstSelf->enState = UART_STATE_READY;
  168. }
  169. if (pstSelf->stInitParam.fCallback)
  170. {
  171. pstSelf->stInitParam.fCallback(UART_DMA_RX_COMPLETE, pstSelf->stInitParam.pCallbackArg, 0);
  172. }
  173. return HV_SUCCESS;
  174. }
  175. static Status Uart_DmaTxCpltCallback(DmaSelf* pstArg)
  176. {
  177. UartSelf *pstSelf = (UartSelf *)Hv_Cal_Dma_GetParent(pstArg);
  178. if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
  179. {
  180. pstSelf->enState = UART_STATE_BUSY_RX;
  181. }
  182. else
  183. {
  184. pstSelf->enState = UART_STATE_READY;
  185. }
  186. if (pstSelf->stInitParam.fCallback)
  187. {
  188. pstSelf->stInitParam.fCallback(UART_DMA_TX_COMPLETE, pstSelf->stInitParam.pCallbackArg, 0);
  189. }
  190. return HV_SUCCESS;
  191. }
  192. static HV_VOS_ISR_RESULT_E Uart_IrqHandler(UINT32 uiIrqNum, void *pArg)
  193. {
  194. UartSelf *pstSelf = (UartSelf *)pArg;
  195. UINT32 uiValue = 0;
  196. HV_UNUSED(uiIrqNum);
  197. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_FCR);
  198. switch (uiValue & 0xf)
  199. {
  200. case UART_INT_MODEM_STATUS:
  201. {
  202. break;
  203. }
  204. case UART_INT_NO_INTERRUPT_PENDING:
  205. {
  206. break;
  207. }
  208. case UART_INT_THR_EMPTY:
  209. {
  210. Uart_IntTransmit(pstSelf);
  211. break;
  212. }
  213. case UART_INT_RECEIVED_DATA_AVAILABLE:
  214. {
  215. Uart_IntReceive(pstSelf);
  216. Hv_Vos_ReleaseSemaphoreFromISR(pstSelf->pstUartBinarySema);
  217. break;
  218. }
  219. case UART_INT_RECEIVER_LINE_STATUS:
  220. {
  221. pstSelf->errorCode = UART_ERROR_NONE;
  222. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR);
  223. if (cpu_sys_uart0_lsr(uiValue)->reg_BI & 0x1)
  224. {
  225. pstSelf->errorCode |= UART_ERROR_BI;
  226. }
  227. if (cpu_sys_uart0_lsr(uiValue)->reg_FE & 0x1)
  228. {
  229. pstSelf->errorCode |= UART_ERROR_FE;
  230. }
  231. if (cpu_sys_uart0_lsr(uiValue)->reg_PE & 0x1)
  232. {
  233. pstSelf->errorCode |= UART_ERROR_PE;
  234. }
  235. if (cpu_sys_uart0_lsr(uiValue)->reg_OE & 0x1)
  236. {
  237. pstSelf->errorCode |= UART_ERROR_ORE;
  238. }
  239. if (cpu_sys_uart0_lsr(uiValue)->reg_RFE & 0x1)
  240. {
  241. pstSelf->errorCode |= UART_ERROR_RFE;
  242. }
  243. //HV_LOGI("error errorCode = 0x%x\n", pstSelf->errorCode);
  244. break;
  245. }
  246. case UART_INT_BUSY_DETECT:
  247. {
  248. //HV_LOGI("busy detect\n");
  249. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_USR);
  250. HV_UNUSED(uiValue);
  251. break;
  252. }
  253. case UART_INT_CHARACTER_TIMEOUT:
  254. {
  255. //HV_LOGI("character timeout\n");
  256. break;
  257. }
  258. default:
  259. {
  260. break;
  261. }
  262. }
  263. return HV_VOS_ISR_HANDLED;
  264. }
  265. void Hv_Drv_Uart_SetDmaTx(UartSelf *pstSelf, DmaSelf *pstHdmaTx)
  266. {
  267. pstSelf->pstHdmaTx = pstHdmaTx;
  268. Hv_Cal_Dma_SetParent(pstHdmaTx,(void*)pstSelf);
  269. Hv_Cal_Dma_SetDstAddr(pstHdmaTx,CPU_SYS_UART0_THR_DLL + pstSelf->uiBaseOffset);
  270. return;
  271. }
  272. void Hv_Drv_Uart_SetDmaRx(UartSelf *pstSelf, DmaSelf *pstHdmaRx)
  273. {
  274. pstSelf->pstHdmaRx = pstHdmaRx;
  275. Hv_Cal_Dma_SetParent(pstHdmaRx,(void*)pstSelf);
  276. Hv_Cal_Dma_SetSrcAddr(pstHdmaRx,CPU_SYS_UART0_THR_DLL + pstSelf->uiBaseOffset);
  277. return;
  278. }
  279. /** Initialize uart
  280. * @param initParam pointer to uart configure parameters
  281. * @return uart structure pointer
  282. */
  283. UartSelf *Hv_Drv_Uart_Init(UartInitParam *pstInitParam)
  284. {
  285. rs_cpu_sys_uart0_fcr fcr = {0};
  286. rs_cpu_sys_uart0_lcr_ext lcr_ext = {0};
  287. UartSelf *pstSelf;
  288. UINT32 uiIrqNum = 0;
  289. HV_ASSERT_TRUE_RET(pstInitParam != NULL,NULL);
  290. HV_ASSERT_PEEK_TRUE(pstInitParam->enPort < UART_PORT_MAX);
  291. pstSelf = &s_astUart[pstInitParam->enPort];
  292. HV_MEMCPY(&s_astUart[pstInitParam->enPort], pstInitParam, sizeof(UartInitParam));
  293. if (pstInitParam->enPort == UART_PORT_0)
  294. {
  295. pstSelf->uiBaseOffset = 0;
  296. uiIrqNum = HV_CHIP_IRQ_UART0;
  297. }
  298. else if (pstInitParam->enPort == UART_PORT_1)
  299. {
  300. pstSelf->uiBaseOffset = HV_UART1_BASE_ADDRESS - HV_UART0_BASE_ADDRESS;
  301. uiIrqNum = HV_CHIP_IRQ_UART1;
  302. }
  303. else
  304. {
  305. }
  306. if (pstInitParam->bFifoEnable)
  307. {
  308. fcr.reg_FIFOE = 1;
  309. fcr.reg_RFIFOR = 1;
  310. fcr.reg_XFIFOR = 1;
  311. fcr.TET = pstInitParam->enTxFiFoTrig;
  312. fcr.RT = pstInitParam->enRxFiFoTrig;
  313. }
  314. if (pstInitParam->b9BitMode)
  315. {
  316. lcr_ext.reg_DLS_E = 1;
  317. lcr_ext.reg_ADDR_MATCH = 0;
  318. lcr_ext.reg_SEND_ADDR = 0;
  319. lcr_ext.reg_TRANSMIT_MODE = 1;
  320. HV_W32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_LCR_EXT, lcr_ext);
  321. }
  322. if (pstInitParam->bNewInterface)
  323. {
  324. if (pstInitParam->fCallback == NULL)
  325. {
  326. HV_LOGE("no callback regisstered\n");
  327. }
  328. }
  329. HV_W32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_FCR, fcr);
  330. Hv_Drv_Uart_SetBaudrate(pstSelf, pstInitParam->uiBaudrate);
  331. Hv_Drv_Uart_SetFormat(pstSelf, pstInitParam->enParity, pstInitParam->enStopbit, pstInitParam->enWordlen);
  332. HV_W32(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER, UART_RECVSTATUS_INT_EN | UART_MODEMSTATUS_INT_EN);
  333. Hv_Vos_AttachIsr(uiIrqNum, Uart_IrqHandler, pstSelf);
  334. //Hv_Vos_SetIrqPrio(uiIrqNum,pstInitParam->uiPriority);
  335. Hv_Vos_UnmaskIrq(uiIrqNum);
  336. Hv_Vos_ConfigIrq(uiIrqNum, HV_TRUE, 0);
  337. pstSelf->errorCode = UART_ERROR_NONE;
  338. pstSelf->enState = UART_STATE_READY;
  339. pstSelf->pstUartBinarySema = Hv_Vos_InitSemaphore(1, 0);
  340. return pstSelf;
  341. }
  342. /** brief De-initialize uart
  343. * @param self uart pointer
  344. */
  345. void Hv_Drv_Uart_Cleanup(UartSelf *pstSelf)
  346. {
  347. HV_ASSERT(pstSelf->stInitParam.enPort < UART_PORT_MAX);
  348. Hv_Drv_Uart_CleanFifo(pstSelf);
  349. if (pstSelf->stInitParam.enPort == UART_PORT_0)
  350. {
  351. Hv_Vos_ConfigIrq(HV_CHIP_IRQ_UART0, HV_FALSE, 0);
  352. Hv_Vos_MaskIrq(HV_CHIP_IRQ_UART0);
  353. Hv_Vos_DetachIsr(HV_CHIP_IRQ_UART0, Uart_IrqHandler);
  354. }
  355. else if (pstSelf->stInitParam.enPort == UART_PORT_1)
  356. {
  357. Hv_Vos_ConfigIrq(HV_CHIP_IRQ_UART1, HV_FALSE, 0);
  358. Hv_Vos_MaskIrq(HV_CHIP_IRQ_UART1);
  359. Hv_Vos_DetachIsr(HV_CHIP_IRQ_UART1, Uart_IrqHandler);
  360. }
  361. else
  362. {
  363. }
  364. pstSelf->stInitParam.fCallback = NULL;
  365. pstSelf->stInitParam.pCallbackArg = NULL;
  366. pstSelf->enState = UART_STATE_RESET;
  367. return;
  368. }
  369. /** brief De-initialize uart
  370. * @param self uart pointer
  371. */
  372. void Hv_Drv_Uart_CleanFifo(UartSelf *pstSelf)
  373. {
  374. UINT32 uiValue = 0;
  375. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_FCR);
  376. HV_W32(pstSelf->uiBaseOffset + CPU_SYS_UART0_FCR, uiValue | UART_FIFO_MASK);
  377. return;
  378. }
  379. /** Detection puiBaudrate of uart
  380. * @param enPort uart enPort
  381. * @param puiBaudrate detection puiBaudrate value
  382. * @return result
  383. */
  384. Status Hv_Drv_Uart_BaudrateDetection(UartPortIndex enPort, UINT32 *puiBaudrate)
  385. {
  386. UINT32 uiValue = 0;
  387. UINT32 uiBaseOffset = 0;
  388. HV_ASSERT(enPort < UART_PORT_MAX);
  389. if (enPort == UART_PORT_0)
  390. {
  391. uiBaseOffset = 0;
  392. }
  393. else if (enPort == UART_PORT_1)
  394. {
  395. uiBaseOffset = HV_UART1_BASE_ADDRESS - HV_UART0_BASE_ADDRESS;
  396. }
  397. else
  398. {
  399. }
  400. /* auto baud rate enable */
  401. HV_W32_FIELD_EX(CPU_SYS_UART0_UART_CTL0, uiBaseOffset, reg_abr_en, 1);
  402. while(1)
  403. {
  404. uiValue = HV_R32(uiBaseOffset + CPU_SYS_UART0_UART_CTL0);
  405. if (cpu_sys_uart0_uart_ctl0(uiValue)->reg_abrf == 1
  406. && cpu_sys_uart0_uart_ctl0(uiValue)->reg_bit_num != 0)
  407. {
  408. *puiBaudrate = HV_CHIP_CLK_APB / cpu_sys_uart0_uart_ctl0(uiValue)->reg_bit_num;
  409. HV_LOGI("get Baudrate = %d\n", *puiBaudrate);
  410. break;
  411. }
  412. }
  413. /* auto baud rate disable */
  414. HV_W32_FIELD_EX(CPU_SYS_UART0_UART_CTL0, uiBaseOffset, reg_abr_en, 0);
  415. return HV_SUCCESS;
  416. }
  417. /** Set baudrate of uart
  418. * @param self uart pointer
  419. * @param baudrate baudrate
  420. * @return result
  421. */
  422. Status Hv_Drv_Uart_SetBaudrate(UartSelf *pstSelf, UINT32 uiBaudrate)
  423. {
  424. UINT32 uiDivider = 0;
  425. FLOAT32 fBrd = 0;
  426. fBrd = (HV_CHIP_CLK_APB >> 4) / (FLOAT32)uiBaudrate + 1 / 2;
  427. uiDivider = (UINT32)fBrd;
  428. /* Enable setup uiBaudrate */
  429. HV_W32_FIELD_EX(CPU_SYS_UART0_LCR, pstSelf->uiBaseOffset, reg_DLAB, 1);
  430. HV_W32_FIELD_EX(CPU_SYS_UART0_THR_DLL, pstSelf->uiBaseOffset, reg_THR_DLL, uiDivider & 0xff);
  431. HV_W32_FIELD_EX(CPU_SYS_UART0_DLH_IER, pstSelf->uiBaseOffset, reg_DLH_IER, (uiDivider >> 8) & 0xff);
  432. /* Disable setup uiBaudrate */
  433. HV_W32_FIELD_EX(CPU_SYS_UART0_LCR, pstSelf->uiBaseOffset, reg_DLAB, 0);
  434. return HV_SUCCESS;
  435. }
  436. /** Set serial format of homebus
  437. * @param self uart pointer
  438. * @param parity parity
  439. * @param stopbit stop bit
  440. * @param wordlen word length
  441. * @return result
  442. */
  443. Status Hv_Drv_Uart_SetFormat(UartSelf *pstSelf, UartParity enParity, UartStopBit enStopbit, UartWordLen enWordlen)
  444. {
  445. UINT32 uiData = 0;
  446. UINT32 uiValue = 0;
  447. pstSelf->stInitParam.enParity = enParity;
  448. pstSelf->stInitParam.enStopbit = enStopbit;
  449. pstSelf->stInitParam.enWordlen = enWordlen;
  450. uiData = (((pstSelf->stInitParam.enStopbit << UART_STOP_POS) & UART_STOP_MASK) | (pstSelf->stInitParam.enWordlen & UART_DATALEN_MASK));
  451. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LCR);
  452. switch (pstSelf->stInitParam.enParity & UART_PARITY_MASK)
  453. {
  454. case UART_PARITY_EVEN:
  455. {
  456. uiValue = (uiValue & UART_LCR_MASK) | UART_PARITY_EVEN_MASK | uiData;
  457. break;
  458. }
  459. case UART_PARITY_ODD:
  460. {
  461. uiValue = (uiValue & UART_LCR_MASK) | UART_PARITY_ODD_MASK | uiData;
  462. break;
  463. }
  464. default:
  465. {
  466. uiValue = (uiValue & UART_LCR_MASK) | UART_PARITY_NONE_MASK | uiData;
  467. break;
  468. }
  469. }
  470. HV_W32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LCR, uiValue);
  471. return HV_SUCCESS;
  472. }
  473. /** Receives an amount of data in polling mode
  474. * @param self uart pointer
  475. * @param data pointer to data buffer
  476. * @param size amount of data to be received
  477. * @param timeout timeout duration ms
  478. * @return result
  479. */
  480. Status Hv_Drv_Uart_Receive(UartSelf *pstSelf, UCHAR8 *pucData, USHORT16 usSize, UINT32 uiTimeout)
  481. {
  482. UINT32 uiValue = 0;
  483. UINT64 ulStartTick = 0;
  484. if (pucData == NULL || usSize == 0)
  485. {
  486. return HV_INVALID;
  487. }
  488. if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_TX)
  489. {
  490. if (pstSelf->enState == UART_STATE_BUSY_TX)
  491. {
  492. pstSelf->enState = UART_STATE_BUSY_TX_RX;
  493. }
  494. else
  495. {
  496. pstSelf->enState = UART_STATE_BUSY_RX;
  497. }
  498. pstSelf->usRxXferSize = usSize;
  499. pstSelf->usRxXferCount = usSize;
  500. ulStartTick = Hv_Vos_GetTick();
  501. while (pstSelf->usRxXferCount > 0)
  502. {
  503. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR);
  504. uiValue = cpu_sys_uart0_lsr(uiValue)->reg_DR;
  505. if (uiValue == 1)
  506. {
  507. pstSelf->usRxXferCount--;
  508. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_THR_DLL);
  509. *pucData++ = (UCHAR8)uiValue;
  510. }
  511. else
  512. {
  513. if (uiTimeout != 0 && Hv_Vos_GetTick() - ulStartTick >= uiTimeout)
  514. {
  515. if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
  516. {
  517. pstSelf->enState = UART_STATE_BUSY_TX;
  518. }
  519. else
  520. {
  521. pstSelf->enState = UART_STATE_READY;
  522. }
  523. HV_LOGE("Receive timeout!\n");
  524. return HV_FAILURE;
  525. }
  526. }
  527. }
  528. if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
  529. {
  530. pstSelf->enState = UART_STATE_BUSY_TX;
  531. }
  532. else
  533. {
  534. pstSelf->enState = UART_STATE_READY;
  535. }
  536. return HV_SUCCESS;
  537. }
  538. else
  539. {
  540. return HV_FAILURE;
  541. }
  542. }
  543. /** enable uart receive int��
  544. * @param ucPort uart port
  545. * @return result
  546. */
  547. Status Hv_Drv_Uart_EnableReceive(UCHAR8 ucPort)
  548. {
  549. UINT32 uiValue = 0;
  550. rs_cpu_sys_uart0_dlh_ier ier = {0};
  551. UartSelf *pstSelf = &s_astUart[ucPort];
  552. if (pstSelf == NULL)
  553. {
  554. HV_LOGE("port not inited\n");
  555. return HV_FAILURE;
  556. }
  557. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER);
  558. /* Enable Received Data Available Interrupt */
  559. ier.reg_DLH_IER = cpu_sys_uart0_dlh_ier(uiValue)->reg_DLH_IER | UART_RECV_INT_EN;
  560. HV_W32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER, ier);
  561. return HV_SUCCESS;
  562. }
  563. /** Receives an amount of data in non blocking mode
  564. * @param self uart pointer
  565. * @param data pointer to data buffer
  566. * @param size amount of data to be received
  567. * @return result
  568. */
  569. Status Hv_Drv_Uart_IntReceive(UartSelf *pstSelf, UCHAR8 *pucData, USHORT16 usSize)
  570. {
  571. UINT32 uiValue = 0;
  572. rs_cpu_sys_uart0_dlh_ier ier = {0};
  573. if (pucData == NULL || usSize == 0)
  574. {
  575. return HV_INVALID;
  576. }
  577. if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_TX)
  578. {
  579. if (pstSelf->enState == UART_STATE_BUSY_TX)
  580. {
  581. pstSelf->enState = UART_STATE_BUSY_TX_RX;
  582. }
  583. else
  584. {
  585. pstSelf->enState = UART_STATE_BUSY_RX;
  586. }
  587. pstSelf->pucRxBuffPtr = pucData;
  588. pstSelf->usRxXferSize = usSize;
  589. pstSelf->usRxXferCount = usSize;
  590. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER);
  591. /* Enable Received Data Available Interrupt */
  592. ier.reg_DLH_IER = cpu_sys_uart0_dlh_ier(uiValue)->reg_DLH_IER | UART_RECV_INT_EN;
  593. HV_W32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER, ier);
  594. return HV_SUCCESS;
  595. }
  596. else
  597. {
  598. return HV_FAILURE;
  599. }
  600. }
  601. /** Receives an amount of data in blocking mode
  602. * @param self uart pointer
  603. * @param data pointer to data buffer
  604. * @param size amount of data to be received
  605. * @return result
  606. */
  607. Status Hv_Drv_Uart_BlockReceive(UartSelf *pstSelf, UCHAR8 *pucData, USHORT16 usSize)
  608. {
  609. while (1)
  610. {
  611. /* Due to UART_RECV_INT_EN is set in Hv_Drv_Uart_IntReceive,
  612. so must run it before P operation.*/
  613. if (Hv_Drv_Uart_IntReceive(pstSelf, pucData, usSize) == HV_SUCCESS)
  614. {
  615. break;
  616. }
  617. else
  618. {
  619. /* P operation */
  620. Hv_Vos_AcquireSemaphore(pstSelf->pstUartBinarySema);
  621. }
  622. }
  623. return HV_SUCCESS;
  624. }
  625. /** Receives an amount of data in non blocking mode
  626. * @param self uart pointer
  627. * @param data pointer to data buffer
  628. * @param size amount of data to be received
  629. * @return result
  630. */
  631. Status Hv_Drv_Uart_DmaReceive(UartSelf *pstSelf, UCHAR8 *pucData, USHORT16 usSize)
  632. {
  633. if (pucData == NULL || usSize == 0)
  634. {
  635. return HV_INVALID;
  636. }
  637. if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_TX)
  638. {
  639. if (pstSelf->enState == UART_STATE_BUSY_TX)
  640. {
  641. pstSelf->enState = UART_STATE_BUSY_TX_RX;
  642. }
  643. else
  644. {
  645. pstSelf->enState = UART_STATE_BUSY_RX;
  646. }
  647. pstSelf->pucRxBuffPtr = pucData;
  648. pstSelf->usRxXferSize = usSize;
  649. pstSelf->usRxXferCount = usSize;
  650. Hv_Cal_Dma_XferCallbackBond(pstSelf->pstHdmaRx, Uart_DmaRxCpltCallback);
  651. Hv_Cal_Dma_SetBlockSize(pstSelf->pstHdmaRx, usSize);
  652. Hv_Cal_Dma_SetDstAddr(pstSelf->pstHdmaRx, (UINT32)pucData);
  653. Hv_Cal_Dma_ChannelEn(pstSelf->pstHdmaRx);
  654. return HV_SUCCESS;
  655. }
  656. else
  657. {
  658. return HV_FAILURE;
  659. }
  660. }
  661. /** Get character by UART
  662. * @param self uart pointer
  663. * @param data pointer to data buffer
  664. * @return result
  665. */
  666. Status Hv_Drv_Uart_GetChar(UartSelf *pstSelf, UCHAR8 *pucData)
  667. {
  668. UINT32 uiValue = 0;
  669. if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_TX)
  670. {
  671. if (pstSelf->enState == UART_STATE_BUSY_TX)
  672. {
  673. pstSelf->enState = UART_STATE_BUSY_TX_RX;
  674. }
  675. else
  676. {
  677. pstSelf->enState = UART_STATE_BUSY_RX;
  678. }
  679. do
  680. {
  681. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR);
  682. uiValue = cpu_sys_uart0_lsr(uiValue)->reg_DR;
  683. }while(uiValue == 0);
  684. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_THR_DLL);
  685. *pucData = (UCHAR8)uiValue;
  686. if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
  687. {
  688. pstSelf->enState = UART_STATE_BUSY_TX;
  689. }
  690. else
  691. {
  692. pstSelf->enState = UART_STATE_READY;
  693. }
  694. return HV_SUCCESS;
  695. }
  696. else
  697. {
  698. return HV_FAILURE;
  699. }
  700. }
  701. /** Output address by UART with 9bit mode
  702. * @param self uart pointer
  703. * @param data device address
  704. * @return result
  705. */
  706. Status Hv_Drv_Uart_PutAddr(UartSelf *pstSelf, UCHAR8 ucAddr)
  707. {
  708. UINT32 uiValue = 0;
  709. if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_RX)
  710. {
  711. if (pstSelf->enState == UART_STATE_BUSY_RX)
  712. {
  713. pstSelf->enState = UART_STATE_BUSY_TX_RX;
  714. }
  715. else
  716. {
  717. pstSelf->enState = UART_STATE_BUSY_TX;
  718. }
  719. do
  720. {
  721. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR);
  722. uiValue = cpu_sys_uart0_lsr(uiValue)->reg_THRE;
  723. } while(uiValue == 0);
  724. uiValue = (1 << 8) | ucAddr;
  725. HV_W32(pstSelf->uiBaseOffset + CPU_SYS_UART0_THR_DLL, uiValue);
  726. if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
  727. {
  728. pstSelf->enState = UART_STATE_BUSY_RX;
  729. }
  730. else
  731. {
  732. pstSelf->enState = UART_STATE_READY;
  733. }
  734. return HV_SUCCESS;
  735. }
  736. else
  737. {
  738. return HV_FAILURE;
  739. }
  740. }
  741. /** Output character by UART
  742. * @param self uart pointer
  743. * @param data outputed character
  744. * @return result
  745. */
  746. Status Hv_Drv_Uart_PutChar(UartSelf *pstSelf, UCHAR8 ucData)
  747. {
  748. UINT32 uiValue = 0;
  749. if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_RX)
  750. {
  751. if (pstSelf->enState == UART_STATE_BUSY_RX)
  752. {
  753. pstSelf->enState = UART_STATE_BUSY_TX_RX;
  754. }
  755. else
  756. {
  757. pstSelf->enState = UART_STATE_BUSY_TX;
  758. }
  759. do
  760. {
  761. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR);
  762. uiValue = cpu_sys_uart0_lsr(uiValue)->reg_THRE;
  763. } while(uiValue == 0);
  764. HV_W32(pstSelf->uiBaseOffset + CPU_SYS_UART0_THR_DLL, ucData);
  765. if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
  766. {
  767. pstSelf->enState = UART_STATE_BUSY_RX;
  768. }
  769. else
  770. {
  771. pstSelf->enState = UART_STATE_READY;
  772. }
  773. return HV_SUCCESS;
  774. }
  775. else
  776. {
  777. return HV_FAILURE;
  778. }
  779. }
  780. /** Sends an amount of data in blocking mode
  781. * @param self uart pointer
  782. * @param data pointer to data buffer
  783. * @param size amount of data to be sent
  784. * @param timeout timeout duration ms
  785. * @return result
  786. */
  787. Status Hv_Drv_Uart_Transmit(UartSelf *pstSelf, const UCHAR8 *pucData, USHORT16 usSize, UINT32 uiTimeout)
  788. {
  789. UINT32 uiValue = 0;
  790. UINT64 ulStartTick = 0;
  791. if (pucData == NULL || usSize == 0)
  792. {
  793. return HV_INVALID;
  794. }
  795. if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_RX)
  796. {
  797. if (pstSelf->enState == UART_STATE_BUSY_RX)
  798. {
  799. pstSelf->enState = UART_STATE_BUSY_TX_RX;
  800. }
  801. else
  802. {
  803. pstSelf->enState = UART_STATE_BUSY_TX;
  804. }
  805. pstSelf->usTxXferSize = usSize;
  806. pstSelf->usTxXferCount = usSize;
  807. ulStartTick = Hv_Vos_GetTick();
  808. while (pstSelf->usTxXferCount > 0)
  809. {
  810. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR);
  811. uiValue = cpu_sys_uart0_lsr(uiValue)->reg_THRE;
  812. if (uiValue == 1)
  813. {
  814. pstSelf->usTxXferCount--;
  815. HV_W32(pstSelf->uiBaseOffset + CPU_SYS_UART0_THR_DLL, *pucData);
  816. pucData += 1;
  817. }
  818. else
  819. {
  820. if (uiTimeout != 0 && Hv_Vos_GetTick() - ulStartTick >= uiTimeout)
  821. {
  822. if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
  823. {
  824. pstSelf->enState = UART_STATE_BUSY_RX;
  825. }
  826. else
  827. {
  828. pstSelf->enState = UART_STATE_READY;
  829. }
  830. HV_LOGE("Transmit timeout!\n");
  831. return HV_FAILURE;
  832. }
  833. }
  834. }
  835. if (pstSelf->enState == UART_STATE_BUSY_TX_RX)
  836. {
  837. pstSelf->enState = UART_STATE_BUSY_RX;
  838. }
  839. else
  840. {
  841. pstSelf->enState = UART_STATE_READY;
  842. }
  843. return HV_SUCCESS;
  844. }
  845. else
  846. {
  847. return HV_FAILURE;
  848. }
  849. }
  850. /** Sends an amount of data
  851. * @param ucPort uart port
  852. * @param data pointer to data buffer
  853. * @param size amount of data to be sent
  854. * @return result
  855. */
  856. Status Hv_Drv_Uart_Send(UCHAR8 ucPort, const UCHAR8 *pucData, USHORT16 usSize)
  857. {
  858. UINT32 uiValue = 0;
  859. UartSelf *pstSelf = &s_astUart[ucPort];
  860. if (pstSelf == NULL)
  861. {
  862. HV_LOGE("port not inited\n");
  863. return HV_FAILURE;
  864. }
  865. rs_cpu_sys_uart0_dlh_ier ier = {0};
  866. if (pucData == NULL || usSize == 0)
  867. {
  868. return HV_INVALID;
  869. }
  870. if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_RX)
  871. {
  872. if (pstSelf->enState == UART_STATE_BUSY_RX)
  873. {
  874. pstSelf->enState = UART_STATE_BUSY_TX_RX;
  875. }
  876. else
  877. {
  878. pstSelf->enState = UART_STATE_BUSY_TX;
  879. }
  880. pstSelf->pucTxBuffPtr = pucData;
  881. pstSelf->usTxXferSize = usSize;
  882. pstSelf->usTxXferCount = usSize;
  883. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER);
  884. /* Enable Transmit Holding Register Empty Interrupt */
  885. ier.reg_DLH_IER = cpu_sys_uart0_dlh_ier(uiValue)->reg_DLH_IER | UART_TRANEMPTY_INT_EN;
  886. HV_W32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER, ier);
  887. return HV_SUCCESS;
  888. }
  889. else
  890. {
  891. return HV_FAILURE;
  892. }
  893. }
  894. /** Sends an amount of data in non blocking mode
  895. * @param self uart pointer
  896. * @param data pointer to data buffer
  897. * @param size amount of data to be sent
  898. * @return result
  899. */
  900. Status Hv_Drv_Uart_IntTransmit(UartSelf *pstSelf, const UCHAR8 *pucData, USHORT16 usSize)
  901. {
  902. UINT32 uiValue = 0;
  903. rs_cpu_sys_uart0_dlh_ier ier = {0};
  904. if (pucData == NULL || usSize == 0)
  905. {
  906. return HV_INVALID;
  907. }
  908. if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_RX)
  909. {
  910. if (pstSelf->enState == UART_STATE_BUSY_RX)
  911. {
  912. pstSelf->enState = UART_STATE_BUSY_TX_RX;
  913. }
  914. else
  915. {
  916. pstSelf->enState = UART_STATE_BUSY_TX;
  917. }
  918. pstSelf->pucTxBuffPtr = pucData;
  919. pstSelf->usTxXferSize = usSize;
  920. pstSelf->usTxXferCount = usSize;
  921. uiValue = HV_R32(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER);
  922. /* Enable Transmit Holding Register Empty Interrupt */
  923. ier.reg_DLH_IER = cpu_sys_uart0_dlh_ier(uiValue)->reg_DLH_IER | UART_TRANEMPTY_INT_EN;
  924. HV_W32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_DLH_IER, ier);
  925. return HV_SUCCESS;
  926. }
  927. else
  928. {
  929. return HV_FAILURE;
  930. }
  931. }
  932. /** Sends an amount of data in non blocking mode
  933. * @param self uart pointer
  934. * @param data pointer to data buffer
  935. * @param size amount of data to be sent
  936. * @return result
  937. */
  938. Status Hv_Drv_Uart_DmaTransmit(UartSelf *pstSelf, const UCHAR8 *pucData, USHORT16 usSize)
  939. {
  940. if (pucData == NULL || usSize == 0)
  941. {
  942. return HV_INVALID;
  943. }
  944. if (pstSelf->enState == UART_STATE_READY || pstSelf->enState == UART_STATE_BUSY_RX)
  945. {
  946. if (pstSelf->enState == UART_STATE_BUSY_RX)
  947. {
  948. pstSelf->enState = UART_STATE_BUSY_TX_RX;
  949. }
  950. else
  951. {
  952. pstSelf->enState = UART_STATE_BUSY_TX;
  953. }
  954. pstSelf->pucTxBuffPtr = pucData;
  955. pstSelf->usTxXferSize = usSize;
  956. pstSelf->usTxXferCount = usSize;
  957. Hv_Cal_Dma_XferCallbackBond(pstSelf->pstHdmaTx, Uart_DmaTxCpltCallback);
  958. Hv_Cal_Dma_SetBlockSize(pstSelf->pstHdmaTx, usSize);
  959. Hv_Cal_Dma_SetSrcAddr(pstSelf->pstHdmaTx, (UINT32)pucData);
  960. Hv_Cal_Dma_ChannelEn(pstSelf->pstHdmaTx);
  961. return HV_SUCCESS;
  962. }
  963. else
  964. {
  965. return HV_FAILURE;
  966. }
  967. }
  968. /** Get errorCode of uart
  969. * @param self uart pointer
  970. * @return errorCode result
  971. */
  972. UINT32 Hv_Drv_Uart_GetErrorCode(UartSelf *pstSelf)
  973. {
  974. HV_LOGI("error errorCode = 0x%x\n", pstSelf->errorCode);
  975. return pstSelf->errorCode;
  976. }
  977. /** Get empty of uart
  978. * @param self uart pointer
  979. * @return result empty or not
  980. */
  981. BOOL Hv_Drv_Uart_IsEmpty(UartSelf *pstSelf)
  982. {
  983. rs_cpu_sys_uart0_lsr lsr = {0};
  984. HV_R32_REG(pstSelf->uiBaseOffset + CPU_SYS_UART0_LSR, lsr);
  985. return !lsr.reg_DR;
  986. }
  987. /**
  988. * @brief uart enable for log.
  989. * @param[in] bEnble: on/off
  990. */
  991. VOID Hv_Drv_EnableUart(BOOL bEnble)
  992. {
  993. HV_LOGI("EnableUart %d",bEnble);
  994. /* uart0_tx swtich */
  995. if (bEnble)
  996. {
  997. HV_W32_FIELD(RX_SH08_TOP_RX_CTRL_4, reg_uart0_tx_func_sel , 1);
  998. //HV_W32_FIELD(RX_SH08_TOP_RX_CTRL_4, reg_uart0_rx_func_sel , 1);
  999. //HV_W32_FIELD(RX_SH08_TOP_RX_CTRL_8, reg_uart0_sin_in_sel , 0);
  1000. }
  1001. else
  1002. {
  1003. HV_W32_FIELD(RX_SH08_TOP_RX_CTRL_4, reg_uart0_tx_func_sel , 0);
  1004. //HV_W32_FIELD(RX_SH08_TOP_RX_CTRL_4, reg_uart0_rx_func_sel , 0);
  1005. //HV_W32_FIELD(RX_SH08_TOP_RX_CTRL_8, reg_uart0_sin_in_sel , 2;
  1006. }
  1007. return;
  1008. }