vex_rt/
serial.rs

1//! API for using smart ports as generic serial ports.
2
3use core::convert::TryInto;
4
5use crate::{
6    bindings,
7    error::{Error, SentinelError},
8    smart_port::{smart_port_type, DeviceType},
9};
10
11/// Represents the generic serial interface of a smart port.
12pub struct Serial(u8);
13
14impl Serial {
15    /// Constructs a new generic serial port.
16    ///
17    /// # Safety
18    /// This function is unsafe because it allows the user to create multiple
19    /// mutable references to the same smart port interface. You likely want to
20    /// implement [`Robot::new()`](crate::robot::Robot::new()) instead.
21    pub unsafe fn new(port: u8, baudrate: i32) -> Result<Self, Error> {
22        bindings::serial_enable(port).check()?;
23        while smart_port_type(port) != DeviceType::Serial {}
24        bindings::serial_set_baudrate(port, baudrate).check()?;
25        Ok(Self(port))
26    }
27
28    #[inline]
29    /// Changes the baudrate of the serial port.
30    pub fn set_baudrate(&mut self, baudrate: i32) -> Result<(), Error> {
31        unsafe { bindings::serial_set_baudrate(self.0, baudrate) }.check()?;
32        Ok(())
33    }
34
35    #[inline]
36    /// Gets the number of bytes available to read in the input buffer of the
37    /// serial port.
38    pub fn get_read_avail(&self) -> Result<usize, Error> {
39        Ok(unsafe { bindings::serial_get_read_avail(self.0) }
40            .check()?
41            .try_into()?)
42    }
43
44    #[inline]
45    /// Gets the number of bytes free in the output buffer of the serial port.
46    pub fn get_write_free(&self) -> Result<usize, Error> {
47        Ok(unsafe { bindings::serial_get_write_free(self.0) }
48            .check()?
49            .try_into()?)
50    }
51
52    #[inline]
53    /// Reads the next available byte in the input buffer of the serial port
54    /// without removing it.
55    pub fn peek_byte(&self) -> Result<u8, Error> {
56        Ok(unsafe { bindings::serial_peek_byte(self.0) }
57            .check()?
58            .try_into()?)
59    }
60
61    #[inline]
62    /// Reads the next available byte in the input buffer of the serial port.
63    pub fn read_byte(&mut self) -> Result<u8, Error> {
64        Ok(unsafe { bindings::serial_read_byte(self.0) }
65            .check()?
66            .try_into()?)
67    }
68
69    #[inline]
70    /// Writes the given byte to the output buffer of the serial port.
71    pub fn write_byte(&mut self, byte: u8) -> Result<(), Error> {
72        unsafe { bindings::serial_write_byte(self.0, byte) }.check()?;
73        Ok(())
74    }
75
76    #[inline]
77    /// Reads as many bytes as possible from the input buffer of the serial port
78    /// into the given buffer, returning the number read.
79    pub fn read(&mut self, buffer: &mut [u8]) -> Result<usize, Error> {
80        Ok(
81            unsafe { bindings::serial_read(self.0, buffer.as_mut_ptr(), buffer.len().try_into()?) }
82                .check()?
83                .try_into()?,
84        )
85    }
86
87    #[inline]
88    /// Writes as many bytes as possible to the output buffer of the serial port
89    /// from the given buffer, returning the number written.
90    pub fn write(&mut self, buffer: &[u8]) -> Result<usize, Error> {
91        Ok(unsafe {
92            bindings::serial_write(self.0, buffer.as_ptr() as *mut _, buffer.len().try_into()?)
93        }
94        .check()?
95        .try_into()?)
96    }
97
98    #[inline]
99    /// Clears the internal input and output buffers of the serial port,
100    /// effectively resetting its state.
101    pub fn flush(&mut self) -> Result<(), Error> {
102        unsafe { bindings::serial_flush(self.0) }.check()?;
103        Ok(())
104    }
105}