driver_uart.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * Copyright(c) 2007-2022 Jianjun Jiang <8192542@qq.com>
  3. * Official site: http://xboot.org
  4. * Mobile phone: +86-18665388956
  5. * QQ: 8192542
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in all
  15. * copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. * SOFTWARE.
  24. *
  25. */
  26. // (C) 2024 Victor Suarez Rovere <suarezvictor@gmail.com>
  27. // (C) 2021 bigmagic123
  28. // SPDX-License-Identifier: AGPL-3.0-only and Apache-2.0
  29. #include "driver_uart.h"
  30. const int UART_LSR = UART0_lsr_OFFSET;
  31. const int UART_USR = UART0_usr_OFFSET;
  32. const uint8_t UART_LSR_DR_MASK = UART0_lsr_dr; // Receiver data ready
  33. const int UART_RBR = UART0_rbr_OFFSET;
  34. #define UART_BASE_n(n) (UART0 + 0x400*n)
  35. /*
  36. CPU BOARD v0.09
  37. PE2: BOOT TX (UART0-TX) / TP8 -- GPIO Function 6
  38. PE3: BOOT RX (UART0-RX) / TP7 -- GPIO Function 6
  39. PB6: DEBUG TX (UART3-TX) / J6 -- GPIO Function 7
  40. PB7: DEBUG RX (UART3-RX) / J6 -- GPIO Function 7
  41. PG6: COMM TX (UART1-TX ) / J8 -- GPIO Function 2
  42. PG7: COMM RX (UART1-RX ) / J8 -- GPIO Function 2
  43. PG8: COMM RTS (UART1-RTS) / J8 -- GPIO Function 2
  44. PG9: COMM CTS (UART1-CTS) / J8 -- GPIO Function 2
  45. */
  46. void uart_probe(UART_dev_t uart_n)
  47. {
  48. uintptr_t addr;
  49. uint32_t val;
  50. switch(uart_n)
  51. {
  52. case 0: //UART 0
  53. // Config GPIOE2 and GPIOE3 to txd0 and rxd0
  54. addr = GPIO_pe_cfg0;
  55. val = io_read32(addr);
  56. val &= ~(0xf << ((2 & 0x7) << 2)); //GPIOE2 - TX
  57. val |= ((0x6 & 0xf) << ((2 & 0x7) << 2));
  58. io_write32(addr, val);
  59. val = io_read32(addr);
  60. val &= ~(0xf << ((3 & 0x7) << 2)); //GPIOE3 - RX
  61. val |= ((0x6 & 0xf) << ((3 & 0x7) << 2));
  62. io_write32(addr, val);
  63. break;
  64. case 1: //UART 1
  65. // Config GPIOG6 and GPIOG7 to txd1 and rxd1
  66. addr = GPIO_pg_cfg0;
  67. val = io_read32(addr);
  68. val &= ~GPIO_pg_cfg0_pg6_select; //TX
  69. val |= 2 << GPIO_pg_cfg0_pg6_select_SHIFT;
  70. io_write32(addr, val);
  71. val = io_read32(addr);
  72. val &= ~GPIO_pg_cfg0_pg7_select; //RX
  73. val |= 2 << GPIO_pg_cfg0_pg7_select_SHIFT;
  74. io_write32(addr, val);
  75. break;
  76. default:
  77. return;
  78. }
  79. // Open the clock gate
  80. addr = CCU_uart_bgr;
  81. val = io_read32(addr);
  82. val |= 1 << uart_n;
  83. io_write32(addr, val);
  84. // Deassert reset
  85. val |= (1<<16) << uart_n;
  86. io_write32(addr, val);
  87. // Config baud to 115200-8-1-0
  88. addr = UART_BASE_n(uart_n);
  89. io_write32(addr + 0x04, 0x0);
  90. io_write32(addr + 0x08, 0xf7);
  91. io_write32(addr + 0x10, 0x0);
  92. val = io_read32(addr + 0x0c);
  93. val |= (1 << 7);
  94. io_write32(addr + 0x0c, val);
  95. io_write32(addr + 0x00, 0xd & 0xff);
  96. io_write32(addr + 0x04, (0xd >> 8) & 0xff);
  97. val = io_read32(addr + 0x0c);
  98. val &= ~(1 << 7);
  99. io_write32(addr + 0x0c, val);
  100. val = io_read32(addr + 0x0c);
  101. val &= ~0x1f;
  102. val |= (0x3 << 0) | (0 << 2) | (0x0 << 3);
  103. io_write32(addr + 0x0c, val);
  104. }
  105. int driver_uart_putc_wontblock(UART_dev_t uart_n)
  106. {
  107. return (io_read32(UART_BASE_n(uart_n) + UART_USR) & (0x1 << 1)) != 0;
  108. }
  109. void driver_uart_putc(UART_dev_t uart_n, char c)
  110. {
  111. while(!driver_uart_putc_wontblock(uart_n));
  112. io_write32(UART_BASE_n(uart_n) + 0x00, c);
  113. }
  114. int driver_uart_getc_wontblock(UART_dev_t uart_n)
  115. {
  116. return (io_read32(UART_BASE_n(uart_n) + UART_LSR) & UART_LSR_DR_MASK) != 0;
  117. }
  118. int driver_uart_getc(UART_dev_t uart_n)
  119. {
  120. if(!driver_uart_getc_wontblock(uart_n))
  121. return -1;
  122. return io_read32(UART_BASE_n(uart_n) + UART_RBR);
  123. }