📄 uart0.c
字号:
#include <string.h>
#include <stdlib.h>
#include "24a0addr.h"
#include "24a0lib.h"
#include "def.h"
#include "uart0.h"
#include "uart1.h"
void Uart_Port_Set(void);
void Uart_Port_Return(void);
//void Ch11_UART(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);
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;
volatile U32 save_rGPCON_U,save_rGPDAT,save_rGPUP; //edited by junon
volatile U32 save_ULCON0,save_UCON0,save_UFCON0,save_UMCON0;
volatile U32 save_ULCON1,save_UCON1,save_UFCON1,save_UMCON1;
volatile static char *uart0TxStr;
volatile static char *uart0RxStr;
void * Uart0_func[][2]=
{
(void *)Test_Uart0_Int, "UART0 Rx/Tx INT ",
(void *)Test_Uart0_Dma, "UART0 Rx/Tx DMA ",
(void *)Test_Uart0_Fifo, "UART0 Rx/Tx FIFO ",
(void *)Test_Uart0_AfcTx, "UART0 AFC Tx ",
(void *)Test_Uart0_AfcRx, "UART0 AFC Rx ",
(void *)Test_Uart0_RxErr, "Uart0 Error Test",
0,0
};
void * Uart1_func[][2]=
{
(void *)Test_Uart1_Int, "UART1 Rx/Tx INT ",
(void *)Test_Uart1_Dma, "UART1 Rx/Tx DMA ",
(void *)Test_Uart1_Fifo, "UART1 Rx/Tx FIFO ",
(void *)Test_Uart1_AfcTx, "UART1 AFC Tx ",
(void *)Test_Uart1_AfcRx, "UART1 AFC Rx ",
(void *)Test_Uart1_RxErr, "Uart1 Error Test ",
(void *)Test_Uart1_SIR_Tx, "SIR Tx ",
(void *)Test_Uart1_SIR_Rx, "SIR Rx ",
0,0
};
void Ch11_UART(void)
{
int j;
Uart_Printf("Select the Uart Port\n");
Uart_Printf("0.Uart0 test 1.Uart1 test\n");
j=Uart_Getch();
switch(j)
{
case '0':
while(1)
{
int i = 0;
while(1)
{ //display menu
Uart_Printf("%2d:%s ",i,Uart0_func[i][1]);
i++;
if((int)(Uart0_func[i][0])==0)
{
Uart_Printf("\n");
break;
}
if((i%4)==0)
Uart_Printf("\n");
}
Uart_Printf("\nSelect the function to test : ");
i = Uart_GetIntNum();
Uart_Printf("\n");
if(i==-1) break;
if(i>=0 && (i<(sizeof(Uart0_func)/8)) )
( (void (*)(void)) (Uart0_func[i][0]) )();
}
break;
case '1':
while(1)
{
int i = 0;
while(1)
{ //display menu
Uart_Printf("%2d:%s ",i,Uart1_func[i][1]);
i++;
if((int)(Uart1_func[i][0])==0)
{
Uart_Printf("\n");
break;
}
if((i%4)==0)
Uart_Printf("\n");
}
Uart_Printf("\nSelect the function to test : ");
i = Uart_GetIntNum();
Uart_Printf("\n");
if(i==-1) break;
if(i>=0 && (i<(sizeof(Uart1_func)/8)) )
( (void (*)(void)) (Uart1_func[i][0]) )();
}
break;
default:
break;
}
}
void Uart_Port_Set(void)
{
//edited by junon
//Push UART GPIO port configuration
save_rGPCON_U=rGPCON_U;
save_rGPDAT=rGPDAT;
save_rGPUP=rGPPU;
//Configure UART port for 24A0
rGPCON_U|=(2<<24)|(2<<22)|(2<<20)|(2<<18); // RxD1, TxD1, RTS1, CTS1 port select
rGPCON_U&=~((1<<24)|(1<<22)|(1<<20)|(1<<18)); // RxD1, TxD1, RTS1, CTS1 port select
rGPPU|=(0xf<<28); //Uart port pull-up disable
//rINTSUBMSK=0x7ff; //SUBINT ALL MASK
//end junon
//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;
}
void Uart_Port_Return(void)
{
//Pop UART GPIO port configuration
rGPCON_U=save_rGPCON_U;
rGPDAT=save_rGPDAT;
rGPPU=save_rGPUP;
//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;
}
void Uart_Uclk_En(int ch,int baud)
{
//int ch, baud;
Uart_Printf("\nSelect UART channel[0:UART0/1:UART1/2:UART2]:\n");
ch=Uart_GetIntNum();
Uart_Printf("\nSelect baud rate :");
baud=Uart_GetIntNum();
if(ch == 0) {
Uart_Select(0);
rUCON0|=0x400; // Select UCLK
rUBRDIV0=( (int)(UCLK/16./baud) -1 ); //Baud rate divisior register
Uart_Printf("UCLK is enabled by UART0.\n");
}
else if(ch==1){
Uart_Select(1);
rUCON1|=0x400; // Select UCLK
rUBRDIV1=( (int)(UCLK/16./baud) -1 ); //Baud rate divisior register
Uart_Select(0);
Uart_Printf("UCLK is enabled by UART1.\n");
}
//for(i=0;i<100;i++); // For the satble operation
}
void Uart_Pclk_En(int ch, int baud)
{
/*
int ch, baud;
Uart_Printf("\nSelect UART channel[0:UART0/1:UART1/2:UART2]:\n");
ch=Uart_GetIntNum();
Uart_Printf("\nSelect baud rate :\n");
baud=Uart_GetIntNum();
*/
if(ch == 0) {
Uart_Select(0);
rUCON0&=0x3ff; // Select PCLK
rUBRDIV0=( (int)(PCLK/16./baud) -1 ); //Baud rate divisior register
Uart_Printf("PCLK is enabled by UART0.\n");
}
else if(ch==1){
Uart_Select(1);
rUCON1|=0x3ff; // Select PCLK
rUBRDIV1=( (int)(PCLK/16./baud) -1 ); //Baud rate divisior register
Uart_Select(0);
Uart_Printf("PCLK is enabled by UART1.\n");
}
//for(i=0;i<100;i++); // For the satble operation
}
//---------------------------------------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)
{
/*
int cnt;
cnt = rUFSTAT0&0x3f;
Uart_Printf("RxFIFO is %d\n", cnt);
Uart_Select(1);
*/
if(RdURXH0()!='\r')
{
Uart_Printf("%c",RdURXH0());
*uart0RxStr++ =(char)RdURXH0();
}
else
{
isRxInt=0;
*uart0RxStr='\0';
Uart_Printf("\n");
}
// Uart_Select(0);
}
void __sub_Uart0_RxErrInt(void)
{
U8 status;
Uart_Select(1);
Uart_Printf("Enter Error interrupt service routine\n");
status = rUERSTAT0; //to clear and check the status of register bits
Uart_Printf(" UERSTAT0 = 0x%x\n", status);
switch(status)
{
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 8:
Uart_Printf("Breake detect\n");
break;
default :
break;
}
Uart_Select(0);
isRxInt=0;
}
void Test_Uart0_Int(void)
{
U8 ch;
Uart_Port_Set();
Uart_Select(0);
// edited by junon start
/******** For operating clock test *********/
Uart_Printf("[Uart channel 0 Interrupt test]\n");
Uart_Printf("Select operating clock 1. PCLK 2. UCLK \nChoose : ");
ch = Uart_Getch();
if (ch == '2')
{
Uart_Uclk_En(0, 115200);
// Timer1 - PCLK/2 setting : connect UCLK input pin & TOUT1 output pin..
rTCFG0 &= ~(0xff); // prescaler0 = 0
rTCFG1 &= ~(0xf<<4); // MUX input of timer1 = 1/2
rTCNTB1 = 0;
rTCMPB1 = 0; // duty 50% clock
rTCON |= (1<<8); // Timer start
}
else
Uart_Pclk_En(0, 115200);
/*********** UART0 Tx test with interrupt ***********/
isTxInt=1;
uart0TxStr="ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890->UART0 Tx interrupt test is good!!!!\r\n";
Uart_Printf("\n[Uart channel 0 Tx Interrupt Test]\n");
pISR_UART0=(unsigned)Uart0_TxInt;
rUFCON0 &= ~(1); // FIFO disable
rULCON0=(0<<6)|(0<<3)|(0<<2)|(3); // Normal,No parity,one stop bit, 8bit
rUCON0 &= 0x400; // For the PCLK <-> UCLK fuction
rUCON0 |= (TX_INTTYPE<<9)|(RX_INTTYPE<<8)|(0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1);
//Clock,Tx:Def,Rx:Def,Rx timeout:x,Rx error int:x,Loop-back:x,Send break:x,Tx:int,Rx:int
Uart_TxEmpty(0); //wait until tx buffer is empty.
rINTMSK=~(BIT_UART0);
rINTSUBMSK=~(BIT_SUB_TXD0);
while(isTxInt);
/*********** UART0 Rx test with interrupt ***********/
isRxInt=1;
uart0RxStr=(char *)UARTBUFFER;
Uart_Printf("\n[Uart channel 0 Rx Interrupt Test]:\n");
Uart_Printf("After typing ENTER key, you will see the characters which was typed by you.");
Uart_Printf("\nTo quit, press ENTER key.!!!\n");
Uart_TxEmpty(0); //wait until tx buffer is empty.
pISR_UART0 =(unsigned)Uart0_RxIntOrErr;
rULCON0=(0<<6)|(0<<3)|(0<<2)|(3); // Normal,No parity,one stop bit, 8bit
rUCON0 &= 0x400; // For the PCLK <-> UCLK fuction
rUCON0 |= (TX_INTTYPE<<9)|(RX_INTTYPE<<8)|(0<<7)|(1<<6)|(0<<5)|(0<<4)|(1<<2)|(1);
//Clock,Tx:pulse,Rx:pulse,Rx timeout:x,Rx error int:o,Loop-back:x,Send break:x,Tx:int,Rx:int
// Clear Int Pending and Unmask
ClearPending(BIT_UART0);
rINTMSK=~(BIT_UART0);
rSUBSRCPND=(BIT_SUB_TXD0|BIT_SUB_RXD0|BIT_SUB_ERR0);
rINTSUBMSK=~(BIT_SUB_RXD0|BIT_SUB_ERR0);
while(isRxInt);
rINTSUBMSK|=(BIT_SUB_RXD0|BIT_SUB_ERR0);
rINTMSK|=(BIT_UART0);
Uart_Printf("%s\n",(char *)UARTBUFFER);
//Uart_Port_Return();
}
void __irq Uart0_TxDmaDone(void)
{
rDMASKTRIG0=0x0; // Stop Dma0
isDone=0;
// edited by junon
rINTSUBMSK|=(BIT_SUB_DMA0);
rSUBSRCPND=(BIT_SUB_DMA0); // clear sub source pending bit
rINTMSK |= BIT_DMA;
ClearPending(BIT_DMA);
// end junon
}
void __irq Uart0_RxDmaOrErr(void)
{
rINTSUBMSK|=(BIT_SUB_RXD0|BIT_SUB_TXD0|BIT_SUB_ERR0);
if(rSUBSRCPND&BIT_SUB_ERR0) Uart_Printf("Error : UART0 Rx Interrupt is occured!!!\n");
else __sub_Uart0_RxErrInt();
ClearPending(BIT_UART0);
rSUBSRCPND=(BIT_SUB_ERR0); // Clear Sub int pending
rINTSUBMSK&=~(BIT_SUB_ERR0);
}
void __irq Uart0_RxDmaDone(void)
{
rDMASKTRIG0=0x0; //DMA0 Channel Off
isDone=0;
*(uart0RxStr+5)='\0';
// edited by junon
rINTSUBMSK|=(BIT_SUB_DMA0);
rSUBSRCPND=(BIT_SUB_DMA0);
rINTMSK|=(BIT_DMA);
ClearPending(BIT_DMA);
// end junon
}
void Test_Uart0_Dma(void)
{
Uart_Port_Set();
Uart_Select(0);
/*********** UART0 Tx test with DMA0 ***********/
isDone=1;
uart0TxStr="ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890->UART0 Tx Test by DMA0 is good!!!!\r\n";
Uart_Printf("\n[Uart channel 0 DMA0 Tx Test]\n");
Uart_TxEmpty(0);
pISR_DMA=(unsigned)Uart0_TxDmaDone;
rULCON0=(0<<6)|(0<<3)|(0<<2)|(3); // Normal,No parity,One stop bit, 8bit
rUCON0 &= 0x400; // For the PCLK <-> UCLK fuction
rUCON0 |= (TX_INTTYPE<<9)|(RX_INTTYPE<<8)|(0<<7)|(0<<6)|(0<<5)|(0<<4)|(2<<2)|(0);
//Clock,Tx:Def,Rx:Def,Rx timeout:x,Rx error int:x,Loop-back:x,Send break:x,Tx:dma0,Rx:x
/***DMA0 init***/
rDISRC0=(U32)uart0TxStr; // Start address
rDISRCC0=(0<<1)|(0); // AHB,Increment
rDIDST0=(U32)UTXH0; // Memory buffer Address
rDIDSTC0=(1<<1)|(1); // APB,Fixed
rDCON0=(1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(1<<24)|(1<<23)|(1<<22)|(0<<20)|strlen((char*)uart0TxStr);
//handshake, sync PCLK, TC int, single tx, single service, Uart0, H/W request,auto-reload off, Byte size Tx, Tx count value
rINTMSK=~(BIT_DMA);
rINTSUBMSK=~(BIT_SUB_DMA0); // added by junon
rDMASKTRIG0=(0<<2)|(1<<1)|(0); //no-stop, DMA0 channel on, no-SW trigger
while(isDone);
/*********** UART0 Rx test with DMA0 ***********/
isDone=1;
uart0RxStr=(char *)UARTBUFFER;
Uart_Printf("\n[Uart channel 0 DMA0 Rx Test]\n");
Uart_Printf("Type any five keys!!!\n");
Uart_Printf("Then you will see what you typed.\n");
pISR_DMA=(unsigned)Uart0_RxDmaDone;
pISR_UART0=(unsigned)Uart0_RxDmaOrErr;
rULCON0=(0<<6)|(0<<3)|(0<<2)|(3); // Normal,No parity,One stop bit, 8bit
rUCON0 &= 0x400; // For the PCLK <-> UCLK fuction
rUCON0 |= (TX_INTTYPE<<9)|(RX_INTTYPE<<8)|(0<<7)|(1<<6)|(0<<5)|(0<<4)|(1<<2)|(2);
//Clock,Tx:Def,Rx:Def,Rx timeout:x,Rx error int:o,Loop-back:x,Send break:x,Tx:int,Rx:dma0
/***DMA0 init***/
rDISRC0=(U32)URXH0; // Start address
rDISRCC0=(1<<1)|(1); // APB,Fixed
rDIDST0=(U32)uart0RxStr; // Memory buffer Address
rDIDSTC0= (0<<1)|(0); // AHB,Increment
rDCON0=(1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(1<<24)|(1<<23)|(1<<22)|(0<<20)|(5);
//handshake, sync PCLK, TC int, single tx, single service, Uart0, H/W request,auto-reload off, Byte size Tx, Tx count value
// edited by junon
// Clear Int Pending and Unmask
ClearPending(BIT_UART0);
rINTMSK=~(BIT_DMA|BIT_UART0);
rSUBSRCPND=(BIT_SUB_TXD0|BIT_SUB_RXD0|BIT_SUB_ERR0|BIT_SUB_DMA0);
rINTSUBMSK=~(BIT_SUB_ERR0|BIT_SUB_DMA0);
rDMASKTRIG0=(0<<2)|(1<<1)|(0); //no-stop, DMA0 channel on, no-SW trigger
// end junon
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -