?? mcc_int.c
字號:
/****************************************************************************
* Property of Motorola, Wireless Infrastructure Systems Division
****************************************************************************
* ANSI C source code
*
* MCC Driver for WISD MSC8101 Driver Library
*
* MOTOROLA GENERAL BUSINESS INFORMATION
****************************************************************************/
/****************************************************************************
*
* MODULE NAME: mcc_int.c
*
*****************************************************************************
* DESCRIPTION:
* This file contains the interrupt drivers and related routines
* for MCC1 and MCC2. Each Rx interrupt performs a data check on the
* received data to ensure integrity.
*
* If MCC1_TEST= 1 (TRUE) then MCC1 will be the MCC used in the test.
* The green LED will flash to indicate MCC1 receive interrupts are ongoing
* and that the receive interrupt based data check is successful.
* LD10 : S-0 : Green ; Indicates successful test result.
*
* If MCC1_TEST= 0 (FALSE) then MCC2 will be the MCC used in the test.
* The red LED will flash to indicate MCC2 receive interrupts are ongoing
* and that the receive interrupt based data check is successful.
* LD9 : S-1 : Red ; Indicates successful test result.
*
*
* AUTHOR: Jim Gilbert.
*
* VERSION: v1.0, 20 Dec 2001.
*
* COMPILER: Metrowerks, CodeWarrior for Starcore Release 1.0
* IDE v4.1 Build 696.
*
* TARGET: StarCore/MSC8101 ADS.
*
* REVISION HISTORY: initial release v0.1, 01 Aug 2001.
* v1.0, 20 Dec 2001.
*****************************************************************************/
/*****************************************************************************
* Include files
*****************************************************************************/
#include "msc8101ads.h" //MSC8101ADS specific settings and functions
#include "msc8101.h"
#include "mcc_int.h" //local header file
#include "mcc.h" //Mcc driver functions header file
/*****************************************************************************
* Global variables
*****************************************************************************/
// MCC1 Buffer handling counters
static UWord16 gusiMcc1Rint0Ctr=0; //MCC Receive Interrupt Ring
static UWord16 gusiMcc1TintCtr=0; //MCC Transmit Interrupt Ring
static UWord16 gusiMcc1RxbufCtr[MCC1_NUM_CH]; //Receive Buffers
static UWord16 gusiMcc1TxbufCtr[MCC1_NUM_CH]; //Transmit Buffers
static UWord16 gusiMcc1RxIrqCtr[MCC1_NUM_CH]; //Receive Interrupt counter
static UWord16 gusiMcc1TxIrqCtr[MCC1_NUM_CH]; //Transmit Interrupt counter
// MCC2 Buffer handling counters
static UWord16 gusiMcc2Rint0Ctr=0; //MCC Receive Interrupt Ring
static UWord16 gusiMcc2TintCtr=0; //MCC Transmit Interrupt Ring
static UWord16 gusiMcc2RxbufCtr[MCC2_NUM_CH]; //Receive Buffers
static UWord16 gusiMcc2TxbufCtr[MCC2_NUM_CH]; //Transmit Buffers
static UWord16 gusiMcc2RxIrqCtr[MCC2_NUM_CH]; //Receive Interrupt counter
static UWord16 gusiMcc2TxIrqCtr[MCC2_NUM_CH]; //Transmit Interrupt counter
// Debug Aids - Interrupt Counters
static UWord16 gusiMcc1RxIntcount=0;
static UWord16 gusiMcc1TxIntcount=0;
static UWord16 gusiMcc1TotalIntcount=0;
static UWord16 gusiMcc2RxIntcount=0;
static UWord16 gusiMcc2TxIntcount=0;
static UWord16 gusiMcc2TotalIntcount=0;
/*****************************************************************************
* FUNCTION: PrepareOpenMcc1Channel()
* PURPOSE: Initialises parameters and variables specific to a channel.
* NOTES: None.
* ENTRY: ucChanI - Channel Number.
* EXIT: None.
*****************************************************************************/
void PrepareOpenMcc1Channel(UByte ucChanI)
{
MCC1_InitSpecific(ucChanI); //Initialize channel specific parameters;
gusiMcc1RxbufCtr[ucChanI]=0;
gusiMcc1TxbufCtr[ucChanI]=0;
gusiMcc1RxIrqCtr[ucChanI]=0; //for debugging/counting interrupts only
gusiMcc1TxIrqCtr[ucChanI]=0;
return;
}
/*****************************************************************************
* FUNCTION: PrepareOpenMcc2Channel()
* PURPOSE: Initialises parameters and variables specific to a channel.
* NOTES: None.
* ENTRY: ucChanI - Channel Number.
* EXIT: None.
*****************************************************************************/
void PrepareOpenMcc2Channel(UByte ucChanI)
{
MCC2_InitSpecific(ucChanI); //Initialize channel specific parameters;
gusiMcc2RxbufCtr[ucChanI]=0;
gusiMcc2TxbufCtr[ucChanI]=0;
gusiMcc2RxIrqCtr[ucChanI]=0; //for debugging/counting interrupts only
gusiMcc2TxIrqCtr[ucChanI]=0;
return;
}
/*****************************************************************************
* FUNCTION: MCC1_Interrupt()
* PURPOSE: Manages MCC1 interrupts, Tx/Rx BDs and checks loopback data.
* NOTES: None.
* ENTRY: None
* EXIT: None.
*****************************************************************************/
#pragma interrupt MCC1_Interrupt()
void MCC1_Interrupt(void)
{
/*
This function is only called when a SIC/MCC1 interrupt occurs.
*/
UWord32* puliMCC1IrqTableBase;
t_Mcc1BDRings* pstMCC1;
UByte ucChan;
UWord16 usiMCCE;
Word16 i,pass, status;
t_8101IMM *pstIMM = (t_8101IMM*)IMM_BASE; // Pointer to internal memory
pstIMM->t_aIORegs[PORTA].vuliPDat ^= 0x00000008; //toggle PA28 output (logic analyzer)
usiMCCE=pstIMM->t_aSIRegs[MCC1].vusiMCCE; //read event cause
if(!(usiMCCE & 0x4000) && !(usiMCCE & 0x0004)) //Catch Unintentional Interrupts
asm(" debug");
/*************/
/*** RINT0 ***/
/*************/
if (usiMCCE & 0x4000) //RINT0 interrupt?
{
pstMCC1 = (t_Mcc1BDRings*)(MCC1_BDRINGS_BASE-LOCAL_BASE);
puliMCC1IrqTableBase = (UWord32*)(MCC1_RINT0_BASE-LOCAL_BASE);
pstIMM->t_aSIRegs[MCC1].vusiMCCE = 0x4000; //clear RINT0 irq flag in MCCE2-reg.
// Read Int Q entry from core side
while(*(puliMCC1IrqTableBase+gusiMcc1Rint0Ctr)&0x80000000)
{
if (*(puliMCC1IrqTableBase+gusiMcc1Rint0Ctr) & 0x00020000)
asm(" debug"); // BSY indicates an overrun
//get channel number from bits 18-25:
ucChan = (UByte)(*(puliMCC1IrqTableBase+gusiMcc1Rint0Ctr)>>6);
*(puliMCC1IrqTableBase+gusiMcc1Rint0Ctr) &= 0x40000000; //Reset irq circ. table entry
pstIMM->t_aIORegs[PORTA].vuliPDat |= ucChan&0x00000007; //sets up PA29-31 with chan-code
if (ucChan<MCC1_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=gusiMcc1RxbufCtr[ucChan];
for(;;)
{
/*-----------------------------------------------*/
/* COMPARE RX BUFFER WITH TX BUFFER */
/*-----------------------------------------------*/
pass=CompareBuffers((UByte*)(pstMCC1->astRxChan[ucChan].astBufD[i].uliBdAddr - LOCAL_BASE),
(UByte*)(pstMCC1->astTxChan[ucChan].astBufD[i].uliBdAddr - LOCAL_BASE),
(UByte )pstMCC1->astTxChan[ucChan].astBufD[i].usiBdLength);
if (!pass)
{
LED(GREEN_OFF);
asm(" debug");
}
/*-----------------------------------------------*/
/* Clear BDs between this int and previous one */
/*-----------------------------------------------*/
pstMCC1->astRxChan[ucChan].astBufD[i].usiBdCstatus |= 0x8000;
pstMCC1->astRxChan[ucChan].astBufD[i].usiBdLength = 0;
status = pstMCC1->astRxChan[ucChan].astBufD[i].usiBdCstatus;
if (status & 0x2000) // if wrap set, wrap count
i=0;
else
i++;
if (status & 0x1000) // if interrupt, finish
break;
}
// Update buffer counter record
gusiMcc1RxbufCtr[ucChan] = i;
}
else
{
//wrong channel number
asm(" debug");
}
if (++gusiMcc1Rint0Ctr==MCC1_RINT0_NUM) gusiMcc1Rint0Ctr=0;
pstIMM->t_aIORegs[PORTA].vuliPDat &= ~0x00000007;//resets PA29-31 to 0
gusiMcc1RxIntcount++; // debug aid
gusiMcc1RxIrqCtr[ucChan]++; // debug aid
}
}
/*************/
/*** TINT ***/
/*************/
if (usiMCCE & 0x0004) // TINT Interrupt
{
pstMCC1 = (t_Mcc1BDRings*)(MCC1_BDRINGS_BASE-LOCAL_BASE);
puliMCC1IrqTableBase = (UWord32*)(MCC1_TINT_BASE-LOCAL_BASE);
pstIMM->t_aSIRegs[MCC1].vusiMCCE = 0x0004; //clear TINT irq flag in MCCE1-reg.
// Read Int Q entry from core side
while(*(puliMCC1IrqTableBase+gusiMcc1TintCtr)&0x80000000)
{
if (*(puliMCC1IrqTableBase+gusiMcc1Rint0Ctr) & 0x00200000)
asm(" debug"); // UN indicates an underrun
//get channel number from bits 18-25:
ucChan = (UByte)(*(puliMCC1IrqTableBase+gusiMcc1TintCtr)>>6);
*(puliMCC1IrqTableBase+gusiMcc1TintCtr) &= 0x40000000; //Reset irq circ. table entry
// pstIMM->t_aIORegs[PORTA].vuliPDat |= ucChan&0x00000007;//sets up PA29-31 with chan-code
if (ucChan<MCC1_NUM_CH)
{
/*-----------------------------------------------*/
/* Multiple Buffer and BD Handling per Interrupt */
/*-----------------------------------------------*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -