📄 aal5_sar.c
字号:
* 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: ExtIntHandler
*
* DESCRIPTION:
*
* Process External Interrupt (assumes only interrupts from SCCx)
*
* Main Processing Steps:
*
* (1) Save off SCCE for SCCx
*
* (2) Test input vector against External Interrupt Vector.
*
* (3) Test Interrupt Code in SIU Interrupt Vector Reg (SIVEC) against
* LEVEL 4.
*
* (4) Clear LEVEL 4 Interrupt Level bit in SIPEND.
*
* (5) Request Interrupt Vector Number from CPM Interrupt Vector Reg
* (CIVR).
*
* (6) Test CIVR Interrupt Vector against Vector for SCCx.
*
* (7) Clear SCCx Event Register
*
* (8) Test SCCx Event
*
* (9) Clear the SAR interrupt queue.
*
* (10) Clear SCCx bit CPM Interrupt In-Service Register
*
*
* NOTE: This ISR will handle Synchronization and Global Interrupt
* events in the SCC event registers. The type of global
* interrupt is further defined in the interrupt queue. Global
* interrupts handled: Received Frame & Transmit Buffer.
*
* EXTERNAL EFFECTS: interrupt related registers
*
* PARAMETERS:
*
* vector - interrupt vector (address)
*
* RETURNS: NONE
*
*-----------------------------------------------------------------------------*/
void ExtIntHandler(UWORD vector)
{
UWORD sivec_ic;
UWORD mask = CISR_SCC1;
BD_860SAR *ptr_xmit_bd;
BD_860SAR *ptr_rcv_bd;
UWORD bd_num;
/* Get the starting address of the txmit buffer descriptor */
ptr_xmit_bd = (BD_860SAR *)(IMMR->PRAM[SCC_num].sar.tbdbase);
/* Get the starting address of the receive buffer descriptor */
ptr_rcv_bd = (BD_860SAR *)(IMMR->PRAM[SCC_num].sar.rbdbase);
/*-----------------------------------------------------------------------*/
/* Shift the byte wide interrupt code down to the least significant byte */
/*-----------------------------------------------------------------------*/
sivec_ic = IMMR->siu_sivec >> 24; /* sivec interrupt code */
/*-----------------------------*/
/* Grab the SCC event register */
/*-----------------------------*/
Event_register = IMMR->scc_regs[SCC_num].scc_scce; /* Save off scce */
/*-----------------------------*/
/* 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 SCCx Vector */
/*-----------------------------------------------*/
if ((IMMR->cpmi_civr >> 11) != (0x1E - SCC_num))
return;
/*-------------------------------------------*/
/* Clear SCCx Event Register (by writing 1s) */
/*-------------------------------------------*/
IMMR->scc_regs[SCC_num].scc_scce = ALL_ONES;
/*-------------------------------------------*/
/* If it's the synchronization event, just */
/* return. main() will enable the xmiter. */
/*-------------------------------------------*/
if(Event_register & SAR_SERIAL_SCCE_SYNC)
{
/* Clear the event and service registers */
/* before returning */
IMMR->scc_regs[SCC_num].scc_scce = ALL_ONES;
IMMR->cpmi_cisr |= (mask >> (1*SCC_num));
/* Return control, the receiver achieved */
/* synchronization */
return;
}
/*----------------------------------------------------------------*/
/* Process Global Interrupt. The only events (as defined in */
/* imask) generating an interrupt queue entry are the Transmit */
/* buffer and Receive Frame events. The valid bit is cleared */
/* in the interrupt queue. */
/*----------------------------------------------------------------*/
if(Event_register & SAR_SERIAL_SCCE_GINT)
{
/*-------------------------------------------------------------------*/
/* The software expects to receive Frames in order of transmission */
/* and as such expects the received buffers to be filled sequentially*/
/* as programmed by InitBDs(). Any errors detected in the status of */
/* Rx or Tx BD status word will result in an error condition. */
/*-------------------------------------------------------------------*/
/*-----------------------------------------*/
/* Get Interrupt queue entry, we process */
/* all entries in the queue. i.e. while */
/* the valid bit in the queue entry is set */
/*-----------------------------------------*/
while(*Ptr_int_queue & Q_ENTRY_VALID)
{
/*****************************************/
/* Check the Transmitt Buffer event. */
/*****************************************/
if(*Ptr_int_queue & TXB)
{
/* Check That all frames where transmitted */
/* (Ready bit is 0) */
for(bd_num=0;bd_num < NUM_FRAMES;bd_num++,ptr_xmit_bd++)
{
/* If the Ready bit is set, then flag an error */
/* This interrupt is generated ONLY when the */
/* last Frame has been transmitted. */
if(BDEmpty(ptr_xmit_bd->status))
RxGood=FALSE;
}
} /* End of if(...TXB) */
/*****************************************/
/* Check the Receive Frame event. */
/*****************************************/
/*---------------------------------------------------------*/
/* Compare the Rx buffer with it's corresponding Tx buffer */
/* buffer. All Frames are received in order in which they */
/* were transmitted. */
/*---------------------------------------------------------*/
if(*Ptr_int_queue & RXF)
{
if (memcmp((Received_frames + (RxProcIndex * FRAME_LENGTH)),
(Frames_to_xmit + (RxProcIndex * FRAME_LENGTH)),
(FRAME_LENGTH)))
{
RxGood=FALSE; /* they didn't compare */
}
/* The receive BD status should indicate that the buffer */
/* is full */
if(BDEmpty(ptr_rcv_bd->status))
RxGood=FALSE;
/* Check if there were any errors */
if(BDRxError(ptr_rcv_bd->status))
RxGood=FALSE;
++ptr_rcv_bd; /* Move on to next Buffer Descriptor */
++RxCount; /* Increment Received Frame Count */
RxProcIndex++;
} /* End of if(...RXF) */
/* Clear the valid bit in the interrupt queue */
*Ptr_int_queue &= 0x4FFFFFFF;
/***********************************************************/
/* Reset the pointer if we've reached the last queue entry */
/***********************************************************/
if(*Ptr_int_queue & 0x40000000)
{
Ptr_int_queue = (UWORD *)IMMR->PRAM[SCC_num].sar.intbase;
}
/* Increment the Queue Pointer */
else
{
++Ptr_int_queue;
}
} /* End of while(...Q_ENTRY_VALID) */
IMMR->scc_regs[SCC_num].scc_scce = ALL_ONES;
IMMR->cpmi_cisr |= (mask >> (1*SCC_num));
} /* End of if(..GINT) */
else
RxGood = FALSE; /* Error, expected a Global Interrupt in SCCE */
/*---------------------------------------------------------------------*/
/* Here's our error loop. Spin here indefinitly if there was an error. */
/* NOTE: if you are debugging with SDS Monitor, set a breakpoint in */
/* the FlashEthled() line below to prevent the debbuger from */
/* hanging. This way, you can determine what caused the error. */
/*---------------------------------------------------------------------*/
if (RxGood == FALSE)
{
while (1)
FlashEthled(); /* spin here if error is flagged */
}
/*-----------------------------------------------------------------*/
/* Clear CPM Interrupt In-Service Register SCCx bit (by writing 1) */
/*-----------------------------------------------------------------*/
IMMR->cpmi_cisr |= (mask >> (1*SCC_num));
} /* end ExtIntHandler */
/*-----------------------------------------------------------------------------
*
* 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -