serial.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /*
  2. * File : serial.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2013, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2013-07-06 Bernard the first version
  13. */
  14. #include <rthw.h>
  15. #include <rtthread.h>
  16. #include <rtdevice.h>
  17. #include <am33xx.h>
  18. #include <interrupt.h>
  19. #include "serial.h"
  20. #include "serial_reg.h"
  21. struct am33xx_uart
  22. {
  23. unsigned long base;
  24. int irq;
  25. };
  26. static void am33xx_uart_isr(int irqno, void* param)
  27. {
  28. rt_uint32_t iir;
  29. struct am33xx_uart* uart;
  30. struct rt_serial_device *serial;
  31. serial = (struct rt_serial_device*)param;
  32. uart = (struct am33xx_uart *)serial->parent.user_data;
  33. iir = UART_IIR_REG(uart->base);
  34. if ((iir & (0x02 << 1)) || (iir & (0x6 << 1)))
  35. {
  36. rt_hw_serial_isr(serial);
  37. }
  38. }
  39. #define NOT_IMPLEMENTED() RT_ASSERT(0)
  40. static rt_err_t am33xx_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  41. {
  42. struct am33xx_uart* uart;
  43. unsigned long base;
  44. RT_ASSERT(serial != RT_NULL);
  45. uart = (struct am33xx_uart *)serial->parent.user_data;
  46. RT_ASSERT(uart);
  47. base = uart->base;
  48. #define __LCR UART_LCR_REG(base)
  49. if (cfg->data_bits == DATA_BITS_8)
  50. __LCR |= 3;
  51. else
  52. NOT_IMPLEMENTED();
  53. if (cfg->stop_bits == STOP_BITS_1)
  54. __LCR &= ~(1<<2);
  55. else
  56. __LCR |= (1<<2);
  57. if (cfg->parity == PARITY_NONE)
  58. __LCR &= ~(1<<3);
  59. else
  60. __LCR |= (1<<3);
  61. __LCR |= (1<<7);
  62. if (cfg->baud_rate == BAUD_RATE_115200)
  63. {
  64. UART_DLL_REG(base) = 26;
  65. UART_DLH_REG(base) = 0;
  66. }
  67. else
  68. {
  69. NOT_IMPLEMENTED();
  70. }
  71. __LCR &= ~(1<<7);
  72. UART_MDR1_REG(base) = 0;
  73. UART_MDR2_REG(base) = 0;
  74. #undef __LCR
  75. return RT_EOK;
  76. }
  77. static rt_err_t am33xx_control(struct rt_serial_device *serial, int cmd, void *arg)
  78. {
  79. struct am33xx_uart* uart;
  80. RT_ASSERT(serial != RT_NULL);
  81. uart = (struct am33xx_uart *)serial->parent.user_data;
  82. switch (cmd)
  83. {
  84. case RT_DEVICE_CTRL_CLR_INT:
  85. /* disable rx irq */
  86. rt_hw_interrupt_mask(uart->irq);
  87. break;
  88. case RT_DEVICE_CTRL_SET_INT:
  89. /* enable rx irq */
  90. rt_hw_interrupt_umask(uart->irq);
  91. break;
  92. }
  93. return RT_EOK;
  94. }
  95. int printkc(char c)
  96. {
  97. int base = 0xf9e09000;
  98. while (!(UART_LSR_REG(base) & 0x20));
  99. UART_THR_REG(base) = c;
  100. return 1;
  101. }
  102. static int am33xx_putc(struct rt_serial_device *serial, char c)
  103. {
  104. struct am33xx_uart* uart;
  105. RT_ASSERT(serial != RT_NULL);
  106. uart = (struct am33xx_uart *)serial->parent.user_data;
  107. while (!(UART_LSR_REG(uart->base) & 0x20));
  108. UART_THR_REG(uart->base) = c;
  109. return 1;
  110. }
  111. static int am33xx_getc(struct rt_serial_device *serial)
  112. {
  113. int ch;
  114. struct am33xx_uart* uart;
  115. RT_ASSERT(serial != RT_NULL);
  116. uart = (struct am33xx_uart *)serial->parent.user_data;
  117. ch = -1;
  118. if (UART_LSR_REG(uart->base) & 0x01)
  119. {
  120. ch = UART_RHR_REG(uart->base) & 0xff;
  121. }
  122. return ch;
  123. }
  124. static const struct rt_uart_ops am33xx_uart_ops =
  125. {
  126. am33xx_configure,
  127. am33xx_control,
  128. am33xx_putc,
  129. am33xx_getc,
  130. };
  131. /* UART1 device driver structure */
  132. struct serial_ringbuffer uart1_int_rx;
  133. struct am33xx_uart uart1 =
  134. {
  135. UART1_BASE,
  136. UART1_INT,
  137. };
  138. struct rt_serial_device serial1;
  139. #define write_reg(base, value) *(int*)(base) = value
  140. #define read_reg(base) *(int*)(base)
  141. #define PRM_PER_INTRANSLATION (1 << 20)
  142. #define PRM_PER_POWSTATEOFF (0)
  143. #define PRM_PER_PERMEMSTATEOFF (0)
  144. static void poweron_per_domain(void)
  145. {
  146. unsigned long prcm_base;
  147. unsigned long prm_state;
  148. prcm_base = AM33XX_PRCM_REGS;
  149. /* wait for ongoing translations */
  150. for (prm_state = PRM_PER_PWRSTST_REG(prcm_base);
  151. prm_state & PRM_PER_INTRANSLATION;
  152. prm_state = PRM_PER_PWRSTST_REG(prcm_base))
  153. ;
  154. /* check power state */
  155. if ((prm_state & 0x03) == PRM_PER_POWSTATEOFF)
  156. /* power on PER domain */
  157. PRM_PER_PWRSTCTRL_REG(prcm_base) |= 0x3;
  158. /* check per mem state */
  159. if ((prm_state & 0x03) == PRM_PER_PERMEMSTATEOFF)
  160. /* power on PER domain */
  161. PRM_PER_PWRSTCTRL_REG(prcm_base) |= 0x3 << 25;
  162. while (PRM_PER_PWRSTST_REG(prcm_base) & PRM_PER_INTRANSLATION)
  163. ;
  164. }
  165. static void start_uart_clk(void)
  166. {
  167. unsigned long prcm_base;
  168. prcm_base = AM33XX_PRCM_REGS;
  169. /* software forced wakeup */
  170. CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) |= 0x2;
  171. /* Waiting for the L4LS clock */
  172. while (!(CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) & (1<<8)))
  173. ;
  174. /* enable uart1 */
  175. CM_PER_UART1_CLKCTRL_REG(prcm_base) |= 0x2;
  176. /* wait for uart1 clk */
  177. while ((CM_PER_UART1_CLKCTRL_REG(prcm_base) & (0x3<<16)) != 0)
  178. ;
  179. /* Waiting for the L4LS UART clock */
  180. while (!(CM_PER_L4LS_CLKSTCTRL_REG(prcm_base) & (1<<10)))
  181. ;
  182. }
  183. static void config_pinmux(void)
  184. {
  185. unsigned long ctlm_base;
  186. ctlm_base = AM33XX_CTLM_REGS;
  187. /* make sure the pin mux is OK for uart */
  188. REG32(ctlm_base + 0x800 + 0x180) = 0x20;
  189. REG32(ctlm_base + 0x800 + 0x184) = 0x00;
  190. }
  191. int rt_hw_serial_init(void)
  192. {
  193. struct am33xx_uart* uart;
  194. struct serial_configure config;
  195. uart = &uart1;
  196. uart->base = UART1_BASE;
  197. poweron_per_domain();
  198. start_uart_clk();
  199. config_pinmux();
  200. config.baud_rate = BAUD_RATE_115200;
  201. config.bit_order = BIT_ORDER_LSB;
  202. config.data_bits = DATA_BITS_8;
  203. config.parity = PARITY_NONE;
  204. config.stop_bits = STOP_BITS_1;
  205. config.invert = NRZ_NORMAL;
  206. serial1.ops = &am33xx_uart_ops;
  207. serial1.int_rx = &uart1_int_rx;
  208. serial1.config = config;
  209. /* enable RX interrupt */
  210. UART_IER_REG(uart->base) = 0x01;
  211. /* install ISR */
  212. rt_hw_interrupt_install(uart->irq, am33xx_uart_isr, &serial1, "uart1");
  213. rt_hw_interrupt_control(uart->irq, 0, 0);
  214. rt_hw_interrupt_mask(uart->irq);
  215. /* register UART1 device */
  216. rt_hw_serial_register(&serial1, "uart1",
  217. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
  218. uart);
  219. return 0;
  220. }
  221. INIT_BOARD_EXPORT(rt_hw_serial_init);