xiuos5/board/aiit-riscv64-board/third_party_driver/include/hardware_uarths.h

303 lines
7.8 KiB
C
Raw Normal View History

2021-04-28 17:49:18 +08:00
/* Copyright 2018 Canaan Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* @brief Universal Asynchronous Receiver/Transmitter (UART)
*
* The UART peripheral supports the following features:
*
* - 8-N-1 and 8-N-2 formats: 8 data bits, no parity bit, 1 start
* bit, 1 or 2 stop bits
*
* - 8-entry transmit and receive FIFO buffers with programmable
* watermark interrupts
*
* - 16× Rx oversampling with 2/3 majority voting per bit
*
* The UART peripheral does not support hardware flow control or
* other modem control signals, or synchronous serial data
* tranfesrs.
*
* @note UART RAM Layout
*
* | Address | Name | Description |
* |-----------|----------|---------------------------------|
* | 0x000 | txdata | Transmit data register |
* | 0x004 | rxdata | Receive data register |
* | 0x008 | txctrl | Transmit control register |
* | 0x00C | rxctrl | Receive control register |
* | 0x010 | ie | UART interrupt enable |
* | 0x014 | ip | UART Interrupt pending |
* | 0x018 | div | Baud rate divisor |
*
*/
/**
* @file hardware_uarths.h
* @brief add from Canaan k210 SDK
* https://canaan-creative.com/developer
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
#ifndef __HARDWARE_UARTHS_H__
#define __HARDWARE_UARTHS_H__
#include <platform.h>
#include "plic.h"
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* clang-format off */
/* Register address offsets */
#define UARTHS_REG_TXFIFO (0x00)
#define UARTHS_REG_RXFIFO (0x04)
#define UARTHS_REG_TXCTRL (0x08)
#define UARTHS_REG_RXCTRL (0x0c)
#define UARTHS_REG_IE (0x10)
#define UARTHS_REG_IP (0x14)
#define UARTHS_REG_DIV (0x18)
/* TXCTRL register */
#define UARTHS_TXEN (0x01)
#define UARTHS_TXWM(x) (((x) & 0xffff) << 16)
/* RXCTRL register */
#define UARTHS_RXEN (0x01)
#define UARTHS_RXWM(x) (((x) & 0xffff) << 16)
/* IP register */
#define UARTHS_IP_TXWM (0x01)
#define UARTHS_IP_RXWM (0x02)
/* clang-format on */
typedef struct _uarths_txdata
{
/* Bits [7:0] is data */
uint32_t data : 8;
/* Bits [30:8] is 0 */
uint32_t zero : 23;
/* Bit 31 is full status */
uint32_t full : 1;
} __attribute__((packed, aligned(4))) uarths_txdata_t;
typedef struct _uarths_rxdata
{
/* Bits [7:0] is data */
uint32_t data : 8;
/* Bits [30:8] is 0 */
uint32_t zero : 23;
/* Bit 31 is empty status */
uint32_t empty : 1;
} __attribute__((packed, aligned(4))) uarths_rxdata_t;
typedef struct _uarths_txctrl
{
/* Bit 0 is txen, controls whether the Tx channel is active. */
uint32_t txen : 1;
/* Bit 1 is nstop, 0 for one stop bit and 1 for two stop bits */
uint32_t nstop : 1;
/* Bits [15:2] is reserved */
uint32_t resv0 : 14;
/* Bits [18:16] is threshold of interrupt triggers */
uint32_t txcnt : 3;
/* Bits [31:19] is reserved */
uint32_t resv1 : 13;
} __attribute__((packed, aligned(4))) uarths_txctrl_t;
typedef struct _uarths_rxctrl
{
/* Bit 0 is txen, controls whether the Tx channel is active. */
uint32_t rxen : 1;
/* Bits [15:1] is reserved */
uint32_t resv0 : 15;
/* Bits [18:16] is threshold of interrupt triggers */
uint32_t rxcnt : 3;
/* Bits [31:19] is reserved */
uint32_t resv1 : 13;
} __attribute__((packed, aligned(4))) uarths_rxctrl_t;
typedef struct _uarths_ip
{
/* Bit 0 is txwm, raised less than txcnt */
uint32_t txwm : 1;
/* Bit 1 is txwm, raised greater than rxcnt */
uint32_t rxwm : 1;
/* Bits [31:2] is 0 */
uint32_t zero : 30;
} __attribute__((packed, aligned(4))) uarths_ip_t;
typedef struct _uarths_ie
{
/* Bit 0 is txwm, raised less than txcnt */
uint32_t txwm : 1;
/* Bit 1 is txwm, raised greater than rxcnt */
uint32_t rxwm : 1;
/* Bits [31:2] is 0 */
uint32_t zero : 30;
} __attribute__((packed, aligned(4))) uarths_ie_t;
typedef struct _uarths_div
{
/* Bits [31:2] is baud rate divisor register */
uint32_t div : 16;
/* Bits [31:16] is 0 */
uint32_t zero : 16;
} __attribute__((packed, aligned(4))) uarths_div_t;
typedef struct _uarths
{
/* Address offset 0x00 */
uarths_txdata_t txdata;
/* Address offset 0x04 */
uarths_rxdata_t rxdata;
/* Address offset 0x08 */
uarths_txctrl_t txctrl;
/* Address offset 0x0c */
uarths_rxctrl_t rxctrl;
/* Address offset 0x10 */
uarths_ie_t ie;
/* Address offset 0x14 */
uarths_ip_t ip;
/* Address offset 0x18 */
uarths_div_t div;
} __attribute__((packed, aligned(4))) UarthsT;
typedef enum _uarths_interrupt_mode
{
UARTHS_SEND = 1,
UARTHS_RECEIVE = 2,
UARTHS_SEND_RECEIVE = 3,
} uarths_interrupt_mode_t;
typedef enum _uarths_stopbit
{
UARTHS_STOP_1,
UARTHS_STOP_2
} uarths_stopbit_t;
extern volatile UarthsT *const uarths;
/**
* @brief Initialization Core UART
*
* @return result
* - 0 Success
* - Other Fail
*/
void uarths_init(void);
/**
* @brief Put a char to UART
*
* @param[in] c The char to put
*
* @note If c is '\n', a '\r' will be appended automatically
*
* @return result
* - 0 Success
* - Other Fail
*/
int uarths_putchar(char c);
/**
* @brief Send a string to UART
*
* @param[in] s The string to send
*
* @note The string must ending with '\0'
*
* @return result
* - 0 Success
* - Other Fail
*/
int uarths_puts(const char *s);
/**
* @brief Get a byte from UART
*
* @return byte as int type from UART
*/
int uarths_getc(void);
/**
* @brief Set uarths interrupt callback
*
* @param[in] interrupt_mode Interrupt mode recevice or send
* @param[in] uarths_callback Interrupt callback
* @param[in] ctx Param of callback
* @param[in] priority Interrupt priority
*
*/
void uarths_set_irq(uarths_interrupt_mode_t interrupt_mode, plic_irq_callback_t uarths_callback, void *ctx, uint32_t priority);
/**
* @brief Uarths receive data
*
* @param[in] buf The data received
* @param[in] BufLen The length of data
*
* @return Number of received data
*/
size_t uarths_receive_data(uint8_t *buf, size_t BufLen);
/**
* @brief Uarths receive data
*
* @param[in] buf The data sended
* @param[in] BufLen The length of data
*
* @return Number of sended data
*/
size_t uarths_send_data(const uint8_t *buf, size_t BufLen);
/**
* @brief Get interrupt mode
*
* @return Mode of interrupt
*/
uarths_interrupt_mode_t uarths_get_interrupt_mode(void);
/**
* @brief Set uarths baud rate and stopbit
*
* @param[in] BaudRate The baud rate
* @param[in] stopbit The stopbit of data
*
*/
void uarths_config(uint32_t BaudRate, uarths_stopbit_t stopbit);
/**
* @brief Set uart interrupt condition
*
* @param[in] interrupt_mode The interrupt mode
* @param[in] cnt The count of tigger
*
*/
void uarths_set_interrupt_cnt(uarths_interrupt_mode_t interrupt_mode, uint8_t cnt);
#ifdef __cplusplus
}
#endif
#endif /* __UARTHS_H__ */