37 #include <sys/select.h> 
   46         : 
rp::hal::serial_rxtx(), _baudrate(0), _flags(0), serial_fd(-1)
 
   51 raw_serial::~raw_serial() { close(); }
 
   52 bool raw_serial::open() { 
return open(_portName, _baudrate, _flags); }
 
   53 bool raw_serial::bind(
const char* portname, 
uint32_t baudrate, 
uint32_t flags)
 
   55         strncpy(_portName, portname, 
sizeof(_portName));
 
   61 bool raw_serial::open(
const char* portname, 
uint32_t baudrate, 
uint32_t flags)
 
   63         if (isOpened()) close();
 
   65         serial_fd = ::open(portname, O_RDWR | O_NOCTTY | O_NDELAY);
 
   67         if (serial_fd == -1) 
return false;
 
   69         struct termios options, oldopt;
 
   70         tcgetattr(serial_fd, &oldopt);
 
   71         bzero(&options, 
sizeof(
struct termios));
 
   73         _u32 termbaud = getTermBaudBitmap(baudrate);
 
   75         if (termbaud == (
_u32)-1)
 
   80         cfsetispeed(&options, termbaud);
 
   81         cfsetospeed(&options, termbaud);
 
   84         options.c_cflag |= (CLOCAL | CREAD);
 
   86         options.c_cflag &= ~PARENB;  
 
   87         options.c_cflag &= ~CSTOPB;  
 
   89         options.c_cflag &= ~CSIZE;
 
   90         options.c_cflag |= CS8; 
 
   93         options.c_cflag &= ~CNEW_RTSCTS;  
 
   96         options.c_iflag &= ~(IXON | IXOFF | IXANY);  
 
   99         options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
 
  101         options.c_oflag &= ~OPOST;
 
  103         tcflush(serial_fd, TCIFLUSH);
 
  111         if (tcsetattr(serial_fd, TCSANOW, &options))
 
  117         _is_serial_opened = 
true;
 
  125 void raw_serial::close()
 
  127         if (serial_fd != -1) ::close(serial_fd);
 
  130         _is_serial_opened = 
false;
 
  133 int raw_serial::senddata(
const unsigned char* 
data, _word_size_t 
size)
 
  136         if (!isOpened()) 
return 0;
 
  138         if (
data == 
nullptr || 
size == 0) 
return 0;
 
  144                 int ans = ::write(serial_fd, 
data + tx_len, 
size - tx_len);
 
  146                 if (ans == -1) 
return tx_len;
 
  149                 required_tx_cnt = tx_len;
 
  150         } 
while (tx_len < 
size);
 
  155 int raw_serial::recvdata(
unsigned char* 
data, _word_size_t 
size)
 
  157         if (!isOpened()) 
return 0;
 
  159         int ans = ::read(serial_fd, 
data, 
size);
 
  161         if (ans == -1) ans = 0;
 
  162         required_rx_cnt = ans;
 
  166 void raw_serial::flush(
_u32 flags) { tcflush(serial_fd, TCIFLUSH); }
 
  167 int raw_serial::waitforsent(
_u32 timeout, _word_size_t* returned_size)
 
  169         if (returned_size) *returned_size = required_tx_cnt;
 
  173 int raw_serial::waitforrecv(
_u32 timeout, _word_size_t* returned_size)
 
  175         if (!isOpened()) 
return -1;
 
  177         if (returned_size) *returned_size = required_rx_cnt;
 
  181 int raw_serial::waitfordata(
 
  182         _word_size_t data_count, 
_u32 timeout, _word_size_t* returned_size)
 
  185         if (returned_size == 
nullptr) returned_size = (_word_size_t*)&
length;
 
  190         struct timeval timeout_val;
 
  194         FD_SET(serial_fd, &input_set);
 
  195         max_fd = serial_fd + 1;
 
  198         timeout_val.tv_sec = timeout / 1000;
 
  199         timeout_val.tv_usec = (timeout % 1000) * 1000;
 
  203                 if (ioctl(serial_fd, FIONREAD, returned_size) == -1) 
return ANS_DEV_ERR;
 
  204                 if (*returned_size >= data_count)
 
  213                 int n = ::select(max_fd, &input_set, 
nullptr, 
nullptr, &timeout_val);
 
  228                         assert(FD_ISSET(serial_fd, &input_set));
 
  230                         if (ioctl(serial_fd, FIONREAD, returned_size) == -1)
 
  232                         if (*returned_size >= data_count)
 
  239                                         timeout_val.tv_sec * 1000000 + timeout_val.tv_usec;
 
  240                                 int expect_remain_time =
 
  241                                         (data_count - *returned_size) * 1000000 * 8 / _baudrate;
 
  242                                 if (remain_timeout > expect_remain_time)
 
  243                                         usleep(expect_remain_time);
 
  250 size_t raw_serial::rxqueue_count()
 
  252         if (!isOpened()) 
return 0;
 
  255         if (::ioctl(serial_fd, FIONREAD, &remaining) == -1) 
return 0;
 
  259 void raw_serial::setDTR()
 
  261         if (!isOpened()) 
return;
 
  264         ioctl(serial_fd, TIOCMBIS, &dtr_bit);
 
  267 void raw_serial::clearDTR()
 
  269         if (!isOpened()) 
return;
 
  272         ioctl(serial_fd, TIOCMBIC, &dtr_bit);
 
  275 void raw_serial::_init()
 
  279         required_tx_cnt = required_rx_cnt = 0;
 
  282 _u32 raw_serial::getTermBaudBitmap(
_u32 baud)
 
  284 #define BAUD_CONV(_baud_) \