📄 uart.c
字号:
//Description : The description of Function Pointer sholud be under 15 characters
#include "system.h"
#include "Uart.h"
#define UART0_REG ( UART_REGS *)UART_REG_BASE // Uart 0 register base address
#define UART1_REG ( UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET)
#define UART2_REG ( UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*2)
#define UART3_REG ( UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*3)
#define UART_BUF (_NONCACHE_STARTADDRESS + 0x10000)
#define FIFO_DEBUG_BUF (_NONCACHE_STARTADDRESS + 0x11000)
#define TX_FIFO_RESET (1<<2)
#define RX_FIFO_RESET (1<<1)
#define TX_INT_TYPE(Bit) ((Bit)<<9) // 0:pulse 1:level
#define RX_INT_TYPE(Bit) ((Bit)<<8) // 0:pulse 1:level
#define RX_TIMEOUT_EN (0<<7) // 0:disable 1:enable, disable for FIFO test
#define RX_ERR_INT_EN (1<<6) // 0:disable 1:enable
#define RTS_ACTIVE (1) // In normal mode, nRTS signal 0:low, 1:High
//2460 -> 2443 porting
#define BIT_UART_ERROR (1<<2)
#define BIT_UART_TXD (1<<1)
#define BIT_UART_RXD (1)
#define BIT_UART (1<<SRCPNDOFFSET)
#define SENDBREAK 0x99
//--------------------------------------------------------------
#define INT_MODE 0
#define DMA_MODE 1
#define DMA_BUF_LEN 8 // for rx
#define TX_END_CHAR NULL
#define RX_END_CHAR '\r'
//Debugging Only
#define STOPHERE while(1)
#define Msg(message) if(1)printf(message)
#define SetBitFReg(rReg, uLenOfBit, uVal, uShiftWidth) rReg = ((rReg & ~((0xFFFFFFFF >>(32-uLenOfBit) ) << uShiftWidth)) | (uVal <<uShiftWidth))
#define PrintBits(strB, a) printf("\n[%s : 0x%x]\n31 27 23 19 15 11 07 03 ", strB, (a));\
printf("\n| | | | | | | | ");\
printf("\n%s%s%s%s%s%s%s%s",\
BitTable[((a) & 0xF0000000)>>28], BitTable[((a) & 0xF000000)>>24],BitTable[((a) & 0xF00000)>>20],\
BitTable[((a) & 0xF0000)>>16],BitTable[((a) & 0xF000)>>12],BitTable[((a) & 0xF00)>>8],\
BitTable[((a) & 0xF0)>>4], BitTable[((a) & 0xF)])
char BitTable[16][10] = {
"0000 ",
"0001 ",
"0010 ",
"0011 ",
"0100 ",
"0101 ",
"0110 ",
"0111 ",
"1000 ",
"1001 ",
"1010 ",
"1011 ",
"1100 ",
"1101 ",
"1110 ",
"1111 "
};
//-->Debugging Only
#define TRUE 1
#define FALSE 0
#define BOOL unsigned int
BOOL g_bIsLevelInt = TRUE; //TRUE : Level Type , FALSE : Pulse Type
typedef struct tag_UART_CON
{
unsigned int iBaudrate;
unsigned char fSelUartIrda; // Uart mode
unsigned char fLoopTest; // UCON[5] (0 : normal, 1 : LoopBack)
unsigned char fAfc;
unsigned char fEnableFifo;
unsigned char cOpClock; // 0,2:PCLK, 1:UEXTCLK, 2:EPLL
unsigned char cDataBit; // 0:5bit, 1:6bit, 2:7bit, 3:8bit
unsigned char cParityBit; // 0:no parity, 1:odd, 2:even, 3:forced 1, 4:forced 0
unsigned char cStopBit; // 0:one stopbit, 1:two stopbit
unsigned char cTxMode; // 0:disable, 1:interrupt or polling, 2:DMA0, 3:DMA1
unsigned char cTxTrig; // 0:empty, 1:16, 2:32, 3:48 (byte)
unsigned char cRxMode; // 0:disable, 1:interrupt or polling, 2:DMA0, 3:DMA1
unsigned char cRxTrig; // 0:1, 1:8, 2:16, 3:32 (byte)
unsigned char cRtsTrig; // 0:63, 1:56, 2:48, ... , 7:8 (byte)
unsigned char cSendBreakSignal; // ULCON[4] (0 : normal, 1 : Send Break Signal)
} UART_CON;
void SetUartPort(void);
void ReturnUartPort(void);
void CalcBaudrate( UART_REGS *, UART_CON *);
int InitializeUart( UART_REGS *, UART_CON *); // initialize with current setting
void UartSubIsr(unsigned char );
void __irq UartIsr0(void);
void __irq UartIsr1(void);
void __irq UartIsr2(void);
void __irq UartIsr3(void);
void __irq DmaIsr(void);
unsigned char SetBaudrate(unsigned char ch, unsigned int Baudrate);
unsigned char SetOpClock(unsigned char ch, unsigned int OpClock);
unsigned char SetLineCon(unsigned char ch, unsigned char DataBit, unsigned char StopBit, unsigned char ParityBit);
unsigned char SetDbgUart(unsigned char ch); // set registers with debug setting
unsigned char UartOpen(unsigned char ch, unsigned int SetIRQ);
unsigned char UartClose(unsigned char ch);
void TestUart(void);
void UartTx(void);
void UartRx(void);
static unsigned int save_rGPHCON;//, save_rGPHPU, save_rSPCON; // for setting Uart Port
static UART_CON UartCon[5] = {{115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0}
, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0}
, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0}
, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0}
, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0}};
// control property per each channel. 4th data is defualt value for initialize
const unsigned int nSlotTable[16] = {0x0000, 0x0080, 0x0808, 0x0888, 0x2222, 0x4924, 0x4a52, 0x54aa,
0x5555, 0xd555, 0xd5d5, 0xddd5, 0xdddd, 0xdfdd, 0xdfdf, 0xffdf};
U32 SRCPNDOFFSET;
U32 SUBINTOFFSET;
volatile unsigned int UextClk = 12000000;
volatile unsigned int EpllClk = 12000000;
static volatile unsigned char isTxDone[4] = {0, 0, 0, 0};
static volatile unsigned char isRxDone[4] = {0, 0, 0, 0};
char *pUartTxStr[4], *pUartRxStr[4];
// buffer for test
char TestString[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890->UART Tx interrupt test is good!!!!\r";
//char TestString[]="UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU!!!!\r"; //Test string for Toggling Value on the oscilloscope
volatile unsigned int *pFifoDebug = (unsigned int *)FIFO_DEBUG_BUF; //temporary for fifo count test
volatile unsigned int fcnt = 0;
void * func_uart_test[][2]=
{
(void *)TestUart, "UART Test ",
0,0
};
void Test_UART(void)
{
int i;
printf("\n====== UART Test program start ======\n");
while(1)
{
i=0;
printf("\n\n");
while(1)
{ //display menu
printf("%2d:%s",i,func_uart_test[i][1]);
i++;
if((int)(func_uart_test[i][0])==0)
{
printf("\n");
break;
}
if((i%4)==0)
printf("\n");
}
printf("\nPress Enter key to exit : ");
i = GetIntNum();
if(i==-1) break; // return.
if(i>=0 && (i<((sizeof(func_uart_test)-1)/8)) ) // select and execute...
( (void (*)(void)) (func_uart_test[i][0]) )();
}
printf("\n====== UART Test program end ======\n");
}
///////////////////////// Test functions ////////////////////////
unsigned char UartConfig(void)
{
unsigned char ch;
int iNum = 0;
// volatile UART_REGS *pUartRegs;
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] : ");
ch = (unsigned char)GetIntNum();
if ( ch>3 ) ch = 0; // default uart 0
pUartCon = &UartCon[ch];
printf("\n\nConnect PC[COM1 or COM2] and UART%d of SMDK2443 with a serial cable for test!!! \n", ch);
//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 ch;
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 \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
printf("\n\nSelect Operating Clock\n 1. PCLK[D] 2. UEXTCLK 3. EPLL \n Choose : ");
switch (GetIntNum())
{
case 2 :
pUartCon->cOpClock = 1;
// connect CLKOUT and UEXTCLK
rGPHCON = rGPHCON & ~(3<<24) | (1<<25);// Uextclk using
UextClk = PCLK;
break;
case 3 :
pUartCon->cOpClock = 3;
SetEPLL(42, 1, 2); // Epll output - 96MHz, pll input - 12MHz
// use EPLL output clock
rCLKSRC = rCLKSRC & ~(1<<6)|(1<<6); // epll output select
EpllClk = 50000000;
break;
default :
pUartCon->cOpClock = 0; // PCLK
break;
}
// 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) : ");
pUartCon->iBaudrate = GetIntNum();
if ((int)pUartCon->iBaudrate == -1) pUartCon->iBaudrate = 115200;
// Select UART operating mode
printf("\n\nSelect Operating Mode\n 1. Interrupt[D] 2. DMA\n Choose : ");
if (GetIntNum() == 2)
{
pUartCon->cTxMode = 2; // DMA0 mode
pUartCon->cRxMode = 3; // DMA1 mode
}
else
{
pUartCon->cTxMode = 1; // Int mode
pUartCon->cRxMode = 1; // Int mode
}
// Select UART FIFO mode
printf("\n\nSelect FIFO Mode (Tx/Rx[byte])\n 1. no FIFO[D] 2. Empty/1 3. 16/8 4. 32/16 5. 48/32 \n Choose : ");
iNum = GetIntNum();
if ( (iNum>1)&&(iNum<6) )
{
pUartCon->fEnableFifo = 1;
pUartCon->cTxTrig = iNum -2;
pUartCon->cRxTrig = iNum -2;
}
else
{
pUartCon->fEnableFifo = 0;
}
// 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
}
return ch;
}
void TxString(unsigned char ch, char *str) // The last character of 'str' should be NULL
{
volatile UART_REGS *pUartRegs;
volatile UART_CON *pUartCon;
int iTemp;
pUartRegs = (volatile UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch);
pUartCon = &UartCon[ch];
isTxDone[ch] = 0;
pUartTxStr[ch] = str;
pFifoDebug = (unsigned int *)FIFO_DEBUG_BUF;
fcnt = 0;
if(ch == 1){ SUBINTOFFSET = 3; SRCPNDOFFSET = 23;}
else if(ch == 2){ SUBINTOFFSET = 6; SRCPNDOFFSET = 15;}
else if(ch == 3){ SUBINTOFFSET = 24; SRCPNDOFFSET = 18;}
else { SUBINTOFFSET = 0; SRCPNDOFFSET = 28;}// CH 0 default
iTemp = pUartCon->cTxMode & 3;
if ( iTemp == 1 ) // interrupt mode
{
rINTMSK &= ~(BIT_UART);
rINTSUBMSK &= ~(BIT_UART_TXD << SUBINTOFFSET);
}
else if ( (iTemp==2) || (iTemp==3) ) // dma mode
{
rDISRC0 = (unsigned int)str; // Start address
rDISRCC0 = (0<<1)|(0); // AHB,Increment
rDIDST0 = (unsigned int)(&pUartRegs->rUtxh); // Memory buffer Address
rDIDSTC0 = (1<<1)|(1); // APB,Fixed
rDCON0 = (1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(1<<22)|(0<<20)|strlen(str);
//handshake, sync PCLK, TC int, single tx, single service,auto-reload off, Byte size Tx, Tx count value
rDMAREQSEL0 = ((19+ch*2)<<1)|1;
// Clear Int Pending and Unmask
rSUBSRCPND = BIT_SUB_DMA0;
ClearPending(BIT_DMA);
rINTMSK &= ~(BIT_DMA);
rINTSUBMSK &= ~(BIT_SUB_DMA0);
rDMASKTRIG0 = (0<<2)|(1<<1)|(0); //no-stop, DMA0 channel on, no-SW trigger
}
while(!isTxDone[ch]);
rINTMSK |= (BIT_UART);
//rINTMSK |= (BIT_DMA);
rINTSUBMSK |= (BIT_UART_TXD<<SUBINTOFFSET);
}
char* RxString(unsigned char ch) // The last character of input string should be '\r'. simple test code
{
volatile UART_REGS *pUartRegs;
volatile UART_CON *pUartCon;
int iTemp;
pUartRegs = (volatile UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch);
pUartCon = &UartCon[ch];
isRxDone[ch] = 0;
pUartRxStr[ch] = ( char *)(UART_BUF+DMA_BUF_LEN);
pFifoDebug = (unsigned int *)FIFO_DEBUG_BUF;
fcnt = 0;
if(ch == 1){ SUBINTOFFSET = 3; SRCPNDOFFSET = 23;}
else if(ch == 2){ SUBINTOFFSET = 6; SRCPNDOFFSET = 15;}
else if(ch == 3){ SUBINTOFFSET = 24; SRCPNDOFFSET = 18;}
else { SUBINTOFFSET = 0; SRCPNDOFFSET = 28; } // CH 0 default
iTemp = pUartCon->cRxMode & 3;
if ( iTemp == 1 ) // interrupt mode
{
rINTMSK &= ~(BIT_UART);
rINTSUBMSK &= ~ ((BIT_UART_ERROR << SUBINTOFFSET)|(BIT_UART_RXD << SUBINTOFFSET));
}
else if ( (iTemp == 2) || (iTemp == 3) ) // dma mode
{
printf("\nIn DMA rxstring mode");
rDISRC1=(unsigned int)(&pUartRegs->rUrxh); // Start address
rDISRCC1=(1<<1)|(1); // APB,Fixed
rDIDST1=(unsigned int)(UART_BUF); // Memory buffer Address
rDIDSTC1= (0<<1)|(0); // AHB,Increment
rDCON1=(1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(1<<22)|(0<<20)|(DMA_BUF_LEN);
//handshake, sync PCLK, TC int, single tx, single service,auto-reload off, Byte size Tx, Tx count value
rDMAREQSEL1 = ((20+ch*2)<<1)|1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -