drv_uart.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /*
  2. * File : drv_uart.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2013, RT-Thread Develop 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://openlab.rt-thread.com/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2013-07-11 reynolds port to TWR-K60F120M
  13. */
  14. #include "drv_uart.h"
  15. static struct rt_serial_device _k60_serial; //abstracted serial for RTT
  16. static struct serial_ringbuffer _k60_int_rx; //UART send buffer area
  17. struct k60_serial_device
  18. {
  19. /* UART base address */
  20. UART_Type *baseAddress;
  21. /* UART IRQ Number */
  22. int irq_num;
  23. /* device config */
  24. struct serial_configure config;
  25. };
  26. //hardware abstract device
  27. static struct k60_serial_device _k60_node =
  28. {
  29. (UART_Type *)UART5,
  30. k60_uasrt_irq_num,
  31. };
  32. static rt_err_t _configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  33. {
  34. unsigned int reg_C1 = 0,reg_C3 = 0,reg_C4 = 0,reg_BDH = 0,reg_BDL = 0,reg_S2,reg_BRFA=0;
  35. unsigned int cal_SBR = 0;
  36. UART_Type *uart_reg;
  37. /* ref : drivers\system_MK60F12.c Line 64 ,BusClock = 60MHz
  38. * calculate baud_rate
  39. */
  40. uart_reg = ((struct k60_serial_device *)serial->parent.user_data)->baseAddress;
  41. /* calc SBR */
  42. cal_SBR = 60000000 / (16 * cfg->baud_rate);
  43. /* calc baud_rate */
  44. reg_BDH = (cal_SBR & 0x1FFF) >> 8 & 0x00FF;
  45. reg_BDL = cal_SBR & 0x00FF;
  46. /* fractional divider */
  47. reg_BRFA = ((60000*32000)/(cfg->baud_rate * 16)) - (cal_SBR * 32);
  48. reg_C4 = (unsigned char)(reg_BRFA & 0x001F);
  49. /*
  50. * set bit order
  51. */
  52. if (cfg->bit_order == BIT_ORDER_LSB)
  53. reg_S2 &= ~(UART_S2_MSBF_MASK<<UART_S2_MSBF_SHIFT);
  54. else if (cfg->bit_order == BIT_ORDER_MSB)
  55. reg_S2 |= UART_S2_MSBF_MASK<<UART_S2_MSBF_SHIFT;
  56. /*
  57. * set data_bits
  58. */
  59. if (cfg->data_bits == DATA_BITS_8)
  60. reg_C1 &= ~(UART_C1_M_MASK<<UART_C1_M_SHIFT);
  61. else if (cfg->data_bits == DATA_BITS_9)
  62. reg_C1 |= UART_C1_M_MASK<<UART_C1_M_SHIFT;
  63. /*
  64. * set parity
  65. */
  66. if (cfg->parity == PARITY_NONE)
  67. {
  68. reg_C1 &= ~(UART_C1_PE_MASK);
  69. }
  70. else
  71. {
  72. /* first ,set parity enable bit */
  73. reg_C1 |= (UART_C1_PE_MASK);
  74. /* second ,determine parity odd or even*/
  75. if (cfg->parity == PARITY_ODD)
  76. reg_C1 |= UART_C1_PT_MASK;
  77. if (cfg->parity == PARITY_EVEN)
  78. reg_C1 &= ~(UART_C1_PT_MASK);
  79. }
  80. /*
  81. * set stop bit
  82. * not supported on Tower? need ur help!
  83. */
  84. /*
  85. * set NZR mode
  86. * not tested
  87. */
  88. if(cfg->invert != NRZ_NORMAL)
  89. {
  90. /* not in normal mode ,set inverted polarity */
  91. reg_C3 |= UART_C3_TXINV_MASK;
  92. }
  93. switch( (int)uart_reg)
  94. {
  95. /* Tower board use UART5 for communication
  96. * if you're using other board
  97. * set clock and pin map for UARTx
  98. */
  99. case UART5_BASE:
  100. //set UART5 clock
  101. SIM->SCGC1 |= SIM_SCGC1_UART5_MASK;//Enable UART gate clocking
  102. SIM->SCGC5 |= SIM_SCGC5_PORTE_MASK;//Enable PORTE gate clocking
  103. //set UART5 pin
  104. PORTE->PCR[ 8] = (3UL << 8); //Pin mux configured as ALT3
  105. PORTE->PCR[ 9] = (3UL << 8); //Pin mux configured as ALT3
  106. break;
  107. default:
  108. break;
  109. }
  110. uart_reg->BDH = reg_BDH;
  111. uart_reg->BDL = reg_BDL;
  112. uart_reg->C1 = reg_C1;
  113. uart_reg->C4 = reg_C4;
  114. uart_reg->S2 = reg_S2;
  115. uart_reg->S2 = 0;
  116. uart_reg->C3 = 0;
  117. uart_reg->RWFIFO = UART_RWFIFO_RXWATER(1);
  118. uart_reg->TWFIFO = UART_TWFIFO_TXWATER(0);
  119. uart_reg->C2 = UART_C2_RE_MASK | //Receiver enable
  120. UART_C2_TE_MASK; //Transmitter enable
  121. return RT_EOK;
  122. }
  123. static rt_err_t _control(struct rt_serial_device *serial, int cmd, void *arg)
  124. {
  125. UART_Type *uart_reg;
  126. int uart_irq_num = 0;
  127. uart_reg = ((struct k60_serial_device *)serial->parent.user_data)->baseAddress;
  128. uart_irq_num = ((struct k60_serial_device *)serial->parent.user_data)->irq_num;
  129. switch (cmd)
  130. {
  131. case RT_DEVICE_CTRL_CLR_INT:
  132. /* disable rx irq */
  133. uart_reg->C2 &= ~UART_C2_RIE_MASK;
  134. //disable NVIC
  135. NVIC->ICER[uart_irq_num / 32] = 1 << (uart_irq_num % 32);
  136. break;
  137. case RT_DEVICE_CTRL_SET_INT:
  138. /* enable rx irq */
  139. uart_reg->C2 |= UART_C2_RIE_MASK;
  140. //enable NVIC,we are sure uart's NVIC vector is in NVICICPR1
  141. NVIC->ICPR[uart_irq_num / 32] = 1 << (uart_irq_num % 32);
  142. NVIC->ISER[uart_irq_num / 32] = 1 << (uart_irq_num % 32);
  143. break;
  144. case RT_DEVICE_CTRL_SUSPEND:
  145. /* suspend device */
  146. uart_reg->C2 &= ~(UART_C2_RE_MASK | //Receiver enable
  147. UART_C2_TE_MASK); //Transmitter enable
  148. break;
  149. case RT_DEVICE_CTRL_RESUME:
  150. /* resume device */
  151. uart_reg->C2 = UART_C2_RE_MASK | //Receiver enable
  152. UART_C2_TE_MASK; //Transmitter enable
  153. break;
  154. }
  155. return RT_EOK;
  156. }
  157. static int _putc(struct rt_serial_device *serial, char c)
  158. {
  159. UART_Type *uart_reg;
  160. uart_reg = ((struct k60_serial_device *)serial->parent.user_data)->baseAddress;
  161. while (!(uart_reg->S1 & UART_S1_TDRE_MASK));
  162. uart_reg->D = (c & 0xFF);
  163. return 1;
  164. }
  165. static int _getc(struct rt_serial_device *serial)
  166. {
  167. UART_Type *uart_reg;
  168. uart_reg = ((struct k60_serial_device *)serial->parent.user_data)->baseAddress;
  169. if (uart_reg->S1 & UART_S1_RDRF_MASK)
  170. return (uart_reg->D);
  171. else
  172. return -1;
  173. }
  174. static const struct rt_uart_ops _k60_ops =
  175. {
  176. _configure,
  177. _control,
  178. _putc,
  179. _getc,
  180. };
  181. void UART5_RX_TX_IRQHandler(void)
  182. {
  183. rt_interrupt_enter();
  184. rt_hw_serial_isr((struct rt_serial_device*)&_k60_serial);
  185. rt_interrupt_leave();
  186. }
  187. void rt_hw_uart_init(void)
  188. {
  189. struct serial_configure config;
  190. /* fake configuration */
  191. config.baud_rate = BAUD_RATE_115200;
  192. config.bit_order = BIT_ORDER_LSB;
  193. config.data_bits = DATA_BITS_8;
  194. config.parity = PARITY_NONE;
  195. config.stop_bits = STOP_BITS_1;
  196. config.invert = NRZ_NORMAL;
  197. _k60_serial.ops = &_k60_ops;
  198. _k60_serial.int_rx = &_k60_int_rx;
  199. _k60_serial.config = config;
  200. rt_hw_serial_register(&_k60_serial, "uart5",
  201. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
  202. (void*)&_k60_node);
  203. }
  204. void rt_hw_console_output(const char *str)
  205. {
  206. while(*str != '\0')
  207. {
  208. if (*str == '\n')
  209. _putc(&_k60_serial,'\r');
  210. _putc(&_k60_serial,*str);
  211. str++;
  212. }
  213. }