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

📄 ds26528e1.c

📁 Sample driver code for Dallas DS26528 T1/E1 framer chip.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* BUILDFLAG:"DS26528E1 = 1" */
/* 
 * Copyright 1997-2005 NComm, Inc.  All rights reserved.
 * 
 *
 *                     *** Important Notice ***
 * The software contained in this file may only be used within a 
 * valid license agreement between your company and NComm, Inc. 
 * The license agreement includes the definition of a PROJECT which 
 * defines the scope that this software can be used in.  Any use outside of
 * the definition of the PROJECT is prohibited without executing an additional 
 * agreement with NComm, Inc. Please refer to you license agreement for 
 * the definition of the PROJECT.
 *
 * Verification of your company's license agreement and copies of 
 * that agreement also may be obtained from:
 *
 * NComm, Inc.
 * 254 N Broadway
 * Suite 106
 * Salem, NH 03079
 * (603) 893-6186
 * sales@ncomm.com
 *
 */

/*
 *	The Device version is the chip revision that is supported by this
 *	driver.
 *
 *	Device Version:
 *		Rev A3
 *
 *	Revision:
 *		08/11/04 - Initial Release
 *		10/10/05 - Tested on A3 Rev Silicon
 *
 *	See CUSTOMIZE HERE for areas that may need to be customized for your
 *	platform.
 */


/*
 * Driver for the Dallas DS26528 DS26528 chip, E1 section
 */

/* -------------------------------------------------------------------------- */
/* Device Issues:  This section lists any issues with the device.
 * The list contains descriptions of:
 * 1) Lack of device features which prevent the NComm TMS software 
 *    from meeting the applicable standards.
 * 2) Work arounds employed to make the NComm TMS software package(s) operate
 *    properly.
 * 3) Special hardware considerations for implementing the device.
 *
 */

#if 0
Device Issues:

1) EU certification test with the Marquest FRAI occasionally fail the TBR4-B53
and CL44 sequences. We are working on determining the cause.

#endif

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Driver Customization Section                                   
 * This section contains any specific customizations required for this chip
 * and/or driver operation.
 * The customizations cover the chip configuration and interfaces to
 * other parts of your platform. 
 */

	/* These get placed in the DEVICE call in the CTRL and POLL driver API.
	 * It allows for platform specific Control and Poll calls .
	 */

#define CUSTOM_CTRL(LnPtr,uparam1,uparam2,uparam3,uparam4) 0

#define CUSTOM_POLL(LnPtr,uparam1,uparam2,uparam3,uparam4) 0


/* -------------------------------------------------------------------------- */
/* Define default E1 technology constraints
 */

#define E1_DRIVER
#define MAX_E1_TIMESLOTS	32
#define TSLOT_IDLECODE		0xD5	/* default idle code */
#define SIGNL_IDLECODE		0x0B	/* default idle abcd bits for CAS */
#define DEFAULT_TX_CLOCK	SYSCLOCK

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Include files
 */

#include "target.h"
#include "apiTE1Dv.h"
#include "ds26528.h"


/* -------------------------------------------------------------------------- */
/* Define API Entry Points
 * These are the names you will use in the API registration processor for
 * this driver
 */

#define TE1_CTRLENTRY _ds26528E1CTRL
#define TE1_POLLENTRY _ds26528E1POLL

int TE1_CTRLENTRY(void *vptr, TE1DCTRL_FC fcode, ...);

/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/* General houskeeping strucucture on a per-line basis
 */
enum {
	INTFLAG_UTIL 	= (1 << 1),	/* Utility interrupt */
	INTFLAG_ALM  	= (1 << 2),	/* Alarm interrupt */
	INTFLAG_ONESEC  = (1 << 3)	/* One second interrupt */
};


struct _E1stuff {
	FRAMER *myfrmr;
	DEVICE *mydevice;
	LIU *myliu;
	int mysubc;
	int rxslip;

	void *sasiThandle;
};


struct _stuff {
	int greset;			/* Tracks global reset */
	int init;			/* 0 = not initalized, 1 = initalized */
	int line;			/* Line Number */
	int subc;			/* sub channel number */
	void *lnPtr;			/* pointer to talk to TMS with */
	void *LIUptr;			/* pointer to talk to LIU with */
	GDEVICE *d;			/* reverse pointer to the dev struct */
	int (*cback)(void *LnPtr, TE1DCLBK_FC,...);
	int int_flag;			/* deterines which interrupts enabled */
	int isr_hooked;			/*  1 = ISR is hooked, 0 = not */

	int utility_init;		/* 0 = util not init, 1 initalized */
	int alarm_init;			/* 0 = alarms not inialized, 1 enabled*/
	int onesec_init;		/* 0 = disabled, 1 = enabled */

	int g826_init;			/* 0 = disabled, 1 = enabled */
	int signal_init;		/* 0 = CAS disabled, 1 = CAS enabled */
	int loop_init;			/* 0 = disabled, 1 = enabled */

	TE1_CONFIG cfg;			/* Current configuration */
	int side;			/* USR_SIDE or NET_SIDE */
	CLOCK_TYPE txclk;		/* current setting for transmit clock */

	int loopback;			/* Loopback information */

	int tx_alm;			/* current transmit alarms */

	struct {
		enum {
			DS0MODE_CLEAR,
			DS0MODE_IDLE,
			DS0MODE_RBCAS
		} mode; 		/* Mode of the DS0 */
		unsigned char ipat;	/* Idle Pattern */
		unsigned char rxbits;	/* Receive Signaling Bits */
		unsigned char txbits;	/* Transmit Signaling Bits */
	} ds0[MAX_E1_TIMESLOTS];
	
	int sasi_init;			/* 0 = disabled, 1 = enabled */
	unsigned char sa_bits;		/* Holds the Tx SaBits - nonCRC */
	unsigned char sabyte[E1SABYTE_MAX]; /* Holds the Tx SaBytes - CRC */
	unsigned char si_bits;		/* Holds the International Bits */
	unsigned char x_bits;		/* Holds the Extra Bits */

	struct _E1stuff e1s;		/* Device specific items */
};

typedef struct _stuff STUFF;

static STUFF E1stuff[MAX_DEVICES][MAX_E1_CHANNELS];

/* -------------------------------------------------------------------------- */
/* Forward References
 */
static int hook_isr(STUFF *sptr, int set_clear, int flag);
static int poll_allrxbits(STUFF *sptr, int *all_rxbits);

/* -------------------------------------------------------------------------- */
/* Define Helper Defines 
 * This is a bit map.
 */

/* Loopbacks */
#define DRV_LOOP_REMOTE 0x01
#define DRV_LOOP_LOCAL 0x02
#define DRV_LOOP_PAYLOAD 0x04
#define DRV_LOOP_FRAMER 0x08

/* Testing transmit Alarms */
#define TXA_ISSET(x) (sptr->tx_alm & (x) & (~TMS_TXALARM))

#define STANDARD_DECLARE FRAMER *f = sptr->e1s.myfrmr;

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* The Device Specific Routines are defined below.
 */

/* -------------------------------------------------------------------------- */
/* Routine to look up the appopriate stuff stucture for the line
 * The pointer returned is local to the E1 driver
 */
static STUFF *_te1_get_stuff(GDEVICE *d, int subc)
{
	return(&E1stuff[d->id][subc]);
}

/* -------------------------------------------------------------------------- */
/* This routine fills out the device specific stuff information
 */
static void _te1_set_chip_stuff(STUFF *sptr)
{
	sptr->e1s.mydevice = (DEVICE *) sptr->d->BaseAdr;
	sptr->e1s.mysubc = sptr->subc % MAX_E1_CHANNELS;
	sptr->e1s.myfrmr = (FRAMER *) 
		&sptr->e1s.mydevice->te1[sptr->e1s.mysubc];
	sptr->e1s.myliu = (LIU *) 
		&sptr->e1s.mydevice->bertliu.liu[sptr->e1s.mysubc];
	sptr->e1s.rxslip = 0;
	return;
}

#define BYTE_FLIP(x) ((((x) & 0x80) >> 7) | (((x) & 0x40) >> 5) | \
	(((x) & 0x20) >> 3) | (((x) & 0x10) >> 1) | \
	(((x) & 0x08) << 1) | (((x) & 0x04) << 3) | \
	(((x) & 0x02) << 5) | (((x) & 0x01) << 7))

#define FLIP_EM(x) ((((x) & 0x08) >> 3) | (((x) & 0x04) >> 1) | \
	(((x) & 0x02) << 1) | (((x) & 0x01) << 3))

static int flip_table[16] = {
	FLIP_EM(0),
	FLIP_EM(1),
	FLIP_EM(2),
	FLIP_EM(3),
	FLIP_EM(4),
	FLIP_EM(5),
	FLIP_EM(6),
	FLIP_EM(7),
	FLIP_EM(8),
	FLIP_EM(9),
	FLIP_EM(10),
	FLIP_EM(11),
	FLIP_EM(12),
	FLIP_EM(13),
	FLIP_EM(14),
	FLIP_EM(15),
	};


/*------------------------------------------------------------------------*/
static void process_SR1_interrupt(STUFF *sptr)
{
volatile unsigned char status, statusl;
STANDARD_DECLARE;

	status = f->rrts1;
	statusl = f->rls1;

	if(statusl & (RLS1_RRAIC | RLS1_RRAID)) {
		(*sptr->cback)(sptr->lnPtr, TE1DCLBK_ALARMRX, TMS_RXRAI, 
			       (status & RRTS1_RRAI) ? 1 : 0);
	}
	
	if(statusl & (RLS1_RAISC | RLS1_RAISD)) {
		(*sptr->cback)(sptr->lnPtr, TE1DCLBK_ALARMRX, TMS_RXAIS, 
			       (status & RRTS1_RAIS) ? 1 : 0);
	}

	if(statusl & (RLS1_RLOSC | RLS1_RLOSD)) {
		(*sptr->cback)(sptr->lnPtr, TE1DCLBK_ALARMRX, TMS_RXLOS, 
			       (status & RRTS1_RLOS) ? 1 : 0);
	}

	if(statusl & (RLS1_RLOFC | RLS1_RLOFD)) {
		(*sptr->cback)(sptr->lnPtr, TE1DCLBK_ALARMRX, TMS_RXOOF, 
			       (status & RRTS1_RLOF) ? 1 : 0);
	}

	f->rls1 = statusl;

}


/*------------------------------------------------------------------------*/
static void process_SR4_interrupt(STUFF *sptr)
{
volatile unsigned char statusl;
STANDARD_DECLARE;

	statusl = f->rls4;
	
	if(statusl & RLS4_TIMER) {
		(*sptr->cback)(sptr->lnPtr, TE1DCLBK_ONESEC);
	}

	if(statusl & RLS4_RSLIP) {
		sptr->e1s.rxslip = 1;
	}

	f->rls4 = statusl;
}


/*------------------------------------------------------------------------*/
/* This routine performs the utility initialization
 */
static int utility_init(STUFF *sptr, int set_clear)
{
int retval = 1;
FRAMER *f = (FRAMER *)&sptr->e1s.mydevice->te1[0];

	if(set_clear) {
		retval = hook_isr(sptr, set_clear, INTFLAG_UTIL);
		f->gfimr |= (1 << sptr->e1s.mysubc);
		if(!retval)
			return(0);
	}
	else {
		f->gfimr &= ~(1 << sptr->e1s.mysubc);
		retval = hook_isr(sptr, set_clear, INTFLAG_UTIL);
		if(!retval)
			return(0);
	}
			
	return(retval);
}

/*------------------------------------------------------------------------*/
/* This routine sets up for signaling 
 */
static int signal_init(STUFF *sptr, int set_clear)
{
int retval = 1;
int val[MAX_E1_TIMESLOTS];
int *sig = &val[0];

	/* The can only enable signaling on MF E1s */

	if(sptr->cfg.framing == FF_E1_CRC ||
	   sptr->cfg.framing == FF_E1)
		return(0);

	if(set_clear) {
		retval = (*sptr->cback)(sptr->lnPtr, TE1DCLBK_SIGNLDEBOUNCE, 1);
		if(!retval)
			return(0);
		poll_allrxbits(sptr, sig);
	}

	return(retval);

}

/*------------------------------------------------------------------------*/
/* This routine set a voice channel as clear channel - no CAS
 */
static int signal_clear(STUFF *sptr, int ts, int set_clear)
{
int retval = 1;

	/* Nothing to be done */
	return(retval);

}

/*------------------------------------------------------------------------*/
/* This routine set a voice channel as clear channel - no CAS
 */
static int signal_idle(STUFF *sptr, int ts, int ipat, int set_clear)
{
int retval = 1;
int index, bit;
STANDARD_DECLARE;

	if(ipat != -1) {
		f->tidr[ts] = ipat;
	}

	index = ts / 8;
	bit = ts % 8;

	if(set_clear) {
		f->tcice[index] |= (1 << bit);
	}
	else {
		f->tcice[index] &= ~(1 << bit);
	}

	return(retval);

}

/*------------------------------------------------------------------------*/
/* This routine set a voice channel as needing CAS processing
 */
static int signal_rbcas(STUFF *sptr, int ts, int set_clear)
{
int retval = 1;

	/* Nothing to be done here */
	return(retval);

}

/*------------------------------------------------------------------------*/
/* This routine sets the transmit signaling bits for a CAS channel
 */
static int signal_txbits(STUFF *sptr, int ts, unsigned char dcba)
{
int retval = 1;
int index;
unsigned int bits;
STANDARD_DECLARE;

	if ((ts == 0) || (ts == 16)) return(retval);
	index = (ts > 15) ? (ts - 16) : ts;
	bits =  flip_table[dcba & 0xf];

	sptr->ds0[ts].txbits = bits;

	/* change bits = 0xDCBA to bits = 0xABCD, move them into
	 * the proper register position, and generate a mask
	 * to keep the undisturbed bits.
	 */

	bits = (ts > 15) ? (((sptr->ds0[ts - 16].txbits) << 4) | bits) : 
	       ((sptr->ds0[ts + 16].txbits) | (bits << 4));	
	f->ts[index] = bits;

	return(retval);
}

/*------------------------------------------------------------------------*/
/* This routine forces a receive framer to re-acquire frame
 */
static int do_resync(STUFF *sptr)
{
int retval = 1;
STANDARD_DECLARE;

	f->rcr1 |= RCR1_RESYNC;
	f->rcr1 &= ~RCR1_RESYNC;

	return(retval);

}

/*------------------------------------------------------------------------*/
/* This routine turns on and off SASI bit processing
 */
static int sasi_init(STUFF *sptr, int set_clear)
{
int retval = 1;
STANDARD_DECLARE;

	/* Let the upper layers do the SaSi bit debouncing and mittoting,
	 * and they must be handled via a periodic poll.
	*/

	(*sptr->cback)(sptr->lnPtr, TE1DCLBK_E1SASISADEBOUNCE, 1);

	(*sptr->cback)(sptr->lnPtr, TE1DCLBK_E1SASISIDEBOUNCE, 1);

	(*sptr->cback)(sptr->lnPtr, TE1DCLBK_E1SASIXDEBOUNCE, 1);

	if ((sptr->cfg.framing == FF_E1_CRC_MF) ||
		    (sptr->cfg.framing == FF_E1_CRC)) {
		f->tsacr |= TSACR_SA4 | TSACR_SA5 | TSACR_SA6 |
				TSACR_SA7 | TSACR_SA8;
	}
	else {
		f->tsacr &= ~(TSACR_SA4 | TSACR_SA5 | TSACR_SA6 |
				TSACR_SA7 | TSACR_SA8);
	}

	if(set_clear) {
		(*sptr->cback)(sptr, TE1DCLBK_HOOKOSTIC,
			SASI_POLL_TICK, &sptr->e1s.sasiThandle,
			TE1_CTRLENTRY, TE1DCTRL_OSTIC, SASI_OSTICKER);
	}
	else {
		(*sptr->cback)(sptr, TE1DCLBK_UNHOOKOSTIC,
					sptr->e1s.sasiThandle);
	}

	return(retval);

}

/*------------------------------------------------------------------------*/
/* This routine transmits the SA (National) bits in nonCRC Framing
 */
static int tx_sabits(STUFF *sptr, int sabits)
{
int retval = 1;
STANDARD_DECLARE;

	f->tsacr = (f->tsacr & 0xe0) | sabits;

	return(retval);

}

/*------------------------------------------------------------------------*/
/* This routine transmits the SA (National) bits in CRC Framing
 */

⌨️ 快捷键说明

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