source: rtems/bsps/microblaze/shared/dev/serial/uartlite.c @ d03776e

Last change on this file since d03776e was d03776e, checked in by Alex White <alex.white@…>, on 10/01/21 at 04:57:01

microblaze: Rework for RTEMS 6

This reworks the existing MicroBlaze? architecture port and BSP to
achieve basic functionality using the latest RTEMS APIs.

  • Property mode set to 100644
File size: 4.0 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSBSPsMicroblaze
7 *
8 * @brief MicroBlaze AXI UART Lite support
9 */
10
11/*
12 * Copyright (C) 2021 On-Line Applications Research Corporation (OAR)
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 *    notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 *    notice, this list of conditions and the following disclaimer in the
21 *    documentation and/or other materials provided with the distribution.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#include <bsp/irq.h>
37#include <dev/serial/uartlite.h>
38
39#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS
40static void microblaze_uart_interrupt( void *arg )
41{
42  rtems_termios_tty *tty = arg;
43  uart_lite_context *ctx = rtems_termios_get_device_context( tty );
44
45  while ( !XUartLite_IsReceiveEmpty( ctx->address ) ) {
46    char c = (char) XUartLite_ReadReg( ctx->address, XUL_RX_FIFO_OFFSET );
47    rtems_termios_enqueue_raw_characters( tty, &c, 1 );
48  }
49
50  while ( ctx->transmitting && !XUartLite_IsTransmitEmpty( ctx ) ) {
51    rtems_termios_dequeue_characters( tty, 1 );
52  }
53}
54#endif
55
56static bool uart_first_open(
57  struct rtems_termios_tty *tty,
58  rtems_termios_device_context *base,
59  struct termios *term,
60  rtems_libio_open_close_args_t *args
61)
62{
63  uart_lite_context *ctx = (uart_lite_context *) base;
64#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS
65  rtems_status_code sc;
66#endif
67
68  rtems_termios_set_initial_baud( tty, ctx->initial_baud );
69
70#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS
71  XUartLite_EnableIntr( ctx->address );
72  sc = rtems_interrupt_handler_install(
73    1,
74    "UART",
75    RTEMS_INTERRUPT_SHARED,
76    microblaze_uart_interrupt,
77    tty
78  );
79  if ( sc != RTEMS_SUCCESSFUL ) {
80    return false;
81  }
82#endif
83
84  return true;
85}
86
87static void uart_last_close(
88  rtems_termios_tty *tty,
89  rtems_termios_device_context *base,
90  rtems_libio_open_close_args_t *args
91)
92{
93#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS
94  rtems_interrupt_handler_remove( 1, microblaze_uart_interrupt, tty );
95#endif
96}
97
98#ifndef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS
99static int uart_read_polled( rtems_termios_device_context *base )
100{
101  uart_lite_context *ctx = (uart_lite_context *) base;
102
103  if ( XUartLite_IsReceiveEmpty( ctx->address ) ) {
104    return -1;
105  }
106
107  return XUartLite_ReadReg( ctx->address, XUL_RX_FIFO_OFFSET );
108}
109#endif
110
111static void uart_write(
112  rtems_termios_device_context *base,
113  const char *s,
114  size_t n
115)
116{
117  uart_lite_context *ctx = (uart_lite_context *) base;
118
119#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS
120  if ( n > 0 ) {
121    ctx->transmitting = true;
122    XUartLite_SendByte( ctx->address, s[0] );
123  } else {
124    ctx->transmitting = false;
125  }
126#else
127  size_t i = 0;
128
129  for ( i = 0; i < n; ++i ) {
130    XUartLite_SendByte( ctx->address, s[i] );
131  }
132#endif
133}
134
135const rtems_termios_device_handler microblaze_uart_fns = {
136  .first_open = uart_first_open,
137  .last_close = uart_last_close,
138  .write = uart_write,
139#ifdef BSP_MICROBLAZE_FPGA_CONSOLE_INTERRUPTS
140  .mode = TERMIOS_IRQ_DRIVEN
141#else
142  .poll_read = uart_read_polled,
143  .mode = TERMIOS_POLLED
144#endif
145};
Note: See TracBrowser for help on using the repository browser.