📄 irda.c
字号:
cStatus = (u8)Inp32(rIrDA_IIR); // Sub-sub pending clear
//printf("\nrIrDA_FCR : 0x%08x\n",rIrDA_FCR);
g_aIrDA_TestInt[g_uIrDA_IntCnt++] = cStatus;
g_aIrDA_TestBuf[g_uIrDA_TestCnt++] = 1;
if(cStatus & (1<<6)) // RX error indication
{
printf("\nrIrDA_IIR : 0x%08x\n",cStatus);
Error = __Isr_IrDA_Sub_RxErr();
g_aIrDA_TestBuf[g_uIrDA_TestCnt++] = 2;
}
if(cStatus & (1<<3)) // RX Overrun
{
printf("IrDA Rx Overrun Error Occurs!!\n");
printf("Rx FIFO Reset.... : 0x%x\n", Error);
uTmp = Inp32(rIrDA_FCR);
uTmp |= 0x02;
Outp32(rIrDA_FCR,uTmp);
while( !(Inp32(rIrDA_FCR) & 0x08) );
Error = RxOverRun_Error;
g_aIrDA_TestBuf[g_uIrDA_TestCnt++] = 3;
}
if(Error == No_Error)
{
//for(i=0 ; i<500 ; i++);
if(cStatus & 0x01)
{
while(Inp32(rIrDA_RXNO) > 0)
{
*(pIrDA_RXBUFFER+g_uIrDA_RxWrPnt) = (u8)Inp32(rIrDA_RBR);
g_uIrDA_RxWrPnt++;
// printf("RxNO : 0x%x\n",Inp32(rIrDA_RXNO));
//for(i=0 ; i<50 ; i++);
}
g_aIrDA_TestBuf[g_uIrDA_TestCnt++] = 4;
}
}
else
{
//Reg_Dump();
g_aIrDA_TestBuf[g_uIrDA_TestCnt++] = 5;
if(Error & CRC_Error)
printf("CRC error...!!!\n");
if(Error & PHY_Error)
printf("Phy error...!!!\n");
if(Error & Frame_Error)
printf("Frame Length error...!!!\n");
//printf("Rx FIFO Reset.... : 0x%x\n", Error);
//rIrDA_FCR |= 0x02;
//while( !(rIrDA_FCR & 0x08) );
}
if(cStatus & 0x04) //Last data read from FIFO
{
g_uIrDA_LastDataRead = 1;
g_aIrDA_TestBuf[g_uIrDA_TestCnt++] = 6;
}
INTC_Enable(NUM_IRDA);
INTC_ClearVectAddr();
}
//////////
// Function Name : __Isr_IrDA_Sub_RxErr
// Function Description : This function is sub Interrupt Service Routine of IrDA Int Rx which presents Error status
// Input : NONE
// Output : eIrDA_Error
// Version : v0.1
eIrDA_Error __Isr_IrDA_Sub_RxErr()
{
u32 uIrDA_ErrorStatus;
// Modified by rb1004
uIrDA_ErrorStatus = IrDA_ReadLSR();
printf("\nError.......[g_uIrDA_ErrorStatus : 0x%08x]\n", uIrDA_ErrorStatus);
uIrDA_ErrorStatus &= 0x1c;
switch(uIrDA_ErrorStatus>>2) //to clear and check the status of register bits
{
case 1:
return CRC_Error;
case 2:
return PHY_Error;
case 3:
return (eIrDA_Error)(CRC_Error | PHY_Error);
case 4:
return Frame_Error;
case 5:
return (eIrDA_Error)(CRC_Error | Frame_Error);
case 6:
return (eIrDA_Error)(PHY_Error | Frame_Error);
case 7:
return (eIrDA_Error)(CRC_Error | PHY_Error | Frame_Error);
default :
return No_Error;
// break;
}
}
//==============================================================================
//////////
// Function Name : Isr_IrDA_Int_Tx
// Function Description : This function is Interrupt Service Routine of IrDA Tx interrupt mode
// Input : NONE
// Output : NONE
// Version : v0.1
void __irq Isr_IrDA_Int_Tx()
{
u8 cStatus=0;
u32 uTemp;
u32 uCnt;
INTC_Disable(NUM_IRDA);
IrDA_IntClear();
cStatus = (u8)Inp32(rIrDA_IIR); // Read IIR(Interrupt Identification Register) of IrDA
if(cStatus & 0x2) // TX Trigger
{
// for (uCnt=0;uCnt<5;uCnt++) //for 65535
for (uCnt=0;uCnt<IrDA_TxBUFLEN;uCnt++)
{
//rIrDA_RBR = g_cData;
//*pIrDA_CKBUFFER++ = g_cData++;
Outp32(rIrDA_RBR , *pIrDA_CKBUFFER++);
// printf("FIFO TxNO : 0x%x\n",Inp32(rIrDA_TXNO));
}
g_uIrDA_TxCnt += IrDA_TxBUFLEN;
// g_uIrDA_TxCnt += 5; //for 65536
//g_uIrDA_TxCnt +=g_uIrDA_TxNum;
if (g_uIrDA_TxNum <= g_uIrDA_TxCnt)
{
uTemp = Inp32(rIrDA_IER);
uTemp &= ~(1<<1);
Outp32(rIrDA_IER,uTemp);
// rIrDA_IER &= ~(1<<1);
g_uIrDA_TxDone = 1;
}
}
// if(cStatus & 0x20) // TX Trigger
// {
// printf("Tx Underrun error!! \n");
// pIrDA_CKBUFFER = (unsigned char *)MemoryCk;
// pIrDA_CKBUFFER1 = (unsigned char *)MemoryCk1;
// for(i=0; i<g_uIrDA_TxCnt ; i++)
// printf("[D:%3d, N:%3d] ", *pIrDA_CKBUFFER++, *pIrDA_CKBUFFER1++);
// }
INTC_Enable(NUM_IRDA);
INTC_ClearVectAddr();
}
// IrDA Interrupt Test Code end============================================================[END]
// IrDA DMA Test Code Start=============================================================[START]
void __irq Isr_IrDA_Dma_RxDone(void)
{
u32 i;
u32 uRegTmp;
eIrDA_Error Error = No_Error;
u8 status = No_Error;
INTC_Disable(NUM_DMA1);
DMACH_Stop(&oIrDADma);
DMACH_ClearIntPending(&oIrDADma);
DMACH_ClearErrIntPending(&oIrDADma);
status = (u8)Inp32(rIrDA_IIR); // Sub-sub pending clear
if(status & (1<<3)) // RX Overrun
{
printf("IrDA Rx Overrun Error Occurs!!\n");
printf("Rx FIFO Reset.... : 0x%x\n", Error);
uRegTmp = Inp32(rIrDA_FCR);
uRegTmp |= 0x02;
Outp32(rIrDA_FCR,uRegTmp);
while( !(Inp32(rIrDA_FCR) & 0x08) );
Error = RxOverRun_Error;
}
if(status & (1<<6)) // RX error indication
{
Error = __Isr_IrDA_Sub_RxErr();
}
if(Error == No_Error)
{
//g_uIrDA_DataRcvCnt += IrDAtoDMA_RX_SIZE;
for(i=0 ; i<IrDAtoDMA_RX_SIZE ; i++)
*g_pbHead++ = *pIrDA_RXBUFFER++;
}
else
{
// printf("\nError.......[g_uIrDA_ErrorStatus : 0x%08x]\n", g_uIrDA_ErrorStatus);
if(Error & CRC_Error)
printf("CRC error...!!!\n");
if(Error & PHY_Error)
printf("Phy error...!!!\n");
if(Error & Frame_Error)
printf("Frame Length error...!!!\n");
//printf("Rx FIFO Reset.... : 0x%x\n", Error);
//rIrDA_FCR |= 0x02;
//while( !(rIrDA_FCR & 0x08) );
}
//if(Irda_Status & 0x80)
g_uIrDA_DONE = 1;
//g_uIrDA_DataRcvCnt += IrDAtoDMA_RX_SIZE;
uRegTmp = DMACH_ReadDstAddr(&oIrDADma);
uRegTmp+=1;
DMACH_Setup(DMA_A,0x0,rIrDA_RBR,1,uRegTmp,0,BYTE,IrDAtoDMA_RX_SIZE,DEMAND,DMA1_IrDA,MEM,BURST16,&oIrDADma);
INTC_Enable(NUM_DMA1);
DMACH_Start(&oIrDADma);
INTC_ClearVectAddr();
}
void Init_Irda_Dma_Rx(void)
{
//--- DMAC 1 Initialize& Channel 1
SYSC_SelectDMA(eSEL_IRDA, 1);
DMAC_InitCh(DMA1, DMA_A,&oIrDADma);
DMACH_ClearIntPending(&oIrDADma);
DMACH_ClearErrIntPending(&oIrDADma);
printf("Source Address = 0x%x\n", rIrDA_RBR);
printf("Dest. Address = 0x%x\n", pIrDA_RXBUFFER);
// Channel Control Register
DMACH_Setup(DMA_A,0x0,(u32)(rIrDA_RBR),1,(u32)pIrDA_RXBUFFER,0,BYTE,IrDAtoDMA_RX_SIZE,DEMAND,DMA1_IrDA,MEM,BURST16,&oIrDADma);
INTC_Enable(NUM_DMA1);
DMACH_Start(&oIrDADma);
}
void __irq Isr_IrDA_Dma_TxDone(void)
{
u32 uRegTmp;
eIrDA_Error Error = No_Error;
u8 status = No_Error;
INTC_Disable(NUM_DMA1);
DMACH_ClearIntPending(&oIrDADma);
DMACH_ClearErrIntPending(&oIrDADma);
g_uIrDA_TxISRcount++;
status = (u8)Inp32(rIrDA_IIR); // Sub-sub pending clear
g_uIrDA_DONE = 1;
if(status & (1<<5)) // RX Overrun
{
printf("IrDA Tx Underrun Error Occurs!!\n");
printf("Tx FIFO Reset.... : 0x%x\n", Error);
uRegTmp = Inp32(rIrDA_FCR);
uRegTmp |= 0x4;
Outp32(rIrDA_FCR,uRegTmp);
while( !(Inp32(rIrDA_FCR) & 0x10) );
Error = TxUnderRun_Error;
}
// if(status & (1<<6)) // RX error indication
// {
// Error = __Isr_IrDA_Sub_RxErr();
// }
if(Error == No_Error)
{
//for(i=0 ; i<IrDA_TxBUFLEN ; i++)
// *g_pbHead++ = *pIrDA_TXBUFFER++;
g_uIrDA_Txcount += DMAtoIrDA_TX_SIZE;
}
/*
else
{
printf("\nError.......[g_uIrDA_ErrorStatus : 0x%08x]\n", g_uIrDA_ErrorStatus);
if(Error & CRC_Error)
printf("CRC error...!!!\n");
if(Error & PHY_Error)
printf("Phy error...!!!\n");
if(Error & Frame_Error)
printf("Frame Length error...!!!\n");
//printf("Rx FIFO Reset.... : 0x%x\n", Error);
//rIrDA_FCR |= 0x02;
//while( !(rIrDA_FCR & 0x08) );
}
*/
//if(Irda_Status & 0x80)
/*
if( g_uIrDA_Txcount < g_uIrDA_TxNum)
{
rDMAC2C2SrcAddr = rDMAC2C2SrcAddr+1;
//rDMAC2C2Control |= (IrDA_TxBUFLEN);
rDMAC2C2Control |= DMAtoIrDA_TX_SIZE;
rDMAC2C2Config |= (1<<0);
printf("g_uIrDA_Txcount < g_uIrDA_TxNum.............\n");
}
else
{
rDMAC2Configuration = 0x0 ;
printf("g_uIrDA_Txcount > g_uIrDA_TxNum..........End\n");
}
*/
INTC_Enable(NUM_DMA1);
INTC_ClearVectAddr();
}
void Init_Irda_Dma_Tx()
{
INTC_Disable(NUM_DMA1);
//--- DMAC 1 Initialize& Channel 2
SYSC_SelectDMA(eSEL_IRDA, 1);
DMAC_InitCh(DMA1,DMA_B,&oIrDADma);
DMACH_ClearIntPending(&oIrDADma);
DMACH_ClearErrIntPending(&oIrDADma);
printf("Source Address = 0x%x\n", pIrDA_TXBUFFER);
printf("Dest. Address = 0x%x\n", rIrDA_RBR);
DMACH_Setup(DMA_B,0x0,(u32)pIrDA_TXBUFFER,0,rIrDA_RBR,1,BYTE,DMAtoIrDA_TX_SIZE,DEMAND,MEM,DMA1_IrDA,BURST32,&oIrDADma);
INTC_Enable(NUM_DMA1);
DMACH_Start(&oIrDADma);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -