Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:42

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  *  @file
0005  *
0006  *  @ingroup RTEMSBSPsARMShared
0007  *
0008  *  @brief ARM PL011 Support Package
0009  */
0010 
0011 /*
0012  * Copyright (C) 2013, 2014 embedded brains GmbH & Co. KG
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #ifndef LIBBSP_ARM_SHARED_ARM_PL011_H
0037 #define LIBBSP_ARM_SHARED_ARM_PL011_H
0038 
0039 #include <rtems/termiostypes.h>
0040 
0041 #include <dev/serial/arm-pl011-regs.h>
0042 #include <bspopts.h>
0043 #ifdef __cplusplus
0044 extern "C" {
0045 #endif /* __cplusplus */
0046 
0047 /**
0048  * @defgroup ARM PL011 Support
0049  * @ingroup RTEMSBSPsARMShared
0050  * @brief UART Support
0051  */
0052 
0053 typedef struct {
0054   pl011_base base;
0055   uint32_t reserved_4c[997];
0056   uint32_t uartperiphid0;
0057   uint32_t uartperiphid1;
0058   uint32_t uartperiphid2;
0059   uint32_t uartperiphid3;
0060   uint32_t uartpcellid0;
0061   uint32_t uartpcellid1;
0062   uint32_t uartpcellid2;
0063   uint32_t uartpcellid3;
0064 } arm_pl011_uart;
0065 
0066 typedef struct {
0067   rtems_termios_device_context base;
0068   volatile arm_pl011_uart *regs;
0069   rtems_vector_number irq;
0070   uint32_t initial_baud;
0071   uint32_t clock;
0072 
0073 #ifdef BSP_CONSOLE_USE_INTERRUPTS
0074     /*
0075      * Due to HW limitation, the first TX interrupt should be triggered by the
0076      * software. This is because TX interrupts are based on transition through
0077      * a level, rather than on the level itself. When the UART interrupt and
0078      * UART is enabled before any data is written to the TXFIFO, the interrupt
0079      * is not set. The interrupt is only set once the TXFIFO becomes empty
0080      * after being filled to the trigger level. Until then, this flag variable
0081      * ensures that the interrupt handler is software triggered.
0082      */
0083     bool needs_sw_triggered_tx_irq;
0084 
0085     int tx_queued_chars;
0086     rtems_termios_tty* tty;
0087 #endif
0088 } arm_pl011_context;
0089 
0090 #ifdef BSP_CONSOLE_USE_INTERRUPTS
0091 
0092 #define FIFO_LEVEL_ONE_EIGHTH   0
0093 #define FIFO_LEVEL_ONE_FOURTH   1
0094 #define FIFO_LEVEL_ONE_HALF     2
0095 #define FIFO_LEVEL_THREE_FOURTH 3
0096 #define FIFO_LELEL_SEVEN_HALF   4
0097 
0098 #define TXFIFO_IRQ_TRIGGER_LEVEL FIFO_LEVEL_ONE_EIGHTH
0099 #define RXFIFO_IRQ_TRIGGER_LEVEL FIFO_LEVEL_ONE_HALF
0100 
0101 #endif
0102 
0103 extern const rtems_termios_device_handler arm_pl011_fns;
0104 
0105 /**
0106  * @brief Initialize pl011 registers.
0107  *
0108  * @param base Termios device context.
0109  *
0110  * @retval true Successfully initialized pl011 registers.
0111  */
0112 bool arm_pl011_probe(rtems_termios_device_context *base);
0113 
0114 /**
0115  * @brief Write a char using polling mode.
0116  *
0117  * @param base Termios device context.
0118  * @param c Character to be written.
0119  */
0120 void arm_pl011_write_polled(rtems_termios_device_context *base, char c);
0121 
0122 /**
0123  * @brief Read a char using polling mode.
0124  *
0125  * @param base Termios device context.
0126  *
0127  * @retval Character read.
0128  * @retval -1 rxfifo is empty.
0129  */
0130 int arm_pl011_read_polled(rtems_termios_device_context *base);
0131 
0132 /**
0133  * @brief Get register base address.
0134  *
0135  * @param base Termios device context.
0136  *
0137  * @retval Register base address.
0138  */
0139 volatile arm_pl011_uart *arm_pl011_get_regs(rtems_termios_device_context *base);
0140 
0141 /**
0142  * @brief Compute baudrate params.
0143  *
0144  * @param ibrd The integer part of the baud rate divisor value.
0145  * @param fbrd The fractional part of the baud rate divisor value.
0146  * @param baudrate Termios device context.
0147  * @param clock The UART reference clock frequency.
0148  * @param max_error Maximum error.
0149  *
0150  * @retval 0 Success.
0151  * @retval 1 The error is too large.
0152  * @retval 2 ibrd is invalid.
0153  */
0154 int arm_pl011_compute_baudrate_params(
0155   uint32_t *ibrd,
0156   uint32_t *fbrd,
0157   const uint32_t baudrate,
0158   const uint32_t clock,
0159   const unsigned short max_error
0160 );
0161 
0162 #ifdef __cplusplus
0163 }
0164 #endif /* __cplusplus */
0165 
0166 #endif /* LIBBSP_ARM_SHARED_ARM_PL011_H */