216 lines
6.1 KiB
C
216 lines
6.1 KiB
C
/*
|
|
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
|
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
|
*
|
|
* 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.
|
|
*
|
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
|
* to endorse or promote products derived from this software without specific prior written
|
|
* permission.
|
|
*
|
|
* 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 HOLDER 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.
|
|
*/
|
|
|
|
#include "los_event.h"
|
|
#include "hisoc/uart.h"
|
|
|
|
|
|
EVENT_CB_S g_uartEvent;
|
|
#ifdef LOSCFG_PLATFORM_UART_WITHOUT_VFS
|
|
#ifdef LOSCFG_SHELL
|
|
#define UART_BUF 128
|
|
static UINT8 g_uart_buf[UART_BUF];
|
|
extern void shellCmdLineParse(CHAR c, pf_OUTPUT pf_put);
|
|
#endif
|
|
#endif
|
|
UINT8 uart_getc(void)
|
|
{
|
|
UINT8 ch = 0;
|
|
|
|
while (!(GET_UINT32(UART_REG_BASE + UART_USR) & 0x08)) { /*lint !e40*/
|
|
LOS_Msleep(100);
|
|
}
|
|
/* receive one char */
|
|
READ_UINT8(ch, UART_REG_BASE + UART_DR);
|
|
return ch;
|
|
}
|
|
|
|
#if defined(LOSCFG_COREDUMP) || defined(LOSCFG_LLTSER)
|
|
UINT8 uart_getc_interrupt(void)
|
|
{
|
|
UINT8 ch = 0;
|
|
|
|
while (!(GET_UINT32(UART_REG_BASE + UART_USR) & 0x08)) { /*lint !e40*/
|
|
}
|
|
/* receive one char */
|
|
READ_UINT8(ch, UART_REG_BASE + UART_DR);
|
|
return ch;
|
|
}
|
|
#endif
|
|
/* send */
|
|
char uart_putc (char c)
|
|
{
|
|
/* Wait until THRE is empyt */
|
|
while (!(GET_UINT32(UART_REG_BASE + UART_USR) & 0x02)); /*lint !e40*/
|
|
/* send one char */
|
|
WRITE_UINT8(c, UART_REG_BASE + UART_DR);
|
|
return c;
|
|
}
|
|
|
|
unsigned int g_uart_fputc_en __attribute__ ((section(".data"))) = 1;
|
|
char uart_fputc(char c, void *f)
|
|
{
|
|
if (g_uart_fputc_en == 1) {
|
|
if (c == '\n') {
|
|
uart_putc('\r'); /*lint !e534*/
|
|
}
|
|
return (uart_putc(c));
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
#ifdef LOSCFG_PLATFORM_UART_WITHOUT_VFS
|
|
#ifdef LOSCFG_SHELL
|
|
static void uart_notice_adapt(void)
|
|
{
|
|
LOS_EventWrite(&g_uartEvent, 0x112);
|
|
}
|
|
|
|
void uart_get_raw(void)
|
|
{
|
|
UINT8 ch;
|
|
static int cnt_ii = 0;
|
|
if (cnt_ii == 0) {
|
|
(VOID)memset_s(g_uart_buf, UART_BUF, 0, UART_BUF);
|
|
}
|
|
ch = uart_getc();
|
|
g_uart_buf[cnt_ii] = ch;
|
|
cnt_ii++;
|
|
switch (cnt_ii) {
|
|
case 1: // only one char
|
|
if (ch != 27) { // un special
|
|
uart_notice_adapt();
|
|
cnt_ii = 0;
|
|
}
|
|
break;
|
|
case 2:
|
|
if (ch != 91) {
|
|
uart_notice_adapt();
|
|
cnt_ii = 0;
|
|
}
|
|
break;
|
|
case 3:
|
|
switch (ch) {
|
|
default:
|
|
case 'A':
|
|
case 'B':
|
|
case 'C':
|
|
case 'D':
|
|
{
|
|
uart_notice_adapt();
|
|
cnt_ii = 0;
|
|
}
|
|
break;
|
|
case 51:
|
|
case 49:
|
|
case 52:
|
|
break;
|
|
}
|
|
break;
|
|
case 4:
|
|
{
|
|
uart_notice_adapt();
|
|
cnt_ii = 0;
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
uart_notice_adapt();
|
|
cnt_ii = 0;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
extern void dprintf(const char *fmt, ...);
|
|
|
|
static void uart_irqhandle(void)
|
|
{
|
|
UINT8 ch;
|
|
shellCmdLineParse(0, dprintf);
|
|
}
|
|
|
|
int uart_hwiCreate(void)
|
|
{
|
|
UINT32 uwRet = 0;
|
|
if (uwRet != LOS_HwiCreate(NUM_HAL_INTERRUPT_UART, 0xa0, 0, uart_irqhandle, 0)) {
|
|
return uwRet;
|
|
}
|
|
uart_interrupt_unmask();
|
|
return 0;
|
|
}
|
|
|
|
#endif
|
|
#endif
|
|
void uart_init()
|
|
{
|
|
unsigned int temp;
|
|
unsigned int divider;
|
|
unsigned char dividerH, dividerL;
|
|
|
|
/* disable UART1 FIFO */
|
|
WRITE_UINT32(0, UART_REG_BASE + UART_FCR); /*lint !e40*/
|
|
|
|
/* reset and enable UART1 FIFO */
|
|
WRITE_UINT32(0x7, UART_REG_BASE + UART_FCR); /*lint !e40*/
|
|
|
|
/* disable UART1 interrupt */
|
|
WRITE_UINT32(0, UART_REG_BASE + UART_IER); /*lint !e40*/
|
|
|
|
/* enable DLL and DLH */
|
|
WRITE_UINT32(0x80, UART_REG_BASE + UART_LCR); /*lint !e40*/
|
|
/* Caculate devide */
|
|
temp = 16 * CONSOLE_UART_BAUDRATE;
|
|
divider = CONFIG_UART_CLK_INPUT / temp;
|
|
dividerH = ((divider) & 0xff00) >> 8;
|
|
dividerL = ((divider) & 0x00ff);
|
|
|
|
/* configure DLL and DLH */
|
|
WRITE_UINT32(dividerL, UART_REG_BASE + UART_DLL); /*lint !e40*/
|
|
WRITE_UINT32(dividerH, UART_REG_BASE + UART_DLH); /*lint !e40*/
|
|
|
|
/* disable DLL and DLH */
|
|
WRITE_UINT32(0x0, UART_REG_BASE + UART_LCR); /*lint !e40*/
|
|
|
|
/* 8bit data, 1bit stop,even parity */
|
|
WRITE_UINT32(0x1b, UART_REG_BASE + UART_LCR); /*lint !e40*/
|
|
|
|
/* enable UART1 */
|
|
WRITE_UINT32(0x1, UART_REG_BASE + UART_IER); /*lint !e40*/
|
|
|
|
(VOID)LOS_EventInit(&g_uartEvent);
|
|
}
|
|
|
|
void uart_interrupt_unmask(void)
|
|
{
|
|
HalIrqUnmask(NUM_HAL_INTERRUPT_UART);
|
|
}
|