📄 uart.c
字号:
}
else
{
rEPLLCON= (32<<16) | (1<<8) | 0;// Epll output - 384Mhz, pll input - 12MHz
rEPLLCON_K = 0;
EpllClk = 384000000;
DivideBy =6;//64Mhz
}
return DivideBy;
}
//Change Clocksource speed,
//set clock speed
//Output : selected clocksource,
unsigned char UART_SelectOpClock(int clocksource)
{
unsigned char OpClock;
int Divideby;
// Set Operation clock
printf("[Select Operating Clock] 0. PCLK[D] 2. PCLK[D] 1. EXTUARTCLK 3. EPLL \t\t\t\t Choose : %d\n", clocksource);
clocksource = (clocksource<0)?GetIntNum() : clocksource;
switch (clocksource)
{
case 1 :
OpClock=1;
rMISCCR = rMISCCR & ~(7<<4) | (5<<4);// clkout0 is pclk divided clock
rGPHCON = rGPHCON & ~(3<<26) | (1<<27);// clkout0 using
// connect CLKOUT and UEXTCLK
rGPHCON = rGPHCON & ~(3<<24) | (1<<25);// Uextclk using
UextClk = PCLK;//divided clock
break;
case 3 :
OpClock=3;
EPLL_setEPLLREF_Source(2);//xtal
Divideby = UART_EpllSel(8);// Epll output - 64Mhz pll input - 12MHz - high speed 4Mbps, 2Mbps
//Divideby = UART_EpllSel(1);// Epll output - 48Mhz pll input - 12MHz - high speed 3Mbps, 1.5Mbps, 1Mbps
//Divideby = UART_EpllSel(6);// Epll output - 406425600, pll input - 12MHz - high speed
//Divideby = UART_EpllSel(7);// Epll output - 36Mhz, pll input - 12MHz - low speed
// use EPLL output clock
Divideby=Divideby-1;
rCLKSRC = rCLKSRC & ~(1<<6)|(1<<6); // epll divided output select
rCLKDIV1 = rCLKDIV1 & ~(0xf<<8) | (Divideby<<8); // uartdiv clock divider for EPLL. (/1~/16)
EpllClk = EpllClk/(Divideby+1);
printf("epllclk:%d , uartdiv of clkdiv1 : %d => 1/(%d+1)\n", EpllClk, Divideby, Divideby);
break;
case 0: OpClock=0; break;// PCLK
default : OpClock=2; break;// PCLK
}
return OpClock;
}
////////////////////// User library functions /////////////////////
// Called from outside
//console.c, uarttest.c
unsigned char SetDbgUart(unsigned char ch)
{
if (ch > 3) return FALSE;
memcpy(&UartCon[ch], &UartCon[4], sizeof(UART_CON));//copy from saved area.
UartOpen(ch,1,0);//ch, SetIRQ, bAFC2
return TRUE;
}
//uarttest.c
bool UART_assignUartCon(unsigned char ch,UART_CON* pUartCon)
{
UartCon[ch] = *pUartCon;
return 1;
}
/*
//none.
unsigned char SetBaudrate(unsigned char ch, unsigned int Baudrate)
{
UART_REGS *pUartRegs;
UART_CON *pUartCon;
if (ch > 2) return FALSE;
pUartCon = &UartCon[ch];
pUartRegs = (UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch);
pUartCon->iBaudrate = Baudrate;
CalcBaudrate(pUartRegs, pUartCon);
return TRUE;
}
//none
unsigned char SetOpClock(unsigned char ch, unsigned int OpClock)
{
volatile UART_REGS *pUartRegs;
volatile UART_CON *pUartCon;
if (ch > 2) return FALSE;
pUartCon = &UartCon[ch];
pUartRegs = (volatile UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch);
pUartCon->cOpClock = OpClock;
pUartRegs->rUCon &= ~(3<<10);
pUartRegs->rUCon |= (pUartCon->cOpClock<<10);
return TRUE;
}
//DataBit 0:5bit, 1:6bit, 2:7bit, 3:8bit
//ParityBit 0,1,2,3:no parity, 4:odd, 5:even, 6:forced 1, 7:forced 0
//StopBit 0:one stopbit, 1:two stopbit
unsigned char SetLineCon(unsigned char ch, unsigned char DataBit, unsigned char ParityBit, unsigned char StopBit)
{
volatile UART_REGS *pUartRegs;
volatile UART_CON *pUartCon;
if (ch > 2) return FALSE;
pUartCon = &UartCon[ch];
pUartRegs = (volatile UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch);
pUartCon->cDataBit = DataBit;
pUartCon->cParityBit = ParityBit;
pUartCon->cStopBit = StopBit;
pUartRegs->rUlCon = pUartRegs->rUlCon&(~0x3f) | (pUartCon->cParityBit<<3)|(pUartCon->cStopBit<<2)|(pUartCon->cDataBit);
return TRUE;
}
char Rxchar(unsigned char ch) // added 060624
{
volatile UART_REGS *pUartRegs;
pUartRegs = (UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch);
if(pUartRegs->rUtrStat & 0x1) //Receive data ready
return pUartRegs->rUrxh;
else
return 0;
}
*/
///////////////////////// Test functions ////////////////////////
//port layout
//[com2] [com1]
//[Uart1]/2/3 uart0
void UART_userguide(int testch)
{
if(testch==0)
{
printf("\n\nConnect a serial cable bewteen Target(PC/other SMDK) and SMDK2450 for TEST!!! as depicted below");
printf(" Target : [whatever your test terminal is connected]\n");
printf(" | \n");
printf("SMDK2450 : [ ] [COM1-uart%d]\n",testch);
}
else
{
printf("\n\nConnect a serial cable bewteen Target(PC/other SMDK) and SMDK2450 for TEST!!! as depicted below");
printf(" Target : [whatever your test terminal is connected]\n");
printf(" | \n");
printf("SMDK2450 : [COM2-uart%d] [ ]\n",testch);
printf(" set CFG9 port setting as follows\n");
printf(" CFG9 [1] [2] [3] [4]\n");
if(testch==1) printf(" UART1: off x x \n");
else if(testch==2){ printf(" UART2: on off off\n");
printf(" IrDA2 : x on on\n");
}
else if(testch==3) printf(" UART3: on on x\n");
}
printf("or SMDK2450 : CON29\n" );
printf(" CTS0- 1 7 -CTS1 \n" );
printf(" RTS0- 2 8 -RTS1 \n" );
printf(" TXD0- 3 9 -TXD1 \n" );
printf(" RXD0- 4 10 -RXD1 \n" );
printf(" TXD2- 5 11 -TXD3 \n" );
printf(" RXD2- 6 12 -RXD3 \n" );
printf("after set, press any key to continue\n");
getchar();
}
//return selected uart channel.
//set UartCon of selected channel before init uart.
//return bAFC2
unsigned char UartConfig(bool * bAFC2)
{
unsigned char testch;
int iNum = 0;
volatile UART_CON *pUartCon;
// Select Channel
printf("Note : [D] mark means default value. If you press ENTER key, default value is selected.\n");
printf("Select Channel(0~3) [D=0] : ");
testch = (unsigned char)GetIntNum();
if ( testch>3 ) testch = 0; // default uart 0
pUartCon = &UartCon[testch];
//Set Other Options
printf("\nSelect Other Options\n 0. Nothing[D] 1.Send Break Signal 2. Loop Back Mode \n Choose : ");
switch(GetIntNum())
{
default : {
pUartCon->cSendBreakSignal = 0;
pUartCon->fLoopTest = 0;
break;
}
case 1 : pUartCon->cSendBreakSignal = 1; return testch;
case 2 : pUartCon->fLoopTest = 1; break;
}
//Set Parity mode
printf("\nSelect Parity Mode\n 1. No parity[D] 2. Odd 3. Even 4. Forced as '1' 5. Forced as '0' \n Choose : ");
switch(GetIntNum())
{
default : pUartCon->cParityBit = 0; break;
case 2 : pUartCon->cParityBit = 4; break;
case 3 : pUartCon->cParityBit = 5; break;
case 4 : pUartCon->cParityBit = 6; break;
case 5 : pUartCon->cParityBit = 7; break;
}
//Set the number of stop bit
printf("\n\nSelect Number of Stop Bit\n 1. One stop bit per frame[D] 2. Two stop bit per frame");
switch(GetIntNum())
{
default : pUartCon->cStopBit = 0; break;
case 2 : pUartCon->cStopBit = 1; break;
}
//Set Word Length
printf("\n\nSelect Word Length\n 1. 5bits 2. 6bits 3. 7bits 4. 8bits[D] \n Choose : ");
switch(GetIntNum())
{
case 1 : pUartCon->cDataBit = 0; break;
case 2 : pUartCon->cDataBit = 1; break;
case 3 : pUartCon->cDataBit = 2; break;
default : pUartCon->cDataBit = 3; break;
}
// Set Operation clock
pUartCon->cOpClock=UART_SelectOpClock(-1);
// Select UART or IrDA 1.0
printf("\n\nSelect External Interface Type\n 1. UART[D] 2. IrDA mode\n Choose : ");
if (GetIntNum() == 2) pUartCon->fSelUartIrda = 1; // IrDA mode
else pUartCon->fSelUartIrda = 0; // IrDA mode
// Set Baudrate
printf("\n\nType the baudrate and then change the same baudrate of host, too.\n");
printf(" Baudrate (ex 9600, 115200[D], 921600) : ");
iNum= GetIntNum();
pUartCon->iBaudrate = ( iNum == -1)? 115200 : iNum;
// Select UART operating mode
printf("\n\nSelect Operating Mode(Tx)\n");
printf("0. Disable 1. Polling or Interrupt[D] 2. DMA tx reqeust:0 3. DMA tx reqeust:1 \n Choose : \n");
iNum = GetIntNum();
if (iNum == 2) pUartCon->cTxMode = 2; // DMA0 mode
else if (iNum == 3) pUartCon->cTxMode = 3; // DMA1 mode
else if (iNum == 0) pUartCon->cTxMode = 0; // Disable
else
{
pUartCon->cTxMode = 1; // Polling and Int mode
printf("\n\nSelect Tx: 0. Interrupt[D] 1.Polling Mod\n");
pUartCon->bTxPolling = (GetIntNum() == 1)?1:0;//0: interrupt[D] 1: polling.
if(!pUartCon->bTxPolling )
{
printf("\n\nSelect Interrupt Type\n 0. pulse 1. Level[D]\n Choose : ");
pUartCon->cTxIntType = (GetIntNum() == 0)?0:1;//0: pulse, 1: level
}
}
printf("\n\nSelect Operating Mode(Rx)\n");
printf("0. Disable 1. Polling or Interrupt[D] 2. DMA rx reqeust:0 3. DMA rx reqeust:1 \n Choose : \n");
iNum = GetIntNum();
if (iNum == 2) pUartCon->cRxMode = 2; // DMA0 mode
else if (iNum == 3) pUartCon->cRxMode = 3; // DMA1 mode
else if (iNum == 0) pUartCon->cRxMode = 0; // Disable
else
{
pUartCon->cRxMode = 1; // Polling and Int mode
printf("\n\nSelect Rx: 0. Interrupt[D] 1.Polling Mod\n");
pUartCon->bRxPolling = (GetIntNum() == 1)?1:0;//0: interrupt[D] 1: polling.
if(!pUartCon->bRxPolling )
{
printf("\n\nSelect Interrupt Type\n 0. pulse 1. Level[D]\n Choose : ");
pUartCon->cRxIntType = (GetIntNum() == 0)?0:1;//0: pulse, 1: level
}
}
//Dma
if(iNum == 2 || iNum ==3)
{
printf("\n\nSelect Rx DMA mode \n");
printf("0. Demand 1. Handshake[D] : \n Choose : ");
iNum = GetIntNum();
if (iNum == 0) pUartCon->cDmaRxDMD_HS = 0; // demand
else pUartCon->cDmaRxDMD_HS = 1; // handshake
printf("\n\nSelect Transfer unit \n");
printf("0. Single[D] 1. burst(4) : \n Choose : ");
iNum = GetIntNum();
if (iNum == 1) pUartCon->cDmaRxTSZ = 1; // burst
else pUartCon->cDmaRxTSZ = 0; // single
}
printf("\n\nSelect RX Timeout enable \n");
printf("0. Disable[D] 1. Enable : \n Choose : ");
iNum = GetIntNum();
if (iNum == 1) pUartCon->bRXTimeOuten = 1; // enable
else pUartCon->bRXTimeOuten = 0; // disalbe
printf("\n\nSelect RX Error interrupt enable \n");
printf("0. Disable[D] 1. Enable : \n Choose : ");
iNum = GetIntNum();
if (iNum == 1) pUartCon->bRXErrorInten = 1; // enable
else pUartCon->bRXErrorInten = 0; // disalbe
// Select UART FIFO mode
printf("\n\nSelect FIFO Mode 0. no FIFO[D] 1. FIFO mode\n Choose : ");
iNum = GetIntNum();
if ( iNum == 1) pUartCon->fEnableFifo = 1;
else pUartCon->fEnableFifo = 0;
pUartCon->cTxTrig =0; //for not affecting to other bit
pUartCon->cRxTrig =0;
if(pUartCon->fEnableFifo)
{
if(pUartCon->cTxMode != 0)
{
printf("\n\nSelect FIFO Size(Tx[byte])\n 0. Empty 1. 16 2. 32 3. 48[D] \n Choose : ");
iNum = GetIntNum();
pUartCon->cTxTrig = ( (iNum>=0)&&(iNum<4) )? iNum : 3 ;
}
if(pUartCon->cRxMode != 0)
{
printf("\n\nSelect FIFO Size(Rx[byte])\n 0. 1 1. 8 2. 16 3. 32[D] \n Choose : ");
iNum = GetIntNum();
pUartCon->cRxTrig = ( (iNum>=0)&&(iNum<4) )? iNum : 3 ;
}
}
// Select AFC mode enable/disable
printf("\n\nSelect AFC Mode\n 1. Disable[D] 2. Enable\n Choose : ");
if (GetIntNum() == 2)
{
pUartCon->fAfc = 1; // AFC mode enable
printf("Select nRTS trigger level(byte)\n 1. 63[D] 2. 56 3. 48 4. 40 5. 32 6. 24 7. 16 8. 8\n Choose : ");
iNum = GetIntNum();
if ( (iNum>1)&&(iNum<9) ) pUartCon->cRtsTrig = iNum -1;
else pUartCon->cRtsTrig = 0; // default 63 byte
}
else
{
pUartCon->fAfc = 0; // AFC mode disable
}
*bAFC2 = (bool)pUartCon->fAfc;
return testch;
}
static UART_CON UartConPolLp = {115200 ,0,1,0,0, 3,3,0,0,1, 0,1,0,0,0, 0,0,1,1,0, 0,1,0,1,0};
// File Name : Uart_LoopBack
// File Description : Check Uart LoopBack mode
// Input : NONE
// Output : NONE
// Version : 0.1
void Uart_LoopBack(void)
{
int iNum;
unsigned char ch;
unsigned int baudrate;
volatile UART_REGS *pUartRegs;
char* pTestLBString="ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567890->UART Tx LoopBack test is good!!!\r";
printf("Which channel do you want to check?\n");
printf("[0 ~ 3] : [0-default]");
ch = GetIntNum();
if(ch>3) ch =0;//default.
printf("%d\n", ch);
pUartRegs = ( UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch);
pUartRxStr[ch]=(char *)(UART_BUF+0x200000);
//RxBufferClear();
pUartTxStr[ch] = pTestLBString;
printf("press baudrate : default 115200\n");
iNum = GetIntNum();
baudrate = (iNum>0)? iNum : 115200;
UART_assignUartCon(ch, &UartConPolLp);
UART_SelectOpClock(3);//epll
UartOpen(ch,1,0);
Delay(1000);
isTxDone[ch]=1;
isRxDone[ch]=1;
while(isTxDone[ch]|isRxDone[ch])
{
if(isTxDone[ch])
{
if(pUartRegs->rUtrStat&0x4)
{
pUartRegs->rUtxh = *pUartTxStr[ch];
if(*pUartTxStr[ch] == '\r') isTxDone[ch] = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -