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