rtl00TstMinAmebaV35a/component/common/mbed/targets/hal/rtl8195a/log_uart_api.c
2016-09-23 07:21:45 +03:00

510 lines
14 KiB
C

/* mbed Microcontroller Library
*******************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#include "objects.h"
#include "log_uart_api.h"
#include <string.h>
const u32 log_uart_support_rate[] = {
UART_BAUD_RATE_2400, UART_BAUD_RATE_4800, UART_BAUD_RATE_9600,
UART_BAUD_RATE_19200, UART_BAUD_RATE_38400, UART_BAUD_RATE_57600,
UART_BAUD_RATE_115200, UART_BAUD_RATE_921600, UART_BAUD_RATE_1152000,
0xFFFFFFFF
};
extern HAL_TIMER_OP HalTimerOp;
extern u32 ConfigDebugErr;
extern u32 ConfigDebugWarn;
extern u32 ConfigDebugInfo;
extern u32 CfgSysDebugErr;
extern u32 CfgSysDebugInfo;
extern u32 CfgSysDebugWarn;
extern HAL_Status RuartIsTimeout (u32 StartCount, u32 TimeoutCnt);
extern u32 HalLogUartInitSetting(HAL_LOG_UART_ADAPTER *pUartAdapter);
extern VOID HalLogUartSetBaudRate(HAL_LOG_UART_ADAPTER *pUartAdapter);
extern VOID HalLogUartSetLineCtrl(HAL_LOG_UART_ADAPTER *pUartAdapter);
extern VOID HalLogUartIrqHandle(VOID * Data);
int32_t log_uart_init (log_uart_t *obj, int baudrate, int data_bits, SerialParity parity, int stop_bits)
{
HAL_LOG_UART_ADAPTER *pUartAdapter;
int i;
_memset((void*)obj, 0, sizeof(log_uart_t));
pUartAdapter = &obj->log_hal_uart;
// Check Baud rate
for (i=0; log_uart_support_rate[i]!=0xFFFFFF; i++) {
if (log_uart_support_rate[i] == baudrate) {
break;
}
}
if (log_uart_support_rate[i]== 0xFFFFFF) {
DBG_UART_ERR("log_uart_init: Not support Baud Rate %d\n", baudrate);
return -1;
}
// check word width
if ((data_bits < 5) || (data_bits > 8)) {
DBG_UART_ERR("log_uart_init: Not support Word Width %d\n", data_bits);
return -1;
}
//4 Inital Log uart
pUartAdapter->BaudRate = baudrate;
pUartAdapter->DataLength = data_bits-5;
pUartAdapter->FIFOControl = FCR_FIFO_EN | FCR_TX_TRIG_HF | FCR_RX_TRIG_HF;
// only enable Rx linstatus at initial,
// Tx & Rx interrupt will be enabled @ transfer start time
pUartAdapter->IntEnReg = IER_ELSI;
switch (parity) {
case ParityNone:
pUartAdapter->Parity = LCR_PARITY_NONE;
break;
case ParityOdd:
pUartAdapter->Parity = LCR_PARITY_ODD;
break;
case ParityEven:
pUartAdapter->Parity = LCR_PARITY_EVEN;
break;
default:
DBG_UART_ERR("log_uart_init: Not support parity type %d\n", parity);
return -1;
}
if (stop_bits > 1) {
// if width is 5 bits, stop bit will be 1.5 bit
pUartAdapter->Stop = LCR_STOP_2B;
} else {
pUartAdapter->Stop = LCR_STOP_1B;
}
//4 Initial Log Uart
HalLogUartInitSetting(pUartAdapter);
// disable all debug message
ConfigDebugErr = 0;
ConfigDebugWarn = 0;
ConfigDebugInfo = 0;
CfgSysDebugErr = 0;
CfgSysDebugInfo = 0;
CfgSysDebugWarn = 0;
return 0;
}
void log_uart_free(log_uart_t *obj)
{
LOG_UART_ADAPTER UartAdapter;
// Recover the Log UART for debug message printing
//4 Release log uart reset and clock
LOC_UART_FCTRL(OFF);
LOC_UART_FCTRL(ON);
ACTCK_LOG_UART_CCTRL(ON);
//4 Inital Log uart
UartAdapter.BaudRate = UART_BAUD_RATE_38400;
UartAdapter.DataLength = UART_DATA_LEN_8BIT;
UartAdapter.FIFOControl = 0xC1;
UartAdapter.IntEnReg = 0x00;
UartAdapter.Parity = UART_PARITY_DISABLE;
UartAdapter.Stop = UART_STOP_1BIT;
// un_register current IRQ first
InterruptUnRegister(&(obj->log_hal_uart.IrqHandle));
//4 Initial Log Uart
HalLogUartInit(UartAdapter);
}
void log_uart_baud(log_uart_t *obj, int baudrate)
{
HAL_LOG_UART_ADAPTER *pUartAdapter;
int i;
pUartAdapter = &obj->log_hal_uart;
// Check Baud rate
for (i=0; log_uart_support_rate[i]!=0xFFFFFFFF; i++) {
if (log_uart_support_rate[i] == baudrate) {
break;
}
}
if (log_uart_support_rate[i]== 0xFFFFFF) {
DBG_UART_ERR("log_uart_baud: Not support Baud Rate %d\n", baudrate);
return;
}
pUartAdapter->BaudRate = baudrate;
HalLogUartSetBaudRate(pUartAdapter);
}
void log_uart_format(log_uart_t *obj, int data_bits, SerialParity parity, int stop_bits)
{
HAL_LOG_UART_ADAPTER *pUartAdapter;
pUartAdapter = &obj->log_hal_uart;
// check word width
if ((data_bits < 5) || (data_bits > 8)) {
DBG_UART_ERR("log_uart_format: Not support Word Width %d\n", data_bits);
return;
}
//4 Inital Log uart
pUartAdapter->DataLength = data_bits - 5;
switch (parity) {
case ParityNone:
pUartAdapter->Parity = LCR_PARITY_NONE;
break;
case ParityOdd:
pUartAdapter->Parity = LCR_PARITY_ODD;
break;
case ParityEven:
pUartAdapter->Parity = LCR_PARITY_EVEN;
break;
default:
DBG_UART_ERR("log_uart_format: Not support parity type %d\n", parity);
return;
}
if (stop_bits > 1) {
// if width is 5 bits, stop bit will be 1.5 bit
pUartAdapter->Stop = LCR_STOP_2B;
} else {
pUartAdapter->Stop = LCR_STOP_1B;
}
HalLogUartSetLineCtrl(pUartAdapter);
}
/******************************************************************************
* INTERRUPTS HANDLING
******************************************************************************/
void log_uart_irq_handler(log_uart_t *obj, loguart_irq_handler handler, uint32_t id)
{
HAL_LOG_UART_ADAPTER *pUartAdapter;
pUartAdapter = &(obj->log_hal_uart);
pUartAdapter->api_irq_handler = handler;
pUartAdapter->api_irq_id = id;
}
void log_uart_irq_set(log_uart_t *obj, LOG_UART_INT_ID irq, uint32_t enable)
{
HAL_LOG_UART_ADAPTER *pUartAdapter;
u8 int_en=0;
pUartAdapter = &(obj->log_hal_uart);
switch (irq) {
case IIR_RX_RDY:
int_en = IER_ERBFI;
break;
case IIR_THR_EMPTY:
int_en = IER_ETBEI;
break;
case IIR_RX_LINE_STATUS:
int_en = IER_ELSI;
break;
case IIR_MODEM_STATUS:
int_en = IER_EDSSI;
break;
default:
DBG_UART_WARN("log_uart_irq_set: Unknown Irq Id\n");
return;
}
if (enable) {
pUartAdapter->IntEnReg |= int_en;
} else {
// disable
pUartAdapter->IntEnReg &= (~int_en);
}
HalLogUartSetIntEn(pUartAdapter);
}
/******************************************************************************
* READ/WRITE
******************************************************************************/
char log_uart_getc(log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
while (!log_uart_readable(obj));
return (char)(HAL_UART_READ32(UART_REV_BUF_OFF) & 0xFF);
}
void log_uart_putc(log_uart_t *obj, char c)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
while (!log_uart_writable(obj));
HAL_UART_WRITE8(UART_TRAN_HOLD_OFF, c);
}
int log_uart_readable(log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
volatile u8 line_status;
line_status = HAL_UART_READ8(UART_LINE_STATUS_REG_OFF);
if (line_status & LSR_DR) {
return 1;
} else {
return 0;
}
}
int log_uart_writable(log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
volatile u8 line_status;
line_status = HAL_UART_READ8(UART_LINE_STATUS_REG_OFF);
if (line_status & LSR_THRE) {
return 1;
} else {
return 0;
}
}
void log_uart_clear(log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
HalLogUartRstFIFO(pUartAdapter, (LOG_UART_RST_TX_FIFO|LOG_UART_RST_TX_FIFO));
pUartAdapter->TxCount = 0;
pUartAdapter->RxCount = 0;
}
void log_uart_clear_tx(log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
HalLogUartRstFIFO(pUartAdapter, LOG_UART_RST_TX_FIFO);
pUartAdapter->TxCount = 0;
}
void log_uart_clear_rx(log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
HalLogUartRstFIFO(pUartAdapter, LOG_UART_RST_RX_FIFO);
pUartAdapter->RxCount = 0;
}
void log_uart_break_set(log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
u32 RegValue;
RegValue = HAL_UART_READ32(UART_LINE_CTL_REG_OFF);
RegValue |= LCR_BC;
HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, RegValue);
}
void log_uart_break_clear(log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
u32 RegValue;
RegValue = HAL_UART_READ32(UART_LINE_CTL_REG_OFF);
RegValue &= ~LCR_BC;
HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, RegValue);
}
void log_uart_tx_comp_handler(log_uart_t *obj, void *handler, uint32_t id)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart);
pUartAdapter->TxCompCallback = (void(*)(void*))handler;
pUartAdapter->TxCompCbPara = (void*)id;
}
void log_uart_rx_comp_handler(log_uart_t *obj, void *handler, uint32_t id)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
pUartAdapter->RxCompCallback = (void(*)(void*))handler;
pUartAdapter->RxCompCbPara = (void*)id;
}
void log_uart_line_status_handler(log_uart_t *obj, void *handler, uint32_t id)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
pUartAdapter->LineStatusCallback = (void(*)(void*, u8))handler;
pUartAdapter->LineStatusCbPara = (void*)id;
}
// Blocked(busy wait) receive, return received bytes count
int32_t log_uart_recv (log_uart_t *obj, char *prxbuf, uint32_t len, uint32_t timeout_ms)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
int ret;
ret = (int)HalLogUartRecv(pUartAdapter, prxbuf, len, timeout_ms);
return (ret);
}
// Blocked(busy wait) send, return transmitted bytes count
int32_t log_uart_send (log_uart_t *obj, char *ptxbuf, uint32_t len, uint32_t timeout_ms)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
int ret;
ret = (int)HalLogUartSend(pUartAdapter, ptxbuf, len, timeout_ms);
return (ret);
}
// Interrupt mode(no wait) receive, return HAL function result
int32_t log_uart_recv_stream (log_uart_t *obj, char *prxbuf, uint32_t len)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
int ret;
ret = (int)HalLogUartIntRecv(pUartAdapter, (u8*)prxbuf, len);
return (ret);
}
// Interrupt Mode(no wait) send, return HAL function result
int32_t log_uart_send_stream (log_uart_t *obj, char *ptxbuf, uint32_t len)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
int ret;
ret = (int)HalLogUartIntSend(pUartAdapter, (u8*)ptxbuf, len);
return (ret);
}
// Interrupt mode(no wait) receive with timeout
// return the byte count received before timeout, or error(<0)
int32_t log_uart_recv_stream_timeout (log_uart_t *obj, char *prxbuf, uint32_t len,
uint32_t timeout_ms, void *force_cs)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
uint32_t TimeoutCount=0, StartCount;
int ret;
void (*task_yield)(void);
task_yield = NULL;
ret = (int)HalLogUartIntRecv(pUartAdapter, (u8*)prxbuf, len);
if ((ret == HAL_OK) && (timeout_ms > 0)) {
TimeoutCount = (timeout_ms*1000/TIMER_TICK_US);
StartCount = HalTimerOp.HalTimerReadCount(1);
task_yield = (void (*)(void))force_cs;
while (pUartAdapter->RxCount > 0) {
if (HAL_TIMEOUT == RuartIsTimeout(StartCount, TimeoutCount)) {
HalLogUartAbortIntRecv(pUartAdapter);
break;
}
if (NULL != task_yield) {
task_yield();
}
}
return (len - pUartAdapter->RxCount);
} else {
return (-ret);
}
}
// Abort Interrupt Mode TX and return how many bytes data has been sent
int32_t log_uart_send_stream_abort (log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
int ret;
HalLogUartAbortIntSend(pUartAdapter);
ret = (u32)pUartAdapter->pTxBuf - (u32)pUartAdapter->pTxStartAddr;
return (ret);
}
// Abort Interrupt Mode RX and return how many bytes data has been received
int32_t log_uart_recv_stream_abort (log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
int ret;
HalLogUartAbortIntRecv(pUartAdapter);
ret = (u32)pUartAdapter->pRxBuf - (u32)pUartAdapter->pRxStartAddr;
return (ret);
}
void log_uart_disable (log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
HalLogUartDisable(pUartAdapter);
}
void log_uart_enable (log_uart_t *obj)
{
HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart);
HalLogUartEnable(pUartAdapter);
}
// to read Line-Status register
// Bit 0: RX Data Ready
// Bit 1: Overrun Error
// Bit 2: Parity Error
// Bit 3: Framing Error
// Bit 4: Break Interrupt (received data input is held in 0 state for a longer than a full word tx time)
// Bit 5: TX FIFO empty (THR empty)
// Bit 6: TX FIFO empty (THR & TSR both empty)
// Bit 7: Receiver FIFO Error (parity error, framing error or break indication)
uint8_t log_uart_raed_lsr(log_uart_t *obj)
{
uint8_t LineStatus;
LineStatus = HAL_UART_READ8(UART_LINE_STATUS_REG_OFF);
return LineStatus;
}
// to read Modem-Status register
// Bit 0: DCTS, The CTS line has changed its state
// Bit 1: DDSR, The DSR line has changed its state
// Bit 2: TERI, RI line has changed its state from low to high state
// Bit 3: DDCD, DCD line has changed its state
// Bit 4: Complement of the CTS input
// Bit 5: Complement of the DSR input
// Bit 6: Complement of the RI input
// Bit 7: Complement of the DCD input
uint8_t log_uart_raed_msr(log_uart_t *obj)
{
uint8_t RegValue;
RegValue = HAL_UART_READ8(UART_MODEM_STATUS_REG_OFF);
return RegValue;
}