📄 uart.c
字号:
* GLOBALS AFFECTED
* external_global
*/
kal_uint8 U_GetUARTByte(UART_PORT port)
{
kal_uint8 data;
while(1)
{
kal_uint16 LSR;
LSR = DRV_Reg(UART_LSR(UART_BaseAddr[port]));
if (LSR & UART_LSR_DR)
{
data = (kal_uint8)DRV_Reg(UART_RBR(UART_BaseAddr[port]));
if( (stack_query_boot_mode()== FACTORY_BOOT && UARTPort[port].DCB.flowControl==fc_sw)||
(uart_support_autoescape()==KAL_FALSE&&UARTPort[port].DCB.flowControl==fc_sw))
{
if(uart_escape_state==0)
{
if(data==0x77)
uart_escape_state=0x77;
else
return data;
}
else if (uart_escape_state==0x77)
{
uart_escape_state=0x0;
switch(data)
{
case 0x01:
return UARTPort[port].DCB.xonChar;
break;
case 0x02:
return UARTPort[port].DCB.xoffChar;
break;
case 0x03:
return 0x77;
break;
default:
break;
}
}
}
else
{
return data;
}
}
}
}
/*
* FUNCTION
* PutUARTByte
*
* DESCRIPTION
* This function is to write data to UART
*
* CALLS
* This function is to transmit data through UART
*
* PARAMETERS
* None
*
* RETURNS
* the data from UART
*
* GLOBALS AFFECTED
* external_global
*/
void PutUARTRingBufferData(UART_PORT port)
{
#ifndef __DMA_UART_VIRTUAL_FIFO__
kal_uint16 index;
kal_uint16 real_count;
kal_uint8 TX_DATA;
kal_uint32 UART_BASE = UART_BaseAddr[port];
/*ISR*/
Buf_GetBytesAvail(&(UARTPort[port].Tx_Buffer_ISR),real_count);
for (index = 0;index < real_count;index++)
{
Buf_Pop(&(UARTPort[port].Tx_Buffer_ISR),TX_DATA);
DRV_WriteReg(UART_THR(UART_BASE),(kal_uint16)TX_DATA);
}
/*Task*/
Buf_GetBytesAvail(&(UARTPort[port].Tx_Buffer),real_count);
for (index = 0;index < real_count;index++)
{
Buf_Pop(&(UARTPort[port].Tx_Buffer),TX_DATA);
DRV_WriteReg(UART_THR(UART_BASE),(kal_uint16)TX_DATA);
}
#endif
}
void U_PutUARTByte(UART_PORT port, kal_uint8 data)
{
kal_uint16 LSR;
while(1)
{
LSR = DRV_Reg(UART_LSR(UART_BaseAddr[port]));
if ( LSR & UART_LSR_THRE )
{
DRV_WriteReg(UART_THR(UART_BaseAddr[port]),(kal_uint16)data);
break;
}
}
}
void PutUARTData(UART_PORT port, kal_uint8 escape_char, kal_uint8 data)
{
if( (stack_query_boot_mode()== FACTORY_BOOT && UARTPort[port].DCB.flowControl==fc_sw)||
(uart_support_autoescape()==KAL_FALSE))
{
if (data == UARTPort[port].DCB.xonChar)
{
PutUARTByte(port, escape_char);
PutUARTByte(port, 0x01);
}
else if (data == UARTPort[port].DCB.xoffChar)
{
PutUARTByte(port, escape_char);
PutUARTByte(port, 0x02);
}
else if (data == escape_char)
{
PutUARTByte(port, escape_char);
PutUARTByte(port, 0x03);
}
else
{
PutUARTByte(port, data);
}
}
else
{
PutUARTByte(port, data);
}
}
void U_PutUARTBytes(UART_PORT port, kal_uint8 *data,kal_uint16 len)
{
kal_uint16 index;
for(index=0;index<len;index++)
PutUARTByte(port,*(data+index));
}
void PutUARTDatas(UART_PORT port, kal_uint8 escape_char, kal_uint8 *data,kal_uint16 len)
{
kal_uint16 index;
for(index=0;index<len;index++)
PutUARTData(port,escape_char,*(data+index));
}
void U_SetBaudRate(UART_PORT port, UART_baudrate baudrate)
{
kal_uint32 tmp_div;
kal_uint16 divisor;
kal_uint16 byte;
kal_uint32 remainder;
kal_uint32 UART_BASE = UART_BaseAddr[port];
if ( baudrate != UART_BAUD_AUTO ) /* no autobaud */
{
if (baudrate <= UART_BAUD_115200)
{
/* Set BaudRate */
tmp_div = (UART_CLOCK)/(16*baudrate);
divisor = (kal_uint16)tmp_div;
remainder = (UART_CLOCK)%(16*baudrate);
if (remainder >= (8*baudrate))
divisor = (kal_uint16)(tmp_div+1);
else
divisor = (kal_uint16)tmp_div;
#if defined(MT6205B)||defined(MT6226M) || defined(MT6218) || defined(MT6218B) || defined(MT6219)||defined(MT6217)|| defined(MT6228)|| defined(MT6229)|| (defined(MT6226))|| (defined(MT6227))
DRV_WriteReg(UART_RATE_STEP(UART_BASE),0x0);
#endif
/* GPIO_WriteAll(divisor); */
byte = DRV_Reg(UART_LCR(UART_BASE)); /* DLAB start */
DRV_WriteReg(UART_LCR(UART_BASE),(byte | UART_LCR_DLAB));
DRV_WriteReg(UART_DLL(UART_BASE),(divisor & 0x00ff));
DRV_WriteReg(UART_DLH(UART_BASE),((divisor >> 8)&0x00ff));
DRV_WriteReg(UART_LCR(UART_BASE),byte); /* DLAB End */
#ifndef __PRODUCTION_RELEASE__
uart_lcr_save[port] = byte;
#endif /*__PRODUCTION_RELEASE__*/
}
#if defined(MT6205B)||defined(MT6226M) || defined(MT6218) || defined(MT6218B) || defined(MT6219)||defined(MT6217)|| defined(MT6228)|| defined(MT6229)|| (defined(MT6226))|| (defined(MT6227))
else //support high speed uart baudrate > 115200
{
tmp_div = (UART_CLOCK)/(4*baudrate);
divisor = (kal_uint16)tmp_div;
remainder = (UART_CLOCK)%(4*baudrate);
if (remainder >= (2*baudrate))
divisor = (kal_uint16)(tmp_div+1);
else
divisor = (kal_uint16)tmp_div;
DRV_WriteReg(UART_RATE_STEP(UART_BASE),0x02);
byte = DRV_Reg(UART_LCR(UART_BASE)); /* DLAB start */
DRV_WriteReg(UART_LCR(UART_BASE),(byte | UART_LCR_DLAB));
DRV_WriteReg(UART_DLL(UART_BASE),(divisor & 0x00ff));
DRV_WriteReg(UART_DLH(UART_BASE),((divisor >> 8)&0x00ff));
DRV_WriteReg(UART_LCR(UART_BASE),byte); /* DLAB End */
}
#endif
}
#if defined(MT6218)||defined(MT6226M) || defined(MT6218B) || defined(MT6219)|| defined(MT6217)|| defined(MT6228)|| defined(MT6229)|| (defined(MT6226))|| (defined(MT6227))
else
{
switch (UART_CLOCK)
{
case 13000000:
DRV_WriteReg(UART_AUTO_BAUDSAMPLE(UART_BASE),AUTOBAUDSAMPLE_13M);
DRV_WriteReg(UART_AUTOBAUD_EN(UART_BASE),AUTOBAUD_EN);
break;
case 26000000:
DRV_WriteReg(UART_AUTO_BAUDSAMPLE(UART_BASE),AUTOBAUDSAMPLE_26M);
DRV_WriteReg(UART_AUTOBAUD_EN(UART_BASE),AUTOBAUD_EN);
break;
case 52000000:
DRV_WriteReg(UART_AUTO_BAUDSAMPLE(UART_BASE),AUTOBAUDSAMPLE_52M);
DRV_WriteReg(UART_AUTOBAUD_EN(UART_BASE),AUTOBAUD_EN);
break;
default:
break;
}
}
#endif
}
/*This function is to cover 6218B/6219 hw bug.
UART should not send receiving data to its FIFO when doing auto baud*/
void U_SetAutoBaud_Div(UART_PORT port)
{
kal_uint32 UART_BASE = UART_BaseAddr[port];
kal_uint8 byte;
/*TY adds this compile option 20041006*/
if(uart_support_autoescape()==KAL_FALSE)
{
byte = DRV_Reg(UART_LCR(UART_BASE)); /* DLAB start */
DRV_WriteReg(UART_LCR(UART_BASE),(byte | UART_LCR_DLAB));
DRV_WriteReg(UART_DLL(UART_BASE),0xff);
DRV_WriteReg(UART_DLH(UART_BASE),0xff);
DRV_WriteReg(UART_LCR(UART_BASE),byte); /* DLAB End */
}
}
void U_SetDCBConfig(UART_PORT port, UARTDCBStruct *UART_Config)
{
kal_uint16 byte;
kal_uint16 IER;
kal_uint32 savedMask;
kal_uint32 UART_BASE = UART_BaseAddr[port];
savedMask = SaveAndSetIRQMask();
IER = DRV_Reg(UART_IER(UART_BASE));
DRV_WriteReg(UART_IER(UART_BASE),UART_IER_ALLOFF);
RestoreIRQMask(savedMask);
U_SetBaudRate(port, UART_Config->baud);
/* Setup N81 */
byte = DRV_Reg(UART_LCR(UART_BASE)); /* DLAB start */
byte &= ~UART_DATA_MASK;
switch(UART_Config->dataBits)
{
case len_5:
byte |= UART_WLS_5;
break;
case len_6:
byte |= UART_WLS_6;
break;
case len_7:
byte |= UART_WLS_7;
break;
case len_8:
byte |= UART_WLS_8;
break;
default:
break;
}
byte &= ~UART_STOP_MASK;
switch(UART_Config->stopBits)
{
case sb_1:
byte |= UART_1_STOP;
break;
case sb_2:
byte |= UART_2_STOP;
break;
case sb_1_5:
byte |= UART_1_5_STOP;
break;
default:
break;
}
byte &= ~UART_PARITY_MASK;
switch(UART_Config->parity)
{
case pa_none:
byte |= UART_NONE_PARITY;
break;
case pa_odd:
byte |= UART_ODD_PARITY;
break;
case pa_even:
byte |= UART_EVEN_PARITY;
break;
case pa_space:
byte |= UART_SPACE_PARITY;
break;
default:
break;
}
DRV_WriteReg(UART_LCR(UART_BASE),byte); /* DLAB End */
/* flowControl */
byte = DRV_Reg(UART_LCR(UART_BASE));
/* DRV_WriteReg(UART_LCR,(byte | UART_LCR_DLAB)); // DLAB start */
DRV_WriteReg(UART_LCR(UART_BASE),0xbf); /* Enchance setting */
switch(UART_Config->flowControl)
{
case fc_none:
DRV_WriteReg(UART_EFR(UART_BASE),UART_EFR_ALLOFF);
break;
case fc_hw:
#ifdef MT6208
if (port == uart_port1)
DRV_WriteReg(UART_EFR(UART_BASE),UART_EFR_AutoRTSCTS);
else
DRV_WriteReg(UART_EFR(UART_BASE),UART_EFR_ALLOFF);
#else /*!MT6208*/
DRV_WriteReg(UART_EFR(UART_BASE),UART_EFR_AutoRTSCTS);
#endif /*MT6208*/
break;
case fc_sw:
DRV_WriteReg(UART_EFR(UART_BASE),UART_EFR_SWFlowCtrlX1);
if(uart_support_autoescape()==KAL_TRUE)
{
/*For META, Dont use auto escape*/
if(stack_query_boot_mode() != FACTORY_BOOT)
{
#if (!defined(MT6205B)&&!defined(MT6208)&&!defined(FPGA))
/*For AutoEscape*/
DRV_WriteReg(UART_ESCAPE_DAT(UART_BaseAddr[port]),0x77);
DRV_WriteReg(UART_ESCAPE_EN(UART_BaseAddr[port]),0x1);
#endif
}
}
break;
default:
break;
}
#ifdef __DMA_UART_VIRTUAL_FIFO__
if(UART_VFIFO_support[port])
DRV_WriteReg(UART_RXDMA(UART_BASE),UART_RXDMA_ON);
#endif
/* XON and XOFF characters */
DRV_WriteReg(UART_XON1(UART_BASE),UART_Config->xonChar);
DRV_WriteReg(UART_XOFF1(UART_BASE),UART_Config->xoffChar);
DRV_WriteReg(UART_XON2(UART_BASE),UART_Config->xonChar);
DRV_WriteReg(UART_XOFF2(UART_BASE),UART_Config->xoffChar);
DRV_WriteReg(UART_LCR(UART_BASE),byte); /* DLAB End */
#ifndef __PRODUCTION_RELEASE__
uart_lcr_save[port] = byte;
#endif /*__PRODUCTION_RELEASE__*/
if (UART_Config->DSRCheck)
{
if (DRV_Reg(UART1_MSR) & UART_MSR_DSR)
{
switch(port)
{
case uart_port1:
DRVPDN_Disable(DRVPDN_CON1,DRVPDN_CON1_UART1,PDN_UART1);
break;
case uart_port2:
DRVPDN_Disable(DRVPDN_CON1,DRVPDN_CON1_UART2,PDN_UART2);
break;
#ifdef __UART3_SUPPORT__
case uart_port3:
#if ( (!defined(MT6217)) && (!defined(MT6218B)) )
DRVPDN_Disable(DRVPDN_CON1,DRVPDN_CON1_UART3,PDN_UART3);
#endif
break;
#endif /*__UART3_SUPPORT__*/
default:
ASSERT(0);
break;
}
}
else
{
switch(port)
{
case uart_port1:
DRVPDN_Enable(DRVPDN_CON1,DRVPDN_CON1_UART1,PDN_UART1);
break;
case uart_port2:
DRVPDN_Enable(DRVPDN_CON1,DRVPDN_CON1_UART2,PDN_UART2);
break;
#ifdef __UART3_SUPPORT__
case uart_port3:
#if ( (!defined(MT6217)) && (!defined(MT6218B)) )
DRVPDN_Enable(DRVPDN_CON1,DRVPDN_CON1_UART3,PDN_UART3);
#endif
break;
#endif /*__UART3_SUPPORT__*/
default:
ASSERT(0);
break;
}
}
}
#if 0 /* power down control is moved to UART_TurnOnPower(). */
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -