📄 aal5_sar.c
字号:
/* point to the start of the table */
ptr_start = (UHWORD *)(IMMR->PRAM[SCC_num].sar.lookup.apbase +
IMMR->udata_bd_ucode);
/* Initialize raw cell entry */
*ptr_start-- = IMMR->PRAM[SCC_num].sar.ctbase;
/* Initialize ch 1 entry (add CT_SIZE to get to Ch 1) */
*ptr_start = IMMR->PRAM[SCC_num].sar.ctbase + CT_SIZE;
/* Configure address match table end (AMEND) to point to the top */
/* entry (in this case we only have 2 entries, ch0 & ch 1) */
IMMR->PRAM[SCC_num].sar.lookup.amend = (IMMR->PRAM[SCC_num].sar.lookup.ambase
- 4);
/*-----------------------------------------------------------------*/
/* Now initialize the entries in the match table */
/*-----------------------------------------------------------------*/
/* Get address of table */
ptr_word = (UWORD *)(IMMR->PRAM[SCC_num].sar.lookup.ambase +
IMMR->udata_bd_ucode);
/* Init Ch 0 entry */
*ptr_word-- = 0x0;
ptr_word2 = (UWORD *)&header_rcv;
/* Init Ch 1 entry */
*ptr_word = ((*ptr_word2) & IMMR->PRAM[SCC_num].sar.lookup.hmask);
/*-----------------------------------------------------------------*/
/* Initialize RISC Timer 0. Timer 0 provides the receive time */
/* stamp for AAL5 frames (time stamp is recorded in the RCT) */
/*-----------------------------------------------------------------*/
IMMR->cp_rccr |= 0x3F90; /* Set timer tick to 65,536 system clocks */
/* Get address of timer parameters */
ptr_risc_timer =
(struct timer_pram *)&IMMR->PRAM[1].pg.other.spi_timer_idma.timer;
ptr_risc_timer->tm_base = 0x0; /* RISC timer base, offset from DPR */
/* Indicate that timer 0 is used for the Time Stamp Timer Address */
/* (TSTA) */
IMMR->PRAM[SCC_num].sar.tsta = ptr_risc_timer->tm_base;
ptr_risc_timer->tm_cnt = 0; /* Indicate that no ticks have occured */
/* i.e. timer count */
/* Set the valid & automatic restart bits */
ptr_risc_timer->tm_cmd = 0xC0000000;
/* wait until CPM is ready to accept a command, i.e., flag = 0 */
while(IMMR->cp_cr & CMD_FLAG);
/* Now, issue the "set timer" command to get timer going */
IMMR->cp_cr = 0x0850 | CMD_FLAG;
/* make sure CPM completes the command before continuing i.e., */
/* flag = 0 */
while(IMMR->cp_cr & CMD_FLAG);
/* enable the RISC timer (start generating ticks) */
IMMR->cp_rccr |= 0x8000;
}
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: InitAPC
*
*
* DESCRIPTION:
*
* Initializes the transmit ATM Pace Controller and Timer 4.
*
* EXTERNAL EFFECTS: Initialize APC Parameters in DPR and Timers.
*
* PARAMETERS: None
*
* RETURNS: None
*
*-----------------------------------------------------------------------------*/
void InitAPC()
{
UBYTE *ptr_char;
UHWORD *ptr_start, *ptr_end;
APC_PARAMETER_TABLE_PL2 *ptr_apc_table;
/*--------------------------------------------------------------------*/
/* Configure the start (address) of the APC Parameters */
/*--------------------------------------------------------------------*/
IMMR->PRAM[SCC_num].sar.apcptr = APC_PARAM_OFFSET;
/*----------------------------------------------------------*/
/* ATM Pace Controller Intialization */
/*----------------------------------------------------------*/
/* Get address of APC Table in DPR */
ptr_char = (UBYTE *)(IMMR->udata_bd_ucode) +
IMMR->PRAM[SCC_num].sar.apcptr;
ptr_apc_table = (APC_PARAMETER_TABLE_PL2 *)(ptr_char);
/* Base/start of APC Table */
ptr_apc_table->apct_base1= APC_BASE_OFFSET;
/* Reset table pointer to the beginning of the table */
ptr_apc_table->apct_ptr1= APC_BASE_OFFSET;
/* Reset service pointer to the beginning of the table */
ptr_apc_table->apct_sptr1= APC_BASE_OFFSET;
/* End of APC Table */
ptr_apc_table->apct_end1 = APC_END_OFFSET;
ptr_apc_table->ncist = 0x0100; /* Transmit 1 cell per time slot */
ptr_apc_table->apc_mi = 0x4; /* maximum iteration */
ptr_apc_table->apcnt = 0x0; /* APC-N Timer, init to 0 */
/*----------------------------------------------------------------*/
/* Initialize the APC first priority table (invalidate table) */
/* entries. */
/*----------------------------------------------------------------*/
/* Get starting address of APC first priority table */
ptr_char = (UBYTE *)(IMMR->udata_bd_ucode) +
ptr_apc_table->apct_base1;
ptr_start = (UHWORD *)ptr_char;
/* Get ending address of APC first priority table */
ptr_char = (UBYTE *)(IMMR->udata_bd_ucode) +
ptr_apc_table->apct_end1;
ptr_end = (UHWORD *)ptr_char;
while(ptr_start < ptr_end)
*ptr_start++ = 0xFFFF;
/*----------------------------------------------------------------*/
/* Configure the APC status register so that it knows SCCx is the */
/* active ATM interface */
/*----------------------------------------------------------------*/
IMMR->PRAM[SCC_num].sar.apcst = 0x7800; /* Both CSER & NSER are */
/* the same */
/*---------------------------------------------------------------*/
/* NOTE: If SCC4 is not used, then SCC4's CSER and NSER must */
/* point to the active SCC (i.e. the SCC selected in SCC_num) and*/
/* bit 13 of the APCST must be set (DISable SCC4 bit). */
/*---------------------------------------------------------------*/
if(SCC_num != SCC4)
{
switch(SCC_num)
{
/* Select SCC1 as the serial interface */
case SCC1:
IMMR->PRAM[SCC4].sar.apcst = 0x0004; /* Both CSER & NSER must be */
/* the same. */
break;
/* Select SCC2 as the serial interface */
case SCC2:
IMMR->PRAM[SCC4].sar.apcst = 0x2804; /* Both CSER & NSER must be */
/* the same. */
break;
/* Select SCC3 as the serial interface */
case SCC3:
IMMR->PRAM[SCC4].sar.apcst = 0x5004; /* Both CSER & NSER must be */
/* the same. */
}
}
/*---------------------------------------------*/
/* Timer 4 Configuration. Timer 4 is used to */
/* drive the APC. */
/*---------------------------------------------*/
/* Reset timer 4 and configure it for normal operation */
/* i.e. not cascaded. */
IMMR->timer_tgcr = (IMMR->timer_tgcr & 0x0FFF); /* Timer is disabled */
IMMR->timer_tmr4 = 0x000a; /* program as a free running timer */
/* with an internally sourced clock */
IMMR->timer_trr4 = 0x8500; /* Timer reference count, i.e. the */
/* number of clock ticks it takes */
/* for the APC to schedule a chan */
/* to xmit */
IMMR->timer_tcn4 = 0x300; /* Intialize the counter to 0x300 */
/*
* NOTE: DON'T ENABLE TIMER4 UNTIL ALL SAR PARAMETERS
* HAVE BEEN CONFIGURED!! ENABLING THE TIMER BEFORE ALL
* INITIALIZATION IS COMPLETE MAY RESULT IN ERRORS (see main()).
*/
}
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: InitBDs
*
*
* DESCRIPTION:
*
* Initializes the transmit and receive Buffer Descriptors (BDs). For this
* example, the BDs initialized correspond to the channel in use as well as the
* raw cell Buffers required for unidentified cells.
*
* EXTERNAL EFFECTS: Disable Tx/Rx functions. Changes BDs in external memory.
*
* PARAMETERS: None
*
* RETURNS: None
*
*-----------------------------------------------------------------------------*/
void InitBDs()
{
UWORD bd_num;
BD_860SAR *ptr_xmit_bd;
BD_860SAR *ptr_rcv_bd;
UWORD *ptr_word, *ptr_queue_end;
UWORD address;
UWORD mask = 0x3; /* Default to SCC1 mask */
/*--------------------------------------------------------------------*/
/* Configure the start of the external receive/transmit connection */
/* table. Note, this is only used when running in extended mode. */
/*--------------------------------------------------------------------*/
IMMR->PRAM[SCC_num].sar.ectbase = EXT_CT_ADDR;
/*--------------------------------------------------------------------*/
/* Configure the base address of the interrupt queue */
/*--------------------------------------------------------------------*/
IMMR->PRAM[SCC_num].sar.intbase = INT_QUEUE_ADDR;
/* point to the beginning the int. queue */
IMMR->PRAM[SCC_num].sar.intptr = INT_QUEUE_ADDR;
Ptr_int_queue = (UWORD *)IMMR->PRAM[SCC_num].sar.intbase;
/*****************************************************************/
/* NOTE: both int_icnt AND int_cnt must be initialized to same */
/* value. In this case, an interrupt is generated after 1 event */
/*****************************************************************/
IMMR->PRAM[SCC_num].sar.int_icnt = 0x1; /* Interrupt initiate count */
/* (copied to int_cnt after an */
/* interrupt). */
IMMR->PRAM[SCC_num].sar.int_cnt = 0x1; /* Interrupt counter, i.e. set */
/* set GINT in SCCE after 1 */
/* interrupt is the int queue */
/*--------------------------------------------------------------*/
/* Intialize interrupt queue entries, for this demo, we've */
/* allocated 0x100 interrupt entries in the queue, each entry */
/* is 32 bits. */
/*--------------------------------------------------------------*/
ptr_word = (UWORD *)IMMR->PRAM[SCC_num].sar.intbase;
ptr_queue_end = ptr_word + NUM_QUEUE_ENTRIES;
while(ptr_word < ptr_queue_end)
*ptr_word++ = 0x0;
/* The last entry in the interrupt queue must have the "wrap" */
/* bit set so that if we get to the end, at starts at the base */
/* again */
--ptr_word; /* point to the last entry */
*ptr_word = 0x40000000; /* set the "w" bit */
/*--------------------------------------------------------------------*/
/* Initialize the CRC32 constant mask (used by receiver to check CRC) */
/* This value is set once and MUST be 0xdebb20e3. */
/*--------------------------------------------------------------------*/
IMMR->PRAM[SCC_num].sar.c_mask = 0xDEBB20E3;
/*--------------------------------------------------------------------*/
/* Empty Cell header */
/*--------------------------------------------------------------------*/
IMMR->PRAM[SCC_num].sar.ehead = 0x0;
IMMR->PRAM[SCC_num].sar.epayload = 0x6A6A6A6A;
/*--------------------------------------------------------------------*/
/* Serial interface parameter configuration (init values per UM). */
/*--------------------------------------------------------------------*/
IMMR->PRAM[SCC_num].sar.alpha = 0x7;
IMMR->PRAM[SCC_num].sar.delta = 0x6;
IMMR->PRAM[SCC_num].sar.shufflestate = 0;
IMMR->PRAM[SCC_num].sar.astatus = 0;
IMMR->PRAM[SCC_num].sar.hec_err = 0;
IMMR->PRAM[SCC_num].sar.rscram = 0;
IMMR->PRAM[SCC_num].sar.rscram1 = 0;
IMMR->PRAM[SCC_num].sar.tscram = 0;
IMMR->PRAM[SCC_num].sar.tscram1 = 0;
/*--------------------------------------------------------------------*/
/* Initialize the Transmit Buffer Descriptor */
/*--------------------------------------------------------------------*/
/* 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 Frames that will transmitted */
address = (UWORD)Frames_to_xmit;
for(bd_num=0;bd_num < NUM_FRAMES;bd_num++,ptr_xmit_bd++)
{
/* Set the length of the frame to transmit */
ptr_xmit_bd->length = FRAME_LENGTH;
/* Point the Frame Data structure (i.e. xmit buffer) */
ptr_xmit_bd->buf= (UBYTE *)address;
/* Increment address for next Frame buffer */
address += FRAME_LENGTH;
/* Initialize CPCS, UU & CPI fields of the PDU */
ptr_xmit_bd->cpcs_uu_cpi = 0;
/* Initialize the control/status word. */
/* NOTE: Do this last. Set "Ready" and "Last" bits */
ptr_xmit_bd->status = 0x8800;
}
/* Initialise the status of the LAST TX buffer descriptor */
/* Set the "Ready" "Wrap" "Interrupt" and "Last" bits. */
--ptr_xmit_bd;
ptr_xmit_bd->status = 0xB800;
/*-------------------------------------------------------------------*/
/* Initialize the Receive Buffer Descriptor */
/*-------------------------------------------------------------------*/
/* Get the starting address of the receive buffer descriptor */
ptr_rcv_bd = (BD_860SAR *)(IMMR->PRAM[SCC_num].sar.rbdbase);
/* Get the Starting address of buffers for incoming frames */
address = (UWORD)Received_frames;
for(bd_num=0;bd_num < NUM_FRAMES;bd_num++,ptr_rcv_bd++)
{
/* Clear the "length" of the frame received */
ptr_rcv_bd->length = 0;
/* Point the Frame Data structure (i.e. receive buffer) */
ptr_rcv_bd->buf= (UBYTE *)address;
/* Increment address for next Frame buffer */
address += FRAME_LENGTH;
/* Initialize the control/status word. */
/* Set the "Empty" and "Interrupt" bits */
ptr_rcv_bd->status = 0x9000;
}
/* Initialise the status of the LAST RX buffer descriptor */
/* Set the "Empty" "Wrap" and "Interrupt" bits. */
--ptr_rcv_bd;
ptr_rcv_bd->status = 0xB000;
/*-------------------------------------------------------------------*/
/* Initialize the Raw Cell Receive Buffer Descriptor */
/*-------------------------------------------------------------------*/
ptr_rcv_bd = (BD_860SAR *)RAW_RBD_ADDR;
/* Set up the raw cell Buffer Descriptors */
address = (UWORD)Raw_cells; /* Get starting address */
/* of raw cell rcv buff */
for(bd_num = 0; bd_num < NUM_RAW_CELL_BUFFS; bd_num++,ptr_rcv_bd++)
{
/* Point the Frame Data structure (i.e. receive buffer) */
ptr_rcv_bd->buf= (UBYTE *)address;
/* Increment buffer address */
address += RAW_CELL_BUFF_SIZE;
/* Clear the "length" of the frame to received */
ptr_rcv_bd->length = 0;
/* Initialize the control/status word */
/* Set the "Empty" bit. */
ptr_rcv_bd->status = 0x8000;
}
/* Initialise the status of the LAST RX RAW buffer descriptor */
/* Set the "Empty" and "Wrap" bits. */
--ptr_rcv_bd;
ptr_rcv_bd->status = 0xA000;
} /* end InitBDs */
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: InitBuffers
*
* DESCRIPTION:
*
* This function will initialize the receive buffers to zero to make sure
* they are at a known state before data is received (helps in debugging).
* The transmit buffers (frames) will have the following patterns:
*
* Buffer 1: 0x01
* Buffer 2: 0x02
* Buffer n: 0xnn
*
*
* EXTERNAL EFFECTS:
*
* ReceivedFrames = 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -