dw_usart.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. /*
  2. * Copyright (C) 2017 C-SKY Microsystems Co., Ltd. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /******************************************************************************
  17. * @file dw_usart.c
  18. * @brief CSI Source File for usart Driver
  19. * @version V1.0
  20. * @date 02. June 2017
  21. ******************************************************************************/
  22. #include <stdbool.h>
  23. #include "csi_core.h"
  24. #include "drv_usart.h"
  25. #include "dw_usart.h"
  26. #include "soc.h"
  27. #define ERR_USART(errno) (CSI_DRV_ERRNO_USART_BASE | errno)
  28. /*
  29. * setting config may be accessed when the USART is not
  30. * busy(USR[0]=0) and the DLAB bit(LCR[7]) is set.
  31. */
  32. #define WAIT_USART_IDLE(addr)\
  33. do { \
  34. int32_t timecount = 0; \
  35. while ((addr->USR & USR_UART_BUSY) && (timecount < UART_BUSY_TIMEOUT)) {\
  36. timecount++;\
  37. }\
  38. if (timecount >= UART_BUSY_TIMEOUT) {\
  39. return ERR_USART(EDRV_TIMEOUT);\
  40. } \
  41. } while(0)
  42. #define USART_NULL_PARAM_CHK(para) \
  43. do { \
  44. if (para == NULL) { \
  45. return ERR_USART(EDRV_PARAMETER); \
  46. } \
  47. } while (0)
  48. typedef struct {
  49. uint32_t base;
  50. uint32_t irq;
  51. usart_event_cb_t cb_event; ///< Event callback
  52. void *cb_arg;
  53. uint32_t rx_total_num;
  54. uint32_t tx_total_num;
  55. uint8_t *rx_buf;
  56. uint8_t *tx_buf;
  57. volatile uint32_t rx_cnt;
  58. volatile uint32_t tx_cnt;
  59. volatile uint32_t tx_busy;
  60. volatile uint32_t rx_busy;
  61. } dw_usart_priv_t;
  62. static dw_usart_priv_t usart_instance[CONFIG_USART_NUM];
  63. static const usart_capabilities_t usart_capabilities = {
  64. .asynchronous = 1, /* supports USART (Asynchronous) mode */
  65. .synchronous_master = 0, /* supports Synchronous Master mode */
  66. .synchronous_slave = 0, /* supports Synchronous Slave mode */
  67. .single_wire = 0, /* supports USART Single-wire mode */
  68. .event_tx_complete = 1, /* Transmit completed event */
  69. .event_rx_timeout = 0, /* Signal receive character timeout event */
  70. };
  71. /**
  72. \brief set the bautrate of usart.
  73. \param[in] addr usart base to operate.
  74. \param[in] baudrate.
  75. \param[in] apbfreq the frequence of the apb.
  76. \return error code
  77. */
  78. static int32_t dw_usart_set_baudrate(dw_usart_reg_t *addr, uint32_t baudrate, uint32_t apbfreq)
  79. {
  80. WAIT_USART_IDLE(addr);
  81. /* baudrate=(seriak clock freq)/(16*divisor); algorithm :rounding*/
  82. uint32_t divisor = ((apbfreq * 10) / baudrate) >> 4;
  83. if ((divisor % 10) >= 5) {
  84. divisor = (divisor / 10) + 1;
  85. } else {
  86. divisor = divisor / 10;
  87. }
  88. addr->LCR |= LCR_SET_DLAB;
  89. /* DLL and DLH is lower 8-bits and higher 8-bits of divisor.*/
  90. addr->DLL = divisor & 0xff;
  91. addr->DLH = (divisor >> 8) & 0xff;
  92. /*
  93. * The DLAB must be cleared after the baudrate is setted
  94. * to access other registers.
  95. */
  96. addr->LCR &= (~LCR_SET_DLAB);
  97. return 0;
  98. }
  99. /**
  100. \brief enable or disable parity.
  101. \param[in] addr usart base to operate.
  102. \param[in] parity ODD=8, EVEN=16, or NONE=0.
  103. \return error code
  104. */
  105. static int32_t dw_usart_set_parity(dw_usart_reg_t *addr, usart_parity_e parity)
  106. {
  107. WAIT_USART_IDLE(addr);
  108. switch (parity) {
  109. case USART_PARITY_NONE:
  110. /*CLear the PEN bit(LCR[3]) to disable parity.*/
  111. addr->LCR &= (~LCR_PARITY_ENABLE);
  112. break;
  113. case USART_PARITY_ODD:
  114. /* Set PEN and clear EPS(LCR[4]) to set the ODD parity. */
  115. addr->LCR |= LCR_PARITY_ENABLE;
  116. addr->LCR &= LCR_PARITY_ODD;
  117. break;
  118. case USART_PARITY_EVEN:
  119. /* Set PEN and EPS(LCR[4]) to set the EVEN parity.*/
  120. addr->LCR |= LCR_PARITY_ENABLE;
  121. addr->LCR |= LCR_PARITY_EVEN;
  122. break;
  123. default:
  124. return ERR_USART(EDRV_USART_PARITY);
  125. }
  126. return 0;
  127. }
  128. /**
  129. \brief set the stop bit.
  130. \param[in] addr usart base to operate.
  131. \param[in] stopbit two possible value: USART_STOP_BITS_1 and USART_STOP_BITS_2.
  132. \return error code
  133. */
  134. static int32_t dw_usart_set_stopbit(dw_usart_reg_t *addr, usart_stop_bits_e stopbit)
  135. {
  136. WAIT_USART_IDLE(addr);
  137. switch (stopbit) {
  138. case USART_STOP_BITS_1:
  139. /* Clear the STOP bit to set 1 stop bit*/
  140. addr->LCR &= LCR_STOP_BIT1;
  141. break;
  142. case USART_STOP_BITS_2:
  143. /*
  144. * If the STOP bit is set "1",we'd gotten 1.5 stop
  145. * bits when DLS(LCR[1:0]) is zero, else 2 stop bits.
  146. */
  147. addr->LCR |= LCR_STOP_BIT2;
  148. break;
  149. default:
  150. return ERR_USART(EDRV_USART_STOP_BITS);
  151. }
  152. return 0;
  153. }
  154. /**
  155. \brief the transmit data length,and we have four choices:5, 6, 7, and 8 bits.
  156. \param[in] addr usart base to operate.
  157. \param[in] databits the data length that user decides.
  158. \return error code
  159. */
  160. static int32_t dw_usart_set_databit(dw_usart_reg_t *addr, usart_data_bits_e databits)
  161. {
  162. WAIT_USART_IDLE(addr);
  163. /* The word size decides by the DLS bits(LCR[1:0]), and the
  164. * corresponding relationship between them is:
  165. * DLS word size
  166. * 00 -- 5 bits
  167. * 01 -- 6 bits
  168. * 10 -- 7 bits
  169. * 11 -- 8 bits
  170. */
  171. switch (databits) {
  172. case USART_DATA_BITS_5:
  173. addr->LCR &= LCR_WORD_SIZE_5;
  174. break;
  175. case USART_DATA_BITS_6:
  176. addr->LCR &= 0xfd;
  177. addr->LCR |= LCR_WORD_SIZE_6;
  178. break;
  179. case USART_DATA_BITS_7:
  180. addr->LCR &= 0xfe;
  181. addr->LCR |= LCR_WORD_SIZE_7;
  182. break;
  183. case USART_DATA_BITS_8:
  184. addr->LCR |= LCR_WORD_SIZE_8;
  185. break;
  186. default:
  187. return ERR_USART(EDRV_USART_DATA_BITS);
  188. }
  189. return 0;
  190. }
  191. /**
  192. \brief get character in query mode.
  193. \param[in] instance usart instance to operate.
  194. \param[in] the pointer to the recieve charater.
  195. \return error code
  196. */
  197. int32_t dw_usart_getchar(usart_handle_t handle, uint8_t *ch)
  198. {
  199. dw_usart_priv_t *usart_priv = handle;
  200. dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
  201. while (!(addr->LSR & LSR_DATA_READY));
  202. *ch = addr->RBR;
  203. return 0;
  204. }
  205. /**
  206. \brief get character in query mode.
  207. \param[in] instance usart instance to operate.
  208. \param[in] the pointer to the recieve charater.
  209. \return error code
  210. */
  211. int32_t dw_usart_getchar_no_poll(usart_handle_t handle, uint8_t *ch)
  212. {
  213. dw_usart_priv_t *usart_priv = handle;
  214. dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
  215. if (addr->LSR & LSR_DATA_READY)
  216. {
  217. *ch = addr->RBR;
  218. return 0;
  219. }
  220. else
  221. {
  222. return -1;
  223. }
  224. }
  225. int32_t dw_usart_set_int_flag(usart_handle_t handle,uint32_t flag)
  226. {
  227. dw_usart_priv_t *usart_priv = handle;
  228. dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
  229. addr->IER |= flag;
  230. return 0;
  231. }
  232. int32_t dw_usart_clr_int_flag(usart_handle_t handle,uint32_t flag)
  233. {
  234. dw_usart_priv_t *usart_priv = handle;
  235. dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
  236. addr->IER &= ~flag;
  237. return 0;
  238. }
  239. /**
  240. \brief transmit character in query mode.
  241. \param[in] instance usart instance to operate.
  242. \param[in] ch the input charater
  243. \return error code
  244. */
  245. int32_t dw_usart_putchar(usart_handle_t handle, uint8_t ch)
  246. {
  247. dw_usart_priv_t *usart_priv = handle;
  248. dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
  249. while ((!(addr->LSR & DW_LSR_TRANS_EMPTY)));
  250. if (ch == '\n')
  251. {
  252. addr->THR = '\r';
  253. while ((!(addr->LSR & DW_LSR_TRANS_EMPTY))) ;
  254. }
  255. addr->THR = ch;
  256. return 0;
  257. }
  258. /**
  259. \brief interrupt service function for transmitter holding register empty.
  260. \param[in] usart_priv usart private to operate.
  261. */
  262. static void dw_usart_intr_threshold_empty(dw_usart_priv_t *usart_priv)
  263. {
  264. if (usart_priv->tx_total_num == 0) {
  265. return;
  266. }
  267. uint8_t remain_txdata = usart_priv->tx_total_num - usart_priv->tx_cnt;
  268. uint8_t txdata_num = (remain_txdata > UART_MAX_FIFO) ? UART_MAX_FIFO : remain_txdata;
  269. dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
  270. uint8_t i = 0u;
  271. for (i = 0; i < txdata_num; i++) {
  272. addr->THR = *((uint8_t *)usart_priv->tx_buf);
  273. usart_priv->tx_cnt++;
  274. usart_priv->tx_buf++;
  275. }
  276. if (usart_priv->tx_cnt >= usart_priv->tx_total_num) {
  277. addr->IER &= (~IER_THRE_INT_ENABLE);
  278. while ((!(addr->LSR & DW_LSR_TEMT)));
  279. usart_priv->tx_cnt = 0;
  280. usart_priv->tx_busy = 0;
  281. usart_priv->tx_buf = NULL;
  282. usart_priv->tx_total_num = 0;
  283. if (usart_priv->cb_event) {
  284. usart_priv->cb_event(USART_EVENT_SEND_COMPLETE, usart_priv->cb_arg);
  285. }
  286. }
  287. }
  288. /**
  289. \brief interrupt service function for receiver data available.
  290. \param[in] usart_priv usart private to operate.
  291. */
  292. static void dw_usart_intr_recv_data(dw_usart_priv_t *usart_priv)
  293. {
  294. if (usart_priv->cb_event && (usart_priv->rx_total_num == 0)) {
  295. usart_priv->cb_event(USART_EVENT_RECEIVED, usart_priv->cb_arg);
  296. return;
  297. }
  298. dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
  299. uint8_t data = addr->RBR;
  300. if ((usart_priv->rx_total_num == 0) || (usart_priv->rx_buf == NULL)) {
  301. return;
  302. }
  303. *((uint8_t *)usart_priv->rx_buf) = data;
  304. usart_priv->rx_cnt++;
  305. usart_priv->rx_buf++;
  306. if (usart_priv->rx_cnt >= usart_priv->rx_total_num) {
  307. usart_priv->rx_cnt = 0;
  308. usart_priv->rx_buf = NULL;
  309. usart_priv->rx_busy = 0;
  310. usart_priv->rx_total_num = 0;
  311. if (usart_priv->cb_event) {
  312. usart_priv->cb_event(USART_EVENT_RECEIVE_COMPLETE, usart_priv->cb_arg);
  313. }
  314. }
  315. }
  316. /**
  317. \brief the interrupt service function.
  318. \param[in] index of usart instance.
  319. */
  320. void dw_usart_irqhandler(int32_t idx)
  321. {
  322. dw_usart_priv_t *usart_priv = &usart_instance[idx];
  323. dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
  324. uint8_t intr_state = addr->IIR & 0xf;
  325. switch (intr_state) {
  326. case DW_IIR_THR_EMPTY: /* interrupt source:transmitter holding register empty */
  327. dw_usart_intr_threshold_empty(usart_priv);
  328. break;
  329. case DW_IIR_RECV_DATA: /* interrupt source:receiver data available or receiver fifo trigger level reached */
  330. dw_usart_intr_recv_data(usart_priv);
  331. break;
  332. default:
  333. break;
  334. }
  335. }
  336. int32_t __attribute__((weak)) target_usart_init(pin_t tx, pin_t rx, uint32_t *base, uint32_t *irq)
  337. {
  338. return -1;
  339. }
  340. /**
  341. \brief Get driver capabilities.
  342. \param[in] handle usart handle to operate.
  343. \return \ref usart_capabilities_t
  344. */
  345. usart_capabilities_t csi_usart_get_capabilities(usart_handle_t handle)
  346. {
  347. return usart_capabilities;
  348. }
  349. /**
  350. \brief Initialize USART Interface. 1. Initializes the resources needed for the USART interface 2.registers event callback function
  351. \param[in] usart pin of tx
  352. \param[in] usart pin of rx
  353. \param[in] cb_event Pointer to \ref usart_event_cb_t
  354. \return return usart handle if success
  355. */
  356. usart_handle_t csi_usart_initialize(pin_t tx, pin_t rx, usart_event_cb_t cb_event, void *cb_arg)
  357. {
  358. uint32_t base = 0u;
  359. uint32_t irq = 0u;
  360. int32_t idx = target_usart_init(tx, rx, &base, &irq);
  361. if (idx < 0 || idx >= CONFIG_USART_NUM) {
  362. return NULL;
  363. }
  364. dw_usart_priv_t *usart_priv = &usart_instance[idx];
  365. usart_priv->base = base;
  366. usart_priv->irq = irq;
  367. usart_priv->cb_event = cb_event;
  368. usart_priv->cb_arg = cb_arg;
  369. dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
  370. /* FIFO enable */
  371. addr->FCR = DW_FCR_FIFOE;
  372. // /* enable received data available */
  373. // addr->IER = IER_RDA_INT_ENABLE;
  374. drv_nvic_enable_irq(usart_priv->irq);
  375. return usart_priv;
  376. }
  377. /**
  378. \brief De-initialize UART Interface. stops operation and releases the software resources used by the interface
  379. \param[in] handle usart handle to operate.
  380. \return error code
  381. */
  382. int32_t csi_usart_uninitialize(usart_handle_t handle)
  383. {
  384. USART_NULL_PARAM_CHK(handle);
  385. dw_usart_priv_t *usart_priv = handle;
  386. drv_nvic_disable_irq(usart_priv->irq);
  387. usart_priv->cb_event = NULL;
  388. return 0;
  389. }
  390. /**
  391. \brief config usart mode.
  392. \param[in] handle usart handle to operate.
  393. \param[in] sysclk configured system clock.
  394. \param[in] mode \ref usart_mode_e
  395. \param[in] parity \ref usart_parity_e
  396. \param[in] stopbits \ref usart_stop_bits_e
  397. \param[in] bits \ref usart_data_bits_e
  398. \param[in] baud configured baud
  399. \return error code
  400. */
  401. int32_t csi_usart_config(usart_handle_t handle,
  402. uint32_t sysclk,
  403. uint32_t baud,
  404. usart_mode_e mode,
  405. usart_parity_e parity,
  406. usart_stop_bits_e stopbits,
  407. usart_data_bits_e bits)
  408. {
  409. USART_NULL_PARAM_CHK(handle);
  410. dw_usart_priv_t *usart_priv = handle;
  411. dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
  412. /* control the data_bit of the usart*/
  413. int32_t ret = dw_usart_set_baudrate(addr, baud, sysclk);
  414. if (ret < 0) {
  415. return ret;
  416. }
  417. /* control the parity of the usart*/
  418. ret = dw_usart_set_parity(addr, parity);
  419. if (ret < 0) {
  420. return ret;
  421. }
  422. /* control the stopbit of the usart*/
  423. ret = dw_usart_set_stopbit(addr, stopbits);
  424. if (ret < 0) {
  425. return ret;
  426. }
  427. ret = dw_usart_set_databit(addr, bits);
  428. if (ret < 0) {
  429. return ret;
  430. }
  431. return 0;
  432. }
  433. /**
  434. \brief config usart default tx value. used in syn mode
  435. \param[in] handle usart handle to operate.
  436. \param[in] value default tx value
  437. \return error code
  438. */
  439. int32_t csi_usart_set_default_tx_value(usart_handle_t handle, uint32_t value)
  440. {
  441. USART_NULL_PARAM_CHK(handle);
  442. return ERR_USART(EDRV_UNSUPPORTED);
  443. }
  444. /**
  445. \brief Start sending data to UART transmitter,(received data is ignored).
  446. The function is non-blocking,UART_EVENT_TRANSFER_COMPLETE is signaled when transfer completes.
  447. csi_usart_get_status can indicates if transmission is still in progress or pending
  448. \param[in] handle usart handle to operate.
  449. \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,
  450. \param[in] num Number of data items to send
  451. \return error code
  452. */
  453. int32_t csi_usart_send(usart_handle_t handle, const void *data, uint32_t num)
  454. {
  455. USART_NULL_PARAM_CHK(handle);
  456. USART_NULL_PARAM_CHK(data);
  457. if (num == 0) {
  458. return ERR_USART(EDRV_PARAMETER);
  459. }
  460. dw_usart_priv_t *usart_priv = handle;
  461. uint8_t *source = NULL;
  462. source = (uint8_t *)data;
  463. usart_priv->tx_buf = (uint8_t *)data;
  464. usart_priv->tx_total_num = num;
  465. usart_priv->tx_cnt = 0;
  466. usart_priv->tx_busy = 1;
  467. dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
  468. /* enable the interrupt*/
  469. addr->IER |= IER_THRE_INT_ENABLE;
  470. return 0;
  471. }
  472. /**
  473. \brief Abort Send data to UART transmitter
  474. \param[in] handle usart handle to operate.
  475. \return error code
  476. */
  477. int32_t csi_usart_abort_send(usart_handle_t handle)
  478. {
  479. USART_NULL_PARAM_CHK(handle);
  480. dw_usart_priv_t *usart_priv = handle;
  481. usart_priv->tx_cnt = usart_priv->tx_total_num;
  482. return 0;
  483. }
  484. /**
  485. \brief Start receiving data from UART receiver.transmits the default value as specified by csi_usart_set_default_tx_value
  486. \param[in] handle usart handle to operate.
  487. \param[out] data Pointer to buffer for data to receive from UART receiver
  488. \param[in] num Number of data items to receive
  489. \return error code
  490. */
  491. int32_t csi_usart_receive(usart_handle_t handle, void *data, uint32_t num)
  492. {
  493. USART_NULL_PARAM_CHK(handle);
  494. USART_NULL_PARAM_CHK(data);
  495. uint8_t *dest = NULL;
  496. dw_usart_priv_t *usart_priv = handle;
  497. dest = (uint8_t *)data;
  498. usart_priv->rx_buf = (uint8_t *)data; // Save receive buffer usart
  499. usart_priv->rx_total_num = num; // Save number of data to be received
  500. usart_priv->rx_cnt = 0;
  501. usart_priv->rx_busy = 1;
  502. return 0;
  503. }
  504. /**
  505. \brief query data from UART receiver FIFO.
  506. \param[in] handle usart handle to operate.
  507. \param[out] data Pointer to buffer for data to receive from UART receiver
  508. \param[in] num Number of data items to receive
  509. \return receive fifo data num
  510. */
  511. int32_t csi_usart_receive_query(usart_handle_t handle, void *data, uint32_t num)
  512. {
  513. USART_NULL_PARAM_CHK(handle);
  514. USART_NULL_PARAM_CHK(data);
  515. dw_usart_priv_t *usart_priv = handle;
  516. dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
  517. int32_t recv_num = 0;
  518. while (addr->LSR & 0x1) {
  519. *((uint8_t *)data++) = addr->RBR;
  520. recv_num++;
  521. if (recv_num >= num) {
  522. break;
  523. }
  524. }
  525. return recv_num;
  526. }
  527. /**
  528. \brief Abort Receive data from UART receiver
  529. \param[in] handle usart handle to operate.
  530. \return error code
  531. */
  532. int32_t csi_usart_abort_receive(usart_handle_t handle)
  533. {
  534. USART_NULL_PARAM_CHK(handle);
  535. dw_usart_priv_t *usart_priv = handle;
  536. usart_priv->rx_cnt = usart_priv->rx_total_num;
  537. return 0;
  538. }
  539. /**
  540. \brief Start sending/receiving data to/from UART transmitter/receiver.
  541. \param[in] handle usart handle to operate.
  542. \param[in] data_out Pointer to buffer with data to send to USART transmitter
  543. \param[out] data_in Pointer to buffer for data to receive from USART receiver
  544. \param[in] num Number of data items to transfer
  545. \return error code
  546. */
  547. int32_t csi_usart_transfer(usart_handle_t handle, const void *data_out, void *data_in, uint32_t num)
  548. {
  549. USART_NULL_PARAM_CHK(handle);
  550. return ERR_USART(EDRV_UNSUPPORTED);
  551. }
  552. /**
  553. \brief abort sending/receiving data to/from USART transmitter/receiver.
  554. \param[in] handle usart handle to operate.
  555. \return error code
  556. */
  557. int32_t csi_usart_abort_transfer(usart_handle_t handle)
  558. {
  559. USART_NULL_PARAM_CHK(handle);
  560. return ERR_USART(EDRV_UNSUPPORTED);
  561. }
  562. /**
  563. \brief Get USART status.
  564. \param[in] handle usart handle to operate.
  565. \return USART status \ref usart_status_t
  566. */
  567. usart_status_t csi_usart_get_status(usart_handle_t handle)
  568. {
  569. usart_status_t usart_status;
  570. dw_usart_priv_t *usart_priv = handle;
  571. dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
  572. uint32_t line_status_reg = addr->LSR;
  573. usart_status.tx_busy = usart_priv->tx_busy;
  574. usart_status.rx_busy = usart_priv->rx_busy;
  575. if (line_status_reg & DW_LSR_BI) {
  576. usart_status.rx_break = 1;
  577. }
  578. if (line_status_reg & DW_LSR_FE) {
  579. usart_status.rx_framing_error = 1;
  580. }
  581. if (line_status_reg & DW_LSR_PE) {
  582. usart_status.rx_parity_error = 1;
  583. }
  584. return usart_status;
  585. }
  586. /**
  587. \brief control the transmit.
  588. \param[in] handle usart handle to operate.
  589. \param[in] enable the transmitter.
  590. \return error code
  591. */
  592. int32_t csi_usart_control_tx(usart_handle_t handle, bool enable)
  593. {
  594. USART_NULL_PARAM_CHK(handle);
  595. return ERR_USART(EDRV_UNSUPPORTED);
  596. }
  597. /**
  598. \brief control the receive.
  599. \param[in] handle usart handle to operate.
  600. \param[in] enable the receive.
  601. \return error code
  602. */
  603. int32_t csi_usart_control_rx(usart_handle_t handle, bool enable)
  604. {
  605. USART_NULL_PARAM_CHK(handle);
  606. return ERR_USART(EDRV_UNSUPPORTED);
  607. }
  608. /**
  609. \brief control the break.
  610. \param[in] handle usart handle to operate.
  611. \param[in] enable the break.
  612. \return error code
  613. */
  614. int32_t csi_usart_control_break(usart_handle_t handle, bool enable)
  615. {
  616. USART_NULL_PARAM_CHK(handle);
  617. return ERR_USART(EDRV_UNSUPPORTED);
  618. }
  619. /**
  620. \brief flush receive/send data.
  621. \param[in] handle usart handle to operate.
  622. \param[in] type \ref usart_flush_type_e.
  623. \return error code
  624. */
  625. int32_t csi_usart_flush(usart_handle_t handle, usart_flush_type_e type)
  626. {
  627. USART_NULL_PARAM_CHK(handle);
  628. dw_usart_priv_t *usart_priv = handle;
  629. dw_usart_reg_t *addr = (dw_usart_reg_t *)(usart_priv->base);
  630. if (type == USART_FLUSH_WRITE) {
  631. addr->FCR |= DW_FCR_XFIFOR;
  632. } else if (type == USART_FLUSH_READ) {
  633. addr->FCR |= DW_FCR_RFIFOR;
  634. } else {
  635. return ERR_USART(EDRV_PARAMETER);
  636. }
  637. return 0;
  638. }