📄 aal5_sar.c
字号:
/*----------------------------------------------------------------------
*
* FILE: aal5_atm.c
*
* DESCRIPTION:
*
* This program sets up the MPC860SAR to transmit and receive 2
* Frames over channel 1 using ATM Adaptation Layer #5 (AAL5).
*
* The user can select which SCC to use by configuring a variable,
* SCC_num. This program uses SCC #4 by default, but the user can
* change SCC_num in main():
*
* SCC_num = SCC1; uses SCC #1
* SCC_num = SCC2; uses SCC #2
* SCC_num = SCC3; uses SCC #3
* SCC_num = SCC4; uses SCC #4
*
* The user can also select how many frames and the length of the
* frame by modifying NUM_FRAMES and FRAME_LENGTH respectively in
* sar.h. Each Frame will have an incremental pattern, i.e. frame
* 1 will have all 1's, frame 2 will have all 2's, frame 3 all 3's
* and so on.
*
* The data path is internally looped back via the DIAG (Diagnostic
* mode bits in the GSMR (General SCC Mode Register, Low).
*
* The transmitted data is compared to the received data. If there
* is an error (data mismatch) then the Ethernet LED on the ADS 860
* board will be flashed. If the transfer of data was successful the
* LED will stay lit constantly.
*
* For a high level explanation, please refer to the applications
* document for this example. This is included in the Zip file you
* received. If you are interested in a ADS 860 development/evaluation
* system, please contact your local sales representative.
*
*
* NOTES <<<IMPORTANT: PLEASE READ>>>:
*
* 1) Specifically Designed to run on 860 ADS board.
*
* 2) DISABLE Data Cache for pages containing Rx/Tx buffers.
*
* 3) This sample code tests the transmitted information against the
* received and turns on the ETH LED on the ADS board if there is
* an exact match. If there is not a match, then the ETH LED will
* flash.
*
* 4) If this program is run under BDM, you must first clear the
* EXTIE bit in the DER. Otherwise, the interrupt from the SCC
* will trap you back into the debugger. You can use the following
* MPC8BUG command to do this: rms der extie 0
*
*
* REFERENCES:
*
* 1) MPC860 Users Manual
* 2) MPC860SAR Communications Controller (Supplement to User's Manual)
* 3) PowerPC Microprocessor Family: The Programming Environments for
* 32-Bit Microprocessors
*
* HISTORY:
*
* April 1998 jes Initial Version.
*-----------------------------------------------------------------------------*/
#include <string.h>
#include <stdlib.h>
#include "netcomm.h" /* global defines */
#include "mpc860.h" /* IMMR definitions and declarations */
#include "sar.h" /* Local header file */
#include "masks860.h" /* Global masks header file */
/***********************/
/* Global Declarations */
/***********************/
EPPC *IMMR; /* IMMR base pointer */
UBYTE SCC_num; /* Variable identifying SCC to run sample on */
UHWORD Event_register; /* Variable containing copy of event register */
UWORD *Ptr_int_queue; /* Interrupt queue pointer */
UBYTE *Received_frames; /* Pointer to received frame buffers */
UBYTE *Frames_to_xmit; /* Pointer to xmit frame buffers */
UBYTE *Raw_cells; /* Pointer to received raw cell buffers */
/*---------------------------------------------------------*/
/* Status parameters of the receive and transmit processes */
/*---------------------------------------------------------*/
UHWORD RxGood; /* Successful RX flag */
UBYTE RxProcIndex; /* keeps track of next BD to process */
UBYTE RxCount; /* Received Frame Count */
/*----------------------------------------------------*/
/* Interrupt Handler Code to be moved to Offset 0x500 */
/*----------------------------------------------------*/
extern UWORD ExtIntTable[];
/***********************/
/* Function Prototypes */
/***********************/
void InterruptInit(UWORD *, UWORD[]);
void InitBDs(void);
void InitCTs(void);
void InitAPC(void);
void SCC_init(void);
void ExtIntHandler(UWORD);
void Main(void);
void InitBuffers(void);
UHWORD BDEmpty(UHWORD);
UHWORD LastBD(UHWORD);
void Ethled(UHWORD);
void FlashEthled(void);
/*----------------------------------------------------------------------------
*
* FUNCTION NAME: main
*
* DESCRIPTION:
*
* This is the main function for the AAL5 example code. It is responsible
* for calling the respective initialization routines. After all the
* parameters have been initialized, it waits for the receiver to achieve
* synchronization and then enables the APC controller, which starts the
* transmission of the frames.
*
* EXTERNAL EFFECT:
*
* PARAMETERS: None
*
* RETURNS: None
*
*---------------------------------------------------------------------------*/
void Main()
{
RxGood = TRUE; /* initialize as good (reception of frames is OK) */
RxProcIndex = 0; /* start with the first Rx buffer */
RxCount = 0; /* Indicate No Frames have been received */
Event_register = 0; /* Clear the event register */
UWORD mask = 0x3; /* Default to SCC1 mask */
/*------------------------*/
/* Establish IMMR pointer */
/*------------------------*/
IMMR = (EPPC *)(GetIMMR() & 0xFFFF0000); /* MPC8xx internal register
map */
/*------------------------*/
/* Turn LED OFF */
/*------------------------*/
Ethled(OFF);
/*------------------------------------*/
/* Select SCC to use for this example */
/*------------------------------------*/
SCC_num = SCC3;
/*-------------------------------------------------------*/
/* Place External Interrupt Handler Code to Offset 0x500 */
/*-------------------------------------------------------*/
InterruptInit((UWORD *) EXT_INT_VECTOR, ExtIntTable);
/*--------------------------------------------------------------------*/
/* First let's ensure the SCCx functions are off while we program the */
/* buffer descriptors and the parameter ram. */
/*--------------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Clear the ENT/ENR bits in the GSMR -- disable Transmit/Receive */
/*----------------------------------------------------------------*/
IMMR->scc_regs[SCC_num].scc_gsmr_l &= ~(GSMR_L1_ENT | GSMR_L1_ENR);
/*------------------------------------------------------------*/
/* Initialize and enable the selected SCC for reception/ */
/* transmission of AAL5 type cells (SCCx is internally looped */
/* back). */
/*------------------------------------------------------------*/
SCC_init();
InitBuffers(); /* Initialize contents of Rx & Tx Buffers (frames) */
InitCTs(); /* Initialize the Connection Tables */
InitBDs(); /* Initialize RX and TX BDs */
InitAPC(); /* Initialize ATM Pace Controller & Timers */
/*-------------------------------------------------------------*/
/* Set the ENT/ENR bits in the GSMR -- Enable Transmit/Receive */
/* and internal loopback */
/*-------------------------------------------------------------*/
IMMR->scc_regs[SCC_num].scc_gsmr_l |= GSMR_L1_ENT | GSMR_L1_ENR;
IMMR->scc_regs[SCC_num].scc_gsmr_l |= GSMR_L1_INT_LB;
/*
* Now that we've enabled the transmitter, receiver and loopback
* wait until the reciever has achieved synchronization and gained
* cell delineation.
*/
while((!(Event_register & SAR_SERIAL_SCCE_SYNC)) &&
(!(IMMR->PRAM[SCC_num].sar.astatus & 0x1)));
/*
* OK, everything has been initialized. Lets get things
* started by enabling Timer 4 (starts ATM pace controller)
*/
IMMR->timer_tgcr |= 0x1000;
/*----------------------------------------------------------------------*/
/* Issue SAR_ACT_XMIT_CHAN (activate transmit channel) command to the */
/* CP. */
/*----------------------------------------------------------------------*/
while ((IMMR->cp_cr & CPCR_FLG) != READY_TO_RX_CMD);
/* Select the channel number in SCC Parameter RAM */
IMMR->PRAM[SCC_num].sar.comm_ch = 0x1;
IMMR->cp_cr = CPCR_SAR_CMD | SAR_ACT_XMIT_CHAN |
(0x40 * SCC_num) |
CPCR_FLG; /* ISSUE COMMAND */
/* Wait for the CPM to finish executing command */
while ((IMMR->cp_cr & CPCR_FLG) != READY_TO_RX_CMD);
/*------------------------------------------------------------------*/
/* Come in to the loop and wait until all frames have been sent and */
/* received. The Ethernet LED on the ADS board will stay lit until */
/* all frames have been received and checked. If there were any */
/* errors the LED will flash. This action is initiated in the */
/* interrupt handler where the checking takes place. */
/* */
/* NOTE: If you are using the SDS Monitor, set a break point at */
/* the Ethled(ON) line in the while(1) loop below. SDS will */
/* will not respond to the STOP if it reaches the while() */
/* loop. */
/*------------------------------------------------------------------*/
while (1)
{
/*-----------------------------------------------------------------*/
/* stay in this tight loop if the transfer of data was successful. */
/* If there wasn't success, stay in a tight loop in the external */
/* interrupt handler. */
/*-----------------------------------------------------------------*/
while ((RxGood == TRUE) && (RxCount == NUM_FRAMES))
{
/*-------------------------------------------------------*/
/* Turn On Ethernet LED to indicate error-free reception */
/*-------------------------------------------------------*/
IMMR->timer_tgcr &= 0xEFFF; /* Test done, disable APC */
Ethled(ON);
}
}
} /* End Main */
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: InitCTs
*
*
* DESCRIPTION:
*
* Initializes the transmit and receive Connection Tables (CTs). For this
* example, 2 sets of CTs are initialized. The raw cell Connection Table and
* Ch 1 connection table. The RISC Timer (for time stamp) is also initialized
* by this function.
*
* EXTERNAL EFFECTS: Initialize CTs in DPR.
*
* PARAMETERS: None
*
* RETURNS: None
*
*-----------------------------------------------------------------------------*/
void InitCTs()
{
/* Temp pointers used by this function */
UWORD *ptr_word, *ptr_word2;
UHWORD *ptr_start;
UBYTE *ptr_char;
struct timer_pram *ptr_risc_timer; /* Pointer to RISC timer */
Ct *ptr_ct; /* Temp pointer to connection tables */
Cell_header_xmit header_xmit; /* Little endian cell header */
Cell_header_rcv header_rcv;; /* Big endian cell header */
/*-------------------------------------------------------------------*/
/* Initialize the Receive/Transmit Conncetion Tables (CT) */
/*-------------------------------------------------------------------*/
ptr_char = (UBYTE *)(IMMR->udata_bd_ucode) +
IMMR->PRAM[SCC_num].sar.ctbase;
ptr_ct = (Ct *)(ptr_char); /* Get starting address of CT */
/* Initialize the raw cell RCT/TCT entry (channel 0) */
ptr_ct->r_status = 0x0;
ptr_ct->rbalen = 0;
ptr_ct->rcrc = 0;
ptr_ct->rb_ptr = 0;
ptr_ct->tstamp = 0;
ptr_ct->rbase = (UHWORD)(RAW_RBD_ADDR >> 2);
ptr_ct->rbd_ptr = ptr_ct->rbase;
/*************************************************************/
/* For this example the only event we care about is the BSY */
/* event (BUSY), which indicates there are no raw cell buf- */
/* fer available. */
/*************************************************************/
ptr_ct->imask = 0x0004;
ptr_ct->rtmlen = 0;
ptr_ct->t_status = 0x0;
ptr_ct->tbalen = 0x0;
ptr_ct->tcrc = 0;
ptr_ct->ttmlen = 0;
ptr_ct->tb_ptr = 0;
ptr_ct->tbase = 0;
ptr_ct->tbd_ptr = 0;
++ptr_ct;
/*----------*/
/* RCT init */
/*----------*/
/* Configure this as an AAL5 Type Connection */
ptr_ct->r_status = 0x0001;
ptr_ct->rbalen = 0;
ptr_ct->rcrc = 0;
ptr_ct->rb_ptr = 0;
ptr_ct->tstamp = 0;
/* Initialize the offset from the start of the RBD memory */
/* where this channel's BD list starts */
ptr_ct->rbase = (UHWORD)(RBD_ADDR >> 2);
/* Initialize the BD pointer to the base offset (beginning of BD list */
ptr_ct->rbd_ptr = ptr_ct->rbase;
/*************************************************************/
/* Interrupt on the following events: Transmit Buffer and */
/* Receive Frame. */
/*************************************************************/
/* Enable Channel 1 interrupts */
ptr_ct->imask = 0x000A;
/* Initialize the receive buffer count to zero */
ptr_ct->rtmlen = 0;
/*----------*/
/* TCT init */
/*----------*/
/* Configure this as an AAL5 Type Connection */
ptr_ct->t_status = 0x0001;
/****************************************************/
/* The transmit buffer available lenght is initia- */
/* lized to a known value. NOTE: This is not re- */
/* quired, it was done as a debugging tool. If the */
/* transmitter is working, this parameter will be */
/* zero when it is done transmitting. */
/****************************************************/
ptr_ct->tbalen = 0xDEAD;
/* Initialize the offset from the start of the TBD memory */
/* where this channel's BD list starts */
ptr_ct->tbase = (UHWORD)(TBD_ADDR >> 2);
/* Initialize the BD pointer to the base offset (beginning of BD list */
ptr_ct->tbd_ptr = ptr_ct->tbase;
/* Initialize Cell Header to be used whith this channel */
header_rcv.gfc = header_xmit.gfc = 0; /* Initialize GFC to zero */
header_rcv.vpi = header_xmit.vpi = 0; /* Initialize VPI */
header_rcv.vci = header_xmit.vci = 0x060; /* Initialize VCI */
header_rcv.pti = header_xmit.pti = 0; /* Initialize PTI */
header_rcv.clp = header_xmit.clp = 0; /* Initialize CLP */
ptr_word = (UWORD *)&header_xmit;
/* Write the header to the TCT */
ptr_ct->chead = *ptr_word;
/* Initialize APC Link to indicate that, initially, this is an */
/* idle channel. */
ptr_ct->apcl = 0xFFFF;
/* Initialize the APC remainder to zero */
ptr_ct->apcpr = 0;
/* Set APC Pace to 1 and fraction to zero */
ptr_ct->apcp = 1;
ptr_ct->apcpf = 0;
/*-----------------------------------------------------------------*/
/* Now, initialize the Address pointing table. This table points */
/* to the corresponding RCT of the received cell. */
/*-----------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -