7 #include <hal_posix/posix_uart.h>
19 #include <sys/ioctl.h>
34 inline tcflag_t baud_lookup(
unsigned baud) {
36 case 9600:
return B9600;
37 case 19200:
return B19200;
38 case 38400:
return B38400;
39 case 57600:
return B57600;
40 case 115200:
return B115200;
41 case 230400:
return B230400;
42 case 460800:
return B460800;
43 case 500000:
return B500000;
44 case 576000:
return B576000;
45 case 921600:
return B921600;
46 case 1000000:
return B1000000;
47 case 1152000:
return B1152000;
48 case 1500000:
return B1500000;
49 case 2000000:
return B2000000;
58 namespace log = satcat5::log;
60 PosixUart::PosixUart(
const char* device,
unsigned baud,
unsigned buffer_size_bytes)
62 new u8[buffer_size_bytes], buffer_size_bytes, 0,
63 new u8[buffer_size_bytes], buffer_size_bytes, 0)
71 snprintf(full_name,
sizeof(full_name),
"\\\\.\\%s", device);
74 m_uart = CreateFile(full_name,
75 GENERIC_READ | GENERIC_WRITE,
76 0, NULL, OPEN_EXISTING, 0, NULL);
80 m_ok = m_ok && GetCommState(m_uart, &dcb);
87 dcb.fDtrControl = DTR_CONTROL_DISABLE;
88 dcb.fDsrSensitivity = 0;
89 dcb.fTXContinueOnXoff = 0;
94 dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
95 dcb.fAbortOnError = 0;
98 dcb.Parity = NOPARITY;
99 dcb.StopBits = ONESTOPBIT;
100 m_ok = !!SetCommState(m_uart, &dcb);
105 COMMTIMEOUTS timeout;
106 m_ok = m_ok && GetCommTimeouts(m_uart, &timeout);
108 timeout.ReadIntervalTimeout = MAXDWORD;
109 timeout.ReadTotalTimeoutMultiplier = 0;
110 timeout.ReadTotalTimeoutConstant = 0;
111 m_ok = !!SetCommTimeouts(m_uart, &timeout);
116 s32 errnum = GetLastError();
122 m_uart = open(device, O_RDWR | O_NDELAY | O_NOCTTY);
123 m_ok = m_ok && (m_uart >= 0);
126 tcflag_t bcode = baud_lookup(baud);
127 m_ok = m_ok && (bcode != 0);
131 m_ok = m_ok && (tcgetattr(m_uart, &tty) >= 0);
133 tty.c_iflag = IGNBRK | IGNPAR;
135 tty.c_cflag = CS8 | CREAD | CLOCAL;
137 cfsetispeed(&tty, bcode);
138 cfsetospeed(&tty, bcode);
139 m_ok = (tcsetattr(m_uart, TCSANOW, &tty) >= 0);
143 int rts_flag = TIOCM_RTS;
144 m_ok = m_ok && (ioctl(m_uart, TIOCMBIS, &rts_flag) >= 0);
148 PosixUart::~PosixUart()
165 while (m_ok && chunk_tx()) {}
172 while (m_ok && chunk_rx()) {}
175 unsigned PosixUart::chunk_rx()
179 unsigned cpy_bytes = 0;
182 m_ok = ReadFile(m_uart, buff,
sizeof(buff), &status, NULL);
184 s32 errnum = GetLastError();
186 }
else if (status > 0) {
187 cpy_bytes = (unsigned)status;
191 m_ok = (ioctl(m_uart, FIONREAD, &status) >= 0);
193 cpy_bytes = min_unsigned(status,
sizeof(buff));
194 status = read(m_uart, buff, cpy_bytes);
195 cpy_bytes = (unsigned)status;
206 unsigned PosixUart::chunk_tx()
209 unsigned cpy_bytes = 0;
211 const u8* buff =
m_tx.
peek(max_bytes);
214 m_ok = WriteFile(m_uart, buff, max_bytes, &status, NULL);
216 s32 errnum = GetLastError();
218 }
else if (status > 0) {
219 cpy_bytes = (unsigned)status;
222 int status =
write(m_uart, buff, max_bytes);
223 if (status > 0) cpy_bytes = (unsigned)status;
233 SlipUart::SlipUart(
const char* device,
unsigned baud,
unsigned buffer)
234 : satcat5::io::WriteableRedirect(&m_slip)
235 , satcat5::io::ReadableRedirect(&m_slip)
236 , m_uart(device, baud, buffer)
237 , m_slip(&m_uart, &m_uart)
Extensible transmit and receive buffer.
satcat5::io::PacketBuffer m_tx
Transmit data (user writes, child reads)
satcat5::io::PacketBuffer m_rx
Receive data (user reads, child writes)
const u8 * peek(unsigned nbytes) const
Peek nbytes into the circular buffer.
unsigned get_peek_ready() const
Find the longest available contiguous segment that can be requested by peek().
bool write_finalize() override
Mark end of frame and release temporary working data.
void write_bytes(unsigned nbytes, const void *src) override
Write 0 or more bytes from a buffer.
u8 * get_buff_dtor() const
Accessor for children that need to delete underlying buffer.
bool read_consume(unsigned nbytes) override
Read and discard 0 or more bytes.
void read_finalize() override
Consume any remaining bytes in this frame, if applicable.
POSIX and Windows interface objects for connecting to a UART.
void data_rcvd(satcat5::io::Readable *src) override
The data_rcvd() callback is polled whenever data is available.
void poll_always() override
Child class MUST override this method.
Abstract API for reading byte-streams and packets.
SLIP-encoded wrapper for the PosixUart class.
The Log class creates and formats one log message.
Log & write10(s32 val)
Print integer as a decimal value with no leading zeros.
Diagnostic logging to UART and/or Ethernet ports.
bool write(satcat5::io::Writeable *dst, unsigned nbytes, const u8 *data)
Write byte array and finalize.
Miscellaneous mathematical utility functions.
constexpr unsigned min_unsigned(unsigned a, unsigned b)
Min and max functions.