67 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			67 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use std::io;
 | |
| use std::os::unix::io::{AsRawFd, RawFd};
 | |
| 
 | |
| use nix::errno::Errno;
 | |
| use nix::fcntl::OFlag;
 | |
| use nix::sys::termios;
 | |
| 
 | |
| pub struct SerialPort {
 | |
|     fd: RawFd,
 | |
| }
 | |
| 
 | |
| impl SerialPort {
 | |
|     pub fn new<P: ?Sized + nix::NixPath>(path: &P, baudrate: termios::BaudRate) -> io::Result<Self> {
 | |
|         let fd = nix::fcntl::open(
 | |
|             path,
 | |
|             OFlag::O_RDWR | OFlag::O_NOCTTY | OFlag::O_NONBLOCK,
 | |
|             nix::sys::stat::Mode::empty(),
 | |
|         )
 | |
|         .map_err(to_io_error)?;
 | |
| 
 | |
|         let mut cfg = termios::tcgetattr(fd).map_err(to_io_error)?;
 | |
|         cfg.input_flags = termios::InputFlags::empty();
 | |
|         cfg.output_flags = termios::OutputFlags::empty();
 | |
|         cfg.control_flags = termios::ControlFlags::empty();
 | |
|         cfg.local_flags = termios::LocalFlags::empty();
 | |
|         termios::cfmakeraw(&mut cfg);
 | |
|         cfg.input_flags |= termios::InputFlags::IGNBRK;
 | |
|         cfg.control_flags |= termios::ControlFlags::CREAD;
 | |
|         //cfg.control_flags |= termios::ControlFlags::CRTSCTS;
 | |
|         termios::cfsetospeed(&mut cfg, baudrate).map_err(to_io_error)?;
 | |
|         termios::cfsetispeed(&mut cfg, baudrate).map_err(to_io_error)?;
 | |
|         termios::cfsetspeed(&mut cfg, baudrate).map_err(to_io_error)?;
 | |
|         // Set VMIN = 1 to block until at least one character is received.
 | |
|         cfg.control_chars[termios::SpecialCharacterIndices::VMIN as usize] = 1;
 | |
|         termios::tcsetattr(fd, termios::SetArg::TCSANOW, &cfg).map_err(to_io_error)?;
 | |
|         termios::tcflush(fd, termios::FlushArg::TCIOFLUSH).map_err(to_io_error)?;
 | |
| 
 | |
|         Ok(Self { fd })
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl AsRawFd for SerialPort {
 | |
|     fn as_raw_fd(&self) -> RawFd {
 | |
|         self.fd
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl io::Read for SerialPort {
 | |
|     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
 | |
|         nix::unistd::read(self.fd, buf).map_err(to_io_error)
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl io::Write for SerialPort {
 | |
|     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
 | |
|         nix::unistd::write(self.fd, buf).map_err(to_io_error)
 | |
|     }
 | |
| 
 | |
|     fn flush(&mut self) -> io::Result<()> {
 | |
|         Ok(())
 | |
|     }
 | |
| }
 | |
| 
 | |
| fn to_io_error(e: Errno) -> io::Error {
 | |
|     e.into()
 | |
| }
 |