diff options
Diffstat (limited to '')
-rw-r--r-- | bsps/microblaze/shared/dev/serial/uartlite.c | 159 | ||||
-rw-r--r-- | bsps/microblaze/shared/dev/serial/uartlite_l.c | 99 |
2 files changed, 258 insertions, 0 deletions
diff --git a/bsps/microblaze/shared/dev/serial/uartlite.c b/bsps/microblaze/shared/dev/serial/uartlite.c new file mode 100644 index 0000000000..611c339371 --- /dev/null +++ b/bsps/microblaze/shared/dev/serial/uartlite.c @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSBSPsMicroblaze + * + * @brief MicroBlaze AXI UART Lite support + */ + +/* + * Copyright (C) 2021 On-Line Applications Research Corporation (OAR) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <bsp/irq.h> +#include <dev/serial/uartlite.h> +#include <bspopts.h> + +#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS +static void microblaze_uart_interrupt( void *arg ) +{ + rtems_termios_tty *tty = arg; + uart_lite_context *ctx = rtems_termios_get_device_context( tty ); + + while ( !XUartLite_IsReceiveEmpty( ctx->address ) ) { + char c = (char) XUartLite_ReadReg( ctx->address, XUL_RX_FIFO_OFFSET ); + rtems_termios_enqueue_raw_characters( tty, &c, 1 ); + } + + if ( ctx->transmitting && XUartLite_IsTransmitEmpty( ctx->address ) ) { + size_t sent = ctx->tx_queued; + ctx->transmitting = false; + ctx->tx_queued = 0; + rtems_termios_dequeue_characters( tty, sent ); + } +} +#endif + +static bool uart_first_open( + struct rtems_termios_tty *tty, + rtems_termios_device_context *base, + struct termios *term, + rtems_libio_open_close_args_t *args +) +{ + uart_lite_context *ctx = (uart_lite_context *) base; +#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS + rtems_status_code sc; +#endif + + rtems_termios_set_initial_baud( tty, ctx->initial_baud ); + +#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS + XUartLite_EnableIntr( ctx->address ); + + sc = rtems_interrupt_handler_install( + ctx->irq, + "UART", + RTEMS_INTERRUPT_SHARED, + microblaze_uart_interrupt, + tty + ); + if ( sc != RTEMS_SUCCESSFUL ) { + return false; + } + + ctx->tty = tty; +#endif + + return true; +} + +static void uart_last_close( + rtems_termios_tty *tty, + rtems_termios_device_context *base, + rtems_libio_open_close_args_t *args +) +{ +#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS + rtems_interrupt_handler_remove( 1, microblaze_uart_interrupt, tty ); +#endif +} + +#ifndef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS +static int uart_read_polled( rtems_termios_device_context *base ) +{ + uart_lite_context *ctx = (uart_lite_context *) base; + + if ( XUartLite_IsReceiveEmpty( ctx->address ) ) { + return -1; + } + + return XUartLite_ReadReg( ctx->address, XUL_RX_FIFO_OFFSET ); +} +#endif + +static void uart_write( + rtems_termios_device_context *base, + const char *s, + size_t n +) +{ + uart_lite_context *ctx = (uart_lite_context *) base; + +#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS + if ( n > 0 ) { + size_t remaining = n; + const char *p = &s[0]; + + while (!XUartLite_IsTransmitFull( ctx->address ) && remaining > 0) { + XUartLite_SendByte( ctx->address, *p ); + p++; + remaining--; + } + + ctx->transmitting = true; + ctx->tx_queued = n - remaining; + } +#else + size_t i = 0; + + for ( i = 0; i < n; ++i ) { + XUartLite_SendByte( ctx->address, s[i] ); + } +#endif +} + +const rtems_termios_device_handler microblaze_uart_fns = { + .first_open = uart_first_open, + .last_close = uart_last_close, + .write = uart_write, +#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS + .mode = TERMIOS_IRQ_DRIVEN +#else + .poll_read = uart_read_polled, + .mode = TERMIOS_POLLED +#endif +}; diff --git a/bsps/microblaze/shared/dev/serial/uartlite_l.c b/bsps/microblaze/shared/dev/serial/uartlite_l.c new file mode 100644 index 0000000000..5acbd6c505 --- /dev/null +++ b/bsps/microblaze/shared/dev/serial/uartlite_l.c @@ -0,0 +1,99 @@ +/****************************************************************************** +* Copyright (C) 2002 - 2020 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/****************************************************************************/ +/** +* +* @file xuartlite_l.c +* @addtogroup uartlite_v3_5 +* @{ +* +* This file contains low-level driver functions that can be used to access the +* device. The user should refer to the hardware device specification for more +* details of the device operation. + +* <pre> +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 1.00b rpm 04/25/02 First release +* 1.12a rpm 07/16/07 Fixed arg type for RecvByte +* 2.00a ktn 10/20/09 The macros have been renamed to remove _m from the name. +* 3.2 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425. +* Changed the prototypes of XUartLite_SendByte, +* XUartLite_RecvByte APIs. +* </pre> +* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#ifndef __rtems__ +#include "xuartlite_l.h" +#else +#include <dev/serial/uartlite_l.h> +#endif /* __rtems__ */ + +/************************** Constant Definitions *****************************/ + + +/**************************** Type Definitions *******************************/ + + +/***************** Macros (Inline Functions) Definitions *********************/ + + +/************************** Function Prototypes ******************************/ + + +/************************** Variable Prototypes ******************************/ + + +/****************************************************************************/ +/** +* +* This functions sends a single byte using the UART. It is blocking in that it +* waits for the transmitter to become non-full before it writes the byte to +* the transmit register. +* +* @param BaseAddress is the base address of the device +* @param Data is the byte of data to send +* +* @return None. +* +* @note None. +* +******************************************************************************/ +void XUartLite_SendByte(UINTPTR BaseAddress, u8 Data) +{ + while (XUartLite_IsTransmitFull(BaseAddress)); + + XUartLite_WriteReg(BaseAddress, XUL_TX_FIFO_OFFSET, Data); +} + + +/****************************************************************************/ +/** +* +* This functions receives a single byte using the UART. It is blocking in that +* it waits for the receiver to become non-empty before it reads from the +* receive register. +* +* @param BaseAddress is the base address of the device +* +* @return The byte of data received. +* +* @note None. +* +******************************************************************************/ +u8 XUartLite_RecvByte(UINTPTR BaseAddress) +{ + while (XUartLite_IsReceiveEmpty(BaseAddress)); + + return (u8)XUartLite_ReadReg(BaseAddress, XUL_RX_FIFO_OFFSET); +} + +/** @} */
\ No newline at end of file |