📄 irda.c
字号:
//===================================================================
// 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 + -