📄 ds26528t1.c
字号:
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 + -