⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hdlcint.c

📁 MPC860的SCC2配置HDLC示例代码
💻 C
📖 第 1 页 / 共 3 页
字号:

/*-----------------------------------------------------------------------------				
*
* FILE:  hdlcint.c
** DESCRIPTION: 
*
*  Exercises SCC2 HDLC transmit/receive functions, using RX interrupts. This 
*  program sends 8 HDLC frames, with each frame comtaining a different data 
*  pattern. SCC2 will receive all 8 frames and then the external interrupt 
*  will be vectored to. In this interrupt, all 8 Rx frames will be checked 
*  against it's corresponding Tx frame. It also checks for Rx errors. If any
*  errors or mismatches exist then the Ethernet LED on the ADS 821/860 board 
*  will be flashed. If the transfer of data was successful the LED stay lit
*  constantly.
*
*  For a high level explanation, please refer to the applications document for
*  this example which 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 821/860 ADS board.
**     2) DISABLE Data Cache for pages containing Rx/Tx buffers.
**     3) If you want to operate in External Loopback Mode:
*        Connect Pins:  P13-A3 to P13-A4
*        Set the DIAG bits in the GSMR Low Register to turn internal 
*        loopback off
**     4) In Internal or External Loopback Mode, the driver 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.
**     5) This driver also takes an external interrupt on a full HDLC
*        packet reception.  If the interrupt handler does not see Received
*        Full status (RXF) in the SCC Event register, then it turns on the
*        ETH LED to signal an error condition.
*
*     6) 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.
** REFERENCES: 
*
*      1) MPC860 Users Manual
*      2) PowerPC Microprocessor Family: The Programming Environments for 
*         32-Bit Microprocessors
*
* HISTORY:
** 7/31/96    saw        Initial version.
* 2/20/97    sgj        Adapted to HDLC from IRDa.
* 8/22/97    sgj        Debugged and completed.
* 11/20/97   jay        Complete Modification and Documented
*
*-----------------------------------------------------------------------------*/
#include <string.h>
#include <stdlib.h>        
#include "netcomm.h"       /* global defines */
#include "mpc860.h"        /* IMMR definitions and declarations */
#include "hdlcint.h"       /* Local header file */
#include "masks860.h"      /* Global masks header file */


/***********************/
/* Global Declarations */
/***********************/

EPPC  *IMMR;      /* IMMR base pointer */
BDRINGS *RxTxBD;  /* buffer descriptors base pointer */

/*--------------------------------------------------------*/
/* Set of Data Buffers for HDLC Receive and Transmit Data */
/* The Rx buffer pools will take up the first 8 buffers   */
/* and the Tx buffer pools will take up the last 8.       */
/*--------------------------------------------------------*/
LB BufferPool[NUM_RXBDS+NUM_TXBDS];

/*---------------------------------------------------------*/
/* Status parameters of the receive and transmit processes */
/*---------------------------------------------------------*/
UHWORD RxGood;	         /* Successful RX flag */
UBYTE  RxProcIndex;     /* keeps track of next BD to process */  	
/*-----------------------------------------------------*//* Interrupt Handler Code to be moved to Address 0x500 */
/*-----------------------------------------------------*/extern UWORD ExtIntTable[];

/***********************/
/* Function Prototypes */
/***********************/
                       void     InterruptInit(UWORD *, UWORD[]);
void     InitBDs(void);
void     SCC2HInit(void);
void     ExtIntHandler(UWORD);
void     Main(void);
void     LoadTxBuffers(void);
UHWORD   BDEmpty(UHWORD);
UHWORD   LastBD(UHWORD);
void     Ethled(UHWORD);
void     FlashEthled(void);
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME:  main 
*
* DESCRIPTION:
*
*  This is the main function for the HDLC example code.
*
* EXTERNAL EFFECT: 
*                 
* PARAMETERS:  None
*
* RETURNS: None
*
*---------------------------------------------------------------------------*/
void Main()
{
   RxGood = TRUE;  /* initialize as good */
   RxProcIndex = 0; /* initialize */  	

   /*------------------------*/
   /* Establish IMMR pointer */
   /*------------------------*/
   
   IMMR = (EPPC *)(GetIMMR() & 0xFFFF0000);  /* MPC8xx internal register
                                                map  */

   /*--------------------------------------------------------*/   /* Place External Interrupt Handler Code to Address 0x500 */
   /*--------------------------------------------------------*/   InterruptInit((UWORD *) EXT_INT_VECTOR, ExtIntTable);

   /***********************************************************/
   /* Establish base pointer for Tx and Rx buffer descriptors */
   /***********************************************************/

   /*-----------------------------------------------------------------------*/
   /* I am adding 64 bytes to the start of the buffer descriptors because   */
   /* I have a monitor program on my target that is using most of the first */
   /* 64 bytes for buffer descriptors. If you are not using the SDS monitor */
   /* with Motorola's ADS development board, you can delete 64 below and    */
   /* start at the beginning of this particular block of Dual Port RAM.     */
   /*-----------------------------------------------------------------------*/

   RxTxBD = (BDRINGS *)(IMMR->udata_bd + 64);    /* Get pointer to BD area 
                                                    on DPRAM  */

   /*------------------------------------------------*/
   /* Load the Tx buffer pool with the test patterns */
   /*------------------------------------------------*/

   LoadTxBuffers();

   /*------------------------------------------------------------------------*/
   /* This function defines a number of buffers for an RX and TX buffer pool,*/
   /* but does not attempt to manage memory.  It just uses the first half    */
   /* of the BD pool for RX and the second half for TX.                      */ 
   /*------------------------------------------------------------------------*/
      InitBDs(); /* Initialize RX and TX BDs */
   /*---------------------------------------------------------------------*/
   /* Initialize and enable SCC2 in HDLC mode, internal loopback, and for */
   /* External Interrupt                                                  */
   /*---------------------------------------------------------------------*/
   SCC2HInit();
   /*------------------------------------------------------------------*/
   /* 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.                */
   /*------------------------------------------------------------------*/

   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)  
      {
         /*-------------------------------------------------------*/
         /* Turn On Ethernet LED to indicate error-free reception */
         /*-------------------------------------------------------*/
        	Ethled(ON);
      }
   }

}  /* End Main */
/*-----------------------------------------------------------------------------
*
* 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 ensures that transmit
*  and recieve functions are disabled before buffer descriptors are initialized.
*
* EXTERNAL EFFECTS: Disable Tx/Rx functions. Changes BDs in dual port ram.
*
* PARAMETERS: None
*
* RETURNS: None
*
*-----------------------------------------------------------------------------*/

void InitBDs()
{
   
UHWORD index;

   /*--------------------------------------------------------------------*/
   /* First let's ensure the SCC2 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[SCC2_REG].scc_gsmr_l &= 0xFFFFFFCF;

   /*--------------------------------------*/
   /* Issue Init Stop TX Command for SCC2. */
   /*--------------------------------------*/
   while ((IMMR->cp_cr & CPCR_FLG) != READY_TO_RX_CMD); 
   IMMR->cp_cr = CPCR_STOP_TX |
                 CPCR_SCC2_CH | 
                 CPCR_FLG;              /* ISSUE COMMAND */

   while ((IMMR->cp_cr & CPCR_FLG) != READY_TO_RX_CMD); 


   /*-------------------*/   /* 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 and the Interrupt bit */
           /*-------------------------------------------------*/           RxTxBD->RxBD[index].bd_cstatus = 0xB000;    
      }
   }
   /*-------------------*/   /* Initialize TxBDs. */
   /*-------------------*/   for (index=0; index < NUM_TXBDS; index++) 
   
   {
      /*---------------------------------------------------------------------*/
      /* load the buffer length - 2 bytes because the SCC will need to write */
      /* the two CRC bytes to Rx buffer.                                     */
      /*---------------------------------------------------------------------*/

      RxTxBD->TxBD[index].bd_length = (BUFFER_SIZE-2);

      /*--------------------------------------------------------*/
      /* 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, Tx CRC, and Last bit */
         /*---------------------------------*/

         RxTxBD->TxBD[index].bd_cstatus = 0x8C00;     
      }

      else

      {
         /*-----------------------------------------------*/
         /* Set Ready, Tx CRC, Last bit, and the Wrap bit */
         /*-----------------------------------------------*/

         RxTxBD->TxBD[index].bd_cstatus = 0xAC00;     
      }
   }
} /* end InitBDs */


/*-----------------------------------------------------------------------------
*
* FUNCTION NAME:  LoadTxBuffers
*
* DESCRIPTION:
*
*  This function will load all 8 Tx buffers with the following data patterns:
*
*     Buffer 1: 0x55
*     Buffer 2: 0xAA
*     Buffer 3: 0x00
*     Buffer 4: 0xFF
*     Buffer 5: Increasing Walking Ones
*     Buffer 6: Decreasing Walking Ones
*     Buffer 7: Increment from 0
*     Buffer 8: Decrement from 255
*
*  Each Tx buffer is loaded with 2 bytes of address, followed by 254 bytes of
*  pattern bytes. Only 252 bytes of pattern bytes are loaded into the receive 
*  buffer because the receive channel will also write 2 byte CRC. The total 
*  number of bytes loaded into the receive buffer will be 2 address bytes + 252 
*  pattern bytes + 2 bytes of CRC. This gives a total of 256 bytes which is the 
*  size the receive buffer needs to be.
*
* EXTERNAL EFFECTS:
*
*  BufferPool
*
* PARAMETERS: none
*
*  RETURNS: none
*
*-----------------------------------------------------------------------------*/

void  LoadTxBuffers()

{

UHWORD   index, pattern;

   /*----------------*/
   /* Load 254 0x55s */
   /*----------------*/

   /*-------------------------------------------------------------------------*/
   /* First load the destination addr in the first two bytes of the buffer.   */
   /* What could follow would be the control field. I'm not going to load     */
   /* it here because this is a simple example and I don't need to process it.*/
   /*-------------------------------------------------------------------------*/

   BufferPool[FIRST_TX_BUF][0] = (STADDR%256); /* Load the low byte first */
   BufferPool[FIRST_TX_BUF][1] = (STADDR/256); /* Load the high byte */

   for (index = 2; index < BUFFER_SIZE; index++)

   {
      BufferPool[FIRST_TX_BUF][index] = 0x55;
   }

   /*----------------*/
   /* Load 254 0xAAs */
   /*----------------*/

   /*--------------------------------*/
   /* Load the destination address   */
   /*--------------------------------*/

   BufferPool[FIRST_TX_BUF+1][0] = (STADDR%256); /* Load the low byte first */
   BufferPool[FIRST_TX_BUF+1][1] = (STADDR/256); /* Load the high byte */

   for (index = 2; index < BUFFER_SIZE; index++)

   {
      BufferPool[FIRST_TX_BUF+1][index] = 0xAA;
   }

   /*----------------*/
   /* Load 254 0x00s */
   /*----------------*/

   /*--------------------------------*/
   /* Load the destination address   */
   /*--------------------------------*/

   BufferPool[FIRST_TX_BUF+2][0] = (STADDR%256); /* Load the low byte first */
   BufferPool[FIRST_TX_BUF+2][1] = (STADDR/256); /* Load the high byte */

   for (index = 2; index < BUFFER_SIZE; index++)

   {
      BufferPool[FIRST_TX_BUF+2][index] = 0x00;
   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -