usbh_rtserial.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. * Copyright (c) 2025, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <rtthread.h>
  7. #include <rtdevice.h>
  8. #include "usbh_core.h"
  9. #include "usbh_serial.h"
  10. static rt_err_t rt_usbh_serial_open(struct rt_device *dev, rt_uint16_t oflag)
  11. {
  12. struct usbh_serial *serial;
  13. RT_ASSERT(dev != RT_NULL && dev->user_data != RT_NULL);
  14. serial = (struct usbh_serial *)dev->user_data;
  15. serial = usbh_serial_open(serial->hport->config.intf[serial->intf].devname, USBH_SERIAL_O_RDWR | USBH_SERIAL_O_NONBLOCK);
  16. if (serial == RT_NULL) {
  17. USB_LOG_ERR("serial open failed\n");
  18. return -RT_ERROR;
  19. }
  20. struct usbh_serial_termios termios;
  21. memset(&termios, 0, sizeof(termios));
  22. termios.baudrate = 115200;
  23. termios.stopbits = 0;
  24. termios.parity = 0;
  25. termios.databits = 8;
  26. termios.rtscts = false;
  27. termios.rx_timeout = 0;
  28. usbh_serial_control(serial, USBH_SERIAL_CMD_SET_ATTR, &termios);
  29. return RT_EOK;
  30. }
  31. static rt_err_t rt_usbh_serial_close(struct rt_device *dev)
  32. {
  33. struct usbh_serial *serial;
  34. RT_ASSERT(dev != RT_NULL && dev->user_data != RT_NULL);
  35. serial = (struct usbh_serial *)dev->user_data;
  36. usbh_serial_close(serial);
  37. return RT_EOK;
  38. }
  39. static rt_ssize_t rt_usbh_serial_read(struct rt_device *dev,
  40. rt_off_t pos,
  41. void *buffer,
  42. rt_size_t size)
  43. {
  44. struct usbh_serial *serial;
  45. RT_ASSERT(dev != RT_NULL && dev->user_data != RT_NULL);
  46. serial = (struct usbh_serial *)dev->user_data;
  47. return usbh_serial_read(serial, buffer, size);
  48. }
  49. static rt_ssize_t rt_usbh_serial_write(struct rt_device *dev,
  50. rt_off_t pos,
  51. const void *buffer,
  52. rt_size_t size)
  53. {
  54. struct usbh_serial *serial;
  55. int ret = 0;
  56. rt_uint8_t *align_buf;
  57. RT_ASSERT(dev != RT_NULL && dev->user_data != RT_NULL);
  58. serial = (struct usbh_serial *)dev->user_data;
  59. align_buf = (rt_uint8_t *)buffer;
  60. if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
  61. align_buf = rt_malloc_align(USB_ALIGN_UP(size, CONFIG_USB_ALIGN_SIZE), CONFIG_USB_ALIGN_SIZE);
  62. if (!align_buf) {
  63. USB_LOG_ERR("serial get align buf failed\n");
  64. return 0;
  65. }
  66. usb_memcpy(align_buf, buffer, size);
  67. }
  68. ret = usbh_serial_write(serial, align_buf, size);
  69. if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
  70. rt_free_align(align_buf);
  71. }
  72. return ret;
  73. }
  74. static rt_err_t rt_usbh_serial_control(struct rt_device *dev,
  75. int cmd,
  76. void *args)
  77. {
  78. struct usbh_serial *serial;
  79. struct serial_configure *config;
  80. int ret = -RT_EINVAL;
  81. RT_ASSERT(dev != RT_NULL && dev->user_data != RT_NULL);
  82. serial = (struct usbh_serial *)dev->user_data;
  83. switch (cmd) {
  84. case RT_DEVICE_CTRL_CONFIG: {
  85. config = (struct serial_configure *)args;
  86. struct usbh_serial_termios termios;
  87. memset(&termios, 0, sizeof(termios));
  88. termios.baudrate = config->baud_rate;
  89. termios.stopbits = 0;
  90. termios.parity = config->parity;
  91. termios.databits = config->data_bits;
  92. termios.rtscts = false;
  93. termios.rx_timeout = 0;
  94. usbh_serial_control(serial, USBH_SERIAL_CMD_SET_ATTR, &termios);
  95. } break;
  96. default:
  97. break;
  98. }
  99. return ret;
  100. }
  101. #ifdef RT_USING_DEVICE_OPS
  102. const static struct rt_device_ops usbh_serial_ops = {
  103. NULL,
  104. rt_usbh_serial_open,
  105. rt_usbh_serial_close,
  106. rt_usbh_serial_read,
  107. rt_usbh_serial_write,
  108. rt_usbh_serial_control
  109. };
  110. #endif
  111. rt_err_t usbh_serial_register(struct usbh_serial *serial)
  112. {
  113. rt_err_t ret;
  114. struct rt_device *device;
  115. RT_ASSERT(serial != RT_NULL);
  116. device = rt_malloc(sizeof(struct rt_device));
  117. if (device == RT_NULL) {
  118. USB_LOG_ERR("serial device malloc failed\n");
  119. return -RT_ENOMEM;
  120. }
  121. memset(device, 0, sizeof(struct rt_device));
  122. device->type = RT_Device_Class_Char;
  123. device->rx_indicate = RT_NULL;
  124. device->tx_complete = RT_NULL;
  125. #ifdef RT_USING_DEVICE_OPS
  126. device->ops = &usbh_serial_ops;
  127. #else
  128. device->init = NULL;
  129. device->open = rt_usbh_serial_open;
  130. device->close = rt_usbh_serial_close;
  131. device->read = rt_usbh_serial_read;
  132. device->write = rt_usbh_serial_write;
  133. device->control = rt_usbh_serial_control;
  134. #endif
  135. device->user_data = serial;
  136. serial->user_data = device;
  137. /* skip /dev/ to avoid BAD file */
  138. const char *dev_name = serial->hport->config.intf[serial->intf].devname;
  139. if (strncmp(dev_name, "/dev/", 5) == 0) {
  140. dev_name += 5;
  141. }
  142. /* register a character device */
  143. ret = rt_device_register(device, dev_name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_REMOVABLE);
  144. #ifdef RT_USING_POSIX_DEVIO
  145. /* set fops */
  146. device->fops = &usbh_serial_fops;
  147. #endif
  148. return ret;
  149. }
  150. void usbh_serial_unregister(struct usbh_serial *serial)
  151. {
  152. struct rt_device *device;
  153. RT_ASSERT(serial != NULL && serial->user_data != NULL);
  154. device = (struct rt_device *)serial->user_data;
  155. rt_device_unregister(device);
  156. rt_free(device);
  157. }
  158. void usbh_serial_run(struct usbh_serial *serial)
  159. {
  160. usbh_serial_register(serial);
  161. }
  162. void usbh_serial_stop(struct usbh_serial *serial)
  163. {
  164. usbh_serial_unregister(serial);
  165. }