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