/* * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include "hardware/uart.h" #if defined(__unix) || defined(__APPLE__) #define _XOPEN_SOURCE 600 /* for ONLCR */ #define __BSD_VISIBLE 1 /* for ONLCR in *BSD */ #include #include #include #include #ifndef FNONBLOCK #define FNONBLOCK O_NONBLOCK #endif struct termios _tty; static tcflag_t _res_oflg = 0; static tcflag_t _res_lflg = 0; void _resettty(void) { if (!isatty(STDIN_FILENO)) return; /* reset tty: */ _tty.c_oflag = _res_oflg; _tty.c_lflag = _res_lflg; tcsetattr(STDIN_FILENO, TCSADRAIN, &_tty); } void _inittty(void) { if (!isatty(STDIN_FILENO)) return; /* save tty: */ tcgetattr(STDIN_FILENO, &_tty); _res_oflg = _tty.c_oflag; _res_lflg = _tty.c_lflag; /* set raw: */ _tty.c_lflag &= ~(ICANON | ICRNL);// | ISIG); //_tty.c_oflag &= ~ONLCR; tcsetattr(STDIN_FILENO, TCSANOW, &_tty); fcntl(STDIN_FILENO, F_SETFL, FNONBLOCK); atexit(_resettty); } #else void _inittty() {} #endif typedef struct { bool dummy; } uart_hw_t; uart_inst_t *const uart0; uart_inst_t *const uart1; static int _nextchar = EOF; static bool _peekchar() { if (_nextchar == EOF) { _nextchar = getchar(); } return _nextchar != EOF; } uint uart_init(uart_inst_t *uart, uint baud_rate) { _inittty(); return baud_rate; } bool uart_is_writable(uart_inst_t *uart) { return 1; } // If returns 0, no data is available to be read from UART. // If returns nonzero, at least that many bytes can be written without blocking. bool uart_is_readable(uart_inst_t *uart) { return _peekchar() ? 1 : 0; } // Write len bytes directly from src to the UART void uart_write_blocking(uart_inst_t *uart, const uint8_t *src, size_t len) { for (size_t i = 0; i < len; i++) { uart_putc(uart, src[i]); } } // Read len bytes directly from the UART to dst void uart_read_blocking(uart_inst_t *uart, uint8_t *dst, size_t len) { for (size_t i = 0; i < len; i++) { dst[i] = uart_getc(uart); } } // ---------------------------------------------------------------------------- // UART-specific operations and aliases void uart_putc(uart_inst_t *uart, char c) { putchar(c); } void uart_putc_raw(uart_inst_t *uart, char c) { putchar(c); } void uart_puts(uart_inst_t *uart, const char *s) { puts(s); } char uart_getc(uart_inst_t *uart) { while (!_peekchar()) { tight_loop_contents(); } char rc = (char) _nextchar; _nextchar = EOF; return rc; } void uart_default_tx_wait_blocking() { }