// Copyright (c) FIRST and other WPILib contributors. // Open Source Software; you can modify and/or share it under the terms of // the WPILib BSD license file in the root directory of this project. #pragma once #include #include #include #include namespace frc { /** * Driver for the RS-232 serial port on the roboRIO. * * The current implementation uses the VISA formatted I/O mode. This means that * all traffic goes through the fomatted buffers. This allows the intermingled * use of Printf(), Scanf(), and the raw buffer accessors Read() and Write(). * * More information can be found in the NI-VISA User Manual here: * http://www.ni.com/pdf/manuals/370423a.pdf * and the NI-VISA Programmer's Reference Manual here: * http://www.ni.com/pdf/manuals/370132c.pdf */ class SerialPort { public: enum Parity { kParity_None = 0, kParity_Odd = 1, kParity_Even = 2, kParity_Mark = 3, kParity_Space = 4 }; enum StopBits { kStopBits_One = 10, kStopBits_OnePointFive = 15, kStopBits_Two = 20 }; enum FlowControl { kFlowControl_None = 0, kFlowControl_XonXoff = 1, kFlowControl_RtsCts = 2, kFlowControl_DtrDsr = 4 }; enum WriteBufferMode { kFlushOnAccess = 1, kFlushWhenFull = 2 }; enum Port { kOnboard = 0, kMXP = 1, kUSB = 2, kUSB1 = 2, kUSB2 = 3 }; /** * Create an instance of a Serial Port class. * * @param baudRate The baud rate to configure the serial port. * @param port The physical port to use * @param dataBits The number of data bits per transfer. Valid values are * between 5 and 8 bits. * @param parity Select the type of parity checking to use. * @param stopBits The number of stop bits to use as defined by the enum * StopBits. */ explicit SerialPort(int baudRate, Port port = kOnboard, int dataBits = 8, Parity parity = kParity_None, StopBits stopBits = kStopBits_One); /** * Create an instance of a Serial Port class. * * Prefer to use the constructor that doesn't take a port name, but in some * cases the automatic detection might not work correctly. * * @param baudRate The baud rate to configure the serial port. * @param port The physical port to use * @param portName The direct port name to use * @param dataBits The number of data bits per transfer. Valid values are * between 5 and 8 bits. * @param parity Select the type of parity checking to use. * @param stopBits The number of stop bits to use as defined by the enum * StopBits. */ SerialPort(int baudRate, std::string_view portName, Port port = kOnboard, int dataBits = 8, Parity parity = kParity_None, StopBits stopBits = kStopBits_One); ~SerialPort(); SerialPort(SerialPort&& rhs) = default; SerialPort& operator=(SerialPort&& rhs) = default; /** * Set the type of flow control to enable on this port. * * By default, flow control is disabled. */ void SetFlowControl(FlowControl flowControl); /** * Enable termination and specify the termination character. * * Termination is currently only implemented for receive. * When the the terminator is received, the Read() or Scanf() will return * fewer bytes than requested, stopping after the terminator. * * @param terminator The character to use for termination. */ void EnableTermination(char terminator = '\n'); /** * Disable termination behavior. */ void DisableTermination(); /** * Get the number of bytes currently available to read from the serial port. * * @return The number of bytes available to read */ int GetBytesReceived(); /** * Read raw bytes out of the buffer. * * @param buffer Pointer to the buffer to store the bytes in. * @param count The maximum number of bytes to read. * @return The number of bytes actually read into the buffer. */ int Read(char* buffer, int count); /** * Write raw bytes to the buffer. * * @param buffer Pointer to the buffer to read the bytes from. * @param count The maximum number of bytes to write. * @return The number of bytes actually written into the port. */ int Write(const char* buffer, int count); /** * Write raw bytes to the buffer. * * Use Write({data, len}) to get a buffer that is shorter than the length of * the string. * * @param buffer the buffer to read the bytes from. * @return The number of bytes actually written into the port. */ int Write(std::string_view buffer); /** * Configure the timeout of the serial port. * * This defines the timeout for transactions with the hardware. * It will affect reads and very large writes. * * @param timeout The time to wait for I/O. */ void SetTimeout(units::second_t timeout); /** * Specify the size of the input buffer. * * Specify the amount of data that can be stored before data * from the device is returned to Read or Scanf. If you want * data that is received to be returned immediately, set this to 1. * * It the buffer is not filled before the read timeout expires, all * data that has been received so far will be returned. * * @param size The read buffer size. */ void SetReadBufferSize(int size); /** * Specify the size of the output buffer. * * Specify the amount of data that can be stored before being * transmitted to the device. * * @param size The write buffer size. */ void SetWriteBufferSize(int size); /** * Specify the flushing behavior of the output buffer. * * When set to kFlushOnAccess, data is synchronously written to the serial * port after each call to either Printf() or Write(). * * When set to kFlushWhenFull, data will only be written to the serial port * when the buffer is full or when Flush() is called. * * @param mode The write buffer mode. */ void SetWriteBufferMode(WriteBufferMode mode); /** * Force the output buffer to be written to the port. * * This is used when SetWriteBufferMode() is set to kFlushWhenFull to force a * flush before the buffer is full. */ void Flush(); /** * Reset the serial port driver to a known state. * * Empty the transmit and receive buffers in the device and formatted I/O. */ void Reset(); private: hal::Handle m_portHandle; }; } // namespace frc