📄 uart.c
字号:
printf("%c", tempChar);
*pUartRxStr[ch]++ = tempChar;
}
else
{
*pUartRxStr[ch] = NULL;
printf("\n");
isRxDone[ch] = 1;
rSUBSRCPND = chBit;
ClearPending(BIT_UART);
return;
}
pUartRegs->rUintM &= ~(BIT_UART_RXD);
}
}
// Modem UART ISR
if (pUartRegs->rUintP & BIT_UART_MODEM)
{
pUartRegs->rUintM |= BIT_UART_MODEM;
pUartRegs->rUintSp = BIT_UART_MODEM;
pUartRegs->rUintP = BIT_UART_MODEM;
// Implementation for modem uart
pUartRegs->rUintM &= ~(BIT_UART_MODEM);
}
// unknown UART interrupt
if (pUartRegs->rUintP & ~(BIT_UART_MODEM|BIT_UART_TXD|BIT_UART_ERROR|BIT_UART_RXD))
printf("UARTx sub INT - unknown sub interrupt!!\n");
rSUBSRCPND = chBit;
ClearPending(BIT_UART);
rINTSUBMSK &= ~chBit;
}
void __irq DmaIsr(void) // only one for test
{
unsigned char ch;
unsigned char* pBuf;
volatile unsigned int i;
rINTMSK |= BIT_DMA_SBUS;
if (rSUBSRCPND&BIT_SUB_DMA0)
{
rDMASKTRIG0=0; // Stop Dma0
rINTSUBMSK |= BIT_SUB_DMA0;
rSUBSRCPND = BIT_SUB_DMA0;
ClearPending(BIT_DMA_SBUS);
ch = ((rDMAREQSEL0>>1) -19)/2;
isTxDone[ch] = 1;
rINTSUBMSK &= ~BIT_SUB_DMA0;
}
if (rSUBSRCPND&BIT_SUB_DMA1)
{
rDMASKTRIG1=0; // Stop Dma1
rINTSUBMSK |= BIT_SUB_DMA1;
rSUBSRCPND = BIT_SUB_DMA1;
ClearPending(BIT_DMA_SBUS);
pBuf = (unsigned char*)UART_BUF;
ch = ((rDMAREQSEL1>>1) -19)/2;
for (i=0; i<DMA_BUF_LEN; i++)
*pUartRxStr[ch]++ = *pBuf++;
if ( *(pUartRxStr[ch]-1) == RX_END_CHAR )
{
isRxDone[ch] = 1;
*pUartRxStr[ch] = NULL; // added null after rx string
}
else
{
rDMASKTRIG1 = (0<<2)|(1<<1)|(0); //no-stop, DMA1 channel on, no-SW trigger
}
rINTSUBMSK &= ~BIT_SUB_DMA1;
}
rINTMSK &= ~BIT_DMA_SBUS;
}
////////////////////// User library functions /////////////////////
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;
}
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;
}
unsigned char SetDbgUart(unsigned char ch)
{
if (ch > 2) return FALSE;
memcpy(&UartCon[ch], &UartCon[3], sizeof(UART_CON));
UartOpen(ch);
return TRUE;
}
unsigned char UartOpen(unsigned char ch) // setting H/W & initializing regiter
{
pISR_UART = (unsigned)UartIsr;
pISR_DMA_SBUS = (unsigned)DmaIsr;
switch(ch)
{
case 0 :
rGPHCON &= ~(0xff); // GPH0~3
rGPHCON |= 0xaa; // Uart 0 Rx, Tx, Rts, Cts
rGPHPU |= 0xf; // pull-up disable
InitializeUart(UART0_REG, &UartCon[0]); // Initialize register set for Uart 0
break;
case 1 :
rGPHCON &= ~(0xff<<8); // GPH4~7
rGPHCON |= (0xaa<<8); // Uart 1 Rx, Tx, Rts, Cts
rGPHPU |= (0xf<<4);
InitializeUart(UART1_REG, &UartCon[1]);
break;
case 2 :
rGPHCON &= ~(0xf<<18); // GPH9~10
rGPHCON |= (0xa<<18); // Uart 2 Rx, Tx
rGPHPU |= (3<<9);
InitializeUart(UART2_REG, &UartCon[2]);
break;
default :
printf("Can't open UARTx!! Select 0,1, or 2!!");
return FALSE;
}
return TRUE;
}
unsigned char UartClose(unsigned char ch) // return to reset value
{
volatile UART_REGS *pUartRegs;
if (ch > 2) return FALSE;
pUartRegs = (volatile UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch);
rINTMSK |= (BIT_UART);
rINTSUBMSK |= (1<<ch);
pUartRegs->rUintM |= (BIT_UART_MODEM|BIT_UART_TXD|BIT_UART_ERROR|BIT_UART_RXD);
rSUBSRCPND = (1<<ch);
ClearPending(BIT_UART);
switch(ch)
{
case 0 :
rGPHCON &= ~(0xff); // GPH0~3
rGPHPU &= ~(0xf); // pull-up disable
break;
case 1 :
rGPHCON &= ~(0xff<<8); // GPH4~7
rGPHPU &= ~(0xf<<4);
break;
case 2 :
rGPHCON &= ~(0xf<<18); // GPH9~10
rGPHPU &= ~(3<<9);
break;
default :
printf("Can't close UARTx!! Select 0,1, or 2!!");
return FALSE;
}
return TRUE;
}
///////////////////////// 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~2) [D=0] : ");
ch = (unsigned char)GetIntNum();
if ( ch>2 )
ch = 0; // default uart 0
pUartCon = &UartCon[ch];
pUartRegs = (volatile UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch);
printf("Select Setting method \n 1. User Setting[D] 2. Use Default Setting(B115200,D8,P0,S1,NC,Int,no FIFO)\n Choose : ");
if (GetIntNum() == 2)
{
memcpy(&UartCon[ch], &UartCon[3], sizeof(UART_CON));
return ch;
}
// Set Operation clock
printf("\nConnect PC[COM1 or COM2] and UART%d of SMDK2460 with a serial cable for test!!! \n", ch);
printf("Select Operating Clock\n 1. PCLK[D] 2. UEXTCLK 3. EPLL \n Choose : ");
switch (GetIntNum())
{
case 2 :
pUartCon->cOpClock = 1;
#if 1 // connect CLKOUT and UEXTCLK
rGPHCON &= ~(3<<16); // Uextclk using
rCLKOUTCON = (4<<12); // clkout = PCLK
rSPCON &= ~(1<<17); // clkout en
UextClk = PCLK;
#else // if you want to use any clock source except the PCLK
printf("\nType External Clock(Hz) [D=PCLK] : ");
UextClk = GetIntNum();
if ((int)UextClk == -1) UextClk = PCLK;
rCLKOUTCON = (5<<12)|(1<<4)|1; // DCLK = PCLK/2
UextClk = PCLK/2;
#endif
break;
case 3 :
pUartCon->cOpClock = 3;
SetEPLL(42, 1, 2); // Epll output - 96MHz, pll input - 12MHz
#if 1 // use EPLL output clock
rCLKSRCCON = rCLKSRCCON&~(1<<10)|(1<<6); // epll output select
EpllClk = 50000000;
#else // use reference clock
rCLKSRCCON |= (1<<10); // crystal input
EpllClk = 12000000;
#endif
printf("rEPLLCON = 0x%x \n", rEPLLCON);
printf("rCLKSRCCON = 0x%x \n", rCLKSRCCON);
printf("rCLKDIVCON = 0x%x \n", rCLKDIVCON);
break;
default :
pUartCon->cOpClock = 0; // PCLK
GlobalCLK();
break;
}
// Select UART or IrDA 1.0
printf("Select 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("Type 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("Select 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("Select 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("Select 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;
iTemp = pUartCon->cTxMode & 3;
if ( iTemp == 1 ) // interrupt mode
{
rINTMSK &= ~(BIT_UART);
rINTSUBMSK &= ~(1<<ch);
pUartRegs->rUintM &= ~(BIT_UART_TXD);
}
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_SBUS);
rINTMSK &= ~(BIT_DMA_SBUS);
rINTSUBMSK &= ~(BIT_SUB_DMA0);
rDMASKTRIG0 = (0<<2)|(1<<1)|(0); //no-stop, DMA0 channel on, no-SW trigger
}
while(!isTxDone[ch]);
// for debugging fifo
if ( (pUartRegs->rUfCon & 1) && (iTemp == 1) ) // 1 : fifo enable
{
pFifoDebug = (unsigned int *)FIFO_DEBUG_BUF;
while(*pFifoDebug) // pFifoDebug address, Tx count, UfCon, fcnt
printf("[0x%x,%d,0x%x,%d] ", pFifoDebug, *pFifoDebug++, *pFifoDebug++,*pFifoDebug++);
}
}
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;
iTemp = pUartCon->cRxMode & 3;
if ( iTemp == 1 ) // interrupt mode
{
pUartRegs->rUintSp = (BIT_UART_MODEM|BIT_UART_TXD|BIT_UART_ERROR|BIT_UART_RXD);
pUartRegs->rUintP = (BIT_UART_MODEM|BIT_UART_TXD|BIT_UART_ERROR|BIT_UART_RXD);
rSUBSRCPND = (1<<ch);
ClearPending(BIT_UART);
rINTMSK &= ~(BIT_UART);
rINTSUBMSK &= ~(1<<ch);
pUartRegs->rUintM &= ~(BIT_UART_ERROR|BIT_UART_RXD);
}
else if ( (iTemp == 2) || (iTemp == 3) ) // dma mode
{
rDISRC1=(unsigned int)(&pUartRegs->rUrxh); // Start address
rDISRCC1=(1<<1)|(1); // APB,Fixed
rDIDST1=(unsigned int)(UART_BUF); // Memory buffer Address
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -