bf16-uartdevice.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include <fcntl.h>
  2. #include <unistd.h>
  3. #include "bf16-uartdevice.h"
  4. #include "miner.h"
  5. #define SRV_TIMEOUT 2
  6. char *uart1_device_name = "/dev/ttyO1";
  7. char *uart2_device_name = "/dev/ttyO4";
  8. int8_t uart_init(device_t* attr, uart_channel_id_t channel_id, int8_t mode, uint32_t speed, uint16_t size)
  9. {
  10. switch (channel_id) {
  11. case UART_CHANNEL1:
  12. attr->device = uart1_device_name;
  13. break;
  14. case UART_CHANNEL2:
  15. attr->device = uart2_device_name;
  16. break;
  17. }
  18. attr->mode = mode;
  19. attr->speed = speed;
  20. attr->bits = 8;
  21. attr->size = size;
  22. attr->rx = malloc(size);
  23. attr->tx = malloc(size);
  24. int fd;
  25. if ((fd = open(attr->device, O_RDWR | O_NOCTTY | O_NDELAY)) < 0)
  26. quit(1, "BF16: %s() failed to open device [%s]: %s",
  27. __func__, attr->device, strerror(errno));
  28. attr->fd = fd;
  29. if (fcntl(fd, F_SETFL, 0) < 0)
  30. quit(1, "BF16: %s() failed to set descriptor status flags [%s]: %s",
  31. __func__, attr->device, strerror(errno));
  32. struct termios settings;
  33. if (tcgetattr(fd, &settings) < 0)
  34. quit(1, "BF16: %s() failed to get device attributes [%s]: %s",
  35. __func__, attr->device, strerror(errno));
  36. settings.c_cflag &= ~PARENB; /* no parity */
  37. settings.c_cflag &= ~CSTOPB; /* 1 stop bit */
  38. settings.c_cflag &= ~CSIZE;
  39. settings.c_cflag |= CS8 | CLOCAL | CREAD; /* 8 bits */
  40. settings.c_cc[VMIN] = 1;
  41. settings.c_cc[VTIME] = 2;
  42. settings.c_lflag = ICANON; /* canonical mode */
  43. settings.c_oflag &= ~OPOST; /* raw output */
  44. if (cfsetospeed(&settings, speed) < 0)
  45. quit(1, "BF16: %s() failed to set device output speed [%s]: %s",
  46. __func__, attr->device, strerror(errno));
  47. if (cfsetispeed(&settings, speed) < 0)
  48. quit(1, "BF16: %s() failed to set device input speed [%s]: %s",
  49. __func__, attr->device, strerror(errno));
  50. if (tcsetattr(fd, TCSANOW, &settings) < 0)
  51. quit(1, "BF16: %s() failed to get device attributes [%s]: %s",
  52. __func__, attr->device, strerror(errno));
  53. if (tcflush(fd, TCOFLUSH) < 0)
  54. quit(1, "BF16: %s() failed to flush device data [%s]: %s",
  55. __func__, attr->device, strerror(errno));
  56. return 0;
  57. }
  58. /* TODO: add errors processing */
  59. static int read_to(int fd, uint8_t* buffer, int len, int timeout)
  60. {
  61. fd_set readset;
  62. int result;
  63. struct timeval tv;
  64. FD_ZERO(&readset);
  65. FD_SET(fd, &readset);
  66. tv.tv_sec = timeout;
  67. tv.tv_usec = 0;
  68. result = select(fd + 1, &readset, NULL, NULL, &tv);
  69. if (result < 0)
  70. return result;
  71. else if (result > 0 && FD_ISSET(fd, &readset)) {
  72. result = read(fd, buffer, len);
  73. return result;
  74. }
  75. return -2;
  76. }
  77. static int write_to(int fd, uint8_t* buffer, int len, int timeout)
  78. {
  79. fd_set writeset;
  80. int result;
  81. struct timeval tv;
  82. FD_ZERO(&writeset);
  83. FD_SET(fd, &writeset);
  84. tv.tv_sec = timeout;
  85. tv.tv_usec = 0;
  86. result = select(fd + 1, NULL, &writeset, NULL, &tv);
  87. if (result < 0)
  88. return result;
  89. else if (result > 0 && FD_ISSET(fd, &writeset)) {
  90. result = write(fd, buffer, len);
  91. return result;
  92. }
  93. return -2;
  94. }
  95. int8_t uart_transfer(device_t *attr)
  96. {
  97. int ret;
  98. if ((ret = write_to(attr->fd, attr->tx, attr->datalen, SRV_TIMEOUT)) < 1) {
  99. applog(LOG_ERR, "BF16: %s() failed to send UART message to [%s]: %s",
  100. __func__, attr->device, strerror(errno));
  101. attr->datalen = 0;
  102. return -1;
  103. }
  104. if ((ret = read_to(attr->fd, attr->rx, attr->size, SRV_TIMEOUT)) < 1) {
  105. applog(LOG_ERR, "BF16: %s() failed to read UART message from [%s]: %s",
  106. __func__, attr->device, strerror(errno));
  107. attr->datalen = 0;
  108. return -1;
  109. }
  110. attr->datalen = ret;
  111. return 0;
  112. }
  113. void uart_release(device_t *attr)
  114. {
  115. free(attr->rx);
  116. free(attr->tx);
  117. close(attr->fd);
  118. }