#define IrDA_BUFLEN 0x100
volatile U8 *IrDAdataPt;
volatile U32 IrDA_cnt,IrDA_end,IrDA_err,IrDA_BAUD;
volatile U8 *IrDAdataFl;
#define pISR_UART2 (*(unsigned *)(_ISR_STARTADDRESS+0x5c))
static int whichUart=1;
#define WrUTXH2(ch) (*(volatile unsigned char *)0x50008023)=(unsigned char)(ch)
// Main clock
#if FIN==12000000
#define FCLK 405000000
//#define FCLK 304800000
//#define FCLK 400000000
//#define FCLK 451200000
//#define FCLK 532800000
#if FCLK==271500000
#define HCLK (FCLK/2)
#define PCLK (HCLK/2)
#elif FCLK==304800000
#define HCLK (FCLK/3)
#define PCLK (HCLK/2)
#elif FCLK==405000000
#define HCLK (FCLK/3)
#define PCLK (HCLK/2)
#elif FCLK==451200000
#define HCLK (FCLK/4)
#define PCLK (HCLK/2)
#elif FCLK==532800000
#define HCLK (FCLK/4)
#define PCLK (HCLK/2)
#endif
#else //FIN=16.9344MHz
#define FCLK 296352000
#if FCLK==266716800
#define HCLK (FCLK/2)
#define PCLK (HCLK/2)
#elif FCLK==296352000
#define HCLK (FCLK/3)
#define PCLK (HCLK/2)
#elif FCLK==399651840
#define HCLK (FCLK/3)
#define PCLK (HCLK/2)
#elif FCLK==530611200
#define HCLK (FCLK/4)
#define PCLK (HCLK/2)
#elif FCLK==541900800
#define HCLK (FCLK/4)
#define PCLK (HCLK/2)
#endif
#endif
/////////////////////////////////////////////////////////////////////
void IrDA_Port_Init(void)
{
//Configure IrDA port
(*(volatile unsigned *)0x56000070) &= ~(0xf<<12); //Port H control
(*(volatile unsigned *)0x56000070) |= (0x9<<12); //Port H control GPH6->TXD[2];GPH7->RXD[2]
(*(volatile unsigned *)0x56000078) |= (3<<6); //Uart port pull-up disable
}
void __irq IrDA_TxInt(void)
{
(*(volatile unsigned *)0x4a00001c) = (0x1<<6) | (0x1<<5) | (0x1<<7); //关闭UART2子中断
if(IrDA_cnt < (IrDA_BUFLEN))
{
(*(volatile unsigned char *)0x50008023)=(unsigned char)(*IrDAdataPt); //uart 2 transmission hold
*IrDAdataPt++;
IrDA_cnt++;
(*(volatile unsigned *)0x4a000000) |= (0x1<<15); //Interrupt request status //清除UART2中断
(*(volatile unsigned *)0x4a000010) |= (0x1<<15); //Interrupt request status
(*(volatile unsigned *)0x4a000018) = (0x1<<7); //Sub source pending 清除TXD2子中断
(*(volatile unsigned *)0x4a00001c) &= ~(0x1<<7) //Interrupt sub mask 开TXD2子中断
}
else
{
IrDA_end=1;
volatile unsigned statvalue = (*(volatile unsigned *)0x50008018);
while(statvalue & 0x2f0); //Until FIFO is empty UART 2 FIFO status
while(!((*(volatile unsigned *)0x50008010) & 0x4)); //Until Tx shifter is empty UART 2 Tx/Rx status
(*(volatile unsigned *)0x4a000000) |= (0x1<<15); //Interrupt request status //清除UART2中断
(*(volatile unsigned *)0x4a000010) |= (0x1<<15); //Interrupt request status
(*(volatile unsigned *)0x4a000008) |= (0x1<<15) //Interrupt mask control 关UART2
}
}
//接收数据中断
void IrDA_SUB_RxInt(void)
{
//FIFO中有数据 //UART 2 FIFO status
while( ((*(volatile unsigned *)0x50008018) & 0x100)
|| ((*(volatile unsigned *)0x50008018) & 0xf) )
{
*IrDAdataPt= (*(volatile unsigned char *)0x50008027); //UART 2 Receive buffer
*IrDAdataPt++;
IrDA_cnt++;
if(IrDA_cnt >= IrDA_BUFLEN)
{
IrDA_end=1;
//关UART2
(*(volatile unsigned *)0x4a000008) |= (0x1<<15) ;
}
}
}
char Uart_GetKey(void)
{
if(whichUart==0)
{
if((*(volatile unsigned *)0x50000010) & 0x1) //Receive data ready
return (*(volatile unsigned char *)0x50000027);
else
return 0;
}
else if(whichUart==1)
{
if((*(volatile unsigned *)0x50004010) & 0x1) //Receive data ready //UART 1 Tx/Rx status
return (*(volatile unsigned char *)0x50004027);
else
return 0;
}
else if(whichUart==2)
{
if((*(volatile unsigned *)0x50004010) & 0x1) //Receive data ready
return (*(volatile unsigned char *)0x50008027);
else
return 0;
}
return 0;
}
//红外模块发送测试程序
void Test_IrDA_Tx(void)
{
int i;
IrDA_cnt=0;
IrDA_end=0;
IrDAdataFl=(volatile U8 *)IrDABUFFER;
IrDAdataPt=(volatile U8 *)IrDABUFFER;
IrDA_Port_Init();
for(i=0;i<IRDA_BUFLEN;I++)
(*(unsigned *)(0x33ffff00+0x5c)) = (U32)IrDA_TxInt;
Uart_Printf("\nSelect the baud rate\n"); // Select IrDA baud rate
Uart_Printf("1)9600 2)19200 3)38400 4)57600 5)115200\n");
i=Uart_Getch();
switch(i)
{
case '1':
IrDA_BAUD=9600;
break;
case '2':
IrDA_BAUD=19200;
break;
case '3':
IrDA_BAUD=38400;
break;
case '4':
IrDA_BAUD=57600;
break;
case '5':
IrDA_BAUD=115200;
break;
default:
break;
}
(*(volatile unsigned *)0x50008028) =( (int)(PCLK/16./IrDA_BAUD) -1 ); ////UART 2 Baud rate divisor
Uart_Printf("rUBRDIV2=%d\n", rUBRDIV2);
Uart_Printf("[UART IrDA Rx Test]\n");
Uart_Printf("Press any key to start Rx and then Start Tx....\n");
Uart_Printf("\nSelect the baud rate\n"); // Select IrDA baud rate
Uart_Printf("1)9600 2)19200 3)38400 4)57600 5)115200\n");
i=Uart_Getch();
switch(i)
{
case '1':
IrDA_BAUD=9600;
break;
case '2':
IrDA_BAUD=19200;
break;
case '3':
IrDA_BAUD=38400;
break;
case '4':
IrDA_BAUD=57600;
break;
case '5':
IrDA_BAUD=115200;
break;
default:
break;
}
rUBRDIV2=( (int)(PCLK/16./IrDA_BAUD) -1 );
Uart_Printf("rUBRDIV2=%d\n", rUBRDIV2);
Uart_Printf("[UART IrDA Rx Test]\n");
Uart_Printf("Press any key to start Rx and then Start Tx....\n");
//transmit FIFO=16B; receive FIFO=1B;Tx FIFO reset;Rx FIFO reset;FIFO Enable
(*(volatile unsigned *)0x50008008) = (1<<6)|(0<<4)|(1<<2)|(1<<1)|(1);
//PCLK;Level;Level;Disable Rx time out interrupt;Generate receive error status interrupt.
//Normal operation;Normal transmit;Tx Disable;Rx Disable
(*(volatile unsigned *)0x50008004) =(0<<10)|(1<<9)|(1<<8)|(0<<7)|(1<<6)|(0<<5)|(0<<4)|(0<<2)|(0); // From H/W //UART 2 Control
//Infrared Tx/Rx mode;No parity;One stop bit;8bit
(*(volatile unsigned *)0x50008000) =(1<<6)|(0<<3)|(0<<2)|(3); //UART 2 Line control
Uart_Getch(); //press any KEY
Uart_Printf("Now... Rx with IrDA\n");
(*(volatile unsigned *)0x50008004) |= 1; // Rx enable, Interrupt request or polling mode //UART 2 Control
//开UART2中断及子中断
(*(volatile unsigned *)0x4a000008) &= ~((0x1<<15) ) //Interrupt mask control
(*(volatile unsigned *)0x4a00001c) &= ~((0x1<<6) ) //Interrupt sub mask
(*(volatile unsigned *)0x4a00001c) &= ~((0x1<<8) ) //Interrupt sub mask
//接收结束或者串口输入回车
while(!IrDA_end) if(Uart_GetKey()=='\r') break;
//关UART2子中断 //Interrupt sub mask
(*(volatile unsigned *)0x4a00001c) |=((0x1<<6) |(0x1<<7) |(0x1<<8) );
//transmit FIFO=48B;receive FIFO=32B;Tx FIFO reset;Rx FIFO reset;FIFO disable
(*(volatile unsigned *)0x50008008)=(3<<6)|(2<<4)|(1<<2)|(1<<1)|(0);
Uart_Printf("\nEnd Rx, receive data count=%d\n",IrDA_cnt);
IrDAdataPt =(volatile U8 *)IrDABUFFER;
for(i=0;i<IRDA_BUFLEN;I++)
{
}
}
//接收出错中断处理
void IrDA_SUB_RxErrInt(void)
{
switch((*(volatile unsigned *)0x50008014))//to clear and check the status of register bits //UART 2 Rx error 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;
}
}