⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irda.c

📁 支持三星原产的S3C24A0开发板
💻 C
📖 第 1 页 / 共 2 页
字号:
//===================================================================
// NAME		: irda.c	
// DESC		: ver 1.1 compatible test module
// History	: 2003.06.25 edited by junon jeon from SMDK5410 test code
//          : 2003.10.09 Edited to verify IrDA core.by Minsoo, Lim
//          : 2003.10.31 Edited by Junon (DMA rx)
//===================================================================

#include <string.h>
#include <stdlib.h>
#include "24a0addr.h"
#include "24a0lib.h"
#include "option.h"
#include "def.h"
#include "irda.h"

#define MemoryRx	(_NONCACHE_STARTADDRESS+0x1000)
#define MemoryTx	(_NONCACHE_STARTADDRESS+0x2000)
#define MemoryCk	(_NONCACHE_STARTADDRESS+0x3000)
#define MemoryCk1	(_NONCACHE_STARTADDRESS+0x4000)

#define IrDA_BUFLEN		16		//Maximum about 255
#define IrDA_TxBUFLEN	16		//Maximum about 255
#define IrDA_RxBUFLEN	16		//Maximum about 255

#define IrDA_FIFOSIZE   1		// 0 : 16, 1 : 64 bytes
#define IrDA_FIFOENB	 1		// 1 : Enbale IrDA Tx/Rx FIFO

//====================================================================
// IrDA Contol Register (IrDA_CNT)
// This value only valid MIR mode.
#define	IrDA_TxINTEnb	1	// 1 : Enable Tx Interrupt
#define	IrDA_RxINTEnb	0	// 1 : Enable Rx Interrupt for loop test
#define	IrDA_LOOP_MODE	0	// 0 : Normal, 1 : Loop mode for core test
#define	MIR_HALF_MODE	0	// 0 : MIR,    1 : MIR-Half
#define	IrDA_SEND_SIP	1	// 1 : Send SIP pulse

//====================================================================
// IrDA Mode Definition Register (IrDA_MDR)

// -----------------------
// IrDA Test Configuration
// -----------------------
#define MODE_VALUE		4
// mode
// MODE			FIR|MIR mode
// 100b			FIR mode
// 010b			MIR mode

#define	PREAMBLE_VALUE		0
// number of preembles (FIR mode only)
// PREAMBLE		number of preambles
// 00b			16
// 01b			04
// 10b			08
// 11b			32

#define	STARTFLAG_VALUE		4
// number of start flags (MIR mode only)
// START_FLAG	number of start flags
// minimum value 3 required !!!

#define	RXFL_VALUE		0x1000
// Number of RX data

#define	RXTR_VALUE		1
// RX FIFO trigger level
// 00b			Reserved
// 01b			04|16
// 10b			08|32
// 11b			14|56

#define	TXFL_VALUE		16
// Number of TX data 

#define	TXTR_VALUE		1
// TX FIFO trigger level
// 00b			Reserved
// 01b			12|48
// 10b			08|32
// 11b			02|08

volatile int IrDA_DONE, IrDA_TxDone, IrDA_RxDone, IrDA_RxCount;
volatile int	IrDA_RxWrPnt, IrDA_RxRdPnt;
unsigned int IrDA_rGPCON,IrDA_rGPUP;
volatile unsigned char * IrDA_RXBUFFER;
volatile unsigned char * IrDA_TXBUFFER;
volatile unsigned char * IrDA_CKBUFFER;
volatile unsigned char * IrDA_CKBUFFER1;

unsigned char cData=0;
volatile int	IrDA_TxNum, IrDA_TxCnt;
volatile int RxISR_cnt,TxISR_cnt;

unsigned char *bHead, *bTail;

void * IrDA_func[][2]=
{
	(void *)Test_IrDA_Fifo_Rx,		"IrDA FIFO Rx",
	(void *)Test_IrDA_Fifo_Tx,		"IrDA FIFO Tx",
	0,0
};

void Ch12_IrDA(void)
{
	while(1)
	{
		int i = 0;
  
		while(1)
		{	//display menu
			Uart_Printf("%2d:%s",i,IrDA_func[i][1]);
			i++;
			if((int)(IrDA_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(IrDA_func)/8)) ) 
		( (void (*)(void)) (IrDA_func[i][0]) )();			
	}
}

void Test_IrDA_Fifo_Rx(void)
{
	IrDA_Port_Init();

	Uart_Printf("IrDA Interrupt Rx Test\n");
	Uart_Printf("Select control mode : 1. Interrupt(D)    2. DMA\n");

	if (Uart_Getch() == '2')
		Test_Irda_Fifo_Dma_Rx(MODE_VALUE, PREAMBLE_VALUE, STARTFLAG_VALUE, RXFL_VALUE, RXTR_VALUE);
	else
		Test_Irda_Fifo_Int_Rx(MODE_VALUE, PREAMBLE_VALUE, STARTFLAG_VALUE, RXFL_VALUE, RXTR_VALUE);

	IrDA_Port_Return();
}

void Test_IrDA_Fifo_Tx(void)
{
	IrDA_Port_Init();

	Uart_Printf("IrDA Interrupt Tx Test\n");
	Uart_Printf("Select control mode : 1. Interrupt(D)    2. DMA\n");

	if (Uart_Getch() == '2')
		Test_Irda_Fifo_Dma_Tx(MODE_VALUE, PREAMBLE_VALUE, STARTFLAG_VALUE, TXFL_VALUE, TXTR_VALUE);
	else
		Test_Irda_Fifo_Int_Tx(MODE_VALUE, PREAMBLE_VALUE, STARTFLAG_VALUE, TXFL_VALUE, TXTR_VALUE);

	IrDA_Port_Return();
}

void IrDA_Port_Init(void)
{
    IrDA_rGPCON=rGPCON_U;
    IrDA_rGPUP=rGPPU;
    rGPCON_U |= (3<<24)|(3<<22)|(3<<20); // Set IrDA_TXD, IrDA_RXD, IrDA_SDBW
    rGPPU |= (7<<29); // Disable IrDA pullup
    Uart_Printf("IrDA Initialize is done!!!\n");
}

void IrDA_Port_Return(void)
{
    rGPCON_M=IrDA_rGPCON;
    rGPPU=IrDA_rGPUP;
}

U8	Init_Irda(int MODE, int PREAMBLE, int STARTFLAG, int RXTXFL, int RXTXTRIG)
// MODE : 010 - MIR mode,  100 - FIR mode	
// PREAMBLE : 00 - 16,  01 - 4,  10 - 8,  11 - 32 preamble data length
// STARTFLAG : 2 ~ 15 start flag
// RXTXFL : 0 ~ 65535 Frame length
// RXTXTRIG : 00 - reserved,  01 - TX(12/48),RX(4/16), 
//					10 - TX(8/32),RX(8/32),  11 - TX(2/8),RX(14/56) [for 16/64byte]
//    				FIFO TRIG level set
{
	int cnt;
	
	// Timing Control Register
	//rIrDA_TIME = 0x7d; // Check please..... Can't read, only write.
	Uart_Printf("\n [Time=4]");

	// IrDA Control Register
	// Tx disable/Rx disable/No Frame abort/SDBE High
	rIrDA_CNT = (IrDA_LOOP_MODE<<5)|(MIR_HALF_MODE<<4)|(IrDA_SEND_SIP<<3)|(0);

	// Mode & Transceiver Set Register
	rIrDA_MDR = (1<<4) | (1<<3) | MODE;	// Sip every frame / HP / Mode 

	if (MODE == 4)		Uart_Printf(" [FIR mode]\n");
	else if (MODE == 2)
	{
		if (MIR_HALF_MODE == 0)
			Uart_Printf(" [MIR mode]\n");	
		else 
			Uart_Printf(" [MIR half mode]\n");	
	}		
	else {
		Uart_Printf(" [No  mode]\n");	
		return 0;
	}

	Uart_Printf("rMDR = 0x%x, rCNT = 0x%x\n",rIrDA_MDR, rIrDA_CNT);

	// Interrupt & DMA Control Register
	rIrDA_CNF = 0x0;		// Disable Interrupt & DMA

	// Interrupt Enable Register
	rIrDA_IER = 0x0;		// Disable All interrupts

	// FIFO Control Register
	// Tx FIFO reset[2] / RX FIFO reset[1]
	rIrDA_FCR = (RXTXTRIG<<6)|(IrDA_FIFOSIZE<<5)|(1<<2)|(1<<1)|(IrDA_FIFOENB);

	// Set Start Field Register or Preamble length
	rIrDA_PLR= ((PREAMBLE << 6) | (RXTXTRIG<<4) | STARTFLAG);

	// Receive Frame Length Register
	rIrDA_RXFLL = RXTXFL & 0xff;
	rIrDA_RXFLH= (RXTXFL>>8) & 0xff;
	Uart_Printf(" [RXFL-L] %d, [RXFL-H] %d\n", (U8)rIrDA_RXFLL, (U8)rIrDA_RXFLH);

	// Transmit Frame Length Register
	rIrDA_TXFLL = RXTXFL & 0xff;
	rIrDA_TXFLH= (RXTXFL>>8) & 0xff;
	Uart_Printf(" [TXFL-L] %d, [TXFL-H] %d\n", (U8)rIrDA_TXFLL, (U8)rIrDA_TXFLH);
/*
	while(!(rIrDA_FCR & 0x18)||(cnt == 10000)) cnt++;
	if (cnt == 10000) {
		Uart_Printf("Fail to initialize FIFO.. \n");
		return 0; // FIFO reset fail
	}
*/
	while(!(rIrDA_FCR & 0x18)) 
		{
		if(Uart_GetKey())
			return;
		}

	Uart_Printf("Tx and Rx FIFO clear is over...\n");
	return 1;
}


// IrDA Interrupt Test Code Start============================================================[END]
#if 1
void __irq Irda_Int_Rx(void)
{
	U8 status=0;
	U8 i;
	U8 RxCount=0;

	// masking
	rINTSUBMSK |= BIT_SUB_IrDA;
	rINTMSK    |= BIT_IrDA_MSTICK;
	

	// clear pending bit
	status = (U8)rIrDA_IIR; // Sub-sub pending clear

	rSUBSRCPND = BIT_SUB_IrDA;
	ClearPending(BIT_IrDA_MSTICK);

//	Uart_Printf("rIrDA_IIR=%x\n",status);	
	
	if(status & 0x40) { // RX error indication
		__sub_Irda_Err_Int_Rx();
	} else {
		if(status & 0x01) {
//			Uart_Printf(".");
			while(rIrDA_RXNO > 0) {
				*(IrDA_RXBUFFER+IrDA_RxWrPnt) = (U8)rIrDA_RBR;
				IrDA_RxWrPnt++;
				IrDA_RxCount++;
				IrDA_DONE = 0;
			}
		} else {
			if(status & 0x08) { // RX Overrun
				Uart_Printf("IrDA Rx Overrun Error Occurs!!\n");
			}
			if((status & 0x80) || (status & 0x10)){
				Uart_Printf("\nLast byte to Rx FIFO !!!!!!!!!\n");
				RxCount = rIrDA_RXNO;
				while(rIrDA_RXNO > 0) {
					*(IrDA_RXBUFFER+IrDA_RxWrPnt) = (U8)rIrDA_RBR;
					IrDA_RxWrPnt++;
					IrDA_RxCount++;
				}
				IrDA_DONE = 0;
			}
			if(status & 0x04) { // last byte read from Rx FIFO
				Uart_Printf("\nLast byte read from Rx FIFO !!!!!!!!!\n");
			}
		}
	}
	// unmasking
	rINTSUBMSK &= ~BIT_SUB_IrDA;
	rINTMSK    &= ~BIT_IrDA_MSTICK;		
}

#else
void __irq Irda_Int_Rx(void)
{
	U8 status=0;
	U8 i,j,RxNO;
	
	RxISR_cnt++;
	// masking	
	rINTSUBMSK |= BIT_SUB_IrDA;
	rINTMSK    |= BIT_IrDA_MSTICK;

	// clear pending bit
	status = (U8)rIrDA_IIR; // Sub-sub pending clear
	RxNO =(U8)rIrDA_RXNO;

	rSUBSRCPND = BIT_SUB_IrDA;
	ClearPending(BIT_IrDA_MSTICK);

	if(status & (1<<6))  // RX error indication
		{
		IrDA_DONE=0;
		ClearPending(BIT_IrDA_MSTICK);
		Uart_Printf("Line Status Error\n");
		__sub_Irda_Err_Int_Rx();
		}

	else if(status & (1<<2))//Last byte detect
		{
		IrDA_DONE=0;
		//Uart_Printf("\nLast byte detect\n");
		while( !(rIrDA_LSR&0x1))
			{
			Uart_Printf("\1\n");
			*(IrDA_RXBUFFER+IrDA_RxWrPnt) = (U8)rIrDA_RBR;
			*(IrDA_CKBUFFER+IrDA_RxWrPnt) = (U8)rIrDA_RXNO;
			IrDA_RxWrPnt++;
			}		

		ClearPending(BIT_IrDA_MSTICK);	
		}
	
	else if(status & (1<<3)) //Overrun Error
		{
		IrDA_DONE=0;
		//rIrDA_IIR&=~(0x8);
		ClearPending(BIT_IrDA_MSTICK);
		rSUBSRCPND = BIT_SUB_IrDA;
		Uart_Printf("Overrun Error\n");
		}
	

	else
		{
		IrDA_DONE=0;
		
		while( !(rIrDA_LSR&0x1)||(status & (1<<2)))
			{		
			*(IrDA_RXBUFFER+IrDA_RxWrPnt) = (U8)rIrDA_RBR;
			*(IrDA_CKBUFFER+IrDA_RxWrPnt) = (U8)rIrDA_RXNO;
			IrDA_RxWrPnt++;
		    
			}
		}
		
	rSUBSRCPND = BIT_SUB_IrDA;
	ClearPending(BIT_IrDA_MSTICK);

	// unmasking
	rINTSUBMSK &= ~BIT_SUB_IrDA;
	rINTMSK    &= ~BIT_IrDA_MSTICK;		
}

#endif
void __sub_Irda_Err_Int_Rx()
{
	switch((rIrDA_LSR & 0x1c)>>2)//to clear and check the status of register bits
	{
		case 1:
			Uart_Printf("CRC error\n");
			break;
		case 2:
			Uart_Printf("Phy error\n");
			break;
		case 3:
			Uart_Printf("CRC and Phy error\n");
			break;
		case 4:
			Uart_Printf("Frame Length error\n");
			break;
		case 5:
			Uart_Printf("CRC and Frame Length error\n");
			break;
		case 6:
			Uart_Printf("Phy and Frame Length error\n");
			break;
		case 7:
			Uart_Printf("CRC, Phy and Frame Length error\n");
			break;
		default :
			break;
	}
}


void Test_Irda_Fifo_Int_Rx(int MODE, int PREAMBLE, int STARTFLAG, int RXFL, int RXTRIG)
{
	int		i;

	// Initialize IrDA
	Init_Irda(MODE, PREAMBLE, STARTFLAG, RXFL, RXTRIG);

	// Register IrDA ISR
	pISR_IrDA_MSTICK=(unsigned)Irda_Int_Rx;

	ClearPending(BIT_IrDA_MSTICK);	// Clear IrDA Int Pending
	rSUBSRCPND = BIT_SUB_IrDA;

	rINTSUBMSK &= ~(BIT_SUB_IrDA);		// Unmask IrDA sub-pending bit
	rINTMSK    &= ~(BIT_IrDA_MSTICK);	// Unmask IrDA pending bit

	IrDA_RXBUFFER=(unsigned char *)MemoryRx;
	for(i=0;i<=IrDA_RxBUFLEN;i++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -