📄 860qmc1h.c
字号:
UHWORD BDRxError(UHWORD bd_cstatus)
{
if (bd_cstatus & BD_RX_ERROR)
{ return TRUE;
}
else
{ return FALSE;
}
} /* end BDRxError */
/*--------------------------------------------------------------------------
*
* FUNCTION NAME: LastBD
*
* DESCRIPTION: Return TRUE if Buffer Descriptor with status and
* control register bd_cstatus is last in frame; Return
* FALSE otherwise.
*
* EXTERNAL EFFECTS: None
** PARAMETERS:
*
* bd_cstatus -
*
* RETURNS:
*
*-------------------------------------------------------------------------*/
UHWORD LastBD(UHWORD bd_cstatus)
{
if (bd_cstatus & 0x0800)
{ return TRUE;
}
else
{ return FALSE;
}
} /* end LastBD */
/*--------------------------------------------------------------------------
*
* FUNCTION NAME: BDEmpty
*
* DESCRIPTION:
*
* Return TRUE if Buffer Descriptor Status bd_cstatus is empty. Return
* FALSE otherwise.
** EXTERNAL EFFECTS: None
*
* PARAMETERS:
*
* bd_cstatus
*
* RETURNS: TRUE if empty and FALSE if it isn't
*
*-------------------------------------------------------------------------*/
UHWORD BDEmpty(UHWORD bd_cstatus)
{
if (bd_cstatus & 0x8000)
{ return TRUE;
}
else
{ return FALSE;
}
} /* end BDEmpty */
/*--------------------------------------------------------------------------
*
* FUNCTION NAME: GetIMMR
*
* DESCRIPTION:
*
* returns in R3, the current value in IMMR register. The IMMR register
* must be accessed in this manner because it is a special purpose
* register.
*
* EXTERNAL EFFECTS: None
*
* PARAMETERS: none
*
* RETURNS: IMMR value in R3.
*-------------------------------------------------------------------------*/
GetIMMR()
{
/*--------------------------------------------------------------------*/
/* r3 is the register that the compiler is using for the return value */
/* In other words, r3 is the implicit return value. */
/*--------------------------------------------------------------------*/
#ifdef MetaWare
_ASM(" mfspr %r3,638 "); /* IMMR is spr #638 */
#else
#ifdef Diab
asm(" mfspr r3,638 "); /* IMMR is spr #638 */
#endif
#endif
} /* end GetIMMR */
/*-------------------------------------------------------------------------
*
* FUNCTION NAME: Ethled
*
* DESCRIPTION:
*
* Turn On/Off Ethernet LED on 821/860 ADS board.
*
* EXTERNAL EFFECTS:
*
* PARAMETERS:
*
* setting - 0 turns off LED; otherwise turn on LED.
*
* RETURNS: NONE
*
*-------------------------------------------------------------------------*/
void Ethled(UHWORD setting)
{
BCSR *csr;
csr = (BCSR *)(IMMR->memc_br1 & 0xFFFF8000);
if (setting)
{ csr->bcsr1 &= ~ETHEN; /* turn on LED, active low */
}
else
{ csr->bcsr1 |= ETHEN; /* turn off LED, active high */
}
} /* end Ethled */
/*-------------------------------------------------------------------------
*
* FUNCTION NAME: FlashEthled
*
* DESCRIPTION: This function flashes the Ethernet LED
*
* EXTERNAL EFFECTS: None
*
* PARAMETERS: none
*
* RETURNS: None
*
*-------------------------------------------------------------------------*/
void FlashEthled()
{
UBYTE ii;
UWORD jj;
for (ii = 0; ii<20; ii++)
{
Ethled(ii%2); /* Turn on every other time through the loop */
for (jj=0; jj < 100000; jj++); /* Wait */
}
Ethled(0); /* LED off */
} /* end FlashEthled */
/*--------------------------------------------------------------------------
*
* FUNCTION NAME: ExtIntHandler
*
* DESCRIPTION:
*
* Process External Interrupt (assumes only interrupts from SCC2)
*
* Main Processing Steps:
*
*
* (1) Match input vector against External Interrupt Vector
** (2) Test Interrupt Code in SIU Interrupt Vector Reg (SIVEC) against
* LEVEL 4.
* * (3) Request Interrupt Vector Number from CPM Interrupt Vector Reg
* (CIVR).
*
* (4) Test CIVR Interrupt Vector against Vector for SCC2.
*
* (5) Save a copy of SCCE.
*
* (6) Clear SCCE.
*
* (7) Process Global Interrupt Event.
* * (8) Clear SCC2 bit CPM Interrupt In-Service Register.
**
* NOTE: This ISR will only handle ONE RX event. This interrupt happens
* when the last frame of eight is received.
*
* EXTERNAL EFFECTS: interrupt related registers
*
* PARAMETERS:
** vector - interrupt vector (address)
*
* RETURNS: NONE
*
*-------------------------------------------------------------------------*/
void ExtIntHandler(UWORD vector)
{
UWORD sivec_ic;
UWORD scce;
UHWORD channel_number;
UHWORD entry_count = 0; /* counter for entries in ICT */
UHWORD index = 0;
/*-------------------------------------*/
/* Match input vector against External */
/* Interrupt Vector -- 0x500 on PPC */
/*-------------------------------------*/
if (vector != EXT_INT_VECTOR)
return;
/*------------------------------------*/
/* Shift the byte wide interrupt code */
/* down to the least significant byte */
/*------------------------------------*/
sivec_ic = IMMR->siu_sivec >> 24; /* sivec interrupt code */
/*-----------------------------*/
/* Process SIU Interrupt Event */
/*-----------------------------*/
switch(INTERRUPT_LEVEL)
{
case 4:
if(sivec_ic != IC_LEVEL_4)
return;
break;
default:
return; /* INTERRUPT NOT Level 4 */
}
/*----------------------------------------------------------*/
/* Set IACK bit in CIVR to request current interrupt vector */
/*----------------------------------------------------------*/
IMMR->cpmi_civr |= CIVR_IACK;
/*-----------------------------------------------*/ /* Test CPM Interrupt Vector against SCC2 Vector */
/*-----------------------------------------------*/ if ((IMMR->cpmi_civr >> 11) != SCC2_VECTOR)
return;
/*----------------------------------------*/
/* Save a copy of the SCC event register, */
/* then clear the actual SCCE. */
/*----------------------------------------*/
scce = IMMR->scc_regs[SCC2_REG].scc_scce;
IMMR->scc_regs[SCC2_REG].scc_scce = ALL_ONES;
/*-------------------------------------------*/
/* Process SCC Global Interrupt Event (GINT) */
/*-------------------------------------------*/
UHWORD exit_flag = FALSE;
if (scce & 0x0004)
{
/*-----------------------------------*/
/* Traverse Interrupt Circular Table */
/* from first entry to last */
/*-----------------------------------*/
while (!exit_flag)
{
/*------------------------------------------*/
/* Look for a set "Valid" bit in each table */
/* entry. Then make sure this entry's event */
/* is RXB. RXB is the only event */
/* ExtIntHandler will process. */
/*------------------------------------------*/
if ((IntCQ[entry_count] & QMC_ITE_V) &&
(IntCQ[entry_count] & QMC_ITE_RXB))
{
/*---------------------------------*/
/* Get Channel Number for this ITE */
/*---------------------------------*/
channel_number = (IntCQ[entry_count] & QMC_ITE_CN);
channel_number = (channel_number >> 6);
/*--------------------------------------------*/
/* Traverse through available Receive Buffers */
/* to locate first filled buffer. */
/*--------------------------------------------*/
while ((!BDEmpty(RxTxBD->RxBD[index].bd_cstatus) &&
(index < NUM_RXBDS)))
{
/*************************************************************/
/* In this example, every frame encompasses a buffer */
/* descriptor's worth of data. This a very simple */
/* example. Normally there could be several BD's in a */
/* frame, and once a data buffer was processed, it could */
/* be released for use. Note also that the BDs in this */
/* example are processed in linear fashion. Typically, */
/* BD's would not be guaranteed to be linear, so more */
/* "realistic" interrupt code would have to search for */
/* the next BD that wasn't empty and process it accordingly. */
/*************************************************************/
/*--------------------------------------------------------*/
/* In this example, EVERY BD is the first and last BD in */
/* frame, because every frame holds one buffer per BD. We */
/* include the function "LastBD()" so that the user can */
/* expand/modify the code to consider multiple BDs in one */
/* frame. */
/*--------------------------------------------------------*/
if(LastBD(RxTxBD->RxBD[index].bd_cstatus))
/*changed for HDLC version from "!LastBD"*/
{
RxTxBD->RxBD[index].bd_cstatus |= 0x8000; /* set empty flag */
/*-------------------------------------*/
/* checking all status bits for errors */
/*-------------------------------------*/
if (BDRxError(RxTxBD->RxBD[index].bd_cstatus))
{
RxGood = FALSE;
}
}
/*------------------------------------------*/
/* This is the last BD in the chain. Clear */
/* all bits but the Ready bit and Wrap bit. */
/*------------------------------------------*/
if (index == (NUM_RXBDS-1))
{
RxTxBD->RxBD[index].bd_cstatus = 0xA000;
}
/*------------------------------------*/
/* Set RX process index to start next */
/* BD scan from the BD after this one */
/*------------------------------------*/
RxProcIndex = index+ 1;
index++;
} // while
} // if
/*--------------------------------------------------*/
/* If "Wrap" bit is set in this ITE: */
/* */
/* 1) Set flag to exit after we process this entry. */
/* 2) Clear the entry, preserving the wrap bit. */
/* */
/* ELSE just clear the entire entry. */
/*--------------------------------------------------*/
if (IntCQ[entry_count] & QMC_ITE_W)
{
exit_flag = TRUE;
IntCQ[entry_count] &= (QMC_ITE_CLEAR | QMC_ITE_W);
}
else
{
IntCQ[entry_count] &= QMC_ITE_CLEAR;
}
entry_count++;
} // while
} // if
else
RxGood = FALSE; /* Expected to see RXB event in SCCE */
/*-----------------------------------------------------------------*/
/* Clear CPM Interrupt In-Service Register SCC2 bit (by writing 1) */
/*-----------------------------------------------------------------*/
IMMR->cpmi_cisr |= CISR_SCC2;
} /* end ExtIntHandler */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -