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

📄 ds26528t1.c

📁 Sample driver code for Dallas DS26528 T1/E1 framer chip.
💻 C
📖 第 1 页 / 共 4 页
字号:
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));
	t1403_init(sptr, (sptr->t1403_init = 0));
	loop_init(sptr, (sptr->loop_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 do */

	return(retval);
}

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

	return(retval);
}

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

	status = f->rls7; 

	if(status & RLS7_BD) {
		data = (f->rboc & 0x3f) << 1;
		(*sptr->cback)(sptr->lnPtr, TE1DCLBK_T1403RXBOC, data);
	}
	if(status & RLS7_BC) {
		(*sptr->cback)(sptr->lnPtr, TE1DCLBK_T1403RXBOC, 0xff);

	}

	f->rls7 = status;
}

/*------------------------------------------------------------------------*/
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->t1s.rxslip = 1;
	}

	f->rls4 = statusl;
}

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

	status = f->rrts3;
	statusl = f->rls3;


	if(statusl & (RLS3_LUPD | RLS3_LUPC)) {
		(*sptr->cback)(sptr->lnPtr, 
			TE1DCLBK_LOOP, 
			LOOP_REMRXUPCODE, (status & RRTS3_LUP) ? 1 : 0,
			sptr->rxlup.code, sptr->rxlup.bits);
	} 

	if(statusl & (RLS3_LDND | RLS3_LDNC)) {
		(*sptr->cback)(sptr->lnPtr, 
			TE1DCLBK_LOOP, 
			LOOP_REMRXDNCODE, (status & RRTS3_LDN) ? 1 : 0,
			sptr->rxldn.code, sptr->rxldn.bits);
	} 
	
	f->rls3 = statusl;
}



/*------------------------------------------------------------------------*/
/* processes transmission of HDLC packets
 * h = the hdlc channel number
 */
static void hdlc_xmit(STUFF *sptr)
{
int count, txroom;
STANDARD_DECLARE;

	if(sptr->t1s.txremaining == 0) {
		f->tim2 &= ~(TIM2_TMEND | TIM2_TLWMS | TIM2_TNFS);
		return;
	}

	txroom = f->tfba & 0x7f;
	if(txroom == 0) 
		txroom = (FIFOSIZE-1);
	if(txroom >=128) 
		txroom = (FIFOSIZE-1);

	/* never fill the fifo up since we can not tell no room from all room */

	count = (sptr->t1s.txremaining > txroom) ? 
		txroom : sptr->t1s.txremaining;

	f->thc1 &= ~(THC1_TEOM);

	while(count--) {
		if (sptr->t1s.txremaining == 1)
			f->thc1 |= THC1_TEOM;

		f->thf = sptr->pkttx.pkt[sptr->pkttx.byte_count -
						   sptr->t1s.txremaining--];
	}

	if(sptr->t1s.txremaining == 0) {
		f->tim2 = (UC)((f->tim2 & ~(TIM2_TLWMS))
		 | TIM2_TMEND);
	}
	else {
		f->tim2 = (UC)((f->tim2 & ~(TIM2_TMEND))
		 | (TIM2_TLWMS));
	}
}

/*------------------------------------------------------------------------*/
/* Handles the HDLC interrupts
 */
static void process_RXHDLC_interrupt(STUFF *sptr)
{
volatile unsigned char status;
volatile unsigned char regval;
int i,cnt;
int packetstart = 0;
unsigned char data;
STANDARD_DECLARE;


	status = f->rls5;
	f->rls5 = status;

	status &= f->rim5;

	if (!status) 
		return;

	/* Check for Packet received
	 */

	if (status & RLS5_RPS) {
		/* packet has started */
		sptr->pktrx.byte_count = 0;
		packetstart = 1;
		f->rim5 = (UC)((f->rim5 & ~(RIM5_RPS)) |
			(RIM5_RPE | RIM5_RHWMS));
	}

	if((status & (RLS5_RPE | RLS5_RHWMS)) || packetstart) {

	   cnt = f->rhpba;
	   if(cnt & RHPBA_MS) {
		if((cnt & 0x7f) == 0) {
			cnt = 128;
		}
		else {
			cnt &= 0x7f;
		}
	   }

	   if ((sptr->pktrx.byte_count + cnt) >= MAX_PACKET) {
		for(i = 0;i < cnt; i++) {
		   	data = f->rhf;
		}
		sptr->pktrx.byte_count = 0;
		return;
	   }
	
	   /* have good data in the fifo */

	   for(i = 0;i < cnt; i++) { 

	   	sptr->pktrx.pkt[sptr->pktrx.byte_count++] = f->rhf;

	   	regval = f->rrts5;

	   	switch(regval & RRTS5_PS(0xff)) {
		   case 2:	/* values 2 through 5 represent errors */
		   case 3:	/* if any of the occur, drop the packet */
		   case 4:
		   case 5:
		   	/* packet being received is no good */
			/* flush it */

		   	for(i = 0; i < cnt; i++) {
		   		data = f->rhf;
			}
			sptr->pktrx.byte_count = 0;
			return;	
		   default:
			break;
	   	}

	   }
		
	   if(status & RLS5_RPE) {
		(*sptr->cback)(sptr->lnPtr, TE1DCLBK_T1403RXPKT,
				sptr->pktrx.byte_count, 
				sptr->pktrx.pkt);
	   	sptr->pktrx.byte_count = 0;
	   	f->rim5 = (UC)((f->rim5 & 
	   		~(RIM5_RPE | RIM5_RHWMS)) | (RIM5_RPS));
	   } 
	}
}
/*------------------------------------------------------------------------*/
/* Handles the HDLC interrupts
 */
static void process_TXHDLC_interrupt(STUFF *sptr)
{
volatile unsigned char status;
STANDARD_DECLARE;


	status = f->tls2;
	f->tls2 = status;

	if (sptr->t1s.sendingBOC || !sptr->t1s.sendingPKT) {
		return;
	}

	if (status & TLS2_TMEND) {
		sptr->t1s.sendingPKT = 0;
		(*sptr->cback)(sptr->lnPtr, TE1DCLBK_T1403TXPKTCOMPLETE);
		hdlc_xmit(sptr);
		return;
	}

	if (status & (TLS2_TLWMS)) {

		if (status & TLS2_TUDR) {
			/* Setup for a retry
			 */
			/* clear out tx */
			f->thc1 = THC1_THR | THC1_THMS;
			f->thc1 = THC1_THMS;
			sptr->t1s.txremaining = sptr->pkttx.byte_count;
		}
		hdlc_xmit(sptr);
	}
}


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

	riir = (f->riir & 0x5D);
	tiir = (f->tiir & 0x02);

	if(riir & 0x01) {
		process_SR1_interrupt(sptr);
		check_again = 1;
	}
	if(riir & 0x04) {
		process_SR3_interrupt(sptr);
		check_again = 1;
	}
	if(riir & 0x08) {
		process_SR4_interrupt(sptr);
		check_again = 1;
	}
	if(riir & 0x10) {
		process_RXHDLC_interrupt(sptr);
		check_again = 1;
	}
	if(riir & 0x40) {
		process_SR7_interrupt(sptr);
		check_again = 1;
	}
	if(tiir & 0x02) {
		process_TXHDLC_interrupt(sptr);
		check_again = 1;
	}

	return(check_again);
}

/* -------------------------------------------------------------------------- */
/* This is the interrupt service routine for the T1 functions 
 * it gets called by the global routine when the T1 interrupt is hooked up 
 * d points to the global device record.
 */
static int T1_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_T1_CHANNELS; i++) {
		if(!((sptr = &T1stuff[id][i])->init))
			continue;
		if(fisr & (1 << i))
			check_again |= process_t1(sptr);
	}

	return(check_again);
}

/* -------------------------------------------------------------------------- */
/* This routine get called from the global function to hook up the isr 
 * If the T1 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 Glob2T1hookISR(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:
		case INTFLAG_TR008:
		default:
			break;
		case INTFLAG_ONESEC:
		case INTFLAG_ALM:
		case INTFLAG_T1403:
		case INTFLAG_LOOP:
			/* Hook the interrupt here */

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

		previous &= ~flag;

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

			if(
				(!(previous & INTFLAG_UTIL)) && 
				(!(previous & INTFLAG_ONESEC)) && 
				(!(previous & INTFLAG_ALM)) && 
				(!(previous & INTFLAG_T1403)) && 
				(!(previous & INTFLAG_LOOP)) && 
				(!(previous & INTFLAG_TR008)) &&
				sptr->isr_hooked
			) {
			   NCID_GHOOKISR(sptr->d, DRVR_IDX_T1,
				set_clear, Glob2T1hookISR, sptr, T1_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 channel device no validation needed */
	return(1);
}


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

#include "apiTE1.inc"

⌨️ 快捷键说明

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