serial.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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. /**
  16. * @brief Configure serial port
  17. *
  18. * This function will configure UART baudrate, parity and so on.
  19. *
  20. * @return RT_EOK.
  21. */
  22. static rt_err_t serial_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  23. {
  24. struct usart_sync_descriptor* desc;
  25. RT_ASSERT(serial != RT_NULL);
  26. desc = (struct usart_sync_descriptor *)serial->parent.user_data;
  27. RT_ASSERT(desc != RT_NULL);
  28. RT_ASSERT(cfg != RT_NULL);
  29. usart_sync_disable(desc);
  30. /* Set baudrate */
  31. usart_sync_set_baud_rate(desc, (const uint32_t)cfg->baud_rate);
  32. /* Set stop bit */
  33. if (cfg->stop_bits == STOP_BITS_1)
  34. usart_sync_set_stopbits(desc, USART_STOP_BITS_ONE);
  35. else if (cfg->stop_bits == STOP_BITS_2)
  36. usart_sync_set_stopbits(desc, USART_STOP_BITS_TWO);
  37. if (cfg->bit_order == BIT_ORDER_LSB)
  38. usart_sync_set_data_order(desc, USART_DATA_ORDER_LSB);
  39. else if (cfg->bit_order == BIT_ORDER_MSB)
  40. usart_sync_set_data_order(desc, USART_DATA_ORDER_MSB);
  41. /* Set character size */
  42. switch (cfg->data_bits)
  43. {
  44. case DATA_BITS_5:
  45. usart_sync_set_character_size(desc, USART_CHARACTER_SIZE_5BITS);
  46. break;
  47. case DATA_BITS_6:
  48. usart_sync_set_character_size(desc, USART_CHARACTER_SIZE_6BITS);
  49. break;
  50. case DATA_BITS_7:
  51. usart_sync_set_character_size(desc, USART_CHARACTER_SIZE_7BITS);
  52. break;
  53. case DATA_BITS_8:
  54. usart_sync_set_character_size(desc, USART_CHARACTER_SIZE_8BITS);
  55. break;
  56. case DATA_BITS_9:
  57. usart_sync_set_character_size(desc, USART_CHARACTER_SIZE_9BITS);
  58. break;
  59. default:
  60. break;
  61. }
  62. if (cfg->parity == PARITY_NONE)
  63. usart_sync_set_parity(desc, USART_PARITY_NONE);
  64. else if (cfg->parity == PARITY_ODD)
  65. usart_sync_set_parity(desc, USART_PARITY_ODD);
  66. else if (cfg->parity == PARITY_EVEN)
  67. usart_sync_set_parity(desc, USART_PARITY_EVEN);
  68. usart_sync_enable(desc);
  69. return RT_EOK;
  70. }
  71. /**
  72. * @brief Control serial port
  73. *
  74. * This function provide UART enable/disable control.
  75. *
  76. * @return RT_EOK.
  77. */
  78. static rt_err_t serial_control(struct rt_serial_device *serial, int cmd, void *arg)
  79. {
  80. struct usart_sync_descriptor* desc;
  81. RT_ASSERT(serial != RT_NULL);
  82. desc = (struct usart_sync_descriptor *)serial->parent.user_data;
  83. RT_ASSERT(desc != RT_NULL);
  84. switch (cmd)
  85. {
  86. /* disable interrupt */
  87. case RT_DEVICE_CTRL_CLR_INT:
  88. usart_sync_disable(desc);
  89. break;
  90. /* enable interrupt */
  91. case RT_DEVICE_CTRL_SET_INT:
  92. usart_sync_enable(desc);
  93. break;
  94. /* UART config */
  95. case RT_DEVICE_CTRL_CONFIG :
  96. break;
  97. }
  98. return RT_EOK;
  99. }
  100. /**
  101. * @brief Serial sends a char
  102. *
  103. * This function will send a char to the UART
  104. *
  105. * @return 1.
  106. */
  107. static int serial_putc(struct rt_serial_device *serial, char c)
  108. {
  109. struct usart_sync_descriptor* desc;
  110. RT_ASSERT(serial != RT_NULL);
  111. desc = (struct usart_sync_descriptor *)serial->parent.user_data;
  112. RT_ASSERT(desc != RT_NULL);
  113. io_write(&desc->io, (const uint8_t *)&c, 1);
  114. return 1;
  115. }
  116. /**
  117. * @brief Serial gets a char
  118. *
  119. * This function will get a char from the UART
  120. *
  121. * @return received char character or -1 if no char received.
  122. */
  123. static int serial_getc(struct rt_serial_device *serial)
  124. {
  125. char c;
  126. int ch;
  127. struct usart_sync_descriptor* desc;
  128. RT_ASSERT(serial != RT_NULL);
  129. desc = (struct usart_sync_descriptor *)serial->parent.user_data;
  130. RT_ASSERT(desc != RT_NULL);
  131. ch = -1;
  132. if (usart_sync_is_rx_not_empty(desc))
  133. {
  134. io_read(&desc->io, (uint8_t *)&c, 1);;
  135. ch = c & 0xff;
  136. }
  137. return ch;
  138. }
  139. static const struct rt_uart_ops sam_serial_ops =
  140. {
  141. serial_configure,
  142. serial_control,
  143. serial_putc,
  144. serial_getc,
  145. };
  146. /**
  147. * @brief Initialize the UART
  148. *
  149. * This function initialize the UART
  150. *
  151. * @return None.
  152. */
  153. int rt_hw_uart_init(void)
  154. {
  155. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  156. sam_serial.ops = &sam_serial_ops;
  157. sam_serial.config = config;
  158. sam_serial.serial_rx = RT_NULL;
  159. sam_serial.serial_rx = RT_NULL;
  160. rt_hw_serial_register(&sam_serial, "uart0",
  161. RT_DEVICE_FLAG_RDWR, (void *)&TARGET_IO);
  162. return 0;
  163. }
  164. /*@}*/