hal_uart.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934
  1. /*
  2. * ===========================================================================================
  3. *
  4. * Filename: hal_uart.c
  5. *
  6. * Description: hal impl. of uart.
  7. *
  8. * Version: Melis3.0
  9. * Create: 2019-11-14 14:20:56
  10. * Revision: none
  11. * Compiler: GCC:version 9.2.1 20170904 (release),ARM/embedded-7-branch revision 255204
  12. *
  13. * Author: bantao@allwinnertech.com
  14. * Organization: SWC-BPD
  15. * Last Modified: 2020-04-29 15:17:36
  16. *
  17. * ===========================================================================================
  18. */
  19. #include <hal_uart.h>
  20. #include <hal_interrupt.h>
  21. #include <hal_queue.h>
  22. #include <hal_clk.h>
  23. #include <hal_reset.h>
  24. #include <hal_gpio.h>
  25. #ifdef CONFIG_DRIVER_SYSCONFIG
  26. #include <hal_cfg.h>
  27. #include <script.h>
  28. #endif
  29. #include "uart.h"
  30. #if (0)
  31. #define UART_LOG_DEBUG
  32. #endif
  33. #define UART_INIT(fmt, ...) printf("uart: "fmt, ##__VA_ARGS__)
  34. #define UART_ERR(fmt, ...) printf("uart: "fmt, ##__VA_ARGS__)
  35. #ifdef UART_LOG_DEBUG
  36. #define UART_INFO(fmt, ...) printf("[%s %d]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  37. #define UART_INFO_IRQ(fmt, ...) printf("[%s %d]"fmt, __func__, __LINE__, ##__VA_ARGS__)
  38. #else
  39. #define UART_INFO(fmt, ...)
  40. #define UART_INFO_IRQ(fmt, ...)
  41. #endif
  42. static unsigned long sunxi_uart_port[] =
  43. {
  44. SUNXI_UART0_BASE, SUNXI_UART1_BASE, SUNXI_UART2_BASE, SUNXI_UART3_BASE
  45. };
  46. static const uint32_t g_uart_irqn[] = {SUNXI_IRQ_UART0, SUNXI_IRQ_UART1,
  47. SUNXI_IRQ_UART2, SUNXI_IRQ_UART3
  48. };
  49. static sunxi_hal_version_t hal_uart_driver =
  50. {
  51. SUNXI_HAL_UART_API_VERSION,
  52. SUNXI_HAL_UART_DRV_VERSION
  53. };
  54. static uart_priv_t g_uart_priv[UART_MAX];
  55. static hal_mailbox_t uart_mailbox[UART_MAX];
  56. static const uint32_t g_uart_baudrate_map[] =
  57. {
  58. 300,
  59. 600,
  60. 1200,
  61. 2400,
  62. 4800,
  63. 9600,
  64. 19200,
  65. 38400,
  66. 57600,
  67. 115200,
  68. 230400,
  69. 576000,
  70. 921600,
  71. 500000,
  72. 1000000,
  73. 1500000,
  74. 3000000,
  75. 4000000,
  76. };
  77. //driver capabilities, support uart function only.
  78. static const sunxi_hal_uart_capabilities_t driver_capabilities =
  79. {
  80. 1, /* supports UART (Asynchronous) mode */
  81. 0, /* supports Synchronous Master mode */
  82. 0, /* supports Synchronous Slave mode */
  83. 0, /* supports UART Single-wire mode */
  84. 0, /* supports UART IrDA mode */
  85. 0, /* supports UART Smart Card mode */
  86. 0, /* Smart Card Clock generator available */
  87. 0, /* RTS Flow Control available */
  88. 0, /* CTS Flow Control available */
  89. 0, /* Transmit completed event: \ref ARM_UARTx_EVENT_TX_COMPLETE */
  90. 0, /* Signal receive character timeout event: \ref ARM_UARTx_EVENT_RX_TIMEOUT */
  91. 0, /* RTS Line: 0=not available, 1=available */
  92. 0, /* CTS Line: 0=not available, 1=available */
  93. 0, /* DTR Line: 0=not available, 1=available */
  94. 0, /* DSR Line: 0=not available, 1=available */
  95. 0, /* DCD Line: 0=not available, 1=available */
  96. 0, /* RI Line: 0=not available, 1=available */
  97. 0, /* Signal CTS change event: \ref ARM_UARTx_EVENT_CTS */
  98. 0, /* Signal DSR change event: \ref ARM_UARTx_EVENT_DSR */
  99. 0, /* Signal DCD change event: \ref ARM_UARTx_EVENT_DCD */
  100. 0, /* Signal RI change event: \ref ARM_UARTx_EVENT_RI */
  101. 0 /* Reserved */
  102. };
  103. #ifdef CONFIG_SUNXI_UART_SUPPORT_POLL
  104. static poll_wakeup_func uart_drv_poll_wakeup = NULL;
  105. int32_t hal_uart_check_poll_state(int32_t dev_id, short key)
  106. {
  107. int ret = -1;
  108. int32_t mask = 0;
  109. if (key & POLLIN)
  110. {
  111. ret = hal_is_mailbox_empty((hal_mailbox_t)uart_mailbox[dev_id]);
  112. if (ret == 1)
  113. {
  114. mask = 0;
  115. }
  116. else
  117. {
  118. mask |= POLLIN;
  119. }
  120. }
  121. if (key & POLLOUT)
  122. {
  123. mask |= POLLOUT;
  124. }
  125. return mask;
  126. }
  127. int32_t hal_uart_poll_wakeup(int32_t dev_id, short key)
  128. {
  129. int ret = -1;
  130. if (uart_drv_poll_wakeup)
  131. {
  132. ret = uart_drv_poll_wakeup(dev_id, key);
  133. }
  134. return ret;
  135. }
  136. int32_t hal_uart_register_poll_wakeup(poll_wakeup_func poll_wakeup)
  137. {
  138. uart_drv_poll_wakeup = poll_wakeup;
  139. return 0;
  140. }
  141. #endif
  142. static bool uart_port_is_valid(uart_port_t uart_port)
  143. {
  144. return (uart_port < UART_MAX);
  145. }
  146. static bool uart_config_is_valid(const _uart_config_t *config)
  147. {
  148. return ((config->baudrate < UART_BAUDRATE_MAX) &&
  149. (config->word_length <= UART_WORD_LENGTH_8) &&
  150. (config->stop_bit <= UART_STOP_BIT_2) &&
  151. (config->parity <= UART_PARITY_EVEN));
  152. }
  153. sunxi_hal_version_t hal_uart_get_version(int32_t dev)
  154. {
  155. HAL_ARG_UNUSED(dev);
  156. return hal_uart_driver;
  157. }
  158. sunxi_hal_uart_capabilities_t hal_uart_get_capabilities(int32_t dev)
  159. {
  160. HAL_ARG_UNUSED(dev);
  161. return driver_capabilities;
  162. }
  163. static void uart_set_format(uart_port_t uart_port, uart_word_length_t word_length,
  164. uart_stop_bit_t stop_bit, uart_parity_t parity)
  165. {
  166. const unsigned long uart_base = sunxi_uart_port[uart_port];
  167. uart_priv_t *uart_priv = &g_uart_priv[uart_port];
  168. uint32_t value;
  169. value = hal_readb(uart_base + UART_LCR);
  170. /* set word length */
  171. value &= ~(UART_LCR_DLEN_MASK);
  172. switch (word_length)
  173. {
  174. case UART_WORD_LENGTH_5:
  175. value |= UART_LCR_WLEN5;
  176. break;
  177. case UART_WORD_LENGTH_6:
  178. value |= UART_LCR_WLEN6;
  179. break;
  180. case UART_WORD_LENGTH_7:
  181. value |= UART_LCR_WLEN7;
  182. break;
  183. case UART_WORD_LENGTH_8:
  184. default:
  185. value |= UART_LCR_WLEN8;
  186. break;
  187. }
  188. /* set stop bit */
  189. switch (stop_bit)
  190. {
  191. case UART_STOP_BIT_1:
  192. default:
  193. value &= ~(UART_LCR_STOP);
  194. break;
  195. case UART_STOP_BIT_2:
  196. value |= UART_LCR_STOP;
  197. break;
  198. }
  199. /* set parity bit */
  200. value &= ~(UART_LCR_PARITY_MASK);
  201. switch (parity)
  202. {
  203. case UART_PARITY_NONE:
  204. value &= ~(UART_LCR_PARITY);
  205. break;
  206. case UART_PARITY_ODD:
  207. value |= UART_LCR_PARITY;
  208. break;
  209. case UART_PARITY_EVEN:
  210. value |= UART_LCR_PARITY;
  211. value |= UART_LCR_EPAR;
  212. break;
  213. }
  214. uart_priv->lcr = value;
  215. hal_writeb(uart_priv->lcr, uart_base + UART_LCR);
  216. }
  217. #define CCM_UART_RST_OFFSET (16)
  218. #define CCM_UART_GATING_OFFSET (0)
  219. static void uart_reset(uart_port_t uart_port)
  220. {
  221. int i;
  222. unsigned int reg_val = 0;
  223. /* 0x3001000(CCU) + 0x90c(UART_BGR_REG: UART Bus Gating Reset Register) */
  224. /* reset */
  225. reg_val = readl(0x0300190c);
  226. reg_val &= ~(1 << (CCM_UART_RST_OFFSET + uart_port));
  227. writel(reg_val, 0x0300190c);
  228. for (i = 0; i < 100; i++)
  229. ;
  230. reg_val = readl(0x300190c);
  231. reg_val |= (1 << (CCM_UART_RST_OFFSET + uart_port));
  232. writel(reg_val, 0x300190c);
  233. /* gating */
  234. reg_val = readl(0x300190c);
  235. reg_val &= ~(1 << (CCM_UART_GATING_OFFSET + uart_port));
  236. writel(reg_val, 0x300190c);
  237. for (i = 0; i < 100; i++)
  238. ;
  239. reg_val = readl(0x300190c);
  240. reg_val |= (1 << (CCM_UART_GATING_OFFSET + uart_port));
  241. writel(reg_val, 0x300190c);
  242. }
  243. static void uart_set_baudrate(uart_port_t uart_port, uart_baudrate_t baudrate)
  244. {
  245. const unsigned long uart_base = sunxi_uart_port[uart_port];
  246. uart_priv_t *uart_priv = &g_uart_priv[uart_port];
  247. uint32_t actual_baudrate = g_uart_baudrate_map[baudrate];
  248. uint32_t quot, uart_clk;
  249. uart_clk = 24000000; /* FIXME: fixed to 24MHz */
  250. quot = (uart_clk + 8 * actual_baudrate) / (16 * actual_baudrate);
  251. UART_INFO("baudrate: %d, quot = %d\r\n", actual_baudrate, quot);
  252. uart_priv->dlh = quot >> 8;
  253. uart_priv->dll = quot & 0xff;
  254. /* hold tx so that uart will update lcr and baud in the gap of tx */
  255. hal_writeb(UART_HALT_HTX | UART_HALT_FORCECFG, uart_base + UART_HALT);
  256. hal_writeb(uart_priv->lcr | UART_LCR_DLAB, uart_base + UART_LCR);
  257. hal_writeb(uart_priv->dlh, uart_base + UART_DLH);
  258. hal_writeb(uart_priv->dll, uart_base + UART_DLL);
  259. hal_writeb(UART_HALT_HTX | UART_HALT_FORCECFG | UART_HALT_LCRUP, uart_base + UART_HALT);
  260. /* FIXME: implement timeout */
  261. while (hal_readb(uart_base + UART_HALT) & UART_HALT_LCRUP)
  262. ;
  263. /* In fact there are two DLABs(DLAB and DLAB_BAK) in the hardware implementation.
  264. * The DLAB_BAK is sellected only when SW_UART_HALT_FORCECFG is set to 1,
  265. * and this bit can be access no matter uart is busy or not.
  266. * So we select the DLAB_BAK always by leaving SW_UART_HALT_FORCECFG to be 1. */
  267. hal_writeb(uart_priv->lcr, uart_base + UART_LCR);
  268. hal_writeb(UART_HALT_FORCECFG, uart_base + UART_HALT);
  269. }
  270. static void uart_set_fifo(uart_port_t uart_port, uint32_t value)
  271. {
  272. const unsigned long uart_base = sunxi_uart_port[uart_port];
  273. uart_priv_t *uart_priv = &g_uart_priv[uart_port];
  274. uart_priv->fcr = value;
  275. hal_writeb(uart_priv->fcr, uart_base + UART_FCR);
  276. }
  277. void hal_uart_set_hardware_flowcontrol(uart_port_t uart_port)
  278. {
  279. const unsigned long uart_base = sunxi_uart_port[uart_port];
  280. uart_priv_t *uart_priv = &g_uart_priv[uart_port];
  281. uint32_t value;
  282. value = hal_readb(uart_base + UART_MCR);
  283. value |= UART_MCR_DTR | UART_MCR_RTS | UART_MCR_AFE;
  284. uart_priv->mcr = value;
  285. hal_writeb(uart_priv->mcr, uart_base + UART_MCR);
  286. /* enable with modem status interrupts */
  287. value = hal_readb(uart_base + UART_IER);
  288. value |= UART_IER_MSI;
  289. uart_priv->ier = value;
  290. hal_writeb(uart_priv->ier, uart_base + UART_IER);
  291. }
  292. void hal_uart_disable_flowcontrol(uart_port_t uart_port)
  293. {
  294. const unsigned long uart_base = sunxi_uart_port[uart_port];
  295. uart_priv_t *uart_priv = &g_uart_priv[uart_port];
  296. uint32_t value;
  297. value = hal_readb(uart_base + UART_MCR);
  298. value &= ~(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_AFE);
  299. uart_priv->mcr = value;
  300. hal_writeb(uart_priv->mcr, uart_base + UART_MCR);
  301. /* disable with modem status interrupts */
  302. value = hal_readb(uart_base + UART_IER);
  303. value &= ~(UART_IER_MSI);
  304. uart_priv->ier = value;
  305. hal_writeb(uart_priv->ier, uart_base + UART_IER);
  306. }
  307. static void uart_force_idle(uart_port_t uart_port)
  308. {
  309. const unsigned long uart_base = sunxi_uart_port[uart_port];
  310. uart_priv_t *uart_priv = &g_uart_priv[uart_port];
  311. if (uart_priv->fcr & UART_FCR_FIFO_EN)
  312. {
  313. hal_writeb(UART_FCR_FIFO_EN, uart_base + UART_FCR);
  314. hal_writeb(UART_FCR_TXFIFO_RST
  315. | UART_FCR_RXFIFO_RST
  316. | UART_FCR_FIFO_EN, uart_base + UART_FCR);
  317. hal_writeb(0, uart_base + UART_FCR);
  318. }
  319. hal_writeb(uart_priv->fcr, uart_base + UART_FCR);
  320. (void)hal_readb(uart_base + UART_FCR);
  321. }
  322. static void uart_handle_busy(uart_port_t uart_port)
  323. {
  324. const unsigned long uart_base = sunxi_uart_port[uart_port];
  325. uart_priv_t *uart_priv = &g_uart_priv[uart_port];
  326. (void)hal_readb(uart_base + UART_USR);
  327. /*
  328. * Before reseting lcr, we should ensure than uart is not in busy
  329. * state. Otherwise, a new busy interrupt will be introduced.
  330. * It is wise to set uart into loopback mode, since it can cut down the
  331. * serial in, then we should reset fifo(in my test, busy state
  332. * (UART_USR_BUSY) can't be cleard until the fifo is empty).
  333. */
  334. hal_writeb(uart_priv->mcr | UART_MCR_LOOP, uart_base + UART_MCR);
  335. uart_force_idle(uart_port);
  336. hal_writeb(uart_priv->lcr, uart_base + UART_LCR);
  337. hal_writeb(uart_priv->mcr, uart_base + UART_MCR);
  338. }
  339. rt_weak void hal_uart_handler_hook(uart_port_t uart_port)
  340. {
  341. }
  342. static uint32_t uart_handle_rx(uart_port_t uart_port, uint32_t lsr)
  343. {
  344. const unsigned long uart_base = sunxi_uart_port[uart_port];
  345. uint8_t ch = 0;
  346. UART_INFO("IRQ uart%d handle rx \n", uart_port);
  347. do
  348. {
  349. if (lsr & UART_LSR_DR)
  350. {
  351. ch = hal_readb(uart_base + UART_RBR);
  352. hal_mailbox_send((hal_mailbox_t)uart_mailbox[uart_port], ch);
  353. #ifdef CONFIG_SUNXI_UART_SUPPORT_POLL
  354. hal_uart_poll_wakeup(uart_port, POLLIN);
  355. #endif
  356. }
  357. lsr = hal_readb(uart_base + UART_LSR);
  358. } while ((lsr & (UART_LSR_DR | UART_LSR_BI)));
  359. /* wakeup console here */
  360. hal_uart_handler_hook(uart_port);
  361. return lsr;
  362. }
  363. static irqreturn_t uart_irq_handler(int irq, void *dev_id)
  364. {
  365. uart_priv_t *uart_priv = dev_id;
  366. uart_port_t uart_port = uart_priv->uart_port;
  367. const unsigned long uart_base = sunxi_uart_port[uart_port];
  368. uint32_t iir, lsr;
  369. iir = hal_readb(uart_base + UART_IIR) & UART_IIR_IID_MASK;
  370. lsr = hal_readb(uart_base + UART_LSR);
  371. UART_INFO_IRQ("IRQ uart%d lsr is %08x \n", uart_port, lsr);
  372. if (iir == UART_IIR_IID_BUSBSY)
  373. {
  374. uart_handle_busy(uart_port);
  375. }
  376. else
  377. {
  378. if (lsr & (UART_LSR_DR | UART_LSR_BI))
  379. {
  380. lsr = uart_handle_rx(uart_port, lsr);
  381. }
  382. else if (iir & UART_IIR_IID_CHARTO)
  383. /* has charto irq but no dr lsr? just read and ignore */
  384. {
  385. hal_readb(uart_base + UART_RBR);
  386. }
  387. /* if (lsr & UART_LSR_THRE)
  388. {
  389. uart_handle_tx(uart_port);
  390. }*/
  391. }
  392. return 0;
  393. }
  394. static void uart_enable_irq(uart_port_t uart_port, uint32_t irq_type)
  395. {
  396. const unsigned long uart_base = sunxi_uart_port[uart_port];
  397. uint32_t value;
  398. value = hal_readb(uart_base + UART_IER);
  399. value |= irq_type;
  400. hal_writeb(value, uart_base + UART_IER);
  401. }
  402. static void uart_enable_busy_cfg(uart_port_t uart_port)
  403. {
  404. const unsigned long uart_base = sunxi_uart_port[uart_port];
  405. uint32_t value;
  406. value = hal_readb(uart_base + UART_HALT);
  407. value |= UART_HALT_FORCECFG;
  408. hal_writeb(value, uart_base + UART_HALT);
  409. }
  410. static int uart_clk_init(int bus, bool enable)
  411. {
  412. hal_clk_status_t ret;
  413. hal_reset_type_t reset_type = HAL_SUNXI_RESET;
  414. u32 reset_id;
  415. hal_clk_type_t clk_type = HAL_SUNXI_CCU;
  416. hal_clk_id_t clk_id;
  417. hal_clk_t clk;
  418. struct reset_control *reset;
  419. switch (bus)
  420. {
  421. case 0:
  422. clk_id = SUNXI_CLK_UART0;
  423. reset_id = SUNXI_RST_UART0;
  424. break;
  425. case 1:
  426. clk_id = SUNXI_CLK_UART1;
  427. reset_id = SUNXI_RST_UART1;
  428. break;
  429. case 2:
  430. clk_id = SUNXI_CLK_UART2;
  431. reset_id = SUNXI_RST_UART2;
  432. break;
  433. case 3:
  434. clk_id = SUNXI_CLK_UART3;
  435. reset_id = SUNXI_RST_UART3;
  436. break;
  437. default:
  438. UART_ERR("uart%d is invalid\n", bus);
  439. return -1;
  440. }
  441. if (enable)
  442. {
  443. reset = hal_reset_control_get(reset_type, reset_id);
  444. hal_reset_control_deassert(reset);
  445. hal_reset_control_put(reset);
  446. clk = hal_clock_get(clk_type, clk_id);
  447. ret = hal_clock_enable(clk);
  448. if (ret)
  449. {
  450. UART_ERR("[uart%d] couldn't enable clk!\n", bus);
  451. return -1;
  452. }
  453. }
  454. else
  455. {
  456. clk = hal_clock_get(clk_type, clk_id);
  457. ret = hal_clock_disable(clk);
  458. if (ret)
  459. {
  460. UART_ERR("[uart%d] couldn't disable clk!\n", bus);
  461. return -1;
  462. }
  463. }
  464. return 0;
  465. }
  466. static void uart_pinctrl_init(uart_port_t uart_port)
  467. {
  468. #ifdef CONFIG_DRIVER_SYSCONFIG
  469. user_gpio_set_t gpio_cfg[4];
  470. int count, i;
  471. char uart_name[16];
  472. gpio_pin_t uart_pin[4];
  473. gpio_muxsel_t uart_muxsel[4];
  474. memset(gpio_cfg, 0, sizeof(gpio_cfg));
  475. sprintf(uart_name, "uart%d", uart_port);
  476. count = Hal_Cfg_GetGPIOSecKeyCount(uart_name);
  477. if (!count)
  478. {
  479. UART_ERR("[uart%d] not support in sys_config\n", uart_port);
  480. return ;
  481. }
  482. Hal_Cfg_GetGPIOSecData(uart_name, gpio_cfg, count);
  483. for (i = 0; i < count; i++)
  484. {
  485. uart_pin[i] = (gpio_cfg[i].port - 1) * 32 + gpio_cfg[i].port_num;
  486. uart_muxsel[i] = gpio_cfg[i].mul_sel;
  487. hal_gpio_pinmux_set_function(uart_pin[i], uart_muxsel[i]);
  488. }
  489. #else
  490. /* TODO:use sys_config instead it, but DSP does not support sys_config */
  491. switch (uart_port)
  492. {
  493. case UART_0:
  494. hal_gpio_set_pull(UART0_RX, GPIO_PULL_UP);
  495. hal_gpio_pinmux_set_function(UART0_TX, UART0_GPIO_FUNCTION);//TX
  496. hal_gpio_pinmux_set_function(UART0_RX, UART0_GPIO_FUNCTION);//RX
  497. break;
  498. case UART_1:
  499. hal_gpio_set_pull(UART1_RX, GPIO_PULL_UP);
  500. hal_gpio_pinmux_set_function(UART1_TX, UART1_GPIO_FUNCTION);//TX
  501. hal_gpio_pinmux_set_function(UART1_RX, UART1_GPIO_FUNCTION);//RX
  502. break;
  503. case UART_2:
  504. hal_gpio_set_pull(UART2_RX, GPIO_PULL_UP);
  505. hal_gpio_pinmux_set_function(UART2_TX, UART2_GPIO_FUNCTION);//TX
  506. hal_gpio_pinmux_set_function(UART2_RX, UART2_GPIO_FUNCTION);//RX
  507. break;
  508. case UART_3:
  509. hal_gpio_set_pull(UART3_RX, GPIO_PULL_UP);
  510. hal_gpio_pinmux_set_function(UART3_TX, UART3_GPIO_FUNCTION);//TX
  511. hal_gpio_pinmux_set_function(UART3_RX, UART3_GPIO_FUNCTION);//RX
  512. break;
  513. default:
  514. UART_ERR("[uart%d] not support \n", uart_port);
  515. break;
  516. }
  517. #endif
  518. }
  519. static void uart_pinctrl_uninit(uart_port_t uart_port)
  520. {
  521. switch (uart_port)
  522. {
  523. case UART_0:
  524. hal_gpio_pinmux_set_function(UART0_TX, GPIO_MUXSEL_DISABLED);//TX
  525. hal_gpio_pinmux_set_function(UART0_RX, GPIO_MUXSEL_DISABLED);//RX
  526. break;
  527. case UART_1:
  528. hal_gpio_pinmux_set_function(UART1_TX, GPIO_MUXSEL_DISABLED);//TX
  529. hal_gpio_pinmux_set_function(UART1_RX, GPIO_MUXSEL_DISABLED);//RX
  530. break;
  531. case UART_2:
  532. hal_gpio_pinmux_set_function(UART2_TX, GPIO_MUXSEL_DISABLED);//TX
  533. hal_gpio_pinmux_set_function(UART2_RX, GPIO_MUXSEL_DISABLED);//RX
  534. break;
  535. case UART_3:
  536. hal_gpio_pinmux_set_function(UART3_TX, GPIO_MUXSEL_DISABLED);//TX
  537. hal_gpio_pinmux_set_function(UART3_RX, GPIO_MUXSEL_DISABLED);//RX
  538. break;
  539. default:
  540. UART_ERR("[uart%d] not support \n", uart_port);
  541. break;
  542. }
  543. }
  544. /* default uart config */
  545. _uart_config_t uart_defconfig =
  546. {
  547. .baudrate = UART_BAUDRATE_115200,
  548. .word_length = UART_WORD_LENGTH_8,
  549. .stop_bit = UART_STOP_BIT_1,
  550. .parity = UART_PARITY_NONE,
  551. };
  552. int32_t hal_uart_init(int32_t uart_port)
  553. {
  554. uart_priv_t *uart_priv = &g_uart_priv[uart_port];
  555. uint32_t irqn = g_uart_irqn[uart_port];
  556. uint32_t value = 0;
  557. _uart_config_t *uart_config = &uart_defconfig;
  558. char uart_name[12] = {0};
  559. if ((!uart_port_is_valid(uart_port)) ||
  560. (!uart_config_is_valid(uart_config)))
  561. {
  562. return HAL_UART_STATUS_ERROR_PARAMETER;
  563. }
  564. /* enable clk */
  565. uart_clk_init(uart_port, true);
  566. /* request gpio */
  567. uart_pinctrl_init(uart_port);
  568. /* config uart attributes */
  569. uart_set_format(uart_port, uart_config->word_length,
  570. uart_config->stop_bit, uart_config->parity);
  571. /* force reset controller to disable transfer */
  572. uart_reset(uart_port);
  573. uart_set_baudrate(uart_port, uart_config->baudrate);
  574. value |= UART_FCR_RXTRG_1_2 | UART_FCR_TXTRG_1_2 | UART_FCR_FIFO_EN;
  575. uart_set_fifo(uart_port, value);
  576. sprintf(uart_name, "uart%d", (int)uart_port);
  577. if (uart_priv->uart_port == uart_port && uart_priv->irqn == irqn)
  578. {
  579. UART_ERR("irq for uart%ld already enabled\n", (long int)uart_port);
  580. }
  581. else
  582. {
  583. uart_priv->uart_port = uart_port;
  584. uart_priv->irqn = irqn;
  585. #if 1
  586. if (request_irq(irqn, uart_irq_handler, 0, uart_name, uart_priv) < 0)
  587. {
  588. UART_ERR("request irq error\n");
  589. return -1;
  590. }
  591. enable_irq(irqn);
  592. #endif
  593. #if 0
  594. rt_hw_interrupt_install(irqn, uart_irq_handler, uart_priv, uart_name);
  595. rt_hw_interrupt_umask(irqn);
  596. #endif
  597. }
  598. uart_mailbox[uart_port] = hal_mailbox_create(uart_name, UART_FIFO_SIZE);
  599. if (uart_mailbox[uart_port] == NULL)
  600. {
  601. UART_ERR("create mailbox fail\n");
  602. return HAL_UART_STATUS_ERROR;
  603. }
  604. /* set uart IER */
  605. uart_enable_irq(uart_port, UART_IER_RDI | UART_IER_RLSI);
  606. /* force config */
  607. uart_enable_busy_cfg(uart_port);
  608. return SUNXI_HAL_OK;
  609. }
  610. int32_t hal_uart_deinit(int32_t uart_port)
  611. {
  612. /* disable clk */
  613. uart_clk_init(uart_port, false);
  614. uart_pinctrl_uninit(uart_port);
  615. return SUNXI_HAL_OK;
  616. }
  617. int32_t hal_uart_power_control(int32_t dev, sunxi_hal_power_state_e state)
  618. {
  619. return SUNXI_HAL_OK;
  620. }
  621. static int _uart_putc(int devid, char c)
  622. {
  623. volatile uint32_t *sed_buf;
  624. volatile uint32_t *sta;
  625. sed_buf = (uint32_t *)(sunxi_uart_port[devid] + UART_THR);
  626. sta = (uint32_t *)(sunxi_uart_port[devid] + UART_USR);
  627. /* FIFO status, contain valid data */
  628. while (!(*sta & 0x02));
  629. *sed_buf = c;
  630. return 1;
  631. }
  632. int32_t hal_uart_put_char(int32_t dev, char c)
  633. {
  634. return _uart_putc(dev, c);
  635. }
  636. int32_t hal_uart_send(int32_t dev, const uint8_t *data, uint32_t num)
  637. {
  638. int size;
  639. hal_assert(data != NULL);
  640. size = num;
  641. while (num)
  642. {
  643. _uart_putc(dev, *data);
  644. ++ data;
  645. -- num;
  646. }
  647. return size - num;
  648. }
  649. static int _uart_getc(int devid)
  650. {
  651. int ch = -1;
  652. volatile uint32_t *rec_buf;
  653. volatile uint32_t *sta;
  654. volatile uint32_t *fifo;
  655. rec_buf = (uint32_t *)(sunxi_uart_port[devid] + UART_RHB);
  656. sta = (uint32_t *)(sunxi_uart_port[devid] + UART_USR);
  657. fifo = (uint32_t *)(sunxi_uart_port[devid] + UART_RFL);
  658. while (!(*fifo & 0x1ff));
  659. /* Receive Data Available */
  660. if (*sta & 0x08)
  661. {
  662. ch = *rec_buf & 0xff;
  663. }
  664. return ch;
  665. }
  666. uint8_t hal_uart_get_char(int32_t dev)
  667. {
  668. return _uart_getc(dev);
  669. }
  670. int32_t hal_uart_receive_polling(int32_t dev, uint8_t *data, uint32_t num)
  671. {
  672. int ch;
  673. int size;
  674. hal_assert(data != NULL);
  675. size = num;
  676. while (num)
  677. {
  678. ch = _uart_getc(dev);
  679. if (ch == -1)
  680. {
  681. break;
  682. }
  683. *data = ch;
  684. data ++;
  685. num --;
  686. /* FIXME: maybe only used for console? move it away! */
  687. if (ch == '\n')
  688. {
  689. break;
  690. }
  691. }
  692. return size - num;
  693. }
  694. int32_t hal_uart_receive(int32_t dev, uint8_t *data, uint32_t num)
  695. {
  696. unsigned int data_rev;
  697. int i = 0;
  698. int32_t ret = -1, rev_count = 0;
  699. hal_assert(data != NULL);
  700. for (i = 0; i < num; i++)
  701. {
  702. ret = hal_mailbox_recv((hal_mailbox_t)uart_mailbox[dev], &data_rev, -1);
  703. if (ret == 0)
  704. {
  705. rev_count++;
  706. *(data + i) = (uint8_t)data_rev;
  707. }
  708. else
  709. {
  710. UART_ERR("receive error");
  711. break;
  712. }
  713. }
  714. return rev_count;
  715. }
  716. int32_t hal_uart_receive_no_block(int32_t dev, uint8_t *data, uint32_t num, int32_t timeout)
  717. {
  718. unsigned int data_rev;
  719. int i = 0;
  720. int32_t ret = -1, rev_count = 0;
  721. hal_assert(data != NULL);
  722. for (i = 0; i < num; i++)
  723. {
  724. ret = hal_mailbox_recv((hal_mailbox_t)uart_mailbox[dev], &data_rev, timeout);
  725. if (ret == 0)
  726. {
  727. rev_count++;
  728. *(data + i) = (uint8_t)data_rev;
  729. }
  730. else
  731. {
  732. break;
  733. }
  734. }
  735. return rev_count;
  736. }
  737. int32_t hal_uart_transfer(int32_t dev, const void *data_out,
  738. void *data_in, uint32_t num)
  739. {
  740. return SUNXI_HAL_OK;
  741. }
  742. uint32_t hal_uart_get_tx_count(int32_t dev)
  743. {
  744. /* TODO: need verify */
  745. return 0;
  746. }
  747. uint32_t hal_uart_get_rx_count(int32_t dev)
  748. {
  749. /* TODO: need verify */
  750. return 0;
  751. }
  752. int32_t hal_uart_control(int32_t uart_port, int cmd, void *args)
  753. {
  754. _uart_config_t *uart_config;
  755. uart_config = (_uart_config_t *)args;
  756. /* config uart attributes */
  757. uart_set_format(uart_port, uart_config->word_length,
  758. uart_config->stop_bit, uart_config->parity);
  759. uart_set_baudrate(uart_port, uart_config->baudrate);
  760. return SUNXI_HAL_OK;
  761. }
  762. sunxi_hal_uart_status_t hal_uart_get_status(int32_t dev)
  763. {
  764. sunxi_hal_uart_status_t status = {1, 1, 0, 0, 0, 0, 0, 0};
  765. return status;
  766. }
  767. int32_t hal_uart_set_modem_control(int32_t dev,
  768. sunxi_hal_uart_modem_control_e control)
  769. {
  770. return SUNXI_HAL_OK;
  771. }
  772. sunxi_hal_uart_modem_status_t hal_uart_get_modem_status(int32_t dev)
  773. {
  774. sunxi_hal_uart_modem_status_t status = {0, 0, 0, 0, 0};
  775. return status;
  776. }
  777. void hal_uart_set_loopback(uart_port_t uart_port, bool enable)
  778. {
  779. const unsigned long uart_base = sunxi_uart_port[uart_port];
  780. uint32_t value;
  781. value = hal_readb(uart_base + UART_MCR);
  782. if (enable)
  783. value |= UART_MCR_LOOP;
  784. else
  785. value &= ~(UART_MCR_LOOP);
  786. hal_writeb(value, uart_base + UART_MCR);
  787. }
  788. int serial_driver_init(void)
  789. {
  790. UART_INFO("serial hal driver init");
  791. return 0;
  792. }