📄 ds26528e1.c
字号:
/* 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 + -