1d6aed566Sopenharmony_ci/*
2d6aed566Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3d6aed566Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4d6aed566Sopenharmony_ci * you may not use this file except in compliance with the License.
5d6aed566Sopenharmony_ci * You may obtain a copy of the License at
6d6aed566Sopenharmony_ci *
7d6aed566Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8d6aed566Sopenharmony_ci *
9d6aed566Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10d6aed566Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11d6aed566Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d6aed566Sopenharmony_ci * See the License for the specific language governing permissions and
13d6aed566Sopenharmony_ci * limitations under the License.
14d6aed566Sopenharmony_ci */
15d6aed566Sopenharmony_ci
16d6aed566Sopenharmony_ci#include "uart.h"
17d6aed566Sopenharmony_ci
18d6aed566Sopenharmony_ci#include "los_arch_interrupt.h"
19d6aed566Sopenharmony_ci#include "los_interrupt.h"
20d6aed566Sopenharmony_ci#include "riscv_hal.h"
21d6aed566Sopenharmony_ci
22d6aed566Sopenharmony_ci#ifdef __cplusplus
23d6aed566Sopenharmony_ci#if __cplusplus
24d6aed566Sopenharmony_ciextern "C" {
25d6aed566Sopenharmony_ci#endif
26d6aed566Sopenharmony_ci#endif
27d6aed566Sopenharmony_ci
28d6aed566Sopenharmony_ciINT32 UartPutc(INT32 c, VOID *file)
29d6aed566Sopenharmony_ci{
30d6aed566Sopenharmony_ci    (VOID) file;
31d6aed566Sopenharmony_ci    /* wait for Transmit Holding Empty to be set in LSR */
32d6aed566Sopenharmony_ci    while ((ReadUartReg(UART_LSR_OFFSET) & UART_LSR_THRE) == 0) {
33d6aed566Sopenharmony_ci        ;
34d6aed566Sopenharmony_ci    }
35d6aed566Sopenharmony_ci    WriteUartReg(UART_THR_OFFSET, (UINT8)c);
36d6aed566Sopenharmony_ci    return c;
37d6aed566Sopenharmony_ci}
38d6aed566Sopenharmony_ci
39d6aed566Sopenharmony_ciINT32 UartGetc(VOID)
40d6aed566Sopenharmony_ci{
41d6aed566Sopenharmony_ci    if (ReadUartReg(UART_LSR_OFFSET) & UART_LSR_DR) {
42d6aed566Sopenharmony_ci        return ReadUartReg(UART_RHR_OFFSET);
43d6aed566Sopenharmony_ci    } else {
44d6aed566Sopenharmony_ci        return 0;
45d6aed566Sopenharmony_ci    }
46d6aed566Sopenharmony_ci}
47d6aed566Sopenharmony_ci
48d6aed566Sopenharmony_ciINT32 UartOut(INT32 c, VOID *file)
49d6aed566Sopenharmony_ci{
50d6aed566Sopenharmony_ci    (VOID) file;
51d6aed566Sopenharmony_ci    return UartGetc();
52d6aed566Sopenharmony_ci}
53d6aed566Sopenharmony_ci
54d6aed566Sopenharmony_ciVOID UartInit(VOID)
55d6aed566Sopenharmony_ci{
56d6aed566Sopenharmony_ci    /* Disable all interrupts */
57d6aed566Sopenharmony_ci    WriteUartReg(UART_IER_OFFSET, 0x00);
58d6aed566Sopenharmony_ci
59d6aed566Sopenharmony_ci    /* special mode to set baud rate */
60d6aed566Sopenharmony_ci    WriteUartReg(UART_LCR_OFFSET, UART_LCR_DLAB);
61d6aed566Sopenharmony_ci
62d6aed566Sopenharmony_ci    /* Set divisor low byte, LSB for baud rate of 38.4K */
63d6aed566Sopenharmony_ci    WriteUartReg(UART_DLL_OFFSET, 0x03);
64d6aed566Sopenharmony_ci
65d6aed566Sopenharmony_ci    /* Set divisor high byte, LSB for baud rate of 38.4K */
66d6aed566Sopenharmony_ci    WriteUartReg(UART_DLM_OFFSET, 0x00);
67d6aed566Sopenharmony_ci
68d6aed566Sopenharmony_ci    /* leave set-baud mode, and set word length to 8 bits, no parity */
69d6aed566Sopenharmony_ci    WriteUartReg(UART_LCR_OFFSET, UART_LCR_8N1);
70d6aed566Sopenharmony_ci
71d6aed566Sopenharmony_ci    /* reset and enable FIFOs */
72d6aed566Sopenharmony_ci    WriteUartReg(UART_FCR_OFFSET, UART_FCR_FIFO_EN | UART_FCR_RXSR | UART_FCR_TXSR);
73d6aed566Sopenharmony_ci}
74d6aed566Sopenharmony_ci
75d6aed566Sopenharmony_ciVOID UartReceiveHandler(VOID)
76d6aed566Sopenharmony_ci{
77d6aed566Sopenharmony_ci    if (ReadUartReg(UART_LSR_OFFSET) & UART_LSR_DR) {
78d6aed566Sopenharmony_ci        (void)LOS_EventWrite(&g_shellInputEvent, 0x1);
79d6aed566Sopenharmony_ci    }
80d6aed566Sopenharmony_ci    return;
81d6aed566Sopenharmony_ci}
82d6aed566Sopenharmony_ci
83d6aed566Sopenharmony_ciVOID Uart0RxIrqRegister(VOID)
84d6aed566Sopenharmony_ci{
85d6aed566Sopenharmony_ci    WriteUartReg(UART_IER_OFFSET, ReadUartReg(UART_IER_OFFSET) | UART_IER_RDI);
86d6aed566Sopenharmony_ci    uint32_t ret = LOS_HwiCreate(RISCV_UART0_Rx_IRQn, OS_HWI_PRIO_HIGHEST, 0, (HWI_PROC_FUNC)UartReceiveHandler, 0);
87d6aed566Sopenharmony_ci    if (ret != LOS_OK) {
88d6aed566Sopenharmony_ci        return;
89d6aed566Sopenharmony_ci    }
90d6aed566Sopenharmony_ci    HalIrqEnable(RISCV_UART0_Rx_IRQn);
91d6aed566Sopenharmony_ci}
92d6aed566Sopenharmony_ci
93d6aed566Sopenharmony_ci#ifdef __cplusplus
94d6aed566Sopenharmony_ci#if __cplusplus
95d6aed566Sopenharmony_ci}
96d6aed566Sopenharmony_ci#endif /* __cplusplus */
97d6aed566Sopenharmony_ci#endif /* __cplusplus */
98