📄 860qmc1h.c
字号:
/*--------------------------------------------------------------------------
*
* FUNCTION NAME: InterruptInit
*
*
* DESCRIPTION:
*
* Copy Interrupt Handler code from its current address to the
* specified PowerPC Interrupt Vector. Additionally, initializes
* interrupt-related parameters in the SIU and CPM. Includes steps 12,
* 19, 21, and 22 of the QMC initialization procedure.
*
*
* EXTERNAL EFFECTS:
*
* PARAMETERS:
*
* interrupt_vector -- address to which interrupt code should be copied
* interrupt_code -- current address of interrupt code
*
* RETURNS: NONE
*
*--------------------------------------------------------------------------*/
void InterruptInit(UWORD *interrupt_vector,
UWORD interrupt_code[])
{
UWORD index;
UWORD *instruction;
UWORD *next_vector;
/*----------------------------------------------*/
/*Copy ExtIntTable code (see "startup.s") into */
/* PPC external interrupt vector (0x500) */
/*----------------------------------------------*/
next_vector = (interrupt_vector + VECTOR_BLOCK_LEN); /* next vector entry */
for(instruction = interrupt_vector, index = 0; instruction < next_vector;
instruction++, index++)
*instruction = interrupt_code[index];
/*-------------------------------------------*/
/* Initialize the Interrupt Circular Table: */
/* */
/* - Clear all 16 bit elements */
/* - Set wrap bit in last element */
/*-------------------------------------------*/
for (UWORD count = 0; count < MAXLOGCHAN; count++)
IntCQ[count] = 0;
IntCQ[MAXLOGCHAN-1] |= QMC_ITE_W;
/*-----------------------------------------*/
/* Clear SCCE Register by writing all 1's. */
/*-----------------------------------------*/
IMMR->scc_regs[SCC2_REG].scc_scce = ALL_ONES;
/*---------------------------------*/
/* Set SCCM for interrupts on GINT */
/*---------------------------------*/
IMMR->scc_regs[SCC2_REG].scc_sccm = 0x04;
/*---------------------------------------------*/
/* Enable SCC2 Interrupts to the CP Interrupt */
/* Controller */
/*---------------------------------------------*/
IMMR->cpmi_cimr = CIMR_SCC2;
/*-------------------------------------------------------------*/
/* Clear Pending Interrupts in CIPR -- Clear bits by writing 1 */
/*-------------------------------------------------------------*/
IMMR->cpmi_cipr = ALL_ONES;
/*-----------------------------------------------*/
/* Set Appropriate Interrupt Level Bit in SIMASK */
/*-----------------------------------------------*/
switch(INTERRUPT_LEVEL)
{
case 0:
IMMR->siu_simask = SIMASK_LVM0;
break;
case 1:
IMMR->siu_simask = SIMASK_LVM1;
break;
case 2:
IMMR->siu_simask = SIMASK_LVM2;
break;
case 3:
IMMR->siu_simask = SIMASK_LVM3;
break;
case 4:
IMMR->siu_simask = SIMASK_LVM4;
break;
case 5:
IMMR->siu_simask = SIMASK_LVM5;
break;
case 6:
IMMR->siu_simask = SIMASK_LVM6;
break;
case 7:
IMMR->siu_simask = SIMASK_LVM7;
break;
default:
break; /* Bad value */
} /* end switch */
/*----------------------------------------------------------------*/
/* Write CICR to Configure SCC2 Interrupt Priority Settings: */
/* */
/* SCC Priorities */
/* SCC2 - Highest Priority */
/* IRL0-IRL2 (Interrupt Request Level) = Constant set by user */
/* HP0-HP4 (Highest Priority) = Original Priority */
/* IEN = Enable CPM Interrupts */
/*----------------------------------------------------------------*/
IMMR->cpmi_cicr = 0x00E11F80 | (INTERRUPT_LEVEL << 13);
/*-----------------------------------------*//* Enable External Interrupts at CPU level */
/*-----------------------------------------*/
#ifdef MetaWare
_ASM(" mtspr 80, 0 "); /* Enable EE Bit in MSR */
#else
#ifdef Diab
asm(" mtspr 80, 0 "); /* Enable EE Bit in MSR */
#endif
#endif
} /* end InterruptInit */
/*-------------------------------------------------------------------------
*
* FUNCTION NAME: LoadTxBuffers
*
*
* DESCRIPTION:
*
* This function loads all 8 Tx buffers with the following data
* patterns:
*
* Buffer 0: 0x55
* Buffer 1: 0xAA
* Buffer 2: 0x00
* Buffer 3: 0xFF
* Buffer 4: Increasing Walking Ones
* Buffer 5: Decreasing Walking Ones
* Buffer 6: Increment from 0
* Buffer 7: Decrement from 255
*
* EXTERNAL EFFECTS:
*
* BufferPool
*
* PARAMETERS: none
*
* RETURNS: none
*
*-------------------------------------------------------------------------*/
void LoadTxBuffers()
{
UWORD index, pattern;
/*---------------------------------------------------*/
/* Load buffers 0 through 3 with the following data */
/* patterns: */
/* */
/* Buffer[0] = 0x55 */
/* Buffer[1] = 0xAA */
/* Buffer[2] = 0x00 */
/* Buffer[3] = 0xFF */
/*---------------------------------------------------*/
/*--------------------------------------------------------------*/
/* Note that the data is a little smaller than the BD length to */
/* leave space for idle characters (FF). */
/*--------------------------------------------------------------*/
for (index = 0; index < (BUFFER_SIZE-4); index++)
{
BufferPool[FIRST_TX_BUF][index] = 0x55;
BufferPool[FIRST_TX_BUF+1][index] = 0xAA;
BufferPool[FIRST_TX_BUF+2][index] = 0x00;
BufferPool[FIRST_TX_BUF+3][index] = 0xFF;
}
/*-----------------------------------------*/
/* Buffer[4]: Load increasing walking ones */
/*-----------------------------------------*/
for (index = 0,pattern = 1; index < (BUFFER_SIZE-4); index++,pattern<<=1)
{
if (pattern == 0x0100)
{
pattern = 0x01;
}
BufferPool[FIRST_TX_BUF+4][index] = pattern;
}
/*-----------------------------------------*/
/* Buffer[5]: Load decreasing walking ones */
/*-----------------------------------------*/
for (index = 0,pattern = 0x80; index < (BUFFER_SIZE-4); index++,pattern>>=1)
{
if (pattern == 0x00)
{
pattern = 0x80;
}
BufferPool[FIRST_TX_BUF+5][index] = pattern;
}
/*--------------------------------------------*/
/* Buffer[6]: Load "Increment from 0" pattern */
/*--------------------------------------------*/
for (index = 0; index < (BUFFER_SIZE-4); index++)
{
BufferPool[FIRST_TX_BUF+6][index] = index-2;
}
/*----------------------------------------------*/
/* Buffer[7]: Load "Decrement from 255" pattern */
/*----------------------------------------------*/
for (index = 0; index < (BUFFER_SIZE-4); index++)
{
BufferPool[FIRST_TX_BUF+7][index] = (257-index);
}
} /* end of LoadTxBuffers */
/*------------------------------------------------------------------------
*
* FUNCTION NAME: InitBDs
*
*
* DESCRIPTION:
*
* Initializes BD rings to point RX BDs to first half of buffer pool and
* TX BDs to second half of buffer pool. This function also initializes the
* buffer descriptors control and data length fields. It also insures that
* transmit and receive functions are disabled before buffer descriptors
* are initialized. Includes steps 17 and 18 of the QMC initialization
* procedure.
*
*
* EXTERNAL EFFECTS: Disable Tx/Rx functions. Changes BDs in dual port ram.
*
* PARAMETERS: None
*
* RETURNS: None
*
*-------------------------------------------------------------------------*/
void InitBDs()
{
UWORD index;
RxTxBD = (BDRINGS *) 0x40000;
/*-------------------*/ /* Initialize RxBDs. */
/*-------------------*/ for (index = 0; index < NUM_RXBDS; index++)
{
/*--------------------------*/
/* Allocate Receive Buffers */
/*--------------------------*/
RxTxBD->RxBD[index].bd_addr = (UBYTE *)&BufferPool[index];
RxTxBD->RxBD[index].bd_length = 0; /* reset */
if( index != (NUM_RXBDS-1) )
{
RxTxBD->RxBD[index].bd_cstatus = 0x8000; /* Empty */
}
else
{
/*-----------------------------------------------------*/ /* Last RX BD. Set the Empty, Wrap, and Interrupt bits */
/*-----------------------------------------------------*/ RxTxBD->RxBD[index].bd_cstatus = 0xB000;
}
}
/*-------------------*/ /* Initialize TxBDs. */
/*-------------------*/ for (index=0; index < NUM_TXBDS; index++)
{
/*------------------------*/
/* load the buffer length */
/*------------------------*/
RxTxBD->TxBD[index].bd_length = (BUFFER_SIZE-4);
/*--------------------------------------------------------*/
/* load the address of the data buffer in external memory */
/*--------------------------------------------------------*/
RxTxBD->TxBD[index].bd_addr = (UBYTE *)&BufferPool[FIRST_TX_BUF+index];
if( index != (NUM_TXBDS-1) )
{
/*----------------------*/
/* Set Ready, Last bits */
/*----------------------*/
RxTxBD->TxBD[index].bd_cstatus = 0x8C00;
}
else
{
/*----------------------------*/
/* Set Ready, Wrap, Last bits */
/*----------------------------*/
RxTxBD->TxBD[index].bd_cstatus = 0xAC00;
}
}} /* end InitBDs */
/*------------------------------------------------------------*
*
* FUNCTION NAME: QMC_ChannelInit
*
* DESCRIPTION:
*
* Initializes the QMC channel-specific parameter ram for
* QMC logical channel 0. Includes steps 16 and 20 of QMC
* initialization procedure.
*
* EXTERNAL EFFECTS: see above
*
* PARAMETERS: none
*
* RETURNS: none
*
*------------------------------------------------------------*/
void QMC_ChannelInit()
{
IMMR->qcp_or_ud.qcp[0].h_or_t.t.rbase=
IMMR->qcp_or_ud.qcp[0].h_or_t.t.rbptr= 0;
IMMR->qcp_or_ud.qcp[0].h_or_t.t.tbase=
IMMR->qcp_or_ud.qcp[0].h_or_t.t.tbptr=0x40;
IMMR->qcp_or_ud.qcp[0].h_or_t.t.tstate=0x30000000;
IMMR->qcp_or_ud.qcp[0].h_or_t.t.rstate=0x31000000;
IMMR->qcp_or_ud.qcp[0].h_or_t.t.zistate=0x100;
IMMR->qcp_or_ud.qcp[0].h_or_t.t.zdstate=0x00000080;
IMMR->qcp_or_ud.qcp[0].h_or_t.t.tmrblr=BUFFER_SIZE;
IMMR->qcp_or_ud.qcp[0].h_or_t.t.intmsk=1;
IMMR->qcp_or_ud.qcp[0].h_or_t.t.chamr=0xB180;
}/* end QMC_ChannelInit */
/*--------------------------------------------------------------------------
*
* FUNCTION NAME: BDRxError
*
* DESCRIPTION:
*
* Return TRUE if Buffer Descriptor Status bd_cstatus indicates Receive
* Error; Return FALSE otherwise note Receive Errors are as follows:
** 0x80: DPLL Error (DE)
* 0x20: Length Violation (LG)
* 0x10: Non-Octet Aligned (NO)
* 0x8: Rx Abort Sequence (AB)
* 0x4: Rx CRC Error (CR)
* 0x2: Overrun (OV)
* 0x1: Carrier Detect Lost (CD)
** EXTERNAL EFFECTS: None
*
* PARAMETERS:
*
* bd_cstatus
*
* RETURNS: TRUE if there was an error and FALSE if there wasn't
*
*-------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -