📄 uart0.c
字号:
/*****************************************
NAME: uart0.c
DESC: UART0 test
WWW.YCTEK.COM
*****************************************/
#include <string.h>
#include <stdlib.h>
#include "def.h"
#include "2410addr.h"
#include "2410lib.h"
#include "uart0.h"
void Uart_Port_Set(void);
void Uart_Port_Return(void);
void __irq Uart0_TxInt(void);
void __irq Uart0_RxIntOrErr(void);
void __irq Uart0_TxDmaDone(void);
void __irq Uart0_RxDmaDone(void);
void __irq Uart0_RxDmaOrErr(void);
void __irq Uart0_TxFifo(void);
void __irq Uart0_RxFifoOrErr(void);
void __irq Uart0_AfcTx(void);
void __irq Uart0_AfcRxOrErr(void);
void __irq Uart0_RxOverrunErr(void);
void __sub_Uart0_RxInt(void);
void __sub_Uart0_RxFifo(void);
void __sub_Uart0_RxAfc(void);
void __sub_Uart0_RxErrInt(void);
void Uart_Fclkn_Dis(void); // for 2440A
volatile U16 rx_dncs;
volatile U32 rx_point,rx_isdone,rx_filesize,rx_checksum;
volatile U32 isDone,isTxInt,isRxInt,tx_cnt,tx_end,rx_cnt,rx_end,afc_err;
volatile U8 *txdataPt;
volatile U8 *txdataFl;
volatile U8 *rxdataPt;
volatile U8 *rxdataCk;
volatile U32 *dbg_data;
U8 temp_exit;
volatile U32 save_rGPHCON,save_rGPHDAT,save_rGPHUP;
volatile U32 save_ULCON0,save_UCON0,save_UFCON0,save_UMCON0,save_UBRDIV0;
volatile U32 save_ULCON1,save_UCON1,save_UFCON1,save_UMCON1,save_UBRDIV1;
volatile U32 save_ULCON2,save_UCON2,save_UFCON2,save_UMCON2,save_UBRDIV2;
volatile static char *uart0TxStr;
volatile static char *uart0RxStr;
volatile static char *uart2TxStr;
volatile static char *uart2RxStr;
//extern U32 Fclk=200000000, Pclk=50000000;
U32 Fclk=200000000, Pclk=50000000;
void Uart_Port_Set(void)
{
//Push UART GPIO port configuration
save_rGPHCON=rGPHCON;
save_rGPHDAT=rGPHDAT;
save_rGPHUP=rGPHUP;
//Configure UART port
rGPHCON&=0x3c0000;
rGPHCON|=0x2aaaa; // enable all uart channel
rGPHUP|=0x1ff; //Uart port pull-up disable
rGPGCON|=(0xf<<18); // nRTS1, nCTS1
rGPGUP|=(0x3<<9);
//rINTSUBMSK=0x7ff; //SUBINT ALL MASK
//Push Uart control registers
save_ULCON0=rULCON0;
save_UCON0=rUCON0;
save_UFCON0=rUFCON0;
save_UMCON0=rUMCON0;
save_ULCON1=rULCON1;
save_UCON1 =rUCON1;
save_UFCON1=rUFCON1;
save_UMCON1=rUMCON1;
save_ULCON2=rULCON2;
save_UCON2 =rUCON2;
save_UFCON2=rUFCON2;
save_UMCON2=rUMCON2;
save_UBRDIV0=rUBRDIV0;
save_UBRDIV1=rUBRDIV1;
save_UBRDIV2=rUBRDIV2;
//Initialize UART1,2 port
}
void Uart_Port_Return(void)
{
//Pop UART GPIO port configuration
rGPHCON=save_rGPHCON;
rGPHDAT=save_rGPHDAT;
rGPHUP=save_rGPHUP;
//Pop Uart control registers
rULCON0=save_ULCON0;
rUCON0 =save_UCON0;
rUFCON0=save_UFCON0;
rUMCON0=save_UMCON0;
rULCON1=save_ULCON1;
rUCON1 =save_UCON1;
rUFCON1=save_UFCON1;
rUMCON1=save_UMCON1;
rULCON2=save_ULCON2;
rUCON2 =save_UCON2;
rUFCON2=save_UFCON2;
rUMCON2=save_UMCON2;
rUBRDIV0=save_UBRDIV0;
rUBRDIV1=save_UBRDIV1;
rUBRDIV2=save_UBRDIV2;
Uart_Fclkn_Dis();
}
// 2440X usage enable
void Uart_Uextclk_En(int ch,int baud, int clock)
{
if(ch == 0) {
rUCON0 = rUCON0 & ~(1<<11) |(1<<10); // Select UEXTCLK
rUBRDIV0=( (int)(clock/16./baud) -1 ); //Baud rate divisior register
}
else if(ch==1){
rUCON1 = rUCON1 & ~(1<<11) |(1<<10); // Select UEXTCLK
rUBRDIV1=( (int)(clock/16./baud) -1 ); //Baud rate divisior register
}
else {
rUCON2 = rUCON2 & ~(1<<11) |(1<<10); // Select UEXTCLK
rUBRDIV2=( (int)(clock/16./baud) -1 ); //Baud rate divisior register
}
}
//2440X usage enable
void Uart_Pclk_En(int ch, int baud)
{
if(ch == 0) {
rUCON0 &= ~(3<<10); // Select PCLK
rUBRDIV0=( (int)(Pclk/16./baud+0.5) -1 ); //Baud rate divisior register
}
else if(ch==1){
rUCON1 &= ~(3<<10); // Select PCLK
rUBRDIV1=( (int)(Pclk/16./baud+0.5) -1 ); //Baud rate divisior register
}
else {
rUCON2 &= ~(3<<10); // Select PCLK
rUBRDIV2=( (int)(Pclk/16./baud+0.5) -1 ); //Baud rate divisior register
}
}
void Uart_Fclkn_En(int ch, int baud) // for 2440A
{
int clock = PCLK;//Pclk;
Uart_Printf("Current FCLK is %d\n", Fclk);
#if 1
// input clock divider setting.
if ( (Fclk>290000000) && (Fclk<300000000) ) // for 296MHz
{
rUCON0 = (rUCON0 & ~(0xf<<12)) | (0xe<<12); // FCLK divider 14(n=20), for max 921.6kbps
rUCON1 &= ~(0xf<<12); // 0 setting
rUCON2 &= ~(0xf<<12); // 0 setting
clock = Fclk / 20;
Uart_Printf("1 : %d\n", clock);
}
else if ( (Fclk>395000000) && (Fclk<405000000) ) // for 399MHz
{
rUCON1 = (rUCON1 & ~(0xf<<12)) | (0x6<<12); // FCLK divider 6(n=27), for max 921.6kbps
rUCON0 &= ~(0xf<<12); // 0 setting
rUCON2 &= ~(0xf<<12); // 0 setting
clock = Fclk / 27;
Uart_Printf("2 : %d\n", clock);
}
else if ( (Fclk>525000000) && (Fclk<535000000) ) // for 530MHz
{
rUCON1 |= (0xf<<12); // FCLK divider 15(n=36), for max. 921.6kbps
rUCON0 &= ~(0xf<<12); // 0 setting
rUCON2 &= ~(0xf<<12); // 0 setting
clock = Fclk / 36;
Uart_Printf("3 : %d\n", clock);
}
rUCON2 |= (1<<15); // enable FCLK/n
#else
// In 921.6kbps case of following code, Fclk must be 296352000
rUCON0 = rUCON0 & ~(0xf<<12) | (0xe<<12); // FCLK divider 14(n=20), for max 921.6kbps
rUCON1 &= ~(0xf<<12); // 0 setting
rUCON2 &= ~(0xf<<12); // 0 setting
clock = Fclk / 20;
rUCON2 |= (1<<15); // enable FCLK/n
#endif
// select buadrate.
if(ch == 0) {
rUCON0 |= (3<<10); // Select FCLK/n
rUBRDIV0=( (int)(clock/16./baud+0.5) -1 ); //Baud rate divisior register
}
else if(ch==1){
rUCON1 |= (3<<10); // Select FCLK/n
rUBRDIV1=( (int)(clock/16./baud+0.5) -1 ); //Baud rate divisior register
}
else {
rUCON2 |= (3<<10); // Select FCLK/n
rUBRDIV2=( (int)(clock/16./baud+0.5) -1 ); //Baud rate divisior register
}
// S/W work-around for using FCLK/n
rGPHCON = rGPHCON & ~(3<<16); //GPH8(UEXTCLK) input
Delay(1);
rGPHCON = rGPHCON & ~(3<<16) | (1<<17); //GPH8(UEXTCLK) UEXTCLK
}
void Uart_Fclkn_Dis(void) // for 2440A
{
// S/W work-around for using FCLK/n
rGPHCON = rGPHCON & ~(3<<16); //GPH8(UEXTCLK) input
Delay(1);
rGPHCON = rGPHCON & ~(3<<16) | (1<<17); //GPH8(UEXTCLK) UEXTCLK
}
//---------------------------------------UART0 test function-------------------------------------
void __irq Uart0_TxInt(void)
{
rINTSUBMSK|=(BIT_SUB_RXD0|BIT_SUB_TXD0|BIT_SUB_ERR0); // Just for the safety
if(*uart0TxStr != '\0')
{
WrUTXH0(*uart0TxStr++);
ClearPending(BIT_UART0); // Clear master pending
rSUBSRCPND=(BIT_SUB_TXD0); // Clear Sub int pending
rINTSUBMSK&=~(BIT_SUB_TXD0); // Unmask sub int
}
else
{
isTxInt=0;
ClearPending(BIT_UART0); // Clear master pending
rSUBSRCPND=(BIT_SUB_TXD0); // Clear Sub int pending
rINTMSK|=(BIT_UART0);
}
}
void __irq Uart0_RxIntOrErr(void)
{
rINTSUBMSK|=(BIT_SUB_RXD0|BIT_SUB_TXD0|BIT_SUB_ERR0);
if(rSUBSRCPND&BIT_SUB_RXD0) __sub_Uart0_RxInt();
else __sub_Uart0_RxErrInt();
ClearPending(BIT_UART0);
rSUBSRCPND=(BIT_SUB_RXD0|BIT_SUB_ERR0); // Clear Sub int pending
rINTSUBMSK&=~(BIT_SUB_RXD0|BIT_SUB_ERR0);
}
void __sub_Uart0_RxInt(void)
{
if(RdURXH0()!='\r')
{
Uart_Printf("%c",RdURXH0());
*uart0RxStr++ =(char)RdURXH0();
}
else
{
isRxInt=0;
*uart0RxStr='\0';
Uart_Printf("\n");
}
}
void __sub_Uart0_RxErrInt(void)
{
U32 iStatus;
iStatus = rUERSTAT0;
switch(iStatus)//to clear and check the status of register bits
{
case 1:
Uart_Printf("Overrun error!\n");
break;
case 2:
Uart_Printf("Parity error!\n");
break;
case 4:
Uart_Printf("Frame error!\n");
break;
case 6:
Uart_Printf("Parity, Frame error!\n");
break;
case 8:
Uart_Printf("Breake detect\n");
break;
case 0xa:
Uart_Printf("Parity error & Break detect!\n");
break;
case 0xc:
Uart_Printf("Frame error & Breake detect\n");
break;
case 0xe:
Uart_Printf("Parity, Frame error & Break detect!\n");
break;
default :
Uart_Printf("Unknown error : 0x%x\n", iStatus);
break;
}
isRxInt=0;
}
void Test_Uart0_Int(void)
{
U8 ch;
int iBaud;
Uart_Printf("Change serial cable to UART0,then press any key to continue......\n");
Uart_Port_Set();
// Uart_Select(1);
// Uart_Printf("\nConnect PC[COM1 or COM2] and UART0 of SMDK2440 with a serial cable!!! \n");
// Uart_Printf("Then, press any key........\n");
Uart_Select(0);
Uart_Getch();
/******** For operating clock test *********/
#if 0
Uart_Printf("[Uart channel 0 Interrupt test]\n");
Uart_Printf("Select operating clock 1. PCLK(D) 2. UCLK 3. FCLK/n \nChoose : ");
ch = Uart_Getch();
switch (ch)
{
case '2' :
rMISCCR = rMISCCR & ~(7<<8) | (1<<10); // CLKOUT1 = PCLK
Uart_Uextclk_En(0, 115200, Pclk);
break;
case '3' :
Uart_Printf("Type the baudrate and then change the same baudrate of host, too.\n");
Uart_Printf("Baudrate (ex 9600, 115200[D], 921600) : ");
iBaud = Uart_GetIntNum();
if (iBaud == -1) iBaud = 115200;
Uart_Fclkn_En(0, iBaud);
Uart_Getch();
break;
default :
Uart_Pclk_En(0, 115200);
}
#endif
Uart_Pclk_En(0, 115200);
#if 0
/******** Select UART or IrDA *********/
Uart_Printf("Select 1. UART(D) or 2. IrDA mode\nChoose : ");
if (Uart_Getch() == '2')
rULCON0 |= (1<<6); // IrDA mode
else
rULCON0 &= ~(1<<6); // UART mode
#endif
#if 0
/*********** UART0 Tx test with interrupt ***********/
isTxInt=1;
uart0TxStr="ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890->UART0 Tx interrupt test is good!!!!\r\n";
Uart_Printf("[Uart channel 0 Tx Interrupt Test]\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -