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

📄 ds26528e1.c

📁 Sample driver code for Dallas DS26528 T1/E1 framer chip.
💻 C
📖 第 1 页 / 共 3 页
字号:
		 */


		if(set_clear) {
			f->rcr3 |= RCR3_FLB;
		}
		else {
			f->rcr3 &= ~RCR3_FLB;
		}
		break;

	default:
		retval = 0;
		break;
	}

	return(retval);
}

/*------------------------------------------------------------------------*/
/* This routine turns on and off loop detection 
 */
static int loop_init(STUFF *sptr, int set_clear)
{
int retval = 1;

	/* Nothing to do here */
	return(retval);
}

/*------------------------------------------------------------------------*/
/* This routine sets up the clock used for the transmitter 
 */
static int set_txclock(STUFF *sptr, CLOCK_TYPE txclk)
{
int retval = 1;
STANDARD_DECLARE;

	switch(txclk) {
	case SYSCLOCK:	/* clock from central timing source */
		f->tcr3 = (f->tcr3 & (~TCR3_TCSS(3))) | TCR3_TCSS(0);
		break;

	case RXCLOCK:	/* loop timing selection */
		f->tcr3 = (f->tcr3 & (~TCR3_TCSS(3))) | TCR3_TCSS(3);
		break;

	case LOCALOSC:	/* clock from a local oscillator */
	case OTHERCLK:	/* some other clock selection */
	default:
		retval = 0;
		break;
	}
	
	return(retval);
}

/*------------------------------------------------------------------------*/
/* 
 * This routine sets up the configration of the channel
 * sptr is the pointer to the stuff structure
 */
static int _e1Config(STUFF *sptr)
{
int retval = 1;
STANDARD_DECLARE;

	switch(sptr->cfg.framing) {
	case FF_E1:
		/* Transmit */
		f->tcr1 &= ~(TCR1_TCRC4); 	/* no CRC4 */
		f->tcr2 &= ~(TCR2_AEBE);	/* turn off E bits */
		/* Receive */
		f->rcr1 &= ~(RCR1_RCRC4);	/* no CRC4 */
		f->rcr1 |= RCR1_RSIGM;		/* CCS mode */
		f->tsacr |= (TSACR_SIAF | TSACR_SINAF); /* si bit control on */
		f->ssie[0] = f->ssie[1] = f->ssie[2] = f->ssie[3] = 0;  
		break;

	case FF_E1_CRC:
		/* Transmit */
		f->tcr1 |= (TCR1_TCRC4); 	/* CRC4 */
		f->tcr2 |= (TCR2_AEBE);		/* turn on E bits */
		/* Receive */
		f->rcr1 |= (RCR1_RCRC4);	/* CRC4 */
		f->rcr1 |= RCR1_RSIGM;		/* CCS mode */
		f->tsacr &= ~(TSACR_SIAF | TSACR_SINAF); /* si bit control off*/
		f->ssie[0] = f->ssie[1] = f->ssie[2] = f->ssie[3] = 0;  
		break;

	case FF_E1_MF:
		/* Transmit */
		f->tcr1 &= ~(TCR1_TCRC4); 	/* no CRC4 */
		f->tcr2 &= ~(TCR2_AEBE);	/* turn off E bits */
		/* Receive */
		f->rcr1 &= ~(RCR1_RCRC4);	/* no CRC4 */
		f->rcr1 &= ~RCR1_RSIGM;		/* CAS mode */
		f->tsacr |= (TSACR_SIAF | TSACR_SINAF); /* si bit control on */
		f->ssie[0] = f->ssie[1] = f->ssie[2] = f->ssie[3] = 0xff;  
		break;

	case FF_E1_CRC_MF:
		/* Transmit */
		f->tcr1 |= (TCR1_TCRC4); 	/* CRC4 */
		f->tcr2 |= (TCR2_AEBE);		/* turn on E bits */
		/* Receive */
		f->rcr1 |= (RCR1_RCRC4);	/* CRC4 */
		f->rcr1 &= ~RCR1_RSIGM;		/* CAS mode */
		f->tsacr &= ~(TSACR_SIAF | TSACR_SINAF); /* si bit control off*/
		f->ssie[0] = f->ssie[1] = f->ssie[2] = f->ssie[3] = 0xff;  
		break;

	default:
		return(0);
	}

	switch(sptr->cfg.coding) {
	case LC_HDB3:
		f->rcr1 |= (RCR1_RHDB3);
		f->tcr1 |= (TCR1_THDB3);
		f->ercnt |= ERCNT_LCVCRF;
		break;

	case LC_AMI:
		f->rcr1 &= ~(RCR1_RHDB3);
		f->tcr1 &= ~(TCR1_THDB3);
		f->ercnt &= ~ERCNT_LCVCRF;
		break;

	default:
		return(0);
	}
	
	return(retval);
}

/*------------------------------------------------------------------------*/
/* 
 * This routine resets the E1 portion of the chip.
 * sptr is the pointer to the stuff structure
 */
static int _te1Reset(STUFF *sptr)
{
int retval = 1, i;
LIU *l = sptr->e1s.myliu;
STANDARD_DECLARE;

	if(!sptr->greset){
		NCID_GRESET(sptr->d);
		sptr->greset = 1;
	}

	/* disable all interrupts
	 */

	utility_init(sptr, (sptr->utility_init = 0));
	alarm_init(sptr, (sptr->alarm_init = 0));
	onesec_init(sptr, (sptr->onesec_init = 0));

	/* Soft Reset into E1 mode */

	f->tmmr = TMMR_SFTRST;
	f->tmmr = TMMR_T1E1;
	
	f->rmmr = RMMR_SFTRST;
	f->rmmr = RMMR_T1E1;

	f->tmmr |= TMMR_FRM_EN | TMMR_T1E1;
	f->rmmr |= RMMR_FRM_EN | RMMR_T1E1;
	
	f->rcr1 = RCR1_RSIGM | RCR1_FRC;

	f->rcr2 = 0;

	f->ribcc_rcr2 = RCR2_RSAS(0x1f);

	f->rcr3 = (RX_UNIPOLAR) ? RCR3_IDF : 0;

	f->riocr = ((RSYNC_MODE1) ? RIOCR_RSMS1 : 0) |
		((RSYNC_MODE2_E1) ? RIOCR_RSMS2 : 0) |
		((RSYNC_IO_SELECT) ? RIOCR_RSIO : 0) |
		((RSYNC_SKIP) ? RIOCR_RSMS : 0) |
		((RSYNC_CLK_MODE_E1) ? RIOCR_RSCLKM : 0) |
		((H100_MODE) ? RIOCR_H100EN : 0) |
		((RSYNC_INV) ? RIOCR_RSYNCINV : 0) |
		((RCLK_INV) ? RIOCR_RCLKINV : 0);

	f->rescr = ((RX_ELASTIC_STORE_EN) ? RESCR_RESE : 0) |
		((RES_MIN_DELAY) ? RESCR_RESMDM : 0) |
		((RXS_ZONE_SEL) ? RESCR_RSZS : 0) |
		((GAP_CLOCK_EN) ? RESCR_RGCLKEN : 0) |
		((RX_CHAN_FORMAT) ? RESCR_RDATFMT : 0);

	f->ercnt =
		((MOS_COUNT_SELECT) ? ERCNT_MOSCRF : 0) |
		((ERROR_ACU_MODE) ? ERCNT_EAMS : 0) |
		((UPDATE_SELECT_E1) ? ERCNT_ECUS : 0) |
		((MANUAL_UPDATE_SEL) ? ERCNT_MCUS : 0) |
		((ONE_SECOND_SEL) ? ERCNT_1SECS : 0);

	f->riboc = (RIBOC_DA(DEVICE_ASSIGNMENT)) |
		((IBO_EN) ? RIBOC_IBOEN : 0) |
		((IBO_SEL) ? RIBOC_IBOSEL : 0) |
		(RIBOC_IBS(IBO_SIZE));
	
	f->tiboc = (TIBOC_DA(DEVICE_ASSIGNMENT)) |
		((IBO_EN) ? TIBOC_IBOEN : 0) |
		((IBO_SEL) ? TIBOC_IBOSEL : 0) |
		(TIBOC_IBS(IBO_SIZE));

	f->tcr1 = TCR1_TSIS;

	f->tslc1_taf = 0x1b; /* must be 1b */

	f->tslc2_tnaf = 0x40; /* must be 40 */
	
	f->tcr3 = (TX_UNIPOLAR) ? TCR3_ODF : 0;

	f->tiocr = ((TSYNC_MODE) ? TIOCR_TSM : 0) |
		((TSYNC_DOUBLE_WIDE) ? TIOCR_TSDW : 0) |
		((TSYNC_IO) ? TIOCR_TSIO : 0) |
		((TSSYNC_MODE) ? TIOCR_TSSM : 0) |
		((TSYSCLK_MODE_E1) ? TIOCR_TSCLKM : 0) |
		((TSYNCIO_INV) ? TIOCR_TSSYNCINV : 0) |
		((TSYNC_INV) ? TIOCR_TSYNCINV : 0) |
		((TCLK_INV) ? TIOCR_TCLKINV : 0);

	f->tescr = ((TX_ELASTIC_STORE_EN) ? TESCR_TESE : 0) |
		((TES_MIN_DELAY) ? TESCR_TESMDM : 0) |
		((TXS_ZONE_SEL) ? TESCR_TSZS : 0) |
		((TDATA_EN) ? TESCR_TDATAEN : 0) |
		((TGAP_CLOCK_EN) ? TESCR_TGCLKEN : 0) |
		((TX_CHAN_FORMAT) ? TESCR_TDATFMT : 0);

	/* set up for multiformat signaling */
	for (i = 1; i < MAX_E1_TIMESLOTS; i++) {
		if (signal_txbits(sptr, i, SIGNL_IDLECODE))
			sptr->ds0[i].txbits = SIGNL_IDLECODE;
	}
	f->ts[0] = 0x0B;

	l->ltrcr = ((JAT_DEPTH) ? LTRCR_JADS : 0) |
		(LTRCR_JAPS(JAT_POSITION)) |
		((LOS_CRITERIA) ? LTRCR_LSC : 0);

	l->ltitsr = ((TXTERM_OFF) ? LTITSR_TIMPTOFF : 0) |
			(LTITSR_TIMPL((TX_IMPEDANCE ? 3 : 0))) |
			LTITSR_TS(TX_IMPEDANCE);
	
	l->lrismr = ((RXTERM_OFF) ? LRISMR_RIMPOFF : 0) |
			(LRISMR_RSMS((RX_IMPEDANCE ? 3 : 0)));


	retval = _e1Config(sptr);
	if(!retval)
		return(0);

	retval = transmit_alarm(sptr, TMS_TXAIS, 1);

	/* after the configuration turn on the framer */
	f->tmmr |= TMMR_INIT_DONE;
	f->rmmr |= RMMR_INIT_DONE;

	l->lmcr = LMCR_TE;

	return(retval);
}


/*------------------------------------------------------------------------*/
/* 
 * This routine UN resets the E1 portion of the chip.
 * sptr is the pointer to the stuff structure
 */
static int _te1UNReset(STUFF *sptr)
{
int retval = 1;

	/* disable all interrupts
	 */

	utility_init(sptr, (sptr->utility_init = 0));
	alarm_init(sptr, (sptr->alarm_init = 0));
	onesec_init(sptr, (sptr->onesec_init = 0));


	retval = _te1Reset(sptr);
	if(!retval)
		return(0);

	retval = transmit_alarm(sptr, TMS_TXAIS, 1);

	if(sptr->greset) {
		NCID_GUNRESET(sptr->d);
		sptr->greset = 0;
	}

	return(retval);
}

/* -------------------------------------------------------------------------- */
/* Set the USR_SIDE vs NET_SIDE indication.
 */
 
static int set_side(STUFF *sptr, int side)
{
int retval = 1;

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

/* -------------------------------------------------------------------------- */
/* Process any polling operations here 
 */
static int process_OSTick(STUFF *sptr, int ticker)
{
int retval = 1;
int bits;
STANDARD_DECLARE;

	switch(ticker) {

	/* do Sa, Si, and Xbits
	 */
	case SASI_OSTICKER:
		/* the Si Bits are only valid in non-CRC formats
		 */
		if ((sptr->cfg.framing == FF_E1) ||
		    (sptr->cfg.framing == FF_E1_MF))
			(*sptr->cback)(sptr->lnPtr, TE1DCLBK_E1SASISIBIT,
				(f->rslc2_rnaf & 0x80) ? 1 : 0);

		if ((sptr->cfg.framing == FF_E1_CRC_MF) ||
		    (sptr->cfg.framing == FF_E1_CRC)) {

			int sabyte[E1SABYTE_MAX];

			sabyte[E1SABYTE4] = (int)BYTE_FLIP(f->rsa4);
			sabyte[E1SABYTE5] = (int)BYTE_FLIP(f->rsa5);
			sabyte[E1SABYTE6] = (int)BYTE_FLIP(f->rsa6);
			sabyte[E1SABYTE7] = (int)BYTE_FLIP(f->rsa7);
			sabyte[E1SABYTE8] = (int)BYTE_FLIP(f->rsa8);

			(*sptr->cback)(sptr->lnPtr, 
			      TE1DCLBK_E1SASISABYTE, sabyte);
		}
		else {
			(*sptr->cback)(sptr->lnPtr, TE1DCLBK_E1SASISABIT, 
					(f->rslc2_rnaf & 0x1f));
		}			
		
		/* the X bits are only valid in MF formats */
		if ((sptr->cfg.framing == FF_E1_CRC_MF) ||
		    (sptr->cfg.framing == FF_E1_MF)) {
		
			bits = f->rs[0];
			bits = (bits & 0x03) | ((bits & 0x08) >> 1);
			(*sptr->cback)(sptr->lnPtr, TE1DCLBK_E1SASIXBIT, bits);
		}
		break;
	default:
		retval = 0;
		break;

	}
	return(retval);
}

/* -------------------------------------------------------------------------- */
/* This is where the real E1 channel processing for an interrupt is done
 */
static int process_e1(STUFF *sptr)
{
int check_again = 0;
unsigned int riir;
STANDARD_DECLARE;

	riir = (f->riir & 0x09);

	if(riir & 0x01) {
		process_SR1_interrupt(sptr);
		check_again = 1;
	}

	if(riir & 0x08) {
		process_SR4_interrupt(sptr);
		check_again = 1;
	}


	return(check_again);
}

/* -------------------------------------------------------------------------- */
/* This is the interrupt service routine for the E1 functions 
 * it gets called by the global routine when the E1 interrupt is hooked up 
 * d points to the global device record.
 */
static int E1_handler(GDEVICE *d)
{
int check_again = 0;
int i;
int id;
STUFF *sptr;
unsigned char fisr, fmask;

	id = d->id;
	fisr = ((DEVICE *) d->BaseAdr)->te1[0].gfisr;
	fmask = ((DEVICE *) d->BaseAdr)->te1[0].gfimr;
	fisr = fisr & fmask;

	for (i = 0; i < MAX_E1_CHANNELS; i++) {
		if(!((sptr = &E1stuff[id][i])->init))
			continue;
		if(fisr & (1 << i))
			check_again |= process_e1(sptr);
	}

	return(check_again);
}

/* -------------------------------------------------------------------------- */
/* This routine get called from the global function to hook up the isr 
 * If the E1 the first to require ISR services, this will be called 
 * if the ISR was hooked up by another technology, this will not get called
 */
static void Glob2E1hookISR(STUFF *sptr, void *device_isr,
	int set_clear)
{

	if(set_clear) {
		/* Hook up the interrupt */
		(*sptr->cback)(sptr->lnPtr, TE1DCLBK_HOOKINTERRUPT, device_isr, 
			USER_DEFINED_HOOKINT_VALUE);
	}
	else {
		/* Unhook the interrupt */
		(*sptr->cback)(sptr->lnPtr, TE1DCLBK_UNHOOKINTERRUPT);
	}
}

/*------------------------------------------------------------------------*/
/* Routine to control hooking up and unhooking interrupts
 */
static int hook_isr(STUFF *sptr, int set_clear, int flag)
{
int retval = 1;
int previous = sptr->int_flag;

	if(set_clear) {
		/* check to see if need to hook interrupt */

		sptr->int_flag |= flag;

		switch(flag) {
		case INTFLAG_UTIL:
		default:
			break;
		case INTFLAG_ONESEC:
		case INTFLAG_ALM:
			/* Hook the interrupt here */

			if(!sptr->isr_hooked) {
			   sptr->isr_hooked = 1;
			   NCID_GHOOKISR(sptr->d, DRVR_IDX_E1,
				set_clear, Glob2E1hookISR, sptr, E1_handler);
			}
			break;
		}
	}
	else {
		/* check to see if need to unhook interrupt */

		previous &= ~flag;

		switch(flag) {
		case INTFLAG_UTIL:
		default:
			break;
		case INTFLAG_ONESEC:
		case INTFLAG_ALM:
			/* UnHook the interrupt here */

			if(
				(!(previous & INTFLAG_UTIL)) && 
				(!(previous & INTFLAG_ONESEC)) && 
				(!(previous & INTFLAG_ALM)) && 
				sptr->isr_hooked
			) {
			   NCID_GHOOKISR(sptr->d, DRVR_IDX_E1,
				set_clear, Glob2E1hookISR, sptr, E1_handler);
			   sptr->isr_hooked = 0;
		
			}
			break;
		}
		sptr->int_flag &= ~flag;
	}

	return(retval);
}

/*------------------------------------------------------------------------*/
/* Validate the line before being bound to a device
 */
static int _te1_valid_channel(GDEVICE *d, int subchannel)
{
	/* Single channl device needs no validation */
	return(1);
}


/* -------------------------------------------------------------------------- */
/* 
 * The include that follows below incorporate the standard E1
 * driver construct.  This Construct is common accross all E1
 * drivers.  You do not want to change the contents of the file that
 * is included below since it will change ALL E1 drivers.
 */
/* -------------------------------------------------------------------------- */

#include "apiTE1.inc"

⌨️ 快捷键说明

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