Files
rtems/bsps/include/dev/serial/arm-pl011.h
Utkarsh Verma 0f42153959 dev/serial: Refactor the pl011 driver
- Refactor the pl011 driver to be extensible.
- Add IRQ support and baudrate configuration support for pl011 driver.
- Modify related BSP.
- Add doxygen comments for arm-pl011.

Close #5026

Co-authored-by: Ning Yang <yangn0@qq.com>
2024-09-18 19:30:21 +00:00

167 lines
4.7 KiB
C

/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSBSPsARMShared
*
* @brief ARM PL011 Support Package
*/
/*
* Copyright (C) 2013, 2014 embedded brains GmbH & Co. KG
*
* 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.
*/
#ifndef LIBBSP_ARM_SHARED_ARM_PL011_H
#define LIBBSP_ARM_SHARED_ARM_PL011_H
#include <rtems/termiostypes.h>
#include <dev/serial/arm-pl011-regs.h>
#include <bspopts.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @defgroup ARM PL011 Support
* @ingroup RTEMSBSPsARMShared
* @brief UART Support
*/
typedef struct {
pl011_base base;
uint32_t reserved_4c[997];
uint32_t uartperiphid0;
uint32_t uartperiphid1;
uint32_t uartperiphid2;
uint32_t uartperiphid3;
uint32_t uartpcellid0;
uint32_t uartpcellid1;
uint32_t uartpcellid2;
uint32_t uartpcellid3;
} arm_pl011_uart;
typedef struct {
rtems_termios_device_context base;
volatile arm_pl011_uart *regs;
rtems_vector_number irq;
uint32_t initial_baud;
uint32_t clock;
#ifdef BSP_CONSOLE_USE_INTERRUPTS
/*
* Due to HW limitation, the first TX interrupt should be triggered by the
* software. This is because TX interrupts are based on transition through
* a level, rather than on the level itself. When the UART interrupt and
* UART is enabled before any data is written to the TXFIFO, the interrupt
* is not set. The interrupt is only set once the TXFIFO becomes empty
* after being filled to the trigger level. Until then, this flag variable
* ensures that the interrupt handler is software triggered.
*/
bool needs_sw_triggered_tx_irq;
int tx_queued_chars;
rtems_termios_tty* tty;
#endif
} arm_pl011_context;
#ifdef BSP_CONSOLE_USE_INTERRUPTS
#define FIFO_LEVEL_ONE_EIGHTH 0
#define FIFO_LEVEL_ONE_FOURTH 1
#define FIFO_LEVEL_ONE_HALF 2
#define FIFO_LEVEL_THREE_FOURTH 3
#define FIFO_LELEL_SEVEN_HALF 4
#define TXFIFO_IRQ_TRIGGER_LEVEL FIFO_LEVEL_ONE_EIGHTH
#define RXFIFO_IRQ_TRIGGER_LEVEL FIFO_LEVEL_ONE_HALF
#endif
extern const rtems_termios_device_handler arm_pl011_fns;
/**
* @brief Initialize pl011 registers.
*
* @param base Termios device context.
*
* @retval true Successfully initialized pl011 registers.
*/
bool arm_pl011_probe(rtems_termios_device_context *base);
/**
* @brief Write a char using polling mode.
*
* @param base Termios device context.
* @param c Character to be written.
*/
void arm_pl011_write_polled(rtems_termios_device_context *base, char c);
/**
* @brief Read a char using polling mode.
*
* @param base Termios device context.
*
* @retval Character read.
* @retval -1 rxfifo is empty.
*/
int arm_pl011_read_polled(rtems_termios_device_context *base);
/**
* @brief Get register base address.
*
* @param base Termios device context.
*
* @retval Register base address.
*/
volatile arm_pl011_uart *arm_pl011_get_regs(rtems_termios_device_context *base);
/**
* @brief Compute baudrate params.
*
* @param ibrd The integer part of the baud rate divisor value.
* @param fbrd The fractional part of the baud rate divisor value.
* @param baudrate Termios device context.
* @param clock The UART reference clock frequency.
* @param max_error Maximum error.
*
* @retval 0 Success.
* @retval 1 The error is too large.
* @retval 2 ibrd is invalid.
*/
int arm_pl011_compute_baudrate_params(
uint32_t *ibrd,
uint32_t *fbrd,
const uint32_t baudrate,
const uint32_t clock,
const unsigned short max_error
);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LIBBSP_ARM_SHARED_ARM_PL011_H */