ck_usart.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141
  1. /*
  2. * Copyright (C) 2017-2019 Alibaba Group Holding Limited
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-08-20 zx.chen CSI Source File for usart Driver
  9. */
  10. #include <csi_config.h>
  11. #include <stdbool.h>
  12. #include <string.h>
  13. #include <drv_irq.h>
  14. #include <drv_usart.h>
  15. #include <ck_usart.h>
  16. #include <soc.h>
  17. #include <csi_core.h>
  18. #define ERR_USART(errno) (CSI_DRV_ERRNO_USART_BASE | errno)
  19. /*
  20. * setting config may be accessed when the USART is not
  21. * busy(USR[0]=0) and the DLAB bit(LCR[7]) is set.
  22. */
  23. #define WAIT_USART_IDLE(addr)\
  24. do { \
  25. int32_t timecount = 0; \
  26. while ((addr->USR & USR_UART_BUSY) && (timecount < UART_BUSY_TIMEOUT)) {\
  27. timecount++;\
  28. }\
  29. if (timecount >= UART_BUSY_TIMEOUT) {\
  30. return ERR_USART(DRV_ERROR_TIMEOUT);\
  31. } \
  32. } while(0)
  33. #define USART_NULL_PARAM_CHK(para) HANDLE_PARAM_CHK(para, ERR_USART(DRV_ERROR_PARAMETER))
  34. typedef struct
  35. {
  36. uint32_t base;
  37. uint32_t irq;
  38. usart_event_cb_t cb_event; ///< Event callback
  39. uint32_t rx_total_num;
  40. uint32_t tx_total_num;
  41. uint8_t *rx_buf;
  42. uint8_t *tx_buf;
  43. volatile uint32_t rx_cnt;
  44. volatile uint32_t tx_cnt;
  45. volatile uint32_t tx_busy;
  46. volatile uint32_t rx_busy;
  47. uint32_t last_tx_num;
  48. uint32_t last_rx_num;
  49. int32_t idx;
  50. } ck_usart_priv_t;
  51. extern int32_t target_usart_init(int32_t idx, uint32_t *base, uint32_t *irq, void **handler);
  52. static ck_usart_priv_t usart_instance[CONFIG_USART_NUM];
  53. static const usart_capabilities_t usart_capabilities =
  54. {
  55. .asynchronous = 1, /* supports USART (Asynchronous) mode */
  56. .synchronous_master = 0, /* supports Synchronous Master mode */
  57. .synchronous_slave = 0, /* supports Synchronous Slave mode */
  58. .single_wire = 0, /* supports USART Single-wire mode */
  59. .event_tx_complete = 1, /* Transmit completed event */
  60. .event_rx_timeout = 0, /* Signal receive character timeout event */
  61. };
  62. /**
  63. \brief set the bautrate of usart.
  64. \param[in] addr usart base to operate.
  65. \return error code
  66. */
  67. int32_t csi_usart_config_baudrate(usart_handle_t handle, uint32_t baud)
  68. {
  69. USART_NULL_PARAM_CHK(handle);
  70. ck_usart_priv_t *usart_priv = handle;
  71. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  72. WAIT_USART_IDLE(addr);
  73. /* baudrate=(seriak clock freq)/(16*divisor); algorithm :rounding*/
  74. uint32_t divisor = ((drv_get_usart_freq(usart_priv->idx) * 10) / baud) >> 4;
  75. if ((divisor % 10) >= 5)
  76. {
  77. divisor = (divisor / 10) + 1;
  78. } else
  79. {
  80. divisor = divisor / 10;
  81. }
  82. addr->LCR |= LCR_SET_DLAB;
  83. /* DLL and DLH is lower 8-bits and higher 8-bits of divisor.*/
  84. addr->DLL = divisor & 0xff;
  85. addr->DLH = (divisor >> 8) & 0xff;
  86. /*
  87. * The DLAB must be cleared after the baudrate is setted
  88. * to access other registers.
  89. */
  90. addr->LCR &= (~LCR_SET_DLAB);
  91. return 0;
  92. }
  93. /**
  94. \brief config usart mode.
  95. \param[in] handle usart handle to operate.
  96. \param[in] mode \ref usart_mode_e
  97. \return error code
  98. */
  99. int32_t csi_usart_config_mode(usart_handle_t handle, usart_mode_e mode)
  100. {
  101. USART_NULL_PARAM_CHK(handle);
  102. if (mode == USART_MODE_ASYNCHRONOUS)
  103. {
  104. return 0;
  105. }
  106. return ERR_USART(USART_ERROR_MODE);
  107. }
  108. /**
  109. \brief config usart parity.
  110. \param[in] handle usart handle to operate.
  111. \param[in] parity \ref usart_parity_e
  112. \return error code
  113. */
  114. int32_t csi_usart_config_parity(usart_handle_t handle, usart_parity_e parity)
  115. {
  116. USART_NULL_PARAM_CHK(handle);
  117. ck_usart_priv_t *usart_priv = handle;
  118. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  119. WAIT_USART_IDLE(addr);
  120. switch (parity)
  121. {
  122. case USART_PARITY_NONE:
  123. /*CLear the PEN bit(LCR[3]) to disable parity.*/
  124. addr->LCR &= (~LCR_PARITY_ENABLE);
  125. break;
  126. case USART_PARITY_ODD:
  127. /* Set PEN and clear EPS(LCR[4]) to set the ODD parity. */
  128. addr->LCR |= LCR_PARITY_ENABLE;
  129. addr->LCR &= LCR_PARITY_ODD;
  130. break;
  131. case USART_PARITY_EVEN:
  132. /* Set PEN and EPS(LCR[4]) to set the EVEN parity.*/
  133. addr->LCR |= LCR_PARITY_ENABLE;
  134. addr->LCR |= LCR_PARITY_EVEN;
  135. break;
  136. default:
  137. return ERR_USART(USART_ERROR_PARITY);
  138. }
  139. return 0;
  140. }
  141. /**
  142. \brief config usart stop bit number.
  143. \param[in] handle usart handle to operate.
  144. \param[in] stopbits \ref usart_stop_bits_e
  145. \return error code
  146. */
  147. int32_t csi_usart_config_stopbits(usart_handle_t handle, usart_stop_bits_e stopbit)
  148. {
  149. USART_NULL_PARAM_CHK(handle);
  150. ck_usart_priv_t *usart_priv = handle;
  151. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  152. WAIT_USART_IDLE(addr);
  153. switch (stopbit)
  154. {
  155. case USART_STOP_BITS_1:
  156. /* Clear the STOP bit to set 1 stop bit*/
  157. addr->LCR &= LCR_STOP_BIT1;
  158. break;
  159. case USART_STOP_BITS_2:
  160. /*
  161. * If the STOP bit is set "1",we'd gotten 1.5 stop
  162. * bits when DLS(LCR[1:0]) is zero, else 2 stop bits.
  163. */
  164. addr->LCR |= LCR_STOP_BIT2;
  165. break;
  166. default:
  167. return ERR_USART(USART_ERROR_STOP_BITS);
  168. }
  169. return 0;
  170. }
  171. /**
  172. \brief config usart data length.
  173. \param[in] handle usart handle to operate.
  174. \param[in] databits \ref usart_data_bits_e
  175. \return error code
  176. */
  177. int32_t csi_usart_config_databits(usart_handle_t handle, usart_data_bits_e databits)
  178. {
  179. USART_NULL_PARAM_CHK(handle);
  180. ck_usart_priv_t *usart_priv = handle;
  181. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  182. WAIT_USART_IDLE(addr);
  183. /* The word size decides by the DLS bits(LCR[1:0]), and the
  184. * corresponding relationship between them is:
  185. * DLS word size
  186. * 00 -- 5 bits
  187. * 01 -- 6 bits
  188. * 10 -- 7 bits
  189. * 11 -- 8 bits
  190. */
  191. switch (databits)
  192. {
  193. case USART_DATA_BITS_5:
  194. addr->LCR &= LCR_WORD_SIZE_5;
  195. break;
  196. case USART_DATA_BITS_6:
  197. addr->LCR &= 0xfd;
  198. addr->LCR |= LCR_WORD_SIZE_6;
  199. break;
  200. case USART_DATA_BITS_7:
  201. addr->LCR &= 0xfe;
  202. addr->LCR |= LCR_WORD_SIZE_7;
  203. break;
  204. case USART_DATA_BITS_8:
  205. addr->LCR |= LCR_WORD_SIZE_8;
  206. break;
  207. default:
  208. return ERR_USART(USART_ERROR_DATA_BITS);
  209. }
  210. return 0;
  211. }
  212. int32_t ck_usart_set_int_flag(usart_handle_t handle,uint32_t flag)
  213. {
  214. ck_usart_priv_t *usart_priv = handle;
  215. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  216. addr->IER |= flag;
  217. return 0;
  218. }
  219. int32_t ck_usart_clr_int_flag(usart_handle_t handle,uint32_t flag)
  220. {
  221. ck_usart_priv_t *usart_priv = handle;
  222. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  223. addr->IER &= ~flag;
  224. return 0;
  225. }
  226. /**
  227. \brief get character in query mode.
  228. \param[in] instance usart instance to operate.
  229. \param[in] the pointer to the recieve charater.
  230. \return error code
  231. */
  232. int32_t csi_usart_getchar(usart_handle_t handle, uint8_t *ch)
  233. {
  234. USART_NULL_PARAM_CHK(handle);
  235. USART_NULL_PARAM_CHK(ch);
  236. ck_usart_priv_t *usart_priv = handle;
  237. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  238. while (!(addr->LSR & LSR_DATA_READY));
  239. *ch = addr->RBR;
  240. return 0;
  241. }
  242. /**
  243. \brief get character in query mode.
  244. \param[in] instance usart instance to operate.
  245. \param[in] the pointer to the recieve charater.
  246. \return error code
  247. */
  248. int csi_uart_getchar(usart_handle_t handle)
  249. {
  250. volatile int ch;
  251. USART_NULL_PARAM_CHK(handle);
  252. ck_usart_priv_t *usart_priv = handle;
  253. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  254. ch = -1;
  255. if (addr->LSR & LSR_DATA_READY)
  256. {
  257. ch = addr->RBR & 0xff;
  258. }
  259. return ch;
  260. }
  261. /**
  262. \brief transmit character in query mode.
  263. \param[in] instance usart instance to operate.
  264. \param[in] ch the input charater
  265. \return error code
  266. */
  267. int32_t csi_usart_putchar(usart_handle_t handle, uint8_t ch)
  268. {
  269. USART_NULL_PARAM_CHK(handle);
  270. ck_usart_priv_t *usart_priv = handle;
  271. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  272. uint32_t timecount = 0;
  273. while ((!(addr->LSR & DW_LSR_TRANS_EMPTY)))
  274. {
  275. timecount++;
  276. if (timecount >= UART_BUSY_TIMEOUT)
  277. {
  278. return ERR_USART(DRV_ERROR_TIMEOUT);
  279. }
  280. }
  281. addr->THR = ch;
  282. return 0;
  283. }
  284. /**
  285. \brief interrupt service function for transmitter holding register empty.
  286. \param[in] usart_priv usart private to operate.
  287. */
  288. void ck_usart_intr_threshold_empty(int32_t idx, ck_usart_priv_t *usart_priv)
  289. {
  290. if (usart_priv->tx_total_num == 0)
  291. {
  292. return;
  293. }
  294. volatile int i = 500;
  295. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  296. if (usart_priv->tx_cnt >= usart_priv->tx_total_num)
  297. {
  298. addr->IER &= (~IER_THRE_INT_ENABLE);
  299. usart_priv->last_tx_num = usart_priv->tx_total_num;
  300. /* fix hardware bug */
  301. while (addr->USR & USR_UART_BUSY);
  302. i = 500;
  303. while (i--);
  304. usart_priv->tx_cnt = 0;
  305. usart_priv->tx_busy = 0;
  306. usart_priv->tx_buf = NULL;
  307. usart_priv->tx_total_num = 0;
  308. if (usart_priv->cb_event)
  309. {
  310. usart_priv->cb_event(idx, USART_EVENT_SEND_COMPLETE);
  311. }
  312. } else
  313. {
  314. /* fix hardware bug */
  315. while (addr->USR & USR_UART_BUSY);
  316. i = 500;
  317. while (i--);
  318. addr->THR = *((uint8_t *)usart_priv->tx_buf);
  319. usart_priv->tx_cnt++;
  320. usart_priv->tx_buf++;
  321. }
  322. }
  323. /**
  324. \brief interrupt service function for receiver data available.
  325. \param[in] usart_priv usart private to operate.
  326. */
  327. static void ck_usart_intr_recv_data(int32_t idx, ck_usart_priv_t *usart_priv)
  328. {
  329. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  330. uint8_t data = addr->RBR;
  331. *((uint8_t *)usart_priv->rx_buf) = data;
  332. usart_priv->rx_cnt++;
  333. usart_priv->rx_buf++;
  334. if (usart_priv->rx_cnt >= usart_priv->rx_total_num)
  335. {
  336. usart_priv->last_rx_num = usart_priv->rx_total_num;
  337. usart_priv->rx_cnt = 0;
  338. usart_priv->rx_buf = NULL;
  339. usart_priv->rx_busy = 0;
  340. usart_priv->rx_total_num = 0;
  341. if (usart_priv->cb_event)
  342. {
  343. usart_priv->cb_event(idx, USART_EVENT_RECEIVE_COMPLETE);
  344. }
  345. }
  346. }
  347. /**
  348. \brief interrupt service function for receiver line.
  349. \param[in] usart_priv usart private to operate.
  350. */
  351. static void ck_usart_intr_recv_line(int32_t idx, ck_usart_priv_t *usart_priv)
  352. {
  353. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  354. uint32_t lsr_stat = addr->LSR;
  355. addr->IER &= (~IER_THRE_INT_ENABLE);
  356. uint32_t timecount = 0;
  357. while (addr->LSR & 0x1)
  358. {
  359. addr->RBR;
  360. timecount++;
  361. if (timecount >= UART_BUSY_TIMEOUT)
  362. {
  363. if (usart_priv->cb_event)
  364. {
  365. usart_priv->cb_event(idx, USART_EVENT_RX_TIMEOUT);
  366. }
  367. return;
  368. }
  369. }
  370. /** Break Interrupt bit. This is used to indicate the detection of a
  371. * break sequence on the serial input data.
  372. */
  373. if (lsr_stat & DW_LSR_BI)
  374. {
  375. if (usart_priv->cb_event)
  376. {
  377. usart_priv->cb_event(idx, USART_EVENT_RX_BREAK);
  378. }
  379. return;
  380. }
  381. /** Framing Error bit. This is used to indicate the occurrence of a
  382. * framing error in the receiver. A framing error occurs when the receiver
  383. * does not detect a valid STOP bit in the received data.
  384. */
  385. if (lsr_stat & DW_LSR_FE)
  386. {
  387. if (usart_priv->cb_event)
  388. {
  389. usart_priv->cb_event(idx, USART_EVENT_RX_FRAMING_ERROR);
  390. }
  391. return;
  392. }
  393. /** Framing Error bit. This is used to indicate the occurrence of a
  394. * framing error in the receiver. A framing error occurs when the
  395. * receiver does not detect a valid STOP bit in the received data.
  396. */
  397. if (lsr_stat & DW_LSR_PE)
  398. {
  399. if (usart_priv->cb_event)
  400. {
  401. usart_priv->cb_event(idx, USART_EVENT_RX_PARITY_ERROR);
  402. }
  403. return;
  404. }
  405. /** Overrun error bit. This is used to indicate the occurrence of an overrun error.
  406. * This occurs if a new data character was received before the previous data was read.
  407. */
  408. if (lsr_stat & DW_LSR_OE)
  409. {
  410. if (usart_priv->cb_event)
  411. {
  412. usart_priv->cb_event(idx, USART_EVENT_RX_OVERFLOW);
  413. }
  414. return;
  415. }
  416. }
  417. /**
  418. \brief interrupt service function for character timeout.
  419. \param[in] usart_priv usart private to operate.
  420. */
  421. static void ck_usart_intr_char_timeout(int32_t idx, ck_usart_priv_t *usart_priv)
  422. {
  423. if ((usart_priv->rx_total_num != 0) && (usart_priv->rx_buf != NULL))
  424. {
  425. ck_usart_intr_recv_data(idx, usart_priv);
  426. return;
  427. }
  428. if (usart_priv->cb_event)
  429. {
  430. usart_priv->cb_event(idx, USART_EVENT_RECEIVED);
  431. } else
  432. {
  433. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  434. uint32_t timecount = 0;
  435. while (addr->LSR & 0x1)
  436. {
  437. addr->RBR;
  438. timecount++;
  439. if (timecount >= UART_BUSY_TIMEOUT)
  440. {
  441. if (usart_priv->cb_event)
  442. {
  443. usart_priv->cb_event(idx, USART_EVENT_RX_TIMEOUT);
  444. }
  445. return;
  446. }
  447. }
  448. }
  449. }
  450. /**
  451. \brief the interrupt service function.
  452. \param[in] index of usart instance.
  453. */
  454. void ck_usart_irqhandler(int32_t idx)
  455. {
  456. ck_usart_priv_t *usart_priv = &usart_instance[idx];
  457. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  458. uint8_t intr_state = addr->IIR & 0xf;
  459. switch (intr_state)
  460. {
  461. case DW_IIR_THR_EMPTY: /* interrupt source:transmitter holding register empty */
  462. ck_usart_intr_threshold_empty(idx, usart_priv);
  463. break;
  464. case DW_IIR_RECV_DATA: /* interrupt source:receiver data available or receiver fifo trigger level reached */
  465. ck_usart_intr_char_timeout(idx, usart_priv);
  466. //ck_usart_intr_recv_data(idx, usart_priv);
  467. break;
  468. case DW_IIR_RECV_LINE:
  469. ck_usart_intr_recv_line(idx, usart_priv);
  470. break;
  471. case DW_IIR_CHAR_TIMEOUT:
  472. ck_usart_intr_char_timeout(idx, usart_priv);
  473. break;
  474. default:
  475. break;
  476. }
  477. }
  478. /**
  479. \brief Get driver capabilities.
  480. \param[in] idx usart index
  481. \return \ref usart_capabilities_t
  482. */
  483. usart_capabilities_t csi_usart_get_capabilities(int32_t idx)
  484. {
  485. if (idx < 0 || idx >= CONFIG_USART_NUM)
  486. {
  487. usart_capabilities_t ret;
  488. memset(&ret, 0, sizeof(usart_capabilities_t));
  489. return ret;
  490. }
  491. return usart_capabilities;
  492. }
  493. /**
  494. \brief Initialize USART Interface. 1. Initializes the resources needed for the USART interface 2.registers event callback function
  495. \param[in] idx usart index
  496. \param[in] cb_event Pointer to \ref usart_event_cb_t
  497. \return return usart handle if success
  498. */
  499. usart_handle_t csi_usart_initialize(int32_t idx, usart_event_cb_t cb_event)
  500. {
  501. uint32_t base = 0u;
  502. uint32_t irq = 0u;
  503. void *handler;
  504. int32_t ret = target_usart_init(idx, &base, &irq, &handler);
  505. if (ret < 0 || ret >= CONFIG_USART_NUM)
  506. {
  507. return NULL;
  508. }
  509. ck_usart_priv_t *usart_priv = &usart_instance[idx];
  510. usart_priv->base = base;
  511. usart_priv->irq = irq;
  512. usart_priv->cb_event = cb_event;
  513. usart_priv->idx = idx;
  514. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  515. /* enable received data available */
  516. addr->IER = IER_RDA_INT_ENABLE | IIR_RECV_LINE_ENABLE;
  517. drv_irq_register(usart_priv->irq, handler);
  518. drv_irq_enable(usart_priv->irq);
  519. return usart_priv;
  520. }
  521. /**
  522. \brief De-initialize UART Interface. stops operation and releases the software resources used by the interface
  523. \param[in] handle usart handle to operate.
  524. \return error code
  525. */
  526. int32_t csi_usart_uninitialize(usart_handle_t handle)
  527. {
  528. USART_NULL_PARAM_CHK(handle);
  529. ck_usart_priv_t *usart_priv = handle;
  530. drv_irq_disable(usart_priv->irq);
  531. drv_irq_unregister(usart_priv->irq);
  532. usart_priv->cb_event = NULL;
  533. return 0;
  534. }
  535. /**
  536. \brief config usart mode.
  537. \param[in] handle usart handle to operate.
  538. \param[in] baud baud rate
  539. \param[in] mode \ref usart_mode_e
  540. \param[in] parity \ref usart_parity_e
  541. \param[in] stopbits \ref usart_stop_bits_e
  542. \param[in] bits \ref usart_data_bits_e
  543. \return error code
  544. */
  545. int32_t csi_usart_config(usart_handle_t handle,
  546. uint32_t baud,
  547. usart_mode_e mode,
  548. usart_parity_e parity,
  549. usart_stop_bits_e stopbits,
  550. usart_data_bits_e bits)
  551. {
  552. int32_t ret;
  553. /* control the data_bit of the usart*/
  554. ret = csi_usart_config_baudrate(handle, baud);
  555. if (ret < 0)
  556. {
  557. return ret;
  558. }
  559. /* control mode of the usart*/
  560. ret = csi_usart_config_mode(handle, mode);
  561. if (ret < 0)
  562. {
  563. return ret;
  564. }
  565. /* control the parity of the usart*/
  566. ret = csi_usart_config_parity(handle, parity);
  567. if (ret < 0)
  568. {
  569. return ret;
  570. }
  571. /* control the stopbit of the usart*/
  572. ret = csi_usart_config_stopbits(handle, stopbits);
  573. if (ret < 0)
  574. {
  575. return ret;
  576. }
  577. ret = csi_usart_config_databits(handle, bits);
  578. if (ret < 0)
  579. {
  580. return ret;
  581. }
  582. return 0;
  583. }
  584. /**
  585. \brief Start sending data to UART transmitter,(received data is ignored).
  586. The function is non-blocking,UART_EVENT_TRANSFER_COMPLETE is signaled when transfer completes.
  587. csi_usart_get_status can indicates if transmission is still in progress or pending
  588. \param[in] handle usart handle to operate.
  589. \param[in] data Pointer to buffer with data to send to UART transmitter. data_type is : uint8_t for 1..8 data bits, uint16_t for 9..16 data bits,uint32_t for 17..32 data bits,
  590. \param[in] num Number of data items to send
  591. \return error code
  592. */
  593. int32_t csi_usart_send(usart_handle_t handle, const void *data, uint32_t num)
  594. {
  595. USART_NULL_PARAM_CHK(handle);
  596. USART_NULL_PARAM_CHK(data);
  597. if (num == 0)
  598. {
  599. return ERR_USART(DRV_ERROR_PARAMETER);
  600. }
  601. ck_usart_priv_t *usart_priv = handle;
  602. usart_priv->tx_buf = (uint8_t *)data;
  603. usart_priv->tx_total_num = num;
  604. usart_priv->tx_cnt = 0;
  605. usart_priv->tx_busy = 1;
  606. usart_priv->last_tx_num = 0;
  607. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  608. ck_usart_intr_threshold_empty(usart_priv->idx, usart_priv);
  609. /* enable the interrupt*/
  610. addr->IER |= IER_THRE_INT_ENABLE;
  611. return 0;
  612. }
  613. /**
  614. \brief Abort Send data to UART transmitter
  615. \param[in] handle usart handle to operate.
  616. \return error code
  617. */
  618. int32_t csi_usart_abort_send(usart_handle_t handle)
  619. {
  620. USART_NULL_PARAM_CHK(handle);
  621. ck_usart_priv_t *usart_priv = handle;
  622. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  623. addr->IER &= (~IER_THRE_INT_ENABLE);
  624. usart_priv->tx_cnt = usart_priv->tx_total_num;
  625. usart_priv->tx_cnt = 0;
  626. usart_priv->tx_busy = 0;
  627. usart_priv->tx_buf = NULL;
  628. usart_priv->tx_total_num = 0;
  629. return 0;
  630. }
  631. /**
  632. \brief Start receiving data from UART receiver.transmits the default value as specified by csi_usart_set_default_tx_value
  633. \param[in] handle usart handle to operate.
  634. \param[out] data Pointer to buffer for data to receive from UART receiver
  635. \param[in] num Number of data items to receive
  636. \return error code
  637. */
  638. int32_t csi_usart_receive(usart_handle_t handle, void *data, uint32_t num)
  639. {
  640. USART_NULL_PARAM_CHK(handle);
  641. USART_NULL_PARAM_CHK(data);
  642. ck_usart_priv_t *usart_priv = handle;
  643. usart_priv->rx_buf = (uint8_t *)data; // Save receive buffer usart
  644. usart_priv->rx_total_num = num; // Save number of data to be received
  645. usart_priv->rx_cnt = 0;
  646. usart_priv->rx_busy = 1;
  647. usart_priv->last_rx_num = 0;
  648. return 0;
  649. }
  650. /**
  651. \brief query data from UART receiver FIFO.
  652. \param[in] handle usart handle to operate.
  653. \param[out] data Pointer to buffer for data to receive from UART receiver
  654. \param[in] num Number of data items to receive
  655. \return receive fifo data num
  656. */
  657. int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num)
  658. {
  659. USART_NULL_PARAM_CHK(handle);
  660. USART_NULL_PARAM_CHK(data);
  661. ck_usart_priv_t *usart_priv = handle;
  662. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  663. int32_t recv_num = 0;
  664. uint8_t *dest = (uint8_t *)data;
  665. while (addr->LSR & 0x1)
  666. {
  667. *dest++ = addr->RBR;
  668. recv_num++;
  669. if (recv_num >= num)
  670. {
  671. break;
  672. }
  673. }
  674. return recv_num;
  675. }
  676. /**
  677. \brief Abort Receive data from UART receiver
  678. \param[in] handle usart handle to operate.
  679. \return error code
  680. */
  681. int32_t csi_usart_abort_receive(usart_handle_t handle)
  682. {
  683. USART_NULL_PARAM_CHK(handle);
  684. ck_usart_priv_t *usart_priv = handle;
  685. usart_priv->rx_cnt = usart_priv->rx_total_num;
  686. return 0;
  687. }
  688. /**
  689. \brief Start sending/receiving data to/from UART transmitter/receiver.
  690. \param[in] handle usart handle to operate.
  691. \param[in] data_out Pointer to buffer with data to send to USART transmitter
  692. \param[out] data_in Pointer to buffer for data to receive from USART receiver
  693. \param[in] num Number of data items to transfer
  694. \return error code
  695. */
  696. int32_t csi_usart_transfer(usart_handle_t handle, const void *data_out, void *data_in, uint32_t num)
  697. {
  698. USART_NULL_PARAM_CHK(handle);
  699. return ERR_USART(DRV_ERROR_UNSUPPORTED);
  700. }
  701. /**
  702. \brief abort sending/receiving data to/from USART transmitter/receiver.
  703. \param[in] handle usart handle to operate.
  704. \return error code
  705. */
  706. int32_t csi_usart_abort_transfer(usart_handle_t handle)
  707. {
  708. USART_NULL_PARAM_CHK(handle);
  709. return ERR_USART(DRV_ERROR_UNSUPPORTED);
  710. }
  711. /**
  712. \brief Get USART status.
  713. \param[in] handle usart handle to operate.
  714. \return USART status \ref usart_status_t
  715. */
  716. usart_status_t csi_usart_get_status(usart_handle_t handle)
  717. {
  718. usart_status_t usart_status;
  719. memset(&usart_status, 0, sizeof(usart_status_t));
  720. if (handle == NULL)
  721. {
  722. return usart_status;
  723. }
  724. ck_usart_priv_t *usart_priv = handle;
  725. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  726. uint32_t line_status_reg = addr->LSR;
  727. usart_status.tx_busy = usart_priv->tx_busy;
  728. usart_status.rx_busy = usart_priv->rx_busy;
  729. if (line_status_reg & DW_LSR_BI)
  730. {
  731. usart_status.rx_break = 1;
  732. }
  733. if (line_status_reg & DW_LSR_FE)
  734. {
  735. usart_status.rx_framing_error = 1;
  736. }
  737. if (line_status_reg & DW_LSR_PE)
  738. {
  739. usart_status.rx_parity_error = 1;
  740. }
  741. usart_status.tx_enable = 1;
  742. usart_status.rx_enable = 1;
  743. return usart_status;
  744. }
  745. /**
  746. \brief control the transmit.
  747. \param[in] handle usart handle to operate.
  748. \param[in] 1 - enable the transmitter. 0 - disable the transmitter
  749. \return error code
  750. */
  751. int32_t csi_usart_control_tx(usart_handle_t handle, uint32_t enable)
  752. {
  753. USART_NULL_PARAM_CHK(handle);
  754. return 0;
  755. }
  756. /**
  757. \brief control the receive.
  758. \param[in] handle usart handle to operate.
  759. \param[in] 1 - enable the receiver. 0 - disable the receiver
  760. \return error code
  761. */
  762. int32_t csi_usart_control_rx(usart_handle_t handle, uint32_t enable)
  763. {
  764. USART_NULL_PARAM_CHK(handle);
  765. return 0;
  766. }
  767. /**
  768. \brief control the break.
  769. \param[in] handle usart handle to operate.
  770. \param[in] 1- Enable continuous Break transmission,0 - disable continuous Break transmission
  771. \return error code
  772. */
  773. int32_t csi_usart_control_break(usart_handle_t handle, uint32_t enable)
  774. {
  775. USART_NULL_PARAM_CHK(handle);
  776. return ERR_USART(DRV_ERROR_UNSUPPORTED);
  777. }
  778. /**
  779. \brief flush receive/send data.
  780. \param[in] handle usart handle to operate.
  781. \param[in] type \ref usart_flush_type_e.
  782. \return error code
  783. */
  784. int32_t csi_usart_flush(usart_handle_t handle, usart_flush_type_e type)
  785. {
  786. USART_NULL_PARAM_CHK(handle);
  787. ck_usart_priv_t *usart_priv = handle;
  788. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  789. uint32_t timecount = 0;
  790. if (type == USART_FLUSH_WRITE) {
  791. while ((!(addr->LSR & DW_LSR_TEMT)))
  792. {
  793. timecount++;
  794. if (timecount >= UART_BUSY_TIMEOUT)
  795. {
  796. return ERR_USART(DRV_ERROR_TIMEOUT);
  797. }
  798. }
  799. } else if (type == USART_FLUSH_READ)
  800. {
  801. while (addr->LSR & 0x1) {
  802. timecount++;
  803. if (timecount >= UART_BUSY_TIMEOUT)
  804. {
  805. return ERR_USART(DRV_ERROR_TIMEOUT);
  806. }
  807. }
  808. } else
  809. {
  810. return ERR_USART(DRV_ERROR_PARAMETER);
  811. }
  812. return 0;
  813. }
  814. /**
  815. \brief set interrupt mode.
  816. \param[in] handle usart handle to operate.
  817. \param[in] type \ref usart_intr_type_e.
  818. \param[in] flag 0-OFF, 1-ON.
  819. \return error code
  820. */
  821. int32_t csi_usart_set_interrupt(usart_handle_t handle, usart_intr_type_e type, int32_t flag)
  822. {
  823. USART_NULL_PARAM_CHK(handle);
  824. ck_usart_priv_t *usart_priv = handle;
  825. ck_usart_reg_t *addr = (ck_usart_reg_t *)(usart_priv->base);
  826. switch (type)
  827. {
  828. case USART_INTR_WRITE:
  829. if (flag == 0)
  830. {
  831. addr->IER &= ~IER_THRE_INT_ENABLE;
  832. } else if (flag == 1)
  833. {
  834. addr->IER |= IER_THRE_INT_ENABLE;
  835. } else
  836. {
  837. return ERR_USART(DRV_ERROR_PARAMETER);
  838. }
  839. break;
  840. case USART_INTR_READ:
  841. if (flag == 0)
  842. {
  843. addr->IER &= ~IER_RDA_INT_ENABLE;
  844. } else if (flag == 1)
  845. {
  846. addr->IER |= IER_RDA_INT_ENABLE;
  847. } else
  848. {
  849. return ERR_USART(DRV_ERROR_PARAMETER);
  850. }
  851. break;
  852. default:
  853. return ERR_USART(DRV_ERROR_PARAMETER);
  854. }
  855. return 0;
  856. }
  857. /**
  858. \brief Get usart send data count.
  859. \param[in] handle usart handle to operate.
  860. \return number of currently transmitted data bytes
  861. */
  862. uint32_t csi_usart_get_tx_count(usart_handle_t handle)
  863. {
  864. USART_NULL_PARAM_CHK(handle);
  865. ck_usart_priv_t *usart_priv = handle;
  866. if (usart_priv->tx_busy)
  867. {
  868. return usart_priv->tx_cnt;
  869. } else
  870. {
  871. return usart_priv->last_tx_num;
  872. }
  873. }
  874. /**
  875. \brief Get usart receive data count.
  876. \param[in] handle usart handle to operate.
  877. \return number of currently received data bytes
  878. */
  879. uint32_t csi_usart_get_rx_count(usart_handle_t handle)
  880. {
  881. USART_NULL_PARAM_CHK(handle);
  882. ck_usart_priv_t *usart_priv = handle;
  883. if (usart_priv->rx_busy)
  884. {
  885. return usart_priv->rx_cnt;
  886. } else
  887. {
  888. return usart_priv->last_rx_num;
  889. }
  890. }
  891. /**
  892. \brief control usart power.
  893. \param[in] handle usart handle to operate.
  894. \param[in] state power state.\ref csi_power_stat_e.
  895. \return error code
  896. */
  897. int32_t csi_usart_power_control(usart_handle_t handle, csi_power_stat_e state)
  898. {
  899. USART_NULL_PARAM_CHK(handle);
  900. return ERR_USART(DRV_ERROR_UNSUPPORTED);
  901. }
  902. /**
  903. \brief config usart flow control type.
  904. \param[in] handle usart handle to operate.
  905. \param[in] flowctrl_type flow control type.\ref usart_flowctrl_type_e.
  906. \return error code
  907. */
  908. int32_t csi_usart_config_flowctrl(usart_handle_t handle,
  909. usart_flowctrl_type_e flowctrl_type)
  910. {
  911. USART_NULL_PARAM_CHK(handle);
  912. switch (flowctrl_type)
  913. {
  914. case USART_FLOWCTRL_CTS:
  915. return ERR_USART(DRV_ERROR_UNSUPPORTED);
  916. case USART_FLOWCTRL_RTS:
  917. return ERR_USART(DRV_ERROR_UNSUPPORTED);
  918. case USART_FLOWCTRL_CTS_RTS:
  919. return ERR_USART(DRV_ERROR_UNSUPPORTED);
  920. break;
  921. case USART_FLOWCTRL_NONE:
  922. return ERR_USART(DRV_ERROR_UNSUPPORTED);
  923. break;
  924. default:
  925. return ERR_USART(DRV_ERROR_UNSUPPORTED);
  926. }
  927. return 0;
  928. }
  929. /**
  930. \brief config usart clock Polarity and Phase.
  931. \param[in] handle usart handle to operate.
  932. \param[in] cpol Clock Polarity.\ref usart_cpol_e.
  933. \param[in] cpha Clock Phase.\ref usart_cpha_e.
  934. \return error code
  935. */
  936. int32_t csi_usart_config_clock(usart_handle_t handle, usart_cpol_e cpol, usart_cpha_e cpha)
  937. {
  938. USART_NULL_PARAM_CHK(handle);
  939. return ERR_USART(DRV_ERROR_UNSUPPORTED);
  940. }