/**
 * @brief       UART Primitive
 * @author      AXELL CORPORATION
 * @description UART Primitive Layer
 * @note        none
 * @history     2017_02_22  初版
 * @history     2017_10_26  Ver2.0
 * @history     2019_12_27  [SDK3.0] UARTのFCRレジスタでのライトアクセスの不具合を修正 (#2575)
 * @history     2019_12_27  [SDK3.0] AG903仕様書AX51903_DS06.pdfの修正を反映 (#2633)
 * @history     2020_07_22  [SDK3.1] UARTのDMAモード2を使用不可に変更 (#2900)
 */
/* DOM-IGNORE-BEGIN */
/*
* This program was created by AXELL CORPORATION.
* Copyright (C) 2017-2020 AXELL CORPORATION, all rights reserved.
*/
/* DOM-IGNORE-END */

#include "AG903_errno.h"
#include "AG903_common.h"
#include "uart/uartprm.h"
#include "register/AG903_uartreg.h"


#define	AG903_UART_READ_REG(CH,REG)			(AG903_UARTn(CH)->REG)
#define	AG903_UART_READ_FLD(CH,REG,POS,MSK)	(((AG903_UARTn(CH)->REG)&MSK) >> POS)
#define	AG903_UART_WRITE_REG(CH,REG,VAL)	(AG903_UARTn(CH)->REG  = (VAL))
#define	AG903_UART_CLR_REG(CH,REG,VAL)		(AG903_UARTn(CH)->REG &= (~VAL))
#define	AG903_UART_SET_REG(CH,REG,VAL)		(AG903_UARTn(CH)->REG |= (VAL))
#define AG903_UART_RMW_VAR(VAR,F,V)         do{(VAR) &= ~(F##_MSK); (VAR) |= ((V)<<F##_POS); }while(0)

static const uint8_t UartLCRSetTbl[AG903_UART_PARITY_TYPE_MAX][AG903_UART_WORDLEN_TYPE_MAX] = {
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, /* Bit[5:3]：Parity, Bit2：StopBits, Bit[1:0]：Word Length */
{0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, /* Bit[5:3]：Parity, Bit2：StopBits, Bit[1:0]：Word Length */
{0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}, /* Bit[5:3]：Parity, Bit2：StopBits, Bit[1:0]：Word Length */
};

static const uint8_t UartFifoTrglSetTbl[AG903_UART_RXTRGL_MAX][AG903_UART_TXTRGL_MAX] = {
{0x00, 0x10, 0x20, 0x30}, /* Bit[7:6]：RXFIFO_TRGL, Bit[5:4]：TXFIFO_TRGL */
{0x40, 0x50, 0x60, 0x70}, /* Bit[7:6]：RXFIFO_TRGL, Bit[5:4]：TXFIFO_TRGL */
{0x80, 0x90, 0xA0, 0xB0}, /* Bit[7:6]：RXFIFO_TRGL, Bit[5:4]：TXFIFO_TRGL */
{0xC0, 0xD0, 0xE0, 0xF0}, /* Bit[7:6]：RXFIFO_TRGL, Bit[5:4]：TXFIFO_TRGL */
};

static uint8_t fcr_reg[AG903_UART_CH_NUM] =
	{0x00,0x00,0x00,0x00}; /* FCR reset value is 0x00 */

/**
 * @brief           UARTnDLL/UARTnDLM,UARTnPSRのレジスタWrite
 * @param           ch [in] UARTチャネル
 * @param           pscale [in] Prescaler設定値
 * @param           div [in] Divisor設定値
 * @return          void
 * @description     UARTnDLL/UARTnDLM,UARTnPSRのレジスタWrite
 * @note            UARTnLCRレジスタのDLABビットを操作します。
*/
void AG903_UARTPrmSetDivisor(uint8_t ch, uint8_t pscale, uint16_t div)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	ASSERT(AG903_UART_PSR_MAXNUM >= pscale);
	
	AG903_UART_SET_REG(ch,LCR,(1<<AG903_UARTn_LCR_DLAB_POS));	/* Divisor Latch Access Enable */

	AG903_UART_WRITE_REG(ch,PSR,pscale);
	AG903_UART_WRITE_REG(ch,DLL,div);
	AG903_UART_WRITE_REG(ch,DLM,(div>>8));

	AG903_UART_CLR_REG(ch,LCR,(1<<AG903_UARTn_LCR_DLAB_POS));	/* Divisor Latch Access Disable */
	return;
}

/**
 * @brief           UARTnLCRのレジスタWrite
 * @param           ch [in] UARTチャネル
 * @param           parity_type [in] パリティ種別
 * @param           length_type [in] データ長種別
 * @return          void
 * @description     UARTnLCRのレジスタWrite
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_UARTPrmSetWordLength(uint8_t ch, uint8_t parity_type, uint8_t length_type)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	ASSERT(AG903_UART_PARITY_TYPE_MAX > parity_type);
	ASSERT(AG903_UART_WORDLEN_TYPE_MAX > length_type);

	AG903_UART_CLR_REG(ch,LCR,(AG903_UARTn_LCR_WL0_MSK|AG903_UARTn_LCR_WL1_MSK|AG903_UARTn_LCR_Stop_Bits_MSK|
		 					   AG903_UARTn_LCR_Parity_Enable_MSK|AG903_UARTn_LCR_Even_Parity_MSK|AG903_UARTn_LCR_Stick_Parity_MSK));
	AG903_UART_SET_REG(ch,LCR,UartLCRSetTbl[parity_type][length_type]);
	return;
}

/**
 * @brief           UARTnFCRレジスタのFIFO_EnableビットClear
 * @param           ch [in] UARTチャネル
 * @return          void
 * @description     UARTnFCRレジスタのFIFO_EnableビットClear
 * @note            FIFOはFCRレジスタでトリガ、DMAモードを設定後に有効にして下さい。
*/
void AG903_UARTPrmDisableFifo(uint8_t ch)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_RMW_VAR(fcr_reg[ch],AG903_UARTn_FCR_FIFO_Enable,0);
	AG903_UART_WRITE_REG(ch,FCR,fcr_reg[ch]);
	return;
}

/**
 * @brief           UARTnFCRレジスタのFIFO_EnableビットSet
 * @param           ch [in] UARTチャネル
 * @return          void
 * @description     UARTnFCRレジスタのFIFO_EnableビットSet
 * @note            FIFOはFCRレジスタでトリガ、DMAモードを設定後に有効にして下さい。
*/
void AG903_UARTPrmEnableFifo(uint8_t ch)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_RMW_VAR(fcr_reg[ch],AG903_UARTn_FCR_FIFO_Enable,1);
	AG903_UART_WRITE_REG(ch,FCR,fcr_reg[ch]);
	return;
}

/**
 * @brief           UARTnFCRレジスタのRXFIFO_TRGLフィールド設定
 * @param           ch [in] UARTチャネル
 * @param           rx_trgl [in] 受信FIFOトリガレベル
 * @param           tx_trgl [in] (無効)
 * @return          void
 * @description     UARTnFCRレジスタのTXFIFO_TRGL,RXFIFO_TRGLフィールド設定
 * @note            FIFOはFCRレジスタでトリガ、DMAモードを設定後に有効にして下さい。
 * @note            送信FIFOトリガレベルは変更できません。tx_trgl引数は無視されます。
*/
void AG903_UARTPrmSetFifoTrigger(uint8_t ch, uint8_t rx_trgl, uint8_t tx_trgl)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	ASSERT(AG903_UART_RXTRGL_MAX > rx_trgl);
	(void)tx_trgl;
	
	fcr_reg[ch] &= ~(AG903_UARTn_FCR_RXFIFO_TRGL_MSK);
	fcr_reg[ch] |= UartFifoTrglSetTbl[rx_trgl][0] & AG903_UARTn_FCR_RXFIFO_TRGL_MSK;
	AG903_UART_WRITE_REG(ch,FCR,fcr_reg[ch]);
	return;
}

/**
 * @brief           UARTnFCRレジスタのTX_FIFO_Reset,RX_FIFO_Resetフィールド設定
 * @param           ch [in] UARTチャネル
 * @param           bit [in] リセット対象FIFO
 * @return          void
 * @description     UARTnFCRレジスタのTX_FIFO_Reset,RX_FIFO_Resetフィールド設定
 * @note            ステータスはリセットされません。要因ごとにアクセスしてクリアして下さい。
 * @note            FIFOはFCRレジスタでトリガ、DMAモードを設定後に有効にして下さい。
*/
void AG903_UARTPrmResetFifo(uint8_t ch, uint8_t bit)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	
	if(AG903_UART_RXFIFO_BIT & bit) {
		AG903_UART_RMW_VAR(fcr_reg[ch],AG903_UARTn_FCR_RX_FIFO_Reset,1);
		AG903_UART_WRITE_REG(ch,FCR,fcr_reg[ch]);
		/* レジスタではリセットのビットは自動的に0に戻る */
		AG903_UART_RMW_VAR(fcr_reg[ch],AG903_UARTn_FCR_RX_FIFO_Reset,0);
	}
	if(AG903_UART_TXFIFO_BIT & bit) {
		AG903_UART_RMW_VAR(fcr_reg[ch],AG903_UARTn_FCR_TX_FIFO_Reset,1);
		AG903_UART_WRITE_REG(ch,FCR,fcr_reg[ch]);
		/* レジスタではリセットのビットは自動的に0に戻る */
		AG903_UART_RMW_VAR(fcr_reg[ch],AG903_UARTn_FCR_TX_FIFO_Reset,0);
	}

	return;
}

/**
 * @brief           UARTnIERレジスタのDSREn,DTREn,CTSEn,RTSEnビットのClear
 * @param           ch [in] UARTチャネル
 * @param           bit [in] Disable対象ビット
 * @return          void
 * @description     UARTnIERレジスタのDSREn,DTREn,CTSEn,RTSEnビットのClear
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_UARTPrmDisableFlowControl(uint8_t ch, uint8_t bit)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_CLR_REG(ch,IER,(bit&0xF0));
	return;
}

/**
 * @brief           UARTnIERレジスタのDSREn,DTREn,CTSEn,RTSEnビットのSet
 * @param           ch [in] UARTチャネル
 * @param           bit [in] Enable対象ビット
 * @return          void
 * @description     UARTnIERレジスタのDSREn,DTREn,CTSEn,RTSEnビットのSet
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_UARTPrmEnableFlowControl(uint8_t ch, uint8_t bit)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_SET_REG(ch,IER,(bit&0xF0));
	return;
}

/**
 * @brief           UARTnFCRレジスタのDMA_ModeビットSet
 * @param           ch [in] UARTチャネル
 * @param           mode [in] DMAモード
 * @return          void
 * @description     UARTnFCRレジスタのDMA_ModeビットSet
 * @note            FIFOはFCRレジスタでトリガ、DMAモードを設定後に有効にして下さい。
 * @note            UARTnMCRレジスタのDMAmode2ビットは常に0にして下さい。またDMAモード2は使用できません。
 * @note            DMAモード1での使用時はRXIFOの閾値とDMACのBeat数を合わせてください。

*/
void AG903_UARTPrmSetDmaMode(uint8_t ch, uint8_t mode)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	ASSERT(AG903_UART_DMA_MODE_MAX > mode);
	
	AG903_UART_CLR_REG(ch,MCR,(1<<AG903_UARTn_MCR_DMAmode2_POS));
	if(AG903_UART_DMA_MODE1 == mode) {
		AG903_UART_RMW_VAR(fcr_reg[ch],AG903_UARTn_FCR_DMA_Mode,1);
		AG903_UART_WRITE_REG(ch,FCR,fcr_reg[ch]);
	}
	else {
		AG903_UART_RMW_VAR(fcr_reg[ch],AG903_UARTn_FCR_DMA_Mode,0);
		AG903_UART_WRITE_REG(ch,FCR,fcr_reg[ch]);
	}
	return;
}

/**
 * @brief           UARTnLCRレジスタのSet_BreakビットSet/Clear
 * @param           ch [in] UARTチャネル
 * @param           enable [in] 出力 or 停止
 * @return          void
 * @description     UARTnLCRレジスタのSet_BreakビットSet /Clear
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_UARTPrmSetBreak(uint8_t ch, _Bool enable)
{
	ASSERT(AG903_UART_CH_NUM > ch);

	if(true == enable) {
		AG903_UART_SET_REG(ch,LCR,(1<<AG903_UARTn_LCR_Set_Break_POS));
	}
	else {
		AG903_UART_CLR_REG(ch,LCR,(1<<AG903_UARTn_LCR_Set_Break_POS));
	}
	return;
}

/**
 * @brief           UARTnIERレジスタのMODEM_Status,Receiver_Line_Status,THR_Empty,Receiver_Data_AvailableビットClear
 * @param           ch [in] UARTチャネル
 * @param           bit [in] 対象ビット
 * @return          void
 * @description     UARTnIERレジスタのMODEM_Status,Receiver_Line_Status,THR_Empty,Receiver_Data_AvailableビットClear
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_UARTPrmDisableInt(uint8_t ch, uint32_t bit)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_CLR_REG(ch,IER,(bit&0x0F));

	return;
}

/**
 * @brief           UARTnIERレジスタのMODEM_Status,Receiver_Line_Status,THR_Empty,Receiver_Data_AvailableビットSet
 * @param           ch [in] UARTチャネル
 * @param           bit [in] 対象ビット
 * @return          void
 * @description     UARTnIERレジスタのMODEM_Status,Receiver_Line_Status,THR_Empty,Receiver_Data_AvailableビットSet
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_UARTPrmEnableInt(uint8_t ch, uint32_t bit)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_SET_REG(ch,IER,(bit&0x0F));
	return;
}

/**
 * @brief           UARTnTHRのレジスタWrite
 * @param           ch [in] UARTチャネル
 * @param           buf [in] 送信データアドレス
 * @param           sndsz [in] 送信サイズ
 * @return          void
 * @description     UARTnTHRのレジスタWrite
*/
void AG903_UARTPrmSendData(uint8_t ch, uint8_t* buf, uint32_t sndsz)
{
	uint32_t loop;
	
	ASSERT(AG903_UART_CH_NUM > ch);
	ASSERT(AG903_UART_FIFO_SIZE >= sndsz);
	ASSERT(NULL != buf);

	for(loop=0; loop<sndsz; loop++) {
		AG903_UART_WRITE_REG(ch,THR,(*buf));
		buf++;
	}

	return;
}

/**
 * @brief           UARTnRBRのレジスタRead
 * @param           ch [in] UARTチャネル
 * @param           buf [out] 受信データ
 * @return          void
 * @description     UARTnRBRのレジスタRead
*/
void AG903_UARTPrmGetReceiveData(uint8_t ch, uint8_t* buf)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	(*buf) = AG903_UART_READ_REG(ch,RBR);
	return;
}

/**
 * @brief           UARTnIIRのレジスタRead
 * @param           ch [in] UARTチャネル
 * @param           type [out] 割込み種別
 * @return          void
 * @description     UARTnIIRのレジスタRead
*/
void AG903_UARTPrmGetIntType(uint8_t ch, uint8_t* type)
{
	uint8_t	val;

	ASSERT(AG903_UART_CH_NUM > ch);
	val = AG903_UART_READ_REG(ch,IIR);
	(*type) = (val&0x0F);

	return;
}

/**
 * @brief           UARTnLSRのレジスタRead
 * @param           ch [in] UARTチャネル
 * @param           status [out] ステータス
 * @return          void
 * @description     UARTnLSRのレジスタRead
*/
void AG903_UARTPrmGetLineStatus(uint8_t ch, uint8_t* status)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	(*status) = AG903_UART_READ_REG(ch,LSR);
	return;
}

/**
 * @brief           UARTnMODレジスタのFCビットClear
 * @param           ch [in] UARTチャネル
 * @return          void
 * @description     UARTnMODレジスタのFCビットClear
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_UARTPrmDisableRS485(uint8_t ch)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_CLR_REG(ch,MOD,(1<<AG903_UARTn_MOD_FC_POS));
	return;
}

/**
 * @brief           UARTnMODレジスタのFCビットSet
 * @param           ch [in] UARTチャネル
 * @return          void
 * @description     UARTnMODレジスタのFCビットSet
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_UARTPrmEnableRS485(uint8_t ch)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_SET_REG(ch,MOD,(1<<AG903_UARTn_MOD_FC_POS));
	return;
}

/**
 * @brief           UARTnMODレジスタのTDビットClear
 * @param           ch [in] UARTチャネル
 * @return          void
 * @description     UARTnMODレジスタのTDビットClear
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_UARTPrmDisableTimeoutDetect(uint8_t ch)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_CLR_REG(ch,MOD,(1<<AG903_UARTn_MOD_TD_POS));
	return;
}

/**
 * @brief           UARTnMODレジスタのTDビットSet
 * @param           ch [in] UARTチャネル
 * @return          void
 * @description     UARTnMODレジスタのTDビットSet
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_UARTPrmEnableTimeoutDetect(uint8_t ch)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_SET_REG(ch,MOD,(1<<AG903_UARTn_MOD_TD_POS));
	return;
}

/**
 * @brief           UARTnINTMASKのレジスタWrite(指定ビットをClear)
 * @param           ch [in] UARTチャネル
 * @param           bit [in] 対象ビット
 * @return          void
 * @description     UARTnINTMASKのレジスタWrite(指定ビットをClear)
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_UARTPrmDisableTimeoutIntMask(uint8_t ch, uint32_t bit)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_CLR_REG(ch,INTMASK,bit);
	return;
}

/**
 * @brief           UARTnINTMASKのレジスタWrite(指定ビットをSet)
 * @param           ch [in] UARTチャネル
 * @param           bit [in] 対象ビット
 * @return          void
 * @description     UARTnINTMASKのレジスタWrite(指定ビットをSet)
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_UARTPrmEnableTimeoutIntMask(uint8_t ch, uint32_t bit)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_SET_REG(ch,INTMASK,bit);
	return;
}

/**
 * @brief           UARTnMODレジスタのHMビット,SMビットSet/Clear
 * @param           ch [in] UARTチャネル
 * @param           hold [in] ホールド時間自動制御有無
 * @param           setup [in] セットアップ時間自動制御有無
 * @return          void
 * @description     UARTnMODレジスタのHMビット,SMビットSet /Clear
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_UARTPrmSetAutoMode(uint8_t ch, _Bool hold, _Bool setup)
{
	ASSERT(AG903_UART_CH_NUM > ch);

	if(true == hold) {
		AG903_UART_CLR_REG(ch,MOD,(1<<AG903_UARTn_MOD_HM_POS));
	}
	else {
		AG903_UART_SET_REG(ch,MOD,(1<<AG903_UARTn_MOD_HM_POS));
	}
	
	if(true == setup) {
		AG903_UART_CLR_REG(ch,MOD,(1<<AG903_UARTn_MOD_SM_POS));
	}
	else {
		AG903_UART_SET_REG(ch,MOD,(1<<AG903_UARTn_MOD_SM_POS));
	}
	return;
}

/**
 * @brief           UARTnSETUPTIMEのレジスタWrite
 * @param           ch [in] UARTチャネル
 * @param           setup_time [in] セットアップ時間 [clk]
 * @return          void
 * @description     UARTnSETUPTIMEのレジスタWrite
*/
void AG903_UARTPrmSetSetuptime(uint8_t ch, uint32_t setup_time)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_WRITE_REG(ch,SETUPTIME,setup_time);
	return;
}

/**
 * @brief           UARTnHOLDTIMEのレジスタWrite
 * @param           ch [in] UARTチャネル
 * @param           hold_time [in] ホールド時間 [clk]
 * @return          void
 * @description     UARTnHOLDTIMEのレジスタWrite
*/
void AG903_UARTPrmSetHoldtime(uint8_t ch, uint32_t hold_time)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_WRITE_REG(ch,HOLDTIME,hold_time);
	return;
}

/**
 * @brief           UARTnRECEIVETIMEのレジスタWrite
 * @param           ch [in] UARTチャネル
 * @param           rcv_time [in] 受信時間 [clk]
 * @return          void
 * @description     UARTnRECEIVETIMEのレジスタWrite
*/
void AG903_UARTPrmSetReceivetime(uint8_t ch, uint32_t rcv_time)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_WRITE_REG(ch,RECEIVETIME,rcv_time);
	return;
}

/**
 * @brief           UARTnCHARINTERVALのレジスタWrite
 * @param           ch [in] UARTチャネル
 * @param           chara_interval [in] キャラクタ間隔 [clk]
 * @return          void
 * @description     UARTnCHARINTERVALのレジスタWrite
*/
void AG903_UARTPrmSetCharainterval(uint8_t ch, uint32_t chara_interval)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_WRITE_REG(ch,CHARINTERVAL,chara_interval);
	return;
}

/**
 * @brief           UARTnTIMEOUTのレジスタWrite
 * @param           ch [in] UARTチャネル
 * @param           timeout [in] タイムアウト時間 [clk]
 * @return          void
 * @description     UARTnTIMEOUTのレジスタWrite
*/
void AG903_UARTPrmSetTimeout(uint8_t ch, uint32_t timeout)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_WRITE_REG(ch,TIMEOUT,timeout);
	return;
}

/**
 * @brief           UARTnCLRのレジスタWrite(指定ビットをSet)
 * @param           ch [in] UARTチャネル
 * @param           bit [in] 対象ビット
 * @return          void
 * @description     UARTnCLRのレジスタWrite(指定ビットをSet)
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_UARTPrmClerTimeoutStatus(uint8_t ch, uint32_t bit)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	AG903_UART_SET_REG(ch,CLR,bit);
	return;
}

/**
 * @brief           UARTnSTATのレジスタRead
 * @param           ch [in] UARTチャネル
 * @param           status [out]  ステータス
 * @return          void
 * @description     UARTnSTATのレジスタRead
*/
void AG903_UARTPrmGetRs485Status(uint8_t ch, uint32_t* status)
{
	ASSERT(AG903_UART_CH_NUM > ch);
	(*status) = AG903_UART_READ_REG(ch,STAT);
	return;
}
