serial.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. * Copyright (c)
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Email Notes
  8. * 2019-07-16 Kevin.Liu kevin.liu.mchp@gmail.com First Release
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <atmel_start.h>
  13. /* SAM MCU serial device */
  14. static struct rt_serial_device sam_serial;
  15. static void serial_rxcallback(const struct usart_async_descriptor *const io_descr)
  16. {
  17. (void)io_descr;
  18. /* enter interrupt */
  19. rt_interrupt_enter();
  20. /* Notify Serial driver to process RX data */
  21. rt_hw_serial_isr(&sam_serial, RT_SERIAL_EVENT_RX_IND);
  22. /* leave interrupt */
  23. rt_interrupt_leave();
  24. }
  25. static void serial_txcallback(const struct usart_async_descriptor *const io_descr)
  26. {
  27. (void)io_descr;
  28. /* enter interrupt */
  29. rt_interrupt_enter();
  30. /* Notify Serial driver to process TX done event */
  31. rt_hw_serial_isr(&sam_serial, RT_SERIAL_EVENT_TX_DONE);
  32. /* leave interrupt */
  33. rt_interrupt_leave();
  34. }
  35. /**
  36. * @brief Configure serial port
  37. *
  38. * This function will configure UART baudrate, parity and so on.
  39. *
  40. * @return RT_EOK.
  41. */
  42. static rt_err_t serial_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  43. {
  44. struct usart_async_descriptor* desc;
  45. RT_ASSERT(serial != RT_NULL);
  46. desc = (struct usart_async_descriptor *)serial->parent.user_data;
  47. RT_ASSERT(desc != RT_NULL);
  48. RT_ASSERT(cfg != RT_NULL);
  49. usart_async_disable(desc);
  50. /* Set baudrate */
  51. usart_async_set_baud_rate(desc, (const uint32_t)cfg->baud_rate);
  52. /* Set stop bit */
  53. if (cfg->stop_bits == STOP_BITS_1)
  54. usart_async_set_stopbits(desc, USART_STOP_BITS_ONE);
  55. else if (cfg->stop_bits == STOP_BITS_2)
  56. usart_async_set_stopbits(desc, USART_STOP_BITS_TWO);
  57. if (cfg->bit_order == BIT_ORDER_LSB)
  58. usart_async_set_data_order(desc, USART_DATA_ORDER_LSB);
  59. else if (cfg->bit_order == BIT_ORDER_MSB)
  60. usart_async_set_data_order(desc, USART_DATA_ORDER_MSB);
  61. /* Set character size */
  62. switch (cfg->data_bits)
  63. {
  64. case DATA_BITS_5:
  65. usart_async_set_character_size(desc, USART_CHARACTER_SIZE_5BITS);
  66. break;
  67. case DATA_BITS_6:
  68. usart_async_set_character_size(desc, USART_CHARACTER_SIZE_6BITS);
  69. break;
  70. case DATA_BITS_7:
  71. usart_async_set_character_size(desc, USART_CHARACTER_SIZE_7BITS);
  72. break;
  73. case DATA_BITS_8:
  74. usart_async_set_character_size(desc, USART_CHARACTER_SIZE_8BITS);
  75. break;
  76. case DATA_BITS_9:
  77. usart_async_set_character_size(desc, USART_CHARACTER_SIZE_9BITS);
  78. break;
  79. default:
  80. break;
  81. }
  82. if (cfg->parity == PARITY_NONE)
  83. usart_async_set_parity(desc, USART_PARITY_NONE);
  84. else if (cfg->parity == PARITY_ODD)
  85. usart_async_set_parity(desc, USART_PARITY_ODD);
  86. else if (cfg->parity == PARITY_EVEN)
  87. usart_async_set_parity(desc, USART_PARITY_EVEN);
  88. usart_async_enable(desc);
  89. return RT_EOK;
  90. }
  91. /**
  92. * @brief Control serial port
  93. *
  94. * This function provide UART enable/disable control.
  95. *
  96. * @return RT_EOK.
  97. */
  98. static rt_err_t serial_control(struct rt_serial_device *serial, int cmd, void *arg)
  99. {
  100. struct usart_async_descriptor* desc;
  101. RT_ASSERT(serial != RT_NULL);
  102. desc = (struct usart_async_descriptor *)serial->parent.user_data;
  103. RT_ASSERT(desc != RT_NULL);
  104. switch (cmd)
  105. {
  106. /* disable interrupt */
  107. case RT_DEVICE_CTRL_CLR_INT:
  108. usart_async_disable(desc);
  109. break;
  110. /* enable interrupt */
  111. case RT_DEVICE_CTRL_SET_INT:
  112. usart_async_enable(desc);
  113. break;
  114. /* UART config */
  115. case RT_DEVICE_CTRL_CONFIG :
  116. break;
  117. }
  118. return RT_EOK;
  119. }
  120. /**
  121. * @brief Serial sends a char
  122. *
  123. * This function will send a char to the UART
  124. *
  125. * @return 1.
  126. */
  127. static int serial_putc(struct rt_serial_device *serial, char c)
  128. {
  129. struct usart_async_descriptor* desc;
  130. RT_ASSERT(serial != RT_NULL);
  131. desc = (struct usart_async_descriptor *)serial->parent.user_data;
  132. RT_ASSERT(desc != RT_NULL);
  133. while (usart_async_is_tx_empty(desc) == 0);
  134. _usart_async_write_byte(&TARGET_IO.device, (uint8_t)c);
  135. return 1;
  136. }
  137. /**
  138. * @brief Serial gets a char
  139. *
  140. * This function will get a char from the UART
  141. *
  142. * @return received char character or -1 if no char received.
  143. */
  144. static int serial_getc(struct rt_serial_device *serial)
  145. {
  146. char c;
  147. int ch;
  148. struct usart_async_descriptor* desc;
  149. RT_ASSERT(serial != RT_NULL);
  150. desc = (struct usart_async_descriptor *)serial->parent.user_data;
  151. RT_ASSERT(desc != RT_NULL);
  152. ch = -1;
  153. if (usart_async_is_rx_not_empty(desc))
  154. {
  155. io_read(&desc->io, (uint8_t *)&c, 1);
  156. ch = c & 0xff;
  157. }
  158. return ch;
  159. }
  160. static const struct rt_uart_ops sam_serial_ops =
  161. {
  162. serial_configure,
  163. serial_control,
  164. serial_putc,
  165. serial_getc,
  166. };
  167. /**
  168. * @brief Initialize the UART
  169. *
  170. * This function initialize the UART
  171. *
  172. * @return None.
  173. */
  174. int rt_hw_uart_init(void)
  175. {
  176. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  177. sam_serial.ops = &sam_serial_ops;
  178. sam_serial.config = config;
  179. sam_serial.serial_rx = RT_NULL;
  180. sam_serial.serial_rx = RT_NULL;
  181. rt_hw_serial_register(&sam_serial, RT_CONSOLE_DEVICE_NAME,
  182. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX |
  183. RT_DEVICE_FLAG_INT_TX, (void *)&TARGET_IO);
  184. usart_async_register_callback(&TARGET_IO, USART_ASYNC_TXC_CB, serial_txcallback);
  185. usart_async_register_callback(&TARGET_IO, USART_ASYNC_RXC_CB, serial_rxcallback);
  186. return 0;
  187. }
  188. /*@}*/