blob: 2d7784be7290b98ae5a41043f4442872807ecc00 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#include "uartdpi.h"
#ifdef __linux__
#include <pty.h>
#elif __APPLE__
#include <util.h>
#endif
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void *uartdpi_create(const char *name) {
struct uartdpi_ctx *ctx =
(struct uartdpi_ctx *)malloc(sizeof(struct uartdpi_ctx));
assert(ctx);
int rv;
struct termios tty;
cfmakeraw(&tty);
rv = openpty(&ctx->master, &ctx->slave, 0, &tty, 0);
assert(rv != -1);
rv = ttyname_r(ctx->slave, ctx->ptyname, 64);
assert(rv == 0 && "ttyname_r failed");
int cur_flags = fcntl(ctx->master, F_GETFL, 0);
assert(cur_flags != -1 && "Unable to read current flags.");
int new_flags = fcntl(ctx->master, F_SETFL, cur_flags | O_NONBLOCK);
assert(new_flags != -1 && "Unable to set FD flags");
printf(
"\n"
"UART: Created %s for %s. Connect to it with any terminal program, e.g.\n"
"$ screen %s\n",
ctx->ptyname, name, ctx->ptyname);
return (void *)ctx;
}
int uartdpi_can_read(void *ctx_void) {
struct uartdpi_ctx *ctx = (struct uartdpi_ctx *)ctx_void;
int rv = read(ctx->master, &ctx->tmp_read, 1);
return (rv == 1);
}
char uartdpi_read(void *ctx_void) {
struct uartdpi_ctx *ctx = (struct uartdpi_ctx *)ctx_void;
return ctx->tmp_read;
}
void uartdpi_write(void *ctx_void, char c) {
struct uartdpi_ctx *ctx = (struct uartdpi_ctx *)ctx_void;
int rv = write(ctx->master, &c, 1);
assert(rv == 1 && "write() failed.");
}