📄 bdihdlc.c
字号:
/*************************************************************************
| COPYRIGHT (c) 2000 BY ABATRON AG
|*************************************************************************
|
| PROJECT NAME: bdiWind
| FILENAME : wdbHdlcPktDrv.c
|
| COMPILER : Tornado 2
|
| TARGET OS : VxWorks
| TARGET HW : MPC8260
|
| PROGRAMMER : Abatron / RD
| CREATION : 6. February 2000
|
|*************************************************************************
|
| DESCRIPTION :
| This modul implements a HDLC UDP-Lite paket driver.
|
| Important: Check use of Dual Port RAM for possible overlaps
|
|*************************************************************************
|
|
| UPDATES :
|
| DATE NAME CHANGES
| -----------------------------------------------------------
| Latest update
| ...
| 13.13.97 aba Bla bla ...
| ...
| First update
|
|*************************************************************************/
/*************************************************************************
| INCLUDES
|*************************************************************************/
#include "string.h"
#include "vxWorks.h"
#include "config.h"
#include "drv/sio/m8260Scc.h"
#include "drv/sio/m8260Sio.h"
#include "drv/sio/m8260Cp.h"
#include "drv/parallel/m8260IOPort.h"
#include "drv/sio/m8260Brg.h"
#include "drv/intrCtl/m8260IntrCtl.h"
#include "wdb/wdbMbufLib.h"
#include "wdbHdlcPktDrv.h"
/*************************************************************************
| DEFINES
|*************************************************************************/
/* SCC HDLC Protocol Specific Mode Register definitions */
#define SCC_HDLC_PSMR_MFF 0x0008 /* multiple frame fifo */
#define SCC_HDLC_PSMR_BRM 0x0010 /* HDLC bus RTS mode */
#define SCC_HDLC_PSMR_BUS 0x0020 /* HDLC bus mode */
#define SCC_HDLC_PSMR_DRT 0x0040 /* disable Rx while Tx */
#define SCC_HDLC_PSMR_FSE 0x0080 /* flasg sharing enable */
#define SCC_HDLC_PSMR_RTE 0x0200 /* retransmit enable */
#define SCC_HDLC_PSMR_CRC16 0x0000 /* 16bit CCITT-CRC */
#define SCC_HDLC_PSMR_CRC32 0x0800 /* 32bit CCITT-CRC */
#define SCC_HDLC_PSMR_NOF_0 0x0000 /* number of flags */
#define SCC_HDLC_PSMR_NOF_1 0x1000 /* number of flags */
#define SCC_HDLC_PSMR_NOF_2 0x2000 /* number of flags */
#define SCC_HDLC_PSMR_NOF_3 0x3000 /* number of flags */
/* SCC HDLC Event and Mask Register definitions */
#define SCC_HDLC_SCCX_RXB 0x0001 /* buffer received */
#define SCC_HDLC_SCCX_TXB 0x0002 /* buffer transmitted */
#define SCC_HDLC_SCCX_BSY 0x0004 /* busy condition */
#define SCC_HDLC_SCCX_RXF 0x0008 /* frame received */
#define SCC_HDLC_SCCX_TXE 0x0010 /* TX error */
#define SCC_HDLC_SCCX_GRA 0x0080 /* graceful stop complete */
#define SCC_HDLC_SCCX_IDL 0x0100 /* idle sequence stat changed */
#define SCC_HDLC_SCCX_FLG 0x0200 /* flag status */
#define SCC_HDLC_SCCX_DCC 0x0400 /* DPLL CS changed */
#define SCC_HDLC_SCCX_GL_T 0x0800 /* glitch on Tx */
#define SCC_HDLC_SCCX_GL_R 0x1000 /* glitch on Rx */
/* SCC HDLC Receive Buffer Descriptor definitions */
#define SCC_HDLC_RX_BD_CD 0x0001 /* carrier detect loss */
#define SCC_HDLC_RX_BD_OV 0x0002 /* receiver overrun */
#define SCC_HDLC_RX_BD_CR 0x0004 /* CRC error */
#define SCC_HDLC_RX_BD_AB 0x0008 /* abort sequence */
#define SCC_HDLC_RX_BD_NO 0x0010 /* no octed aligned frame */
#define SCC_HDLC_RX_BD_LG 0x0020 /* frame length violation */
#define SCC_HDLC_RX_BD_DE 0x0080 /* DPLL error */
#define SCC_HDLC_RX_BD_CM 0x0200 /* continous mode */
#define SCC_HDLC_RX_BD_F 0x0400 /* first in frame */
#define SCC_HDLC_RX_BD_L 0x0800 /* last in frame */
#define SCC_HDLC_RX_BD_INT 0x1000 /* interrupt generated */
#define SCC_HDLC_RX_BD_WRAP 0x2000 /* wrap back to first BD */
#define SCC_HDLC_RX_BD_EMPTY 0x8000 /* buffer is empty */
/* SCC HDLC Transmit Buffer Descriptor definitions */
#define SCC_HDLC_TX_BD_CT 0x0001 /* cts was lost during tx */
#define SCC_HDLC_TX_BD_UN 0x0002 /* underrun */
#define SCC_HDLC_TX_BD_CM 0x0200 /* continous mode */
#define SCC_HDLC_TX_BD_TC 0x0400 /* TX CRC */
#define SCC_HDLC_TX_BD_L 0x0800 /* last */
#define SCC_HDLC_TX_BD_INT 0x1000 /* interrupt generated */
#define SCC_HDLC_TX_BD_WRAP 0x2000 /* wrap back to first BD */
#define SCC_HDLC_TX_BD_READY 0x8000 /* buffer is being sent */
#define HDLC_RX_ERRORS 0x00BF /* RX-BD errors */
#define SCC_NUM 3 /* !!! update also port configuration !!! */
#define SCC_RBD_NUM 2
#define SCC_TBD_NUM 2
#define SCC_RBD_OFF 0x400
#define SCC_TBD_OFF (SCC_RBD_OFF + (SCC_RBD_NUM * 8))
#define SCC_RX_BUFF_SIZE (WDB_HDLC_PKT_MTU + 8) /* the size of a receive buffer */
#define SCC_TX_BUFF_SIZE WDB_HDLC_PKT_MTU /* the size of a transmit buffer */
#define SCC_RX_BUFF_ADDR 0x8000 /* mapped to non cached area */
#define SCC_TX_BUFF_ADDR (SCC_RX_BUFF_ADDR + (SCC_RBD_NUM * SCC_RX_BUFF_SIZE))
/*************************************************************************
| MACROS
|*************************************************************************/
#define MIN min
/*************************************************************************
| TYPEDEFS
|*************************************************************************/
typedef struct /* SCC_HDLC_BD */
{
VUINT16 statusMode; /* status and control */
VINT16 dataLength; /* length of data buffer in bytes */
u_char * dataPointer; /* points to data buffer */
} SCC_HDLC_BD;
typedef struct /* SCC_HDLC_DEV */
{
int sccNum; /* number of SCC device */
int txBdNum; /* number of transmit buf descriptors */
int rxBdNum; /* number of receive buf descriptors */
SCC_HDLC_BD * txBdBase; /* transmit BD base address */
SCC_HDLC_BD * rxBdBase; /* receive BD base address */
u_char * txBufBase; /* transmit buffer base address */
u_char * rxBufBase; /* receive buffer base address */
int txBdNext; /* next transmit BD to fill */
int rxBdNext; /* next receive BD to read */
} SCC_HDLC_DEV;
typedef struct scc_chan {
UINT32 immrVal; /* Internal Memory Map Register */
VINT16 *pSCCE; /* points to SCCE register */
SCC_HDLC_DEV hdlc;
} SCC_CHAN;
/*************************************************************************
| LOCALS
|*************************************************************************/
static SCC_CHAN sccChan; /* info about the SCC channel */
/*************************************************************************
| FORWARD DECLARATIONS
|*************************************************************************/
static STATUS wdbPktPoll (void *pDev);
static STATUS wdbPktTx (void *pDev, struct mbuf * pMbuf);
static STATUS wdbPktModeSet (void *pDev, uint_t newMode);
static void wdbPktFree (void *pDev);
/*******************************************************************************
*
* sccInit - initialize the SCC
*/
static void sccInit(void)
{
UINT32 immrVal;
UINT8 scc;
UINT32 clockDivider;
int frame;
UINT32 cpcrVal;
VINT16 *pSCCM;
VINT16 *pSCCE;
VINT32 *pBRGC;
VINT32 *pGSMR_L;
VINT32 *pGSMR_H;
VINT16 *pPSMR;
VINT16 *pRBASE;
VINT16 *pTBASE;
VINT8 *pRFCR;
VINT8 *pTFCR;
VINT16 *pMRBLR;
VINT32 *pCMASK;
VINT32 *pCPRES;
VINT16 *pDISFC;
VINT16 *pCRCEC;
VINT16 *pABTSC;
VINT16 *pNMARC;
VINT16 *pRETRC;
VINT16 *pMFLR;
VINT16 *pRFTHR;
VINT16 *pHMASK;
VINT16 *pHADDR1;
VINT16 *pHADDR2;
VINT16 *pHADDR3;
VINT16 *pHADDR4;
/* lock interrupts */
int oldlevel = intLock ();
/* setup SCC register pointers */
immrVal = vxImmrGet();
scc = SCC_NUM - 1;
pBRGC = (VINT32 *) (immrVal + M8260_BRGC_BASE + (scc * M8260_BRGC_OFFSET_NEXT_BRGC));
pSCCM = (VINT16 *) (immrVal + M8260_SCC_BASE + (scc * M8260_SCC_OFFSET_NEXT_SCC) + M8260_SCCM_OFFSET);
pSCCE = (VINT16 *) (immrVal + M8260_SCC_BASE + (scc * M8260_SCC_OFFSET_NEXT_SCC) + M8260_SCCE_OFFSET);
pGSMR_L = (VINT32 *) (immrVal + M8260_SCC_BASE + (scc * M8260_SCC_OFFSET_NEXT_SCC) + M8260_GSMR_L_OFFSET);
pGSMR_H = (VINT32 *) (immrVal + M8260_SCC_BASE + (scc * M8260_SCC_OFFSET_NEXT_SCC) + M8260_GSMR_H_OFFSET);
pPSMR = (VINT16 *) (immrVal + M8260_SCC_BASE + (scc * M8260_SCC_OFFSET_NEXT_SCC) + M8260_PSMR_OFFSET);
pSCCM = (VINT16 *) (immrVal + M8260_SCC_BASE + (scc * M8260_SCC_OFFSET_NEXT_SCC) + M8260_SCCM_OFFSET);
pRBASE = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + M8260_SCC_PRAM_RBASE);
pTBASE = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + M8260_SCC_PRAM_TBASE);
pRFCR = (VINT8 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + M8260_SCC_PRAM_RFCR);
pTFCR = (VINT8 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + M8260_SCC_PRAM_TFCR);
pMRBLR = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + M8260_SCC_PRAM_MRBLR);
pCMASK = (VINT32 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + 0x34);
pCPRES = (VINT32 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + 0x38);
pDISFC = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + 0x3C);
pCRCEC = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + 0x3E);
pABTSC = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + 0x40);
pNMARC = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + 0x42);
pRETRC = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + 0x44);
pMFLR = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + 0x46);
pRFTHR = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + 0x4A);
pHMASK = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + 0x4E);
pHADDR1 = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + 0x50);
pHADDR2 = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + 0x52);
pHADDR3 = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + 0x54);
pHADDR4 = (VINT16 *) (immrVal + M8260_SCC_PRAM_BASE + (scc * M8260_SCC_PRAM_OFFSET_NEXT_PRAM) + 0x56);
/* setup channel info */
sccChan.immrVal = immrVal;
sccChan.pSCCE = pSCCE;
sccChan.hdlc.sccNum = SCC_NUM;
/* Disable all interrupts */
*pSCCM = 0;
/* configure port D pins for SCC3 */
*M8260_IOP_PDDIR(immrVal) |= 0x00000080L; /* set bit 24 for SCC3 */
*M8260_IOP_PDDIR(immrVal) &= ~0x00000040L; /* clear bit 25 for SCC3 */
*M8260_IOP_PDPAR(immrVal) |= 0x000000C0L; /* set bits 24,25 for SCC3 */
*M8260_IOP_PDSO(immrVal) &= ~0x000000C0L; /* clear bits 24,25 for SCC3 */
*M8260_IOP_PDODR(immrVal) &= ~0x000000C0L; /* clear bits 24,25 for SCC3 */
/* reset baud rate generator, wait for reset to clear... */
*pBRGC |= M8260_BRGC_RST;
while ((*pBRGC) & M8260_BRGC_RST);
/* select baudrate: BRGCLK is 10MHz (40MHz * 4 / 16) */
/* BRGCx.CD: 8260: BDI: */
/* 0 625'000 - */
/* 1 312'500 298'000 */
/* 2 208'000 208'000 */
/* 3 156'000 160'000 */
/* 4 125'000 122'000 */
/* 5 104'000 104'000 */
clockDivider = 2;
*pBRGC = (M8260_BRGC_CD_MASK & (clockDivider << 1)) | M8260_BRGC_EN;
/* set up transmit buffer descriptors */
sccChan.hdlc.txBdNum = SCC_TBD_NUM;
sccChan.hdlc.txBdBase = (SCC_HDLC_BD*)(immrVal + SCC_TBD_OFF);
sccChan.hdlc.txBufBase = (u_char*)(SCC_TX_BUFF_ADDR);
sccChan.hdlc.txBdNext = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -