📄 slic.c
字号:
writeDirectReg(74, INIT_DR74 , channel);/*0X32 74 0x4A 0x32 Initialization VBATH (ringing) = 75 V (1.5 V/LSB) */ writeDirectReg(75, INIT_DR75 , channel);/*0X10 75 0x4B 0x10 Initialization VBATL (off-hook) = 24 V (TRACK = 0)(1.5 V/LSB) */ if (chipData[current_channel].type != 3) writeDirectReg(92,INIT_DR92 , channel);/*0x7f 92 0x5C 0xFF 7F Initialization DCDC Converter PWM Period (61.035 ns/LSB) */ else writeDirectReg(92,INIT_SI3210M_DR92,channel);/*0x60 92 0x5C 0xFF 7F Initialization DCDC Converter PWM Period (61.035 ns/LSB) */ writeDirectReg(93, INIT_DR93 , channel);/*0x14 93 0x5D 0x14 0x19 Initialization DCDC Converter Min. Off Time (61.035 ns/LSB) */ writeDirectReg(96, INIT_DR96 , channel);/*0x00 96 0x60 0x1F Initialization Calibration Control Register 1(written second and starts calibration) */ writeDirectReg(97, INIT_DR97 , channel);/*0X1F 97 0x61 0x1F Initialization Calibration Control Register 2(written before Register 96) */ writeDirectReg(98, INIT_DR98 , channel);/*0X10 98 0x62 0x10 Informative Calibration result (see data sheet) */ writeDirectReg(99, INIT_DR99 , channel);/*0X10 99 0x63 0x10 Informative Calibration result (see data sheet) */ writeDirectReg(100, INIT_DR100 , channel);/*0X11 100 0x64 0x11 Informative Calibration result (see data sheet) */ writeDirectReg(101, INIT_DR101 , channel);/*0X11 101 0x65 0x11 Informative Calibration result (see data sheet) */ writeDirectReg(102, INIT_DR102 , channel);/*0x08 102 0x66 0x08 Informative Calibration result (see data sheet) */ writeDirectReg(103, INIT_DR103 , channel);/*0x88 103 0x67 0x88 Informative Calibration result (see data sheet) */ writeDirectReg(104, INIT_DR104 , channel);/*0x00 104 0x68 0x00 Informative Calibration result (see data sheet) */ writeDirectReg(105, INIT_DR105 , channel);/*0x00 105 0x69 0x00 Informative Calibration result (see data sheet) */ writeDirectReg(106, INIT_DR106 , channel);/*0x20 106 0x6A 0x20 Informative Calibration result (see data sheet) */ writeDirectReg(107, INIT_DR107 , channel);/*0x08 107 0x6B 0x08 Informative Calibration result (see data sheet) */ writeDirectReg(108, INIT_DR108 , channel);/*0xEB 108 0x63 0x00 0xEB Initialization Feature enhancement register */}int32 slic_init_powerUp(int channel){ int32 i; extern unsigned long jiffies; unsigned long initialTime, powerTime=0; if (chipData[channel].type == 3) /* M version correction */ { writeDirectReg(92,INIT_SI3210M_DR92, channel);/* M version */ writeDirectReg(93,INIT_SI3210M_DR93, channel);/* M version */ } else { /* set the period of the DC-DC converter to 1/64 kHz START OUT SLOW*/ writeDirectReg(93, 0x12, channel); writeDirectReg(92, 0x7f, channel); } initialTime = jiffies; writeDirectReg(14, 0, channel); /* Engage the DC-DC converter */ i = 0; while (readDirectReg(82, channel) < 0xC0)/* 0xC0 is 72 volt */ { if( i++ > 2000 ) { if( i == 2001 ) { rtlglue_printf("TimeUp for powerup!\n"); } if( (jiffies - initialTime) > 50 )/* 0.5 seconds */ { rtlglue_printf("Exception: timeout for powerup! ::%02X\n", readDirectReg(82, channel)); return FAILED; } } } powerTime = jiffies - initialTime; if ( powerTime > 50)/* 0.5 seconds */ { rtlglue_printf("\nWarning Power Up took %lu milliseconds.\t",powerTime); rtlglue_printf("more than 0.5 seconds\n"); } writeDirectReg(93, 0x80, channel); /* DC-DC Calibration */ rtlglue_printf("Wait for DC-DC Calibration to complete\n"); /* Wait for DC-DC Calibration to complete */ while( 0x80 & readDirectReg(93, channel)); rtlglue_printf("power up complete!\n"); return SUCCESS;} int32 slic_init_powerLeakTest(int channel){ unsigned long Leaktime; extern unsigned long volatile jiffies; unsigned char vBat; writeDirectReg(64, 0x00, channel); writeDirectReg(14, 0x10, channel);/*Force DC-DC circuitry off*/ Leaktime = jiffies; while((jiffies - Leaktime)<100);/* 1 second */ vBat = readDirectReg(82, channel); if ( vBat < 0x4) /* 4x1.5 = 6 volts */ { rtlglue_printf("Exception: power is leaking!\n"); return FAILED; } rtlglue_printf("Power not leaking!\n"); return SUCCESS;}void slic_init_calibrate(int channel){ extern unsigned long volatile jiffies; unsigned long Caltime; unsigned char x,y,i=0,progress=0; /* Do Flush durring powerUp and calibrate */ writeDirectReg(21,DISABLE_ALL_DR21, channel);/* Disable all interupts in DR21 */ writeDirectReg(22,DISABLE_ALL_DR22, channel);/* Disable all interupts in DR21 */ writeDirectReg(23,DISABLE_ALL_DR23, channel);/* Disabel all interupts in DR21 */ writeDirectReg(64,OPEN_DR64, channel); /*(0x18)Calibrations without the ADC and DAC offset and without common mode calibration. */ writeDirectReg(97,STANDARD_CAL_DR97, channel); /* Calibrate common mode and differential DAC mode DAC + ILIM */ writeDirectReg(96,STANDARD_CAL_DR96, channel); while (readDirectReg(96, channel) != 0 ); /* Initialized DR 98 and 99 to get consistant results. 98 and 99 are the results registers and the search should have same intial conditions. The following is the manual gain mismatch calibration This is also available as a function */ Caltime= jiffies; while((jiffies-Caltime)<1);/* 0.01 seconds */ writeIndirectReg(88,0, channel); writeIndirectReg(89,0, channel); writeIndirectReg(90,0, channel); writeIndirectReg(91,0, channel); writeIndirectReg(92,0, channel); writeIndirectReg(93,0, channel); /* This is necessary if the calibration occurs other than at reset time */ writeDirectReg(98,0x10, channel); writeDirectReg(99,0x10, channel); for ( i=0x1f; i>0; i--) { writeDirectReg(98,i, channel); Caltime = jiffies; while((jiffies-Caltime)<4);/* 0.04 seconds */ if((readDirectReg(88, channel)) == 0) { progress|=1; x=i; break; } } for ( i=0x1f; i>0; i--) { writeDirectReg(99,i, channel); Caltime = jiffies; while((jiffies-Caltime)<4); if((readDirectReg(89, channel)) == 0) { progress|=2; y=i; break; } } /* The preceding is the manual gain mismatch calibration The following is the longitudinal Balance Cal */ goActive(channel); if((readDirectReg(68, channel) & 0x3) & 4) return ; writeDirectReg(64,OPEN_DR64, channel); writeDirectReg(23,ENB2_DR23, channel); /* enable interrupt for the balance Cal */ writeDirectReg(97,BIT_CALCM_DR97, channel); /* this is a singular calibration bit for longitudinal calibration */ writeDirectReg(96,0x40, channel); while(readDirectReg(96, channel) != 0 ); writeDirectReg(21,INIT_DR21, channel); writeDirectReg(22,INIT_DR22, channel); writeDirectReg(23,INIT_DR23, channel); /*The preceding is the longitudinal Balance Cal*/}/*THIRD*/void slic_init_PCM(uint32 channel, int32 pcmFormat ){ uint8 modeReg = 0; writeDirectReg( 1, 0x00, channel);/*Disable slic pcm function */ switch(pcmFormat) { case PCM_LINEAR: modeReg |= 0x18; break; case PCM_ULAW: modeReg |= 0x08; break; case PCM_ALAW: modeReg |= 0x00; break; default:/*Linear*/ modeReg |= 0x18; break; } modeReg |= 0x01; /*Tri-state bit 0 on negative edge of PCLK*/ modeReg |= 0x20; /*Enable pcm*/ //modeReg |= 0x04; /* 16 bit tx mode */ /* Set pcm time slot needs be careful */ writeDirectReg( 2 , 1 + channel * 8, channel);/*'1' correspond time slot 0 in pcm */ writeDirectReg( 3 , 0x00, channel);/*High byte TXS*/ writeDirectReg( 4 , 1 + channel * 8, channel); writeDirectReg( 5 , 0x00, channel);/*High byte RXS*/#ifdef STATE_ROLL chipData[channel].pcm_channel = channel;/* Slic channel must equal PCM channel */ chipData[channel].mid = 0;#endif writeDirectReg( 8 , 0x00, channel);/* disable loop back */ writeDirectReg( 9 , 0x00, channel);/* TX RX gain = 0 db & digital mute */ writeDirectReg( 10, 0x28, channel); writeDirectReg( 11, 0x00, channel);/*Hybrid adjustment 0dB*/ writeDirectReg( 1 , modeReg, channel);/*pcm enabled*/}void slic_init_Value(uint32 channel, int32 pcm_mode){ unsigned long timeEpoch; extern unsigned long volatile jiffies; int freq; char* freqs[ ] = {"8192","4028","2048","1024","512","256","1536","768","32768"}; slic_init_PCM(channel, pcm_mode); /* Set Ring cadence 1 sec ON , 2 sec OFF */ slic_ring_standard(channel); /* Set loop current limit */ writeDirectReg( 71 , 0x04, channel ); /* Set external BJT and battery feed control and loop closure debounce */ writeDirectReg( 65 , 0x11, channel ); writeDirectReg( 66 , 0x01, channel ); writeDirectReg( 69 , 0x0C, channel ); /* print out the PCM clock frequecy and the revision */ freq = readDirectReg(13, channel)>>4; /* Read the frequency */ rtlglue_printf("\nPCM clock = %s KHz Rev %c\n", freqs[freq], 'A'-1 + chipData[channel].version); /* Set Linefeed state to Forward on-hook transmission */ writeDirectReg(64, 2, channel); if(slic_init_VerifyIReg(channel)!=SUCCESS) { rtlglue_printf("SLIC indirect register's initial values are lost\n"); } //slic_ring_activate(channel); /* hold three seconds */ timeEpoch = jiffies + 300; while(jiffies < timeEpoch); writeDirectReg(64, 0, channel); goActive(channel); if(readDirectReg(68, channel)&4) /*ONHOOK: put down the phone*/ chipData[channel].bOffHook = FALSE; else /*OFFHOOK: take off the phone*/ chipData[channel].bOffHook = TRUE; chipData[channel].bEnabled = TRUE; #ifdef STATE_ROLL chipData[channel].preState = DEMURE; if(chipData[channel].bOffHook == TRUE) chipData[channel].nowState = OFFHOOK; else chipData[channel].nowState = ONHOOK;#endif}int32 slic_init_VerifyIReg(int channel){ int32 ret = SUCCESS; uint16 i,j, initial; for (i=0; i<42; i++) { j = readIndirectReg((unsigned char) i, channel); initial= indirectRegisters[i].initial; if ( j != initial ) { rtlglue_printf("The %d indirect register %04X(normal):%04X(lost)\n", i, initial,j); ret = FAILED; } } return ret;}/*@ ZONE: interrupt service, the functions in the following is@ only used when kernel is polling at it. @ check state, take short response etc.*/int32 _slic_PollInt(void){ uint8 isr_status; int32 ret = SUCCESS; int channel;#ifdef STATE_ROLL static uint8 myPack;#endif for( channel = 0 ; channel < TOTAL_SLIC_CHANNEL ; channel++ ) { if( chipData[channel].bEnabled == FALSE ) { continue; } /*------------------------------------------------ * ISR 20 *------------------------------------------------*/ isr_status = readDirectReg(20, channel); if(isr_status & DTMFP) { rtlglue_printf("CH_%d DTMF \n", channel); isr_status |= DTMFP; writeDirectReg(20, isr_status, channel); slic_tone_diableOSCs(channel); dtmfAction(channel); } /*------------------------------------------------ * ISR 19 *------------------------------------------------*/ /* Loop closure detection, when you pick up or put down the phone this interrupt is generated and inform you to act. */ isr_status = readDirectReg(19, channel); if(isr_status & LCIP) { isr_status |= LCIP; writeDirectReg(19, isr_status, channel); #ifdef STATE_ROLL if(readDirectReg(68, channel)&0x04) /*ONHOOK: put down the phone*/ { chipData[channel].bOffHook = FALSE; ENTER_STATE(ONHOOK); switch( chipData[channel].preState ) { case BUSYTONE: case RINGTONE: slic_tone_diableOSCs(channel); myPack = I_STOP_CALLING; voip_TxRtpPkt(chipData[channel].pcm_channel, chipData[channel].mid, &myPack, 1, TYPE_NONE); rtlglue_printf("CH_%d Stop Calling\n", channel); ENTER_STATE(DEMURE); break; case TALKING: myPack = I_QUIT_TALK; voip_TxRtpPkt(chipData[channel].pcm_channel, chipData[channel].mid, &myPack, 1, TYPE_NONE); ENTER_STATE(DEMURE); break; default: slic_tone_diableOSCs(channel); ENTER_STATE(DEMURE); break; } } /* OFFHOOK: the phone is being taken up */ else { chipData[channel].bOffHook = TRUE; ENTER_STATE(OFFHOOK); /* FIXME : ask for talk wait for status sure */ switch( chipData[channel].preState ) { case DEMURE: case ONHOOK: myPack = I_INIT_CALLING; voip_TxRtpPkt(chipData[channel].pcm_channel, chipData[channel].mid, &myPack, 1, TYPE_NONE); break; case RING: myPack = I_RECV_CALLING; voip_TxRtpPkt(chipData[channel].pcm_channel, chipData[channel].mid, &myPack, 1, TYPE_NONE); ENTER_STATE(TALKING); break; default: break; } } #endif } if(isr_status & RTIP) { rtlglue_printf("CH_%d up when RING\n",channel); isr_status |= RTIP; writeDirectReg(19, isr_status, channel); #ifdef STATE_ROLL if((readDirectReg(68, channel)&0x04)==0) /*OFFHOOK*/ { chipData[channel].bOffHook = TRUE; ENTER_STATE(OFFHOOK); /* FIXME : ask for talk wait for status sure */ switch( chipData[channel].preState ) { case DEMURE: case ONHOOK: break; case RING: myPack = I_RECV_CALLING; voip_TxRtpPkt(chipData[channel].pcm_channel, chipData[channel].mid, &myPack, 1, TYPE_NONE); ENTER_STATE(TALKING); break; default: break; } } #endif } /*------------------------------------------------ * ISR 18 *------------------------------------------------*/ isr_status = readDirectReg(18, channel); if(isr_status & PMIP)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -