📄 mcc_int.c
字号:
// If handling one buffer per IRQ then simple -> clear the BD
// However handling multi buffers per frame/subframe interrupt...
// So, clear BDs between the current interrupt & previous one handled
i=gusiMcc1TxbufCtr[ucChan];
for(;;)
{
/*-----------------------------------------------*/
/* Clear BDs between this int and previous one */
/*-----------------------------------------------*/
pstMCC1->astTxChan[ucChan].astBufD[i].usiBdCstatus |= 0x8000;
status = pstMCC1->astTxChan[ucChan].astBufD[i].usiBdCstatus;
if (status & 0x2000) // if wrap set, wrap counts
i=0;
else
i++;
if (status & 0x1000) // if interrupt set, finish
break;
}
// Update buffer counter record
gusiMcc1TxbufCtr[ucChan] = i;
}
else
{
//wrong channel number
asm(" debug");
}
if (++gusiMcc1TintCtr==MCC1_TINT_NUM) gusiMcc1TintCtr=0;
pstIMM->t_aIORegs[PORTA].vuliPDat &= ~0x00000007;//resets PA29-31 to 0
gusiMcc1TxIntcount++; // debug aid
gusiMcc1TxIrqCtr[ucChan]++; // debug aid
}
}
if (gusiMcc1RxIntcount & 0x0080) LED(GREEN_ON);
else LED(GREEN_OFF);
pstIMM->t_aIORegs[PORTA].vuliPDat ^= 0x00000008; //toggle PA28 output (logic analyzer)
gusiMcc1TotalIntcount++; // debug aid
return;
}
/*****************************************************************************
* FUNCTION: MCC2_Interrupt()
* PURPOSE: Manages MCC2 interrupts, Tx/Rx BDs and checks loopback data.
* NOTES: None.
* ENTRY: None
* EXIT: None.
*****************************************************************************/
#pragma interrupt MCC2_Interrupt()
void MCC2_Interrupt(void)
{
/*
This function is only called when a SIC/MCC2 interrupt occurs.
*/
UWord32* puliMCC2IrqTableBase;
t_Mcc2BDRings* pstMCC2;
UByte ucChan;
UWord16 usiMCCE;
Word16 i,pass, status;
t_8101IMM *pstIMM = (t_8101IMM*)IMM_BASE; // Pointer to internal memory
pstIMM->t_aIORegs[PORTA].vuliPDat ^= 0x00000080; //toggle PA24 output (logic analyzer)
usiMCCE=pstIMM->t_aSIRegs[MCC2].vusiMCCE; //read event cause
if(!(usiMCCE & 0x4000) && !(usiMCCE & 0x0004)) //Catch Unintentional Interrupts
asm(" debug");
/*************/
/*** RINT0 ***/
/*************/
if (usiMCCE & 0x4000) //RINT0 interrupt ?
{
pstMCC2 = (t_Mcc2BDRings*)(MCC2_BDRINGS_BASE-LOCAL_BASE);
puliMCC2IrqTableBase = (UWord32*)(MCC2_RINT0_BASE-LOCAL_BASE);
pstIMM->t_aSIRegs[MCC2].vusiMCCE = 0x4000; //clear RINT0 irq flag in MCCE2-reg.
// Read Int Q entry from core side
while(*(puliMCC2IrqTableBase+gusiMcc2Rint0Ctr)&0x80000000)
{
if (*(puliMCC2IrqTableBase+gusiMcc2Rint0Ctr) & 0x00020000)
asm(" debug"); // BSY indicates an overrun
//get channel number from bits 18-25:
ucChan = ((UByte)(*(puliMCC2IrqTableBase+gusiMcc2Rint0Ctr)>>6)) & 0x7f;
*(puliMCC2IrqTableBase+gusiMcc2Rint0Ctr) &= 0x40000000; //Reset irq circ. table entry
pstIMM->t_aIORegs[PORTA].vuliPDat |= ((ucChan&0x00000007)<<4);//sets up PA25-27 with chan-code
if (ucChan<MCC2_NUM_CH)
{
/*-----------------------------------------------*/
/* Multiple Buffer and BD Handling per Interrupt */
/*-----------------------------------------------*/
// If handling one buffer per IRQ then simple -> clear the BD
// However handling multi buffers per frame/subframe interrupt...
// So, clear BDs between the current interrupt & previous one handled
i=gusiMcc2RxbufCtr[ucChan];
for(;;)
{
/*-----------------------------------------------*/
/* COMPARE RX BUFFER WITH TX BUFFER */
/*-----------------------------------------------*/
pass=CompareBuffers((UByte*)(pstMCC2->astRxChan[ucChan].astBufD[i].uliBdAddr - LOCAL_BASE),
(UByte*)(pstMCC2->astTxChan[ucChan].astBufD[i].uliBdAddr - LOCAL_BASE),
(UByte )pstMCC2->astTxChan[ucChan].astBufD[i].usiBdLength);
if (!pass)
{
LED(RED_OFF);
asm(" debug");
}
/*-----------------------------------------------*/
/* Clear BDs between this int and previous one */
/*-----------------------------------------------*/
pstMCC2->astRxChan[ucChan].astBufD[i].usiBdCstatus |= 0x8000;
pstMCC2->astRxChan[ucChan].astBufD[i].usiBdLength = 0;
status = pstMCC2->astRxChan[ucChan].astBufD[i].usiBdCstatus;
if (status & 0x2000) // if wrap set, wrap counts
i=0;
else
i++;
if (status & 0x1000) // if interrupt, finish
break;
}
// Wrap buffer counter record if last buffer
gusiMcc2RxbufCtr[ucChan] = i;
}
else
{
asm(" debug");
}
if (++gusiMcc2Rint0Ctr==MCC2_RINT0_NUM) gusiMcc2Rint0Ctr=0;
pstIMM->t_aIORegs[PORTA].vuliPDat &= ~0x00000070;//resets PA25-27 to 0
gusiMcc2RxIntcount++; // debug aid
gusiMcc2RxIrqCtr[ucChan]++; // debug aid
}
}
/*************/
/*** TINT ***/
/*************/
if (usiMCCE & 0x0004) // TINT Interrupt
{
pstMCC2 = (t_Mcc2BDRings*)(MCC2_BDRINGS_BASE-LOCAL_BASE);
puliMCC2IrqTableBase = (UWord32*)(MCC2_TINT_BASE-LOCAL_BASE);
pstIMM->t_aSIRegs[MCC2].vusiMCCE = 0x0004; //clear TINT irq flag in MCCE1-reg.
// Read Int Q entry from core side
while(*(puliMCC2IrqTableBase+gusiMcc2TintCtr)&0x80000000)
{
if (*(puliMCC2IrqTableBase+gusiMcc2Rint0Ctr) & 0x00200000)
asm(" debug"); // UN indicates an underrun
//get channel number from bits 18-25:
ucChan = ((UByte)(*(puliMCC2IrqTableBase+gusiMcc2TintCtr)>>6)) & 0x7f;
*(puliMCC2IrqTableBase+gusiMcc2TintCtr) &= 0x40000000; //Reset irq circ. table entry
// pstIMM->t_aIORegs[PORTA].vuliPDat |= ucChan&0x00000007;//sets up PA29-31 with chan-code
if (ucChan<MCC2_NUM_CH)
{
/*-----------------------------------------------*/
/* Multiple Buffer and BD Handling per Interrupt */
/*-----------------------------------------------*/
// If handling one buffer per IRQ then simple -> clear the BD
// However handling multi buffers per frame/subframe interrupt...
// So, clear BDs between the current interrupt & previous one handled
i=gusiMcc2TxbufCtr[ucChan];
for(;;)
{
/*-----------------------------------------------*/
/* Clear BDs between this int and previous one */
/*-----------------------------------------------*/
pstMCC2->astTxChan[ucChan].astBufD[i].usiBdCstatus |= 0x8000;
status = pstMCC2->astTxChan[ucChan].astBufD[i].usiBdCstatus;
if (status & 0x2000) // if wrap set, wrap counts
i=0;
else
i++;
if (status & 0x1000) // if interrupt set, finish
break;
}
// Update buffer counter record
gusiMcc2TxbufCtr[ucChan] = i;
}
else
{
//wrong channel number
asm(" nop");
asm(" debug");
}
if (++gusiMcc2TintCtr==MCC2_TINT_NUM) gusiMcc2TintCtr=0;
pstIMM->t_aIORegs[PORTA].vuliPDat &= ~0x00000007;//resets PA29-31 to 0
gusiMcc2TxIntcount++; // debug aid
gusiMcc2TxIrqCtr[ucChan]++; // debug aid
}
}
if (gusiMcc2RxIntcount & 0x0080) LED(RED_ON);
else LED(RED_OFF);
pstIMM->t_aIORegs[PORTA].vuliPDat ^= 0x00000080; //toggle PA24 output (logic analyzer)
gusiMcc2TotalIntcount++; // debug aid
return;
}
/*****************************************************************************
* FUNCTION: CompareBuffers()
* PURPOSE: Compares 2 Buffers.
* NOTES: None.
* ENTRY: UByte *pucBuf1 - Pointer to source buffer
* UByte *pucBuf2 - Pointer to destination buffer
* UWord16 usiLen - Length for comparison
* EXIT: None.
*****************************************************************************/
Word16 CompareBuffers(UByte *pucBuf1, UByte *pucBuf2, UWord16 usiLen)
{
Word16 usiI;
Word16 usiMatch=1;
for (usiI=0; usiI<usiLen; usiI++)
{
if (*pucBuf1++ != *pucBuf2++)
usiMatch =0;
}
return (usiMatch);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -