developer | e0cea0f | 2021-12-16 16:08:26 +0800 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0
|
| 2 | /*
|
| 3 | * SI3218X ProSLIC interface implementation file
|
| 4 | *
|
| 5 | * Author(s):
|
| 6 | * cdp
|
| 7 | *
|
| 8 | * Distributed by:
|
| 9 | * Silicon Laboratories, Inc
|
| 10 | *
|
| 11 | * This file contains proprietary information.
|
| 12 | * No dissemination allowed without prior written permission from
|
| 13 | * Silicon Laboratories, Inc.
|
| 14 | *
|
| 15 | */
|
| 16 |
|
| 17 | #include "../config_inc/si_voice_datatypes.h"
|
| 18 | #include "../inc/si_voice_ctrl.h"
|
| 19 | #include "../inc/si_voice_timer_intf.h"
|
| 20 | #include "../inc/proslic.h"
|
| 21 | #include "../inc/si3218x.h"
|
| 22 | #include "../inc/si3218x_intf.h"
|
| 23 | #include "../inc/si3218x_registers.h"
|
| 24 | #include "../config_inc/proslic_api_config.h"
|
| 25 |
|
| 26 | #define SI3218X_IRING_LIM_MAX 0xA00000L /* 103mA */
|
| 27 | #define SI3218X_REVA 2
|
| 28 |
|
| 29 | #define WriteReg pProslic->deviceId->ctrlInterface->WriteRegister_fptr
|
| 30 | #define ReadReg pProslic->deviceId->ctrlInterface->ReadRegister_fptr
|
| 31 | #define pProHW pProslic->deviceId->ctrlInterface->hCtrl
|
| 32 | #define Reset pProslic->deviceId->ctrlInterface->Reset_fptr
|
| 33 | #define Delay pProslic->deviceId->ctrlInterface->Delay_fptr
|
| 34 | #define pProTimer pProslic->deviceId->ctrlInterface->hTimer
|
| 35 | #define WriteRAM pProslic->deviceId->ctrlInterface->WriteRAM_fptr
|
| 36 | #define ReadRAM pProslic->deviceId->ctrlInterface->ReadRAM_fptr
|
| 37 | #define TimeElapsed pProslic->deviceId->ctrlInterface->timeElapsed_fptr
|
| 38 | #define getTime pProslic->deviceId->ctrlInterface->getTime_fptr
|
| 39 |
|
| 40 | #define WriteRegX deviceId->ctrlInterface->WriteRegister_fptr
|
| 41 | #define ReadRegX deviceId->ctrlInterface->ReadRegister_fptr
|
| 42 | #define pProHWX deviceId->ctrlInterface->hCtrl
|
| 43 | #define DelayX deviceId->ctrlInterface->Delay_fptr
|
| 44 | #define pProTimerX deviceId->ctrlInterface->hTimer
|
| 45 | #define ReadRAMX deviceId->ctrlInterface->ReadRAM_fptr
|
| 46 | #define WriteRAMX deviceId->ctrlInterface->WriteRAM_fptr
|
| 47 |
|
| 48 | #define DEVICE_KEY_MIN 0x6E
|
| 49 | #define DEVICE_KEY_MAX 0x77
|
| 50 |
|
| 51 | #ifdef ENABLE_DEBUG
|
| 52 | static const char LOGPRINT_PREFIX[] = "Si3218x: ";
|
| 53 | #endif
|
| 54 |
|
| 55 | /*
|
| 56 | ** Externs
|
| 57 | */
|
| 58 |
|
| 59 | /* General Configuration */
|
| 60 | extern Si3218x_General_Cfg Si3218x_General_Configuration;
|
| 61 | #ifdef SIVOICE_MULTI_BOM_SUPPORT
|
| 62 | extern const proslicPatch SI3218X_PATCH_A;
|
| 63 | extern Si3218x_General_Cfg Si3218x_General_Configuration_MultiBOM[];
|
| 64 | extern int si3218x_genconf_multi_max_preset;
|
| 65 | #else
|
| 66 | extern const proslicPatch SI3218X_PATCH_A_DEFAULT;
|
| 67 | #endif
|
| 68 |
|
| 69 | /* Ringing */
|
| 70 | #ifndef DISABLE_RING_SETUP
|
| 71 | extern Si3218x_Ring_Cfg Si3218x_Ring_Presets[];
|
| 72 | #endif
|
| 73 |
|
| 74 | /* Zsynth */
|
| 75 | #ifndef DISABLE_ZSYNTH_SETUP
|
| 76 | extern Si3218x_Impedance_Cfg Si3218x_Impedance_Presets [];
|
| 77 | #endif
|
| 78 |
|
| 79 | /* Audio Gain Scratch */
|
| 80 | extern Si3218x_audioGain_Cfg Si3218x_audioGain_Presets[];
|
| 81 |
|
| 82 | /* Pulse Metering */
|
| 83 | #ifndef DISABLE_PULSE_SETUP
|
| 84 | extern Si3218x_PulseMeter_Cfg Si3218x_PulseMeter_Presets [];
|
| 85 | #endif
|
| 86 |
|
| 87 | /* PCM */
|
| 88 | #ifndef DISABLE_PCM_SETUP
|
| 89 | extern Si3218x_PCM_Cfg Si3218x_PCM_Presets [];
|
| 90 | #endif
|
| 91 |
|
| 92 | #define SI3218X_RAM_DCDC_DCFF_ENABLE SI3218X_RAM_GENERIC_8
|
| 93 | #define GCONF Si3218x_General_Configuration
|
| 94 |
|
| 95 | /*
|
| 96 | ** Constants
|
| 97 | */
|
| 98 | #define BIT20LSB 1048576L
|
| 99 | #define OITHRESH_OFFS 900L
|
| 100 | #define OITHRESH_SCALE 100L
|
| 101 | #define OVTHRESH_OFFS 71000
|
| 102 | #define OVTHRESH_SCALE 3000L
|
| 103 | #define UVTHRESH_OFFS 4057L
|
| 104 | #define UVTHRESH_SCALE 187L
|
| 105 | #define UVHYST_OFFS 548L
|
| 106 | #define UVHYST_SCALE 47L
|
| 107 |
|
| 108 | /*
|
| 109 | ** Local functions are defined first
|
| 110 | */
|
| 111 |
|
| 112 | /*
|
| 113 | ** Function: getChipType
|
| 114 | **
|
| 115 | ** Description:
|
| 116 | ** Decode ID register to identify chip type
|
| 117 | **
|
| 118 | ** Input Parameters:
|
| 119 | ** ID register value
|
| 120 | **
|
| 121 | ** Return:
|
| 122 | ** partNumberType
|
| 123 | */
|
| 124 | static partNumberType getChipType(uInt8 data)
|
| 125 | {
|
| 126 | /* For the parts that have a HV variant, we map to the lower voltage version,
|
| 127 | the actual differences are handled in the constants file
|
| 128 | */
|
| 129 |
|
| 130 | const uInt8 partNums[8] =
|
| 131 | {
|
| 132 | UNSUPPORTED_PART_NUM, UNSUPPORTED_PART_NUM, UNSUPPORTED_PART_NUM, UNSUPPORTED_PART_NUM,
|
| 133 | SI32184, SI32182, SI32185, SI32183
|
| 134 | };
|
| 135 |
|
| 136 | uInt8 partNum = (data & 0x38) >> 3; /* PART_NUM[2:0] = ID[5:3] */
|
| 137 |
|
| 138 | return partNums[ partNum ];
|
| 139 | }
|
| 140 |
|
| 141 | int Si3218x_GetChipInfo(proslicChanType_ptr pProslic)
|
| 142 | {
|
| 143 | uInt8 id;
|
| 144 | id = ReadReg(pProHW, pProslic->channel, PROSLIC_REG_ID);
|
| 145 |
|
| 146 | pProslic->deviceId->chipRev = id & 0x7;
|
| 147 | pProslic->deviceId->chipType = getChipType(id);
|
| 148 |
|
| 149 | if(pProslic->deviceId->chipType == UNSUPPORTED_PART_NUM)
|
| 150 | {
|
| 151 | #ifdef ENABLE_DEBUG
|
| 152 | LOGPRINT("%sregister 0 read = 0x%02X\n", LOGPRINT_PREFIX, id);
|
| 153 | #endif
|
| 154 | return RC_SPI_FAIL;
|
| 155 | }
|
| 156 | else
|
| 157 | {
|
| 158 | return RC_NONE;
|
| 159 | }
|
| 160 | }
|
| 161 |
|
| 162 | /*
|
| 163 | ** Function: Si3218x_ConverterSetup
|
| 164 | **
|
| 165 | ** Description:
|
| 166 | ** Program revision specific settings before powering converter
|
| 167 | **
|
| 168 | ** Specifically, from general parameters and knowledge that this
|
| 169 | ** is Si32188x, setup dcff drive, gate drive polarity, and charge pump.
|
| 170 | **
|
| 171 | ** Returns:
|
| 172 | ** int (error)
|
| 173 | **
|
| 174 | */
|
| 175 | int Si3218x_ConverterSetup(proslicChanType_ptr pProslic)
|
| 176 | {
|
| 177 | ramData inv_off;
|
| 178 |
|
| 179 | /* Option to add a per-channel inversion for maximum flexibility */
|
| 180 | if(pProslic->dcdc_polarity_invert)
|
| 181 | {
|
| 182 | inv_off = 0x100000L;
|
| 183 | }
|
| 184 | else
|
| 185 | {
|
| 186 | inv_off = 0x0L;
|
| 187 | }
|
| 188 |
|
| 189 | switch(Si3218x_General_Configuration.bom_option)
|
| 190 | {
|
| 191 | case BO_DCDC_LCQC_5W:
|
| 192 | case BO_DCDC_LCCB:
|
| 193 | case BO_DCDC_LCCB110:
|
| 194 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_LIFT_EN,
|
| 195 | 0x0L); /* dcff disabled */
|
| 196 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_SWDRV_POL,
|
| 197 | inv_off); /* non-inverted */
|
| 198 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_CPUMP,
|
| 199 | 0x100000L); /* Charge pump on */
|
| 200 | Delay(pProTimer,20); /* Cpump settle */
|
| 201 | break;
|
| 202 |
|
| 203 | case BO_DCDC_BUCK_BOOST:
|
| 204 | /*
|
| 205 | ** RevC buck-boost designs are identical to RevB - no gate drive,
|
| 206 | ** dcff enabled, non-inverting (charge pump off)
|
| 207 | */
|
| 208 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_CPUMP,0x0L);
|
| 209 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_SWDRV_POL,inv_off);
|
| 210 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_LIFT_EN,
|
| 211 | 0x100000L); /* dcff enabled */
|
| 212 | break;
|
| 213 |
|
| 214 | default:
|
| 215 | return RC_DCDC_SETUP_ERR;
|
| 216 | }
|
| 217 |
|
| 218 | return RC_NONE;
|
| 219 | }
|
| 220 |
|
| 221 | /*
|
| 222 | ** Function: Si3218x_PowerUpConverter
|
| 223 | **
|
| 224 | ** Description:
|
| 225 | ** Powers all DC/DC converters sequentially with delay to minimize
|
| 226 | ** peak power draw on VDC.
|
| 227 | **
|
| 228 | ** Returns:
|
| 229 | ** int (error)
|
| 230 | **
|
| 231 | */
|
| 232 |
|
| 233 | int Si3218x_PowerUpConverter(proslicChanType_ptr pProslic)
|
| 234 | {
|
| 235 | errorCodeType error = RC_DCDC_SETUP_ERR;
|
| 236 | int32 vbath,vbat;
|
| 237 | uInt8 reg = 0;
|
| 238 | int timer = 0;
|
| 239 |
|
| 240 |
|
| 241 | if(pProslic->channelType != PROSLIC)
|
| 242 | {
|
| 243 | return RC_CHANNEL_TYPE_ERR;
|
| 244 | }
|
| 245 |
|
| 246 | /*
|
| 247 | ** - powerup digital dc/dc w/ OV clamping and shutdown
|
| 248 | ** - delay
|
| 249 | ** - verify no short circuits by looking for vbath/2
|
| 250 | ** - clear dcdc status
|
| 251 | ** - switch to analog converter with OV clamping only (no shutdown)
|
| 252 | ** - select analog dcdc and disable pwrsave
|
| 253 | ** - delay
|
| 254 | */
|
| 255 |
|
| 256 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,
|
| 257 | LF_FWD_OHT); /* Force out of pwrsave mode if called in error */
|
| 258 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,
|
| 259 | LF_OPEN); /* Ensure open line before powering up converter */
|
| 260 | reg = ReadReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE);
|
| 261 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE,
|
| 262 | reg&0x07); /* Disable powersave mode */
|
| 263 |
|
| 264 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_DCDC,
|
| 265 | 0x700000L); /* In case OV or UV previously occurred */
|
| 266 |
|
| 267 | /*
|
| 268 | ** Setup converter drive polarity and charge pump enable
|
| 269 | ** based on bom
|
| 270 | */
|
| 271 |
|
| 272 | error = Si3218x_ConverterSetup(pProslic);
|
| 273 |
|
| 274 | if(error != RC_NONE)
|
| 275 | {
|
| 276 | DEBUG_PRINT (pProslic, "%sChannel %d : DCDC initialization failed\n",
|
| 277 | LOGPRINT_PREFIX, pProslic->channel);
|
| 278 | return error;
|
| 279 | }
|
| 280 |
|
| 281 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_DCDC,0x600000L);
|
| 282 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_BIAS,0x200000L);
|
| 283 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_HVIC,0x200000L);
|
| 284 | Delay(pProTimer,50);
|
| 285 |
|
| 286 | vbath = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_VBATH_EXPECT);
|
| 287 | vbat = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_VBAT);
|
| 288 | if(vbat & 0x10000000L)
|
| 289 | {
|
| 290 | vbat |= 0xF0000000L;
|
| 291 | }
|
| 292 | if(vbat < (vbath / 2))
|
| 293 | {
|
| 294 | pProslic->channelEnable = 0;
|
| 295 | error = RC_VBAT_UP_TIMEOUT;
|
| 296 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_DCDC,
|
| 297 | 0x300000L); /* shutdown converter */
|
| 298 | DEBUG_PRINT (pProslic,
|
| 299 | "%sChannel %d : DCDC Short Circuit Failure - disabling channel\n%sVBAT = %d.%d\n",
|
| 300 | LOGPRINT_PREFIX, pProslic->channel, LOGPRINT_PREFIX,
|
| 301 | (int)((vbat/SCALE_V_MADC)/1000),
|
| 302 | SIVOICE_ABS(((vbat/SCALE_V_MADC) - (vbat/SCALE_V_MADC)/1000*1000)));
|
| 303 | return error;
|
| 304 | }
|
| 305 | else /* Enable analog converter */
|
| 306 | {
|
| 307 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_DCDC_STATUS,0L);
|
| 308 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_DCDC,0x400000L);
|
| 309 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE,
|
| 310 | reg); /* Restore ENHANCE */
|
| 311 | Delay(pProTimer,50);
|
| 312 | }
|
| 313 |
|
| 314 | /*
|
| 315 | ** - monitor vbat vs expected level (VBATH_EXPECT)
|
| 316 | */
|
| 317 | vbath = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_VBATH_EXPECT);
|
| 318 | do
|
| 319 | {
|
| 320 | vbat = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_VBAT);
|
| 321 | if(vbat & 0x10000000L)
|
| 322 | {
|
| 323 | vbat |= 0xF0000000L;
|
| 324 | }
|
| 325 | Delay(pProTimer,10);
|
| 326 | }
|
| 327 | while((vbat < (vbath - COMP_5V))
|
| 328 | &&(timer++ < SI3218X_TIMEOUT_DCDC_UP)); /* 2 sec timeout */
|
| 329 |
|
| 330 | DEBUG_PRINT (pProslic, "%sChannel %d : VBAT Up = %d.%d v\n",
|
| 331 | LOGPRINT_PREFIX,
|
| 332 | pProslic->channel,(int)((vbat/SCALE_V_MADC)/1000),
|
| 333 | SIVOICE_ABS(((vbat/SCALE_V_MADC) - (vbat/SCALE_V_MADC)/1000*1000)));
|
| 334 | if(timer > SI3218X_TIMEOUT_DCDC_UP)
|
| 335 | {
|
| 336 | /* Error handling - shutdown converter, disable channel, set error tag */
|
| 337 | pProslic->channelEnable = 0;
|
| 338 | error = RC_VBAT_UP_TIMEOUT;
|
| 339 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_DCDC,
|
| 340 | 0x900000L); /* shutdown converter */
|
| 341 | DEBUG_PRINT (pProslic, "%sChannel %d : DCDC Power up timeout : Status=0x%08X\n",
|
| 342 | LOGPRINT_PREFIX, pProslic->channel, ReadRAM(pProHW,pProslic->channel,
|
| 343 | SI3218X_RAM_DCDC_STATUS));
|
| 344 | }
|
| 345 |
|
| 346 | return error;
|
| 347 | }
|
| 348 |
|
| 349 | /*
|
| 350 | **
|
| 351 | ** PROSLIC INITIALIZATION FUNCTIONS
|
| 352 | **
|
| 353 | */
|
| 354 |
|
| 355 | /*
|
| 356 | ** Function: Si3218x_Init_MultiBOM
|
| 357 | **
|
| 358 | ** Description:
|
| 359 | ** - probe SPI to establish daisy chain length
|
| 360 | ** - load patch
|
| 361 | ** - initialize general parameters
|
| 362 | ** - calibrate madc
|
| 363 | ** - bring up DC/DC converters
|
| 364 | ** - calibrate everything except madc & lb
|
| 365 | **
|
| 366 | ** Input Parameters:
|
| 367 | ** pProslic: pointer to PROSLIC object array
|
| 368 | ** fault: error code
|
| 369 | **
|
| 370 | ** Return:
|
| 371 | ** error code
|
| 372 | */
|
| 373 |
|
| 374 | #ifdef SIVOICE_MULTI_BOM_SUPPORT
|
| 375 | int Si3218x_Init_MultiBOM (proslicChanType_ptr *pProslic, int size, int preset)
|
| 376 | {
|
| 377 |
|
| 378 | if(preset < si3218x_genconf_multi_max_preset)
|
| 379 | {
|
| 380 | /* Copy selected General Configuration parameters to Std structure */
|
| 381 | Si3218x_General_Configuration = Si3218x_General_Configuration_MultiBOM[preset];
|
| 382 | }
|
| 383 | else
|
| 384 | {
|
| 385 | return RC_INVALID_PRESET;
|
| 386 | }
|
| 387 | return Si3218x_Init_with_Options(pProslic,size, INIT_NO_OPT);
|
| 388 | }
|
| 389 | #endif
|
| 390 |
|
| 391 |
|
| 392 | /*
|
| 393 | ** Function: Si3218x_SelectPatch
|
| 394 | **
|
| 395 | ** Select patch based on general parameters
|
| 396 | **
|
| 397 | ** Input Parameters:
|
| 398 | ** pProslic: pointer to PROSLIC object array
|
| 399 | ** fault: error code
|
| 400 | ** patch: Pointer to proslicPatch pointer
|
| 401 | **
|
| 402 | ** Return:
|
| 403 | ** error code
|
| 404 | */
|
| 405 | int Si3218x_SelectPatch(proslicChanType_ptr pProslic,
|
| 406 | const proslicPatch **patch)
|
| 407 | {
|
| 408 |
|
| 409 | #ifdef SIVOICE_MULTI_BOM_SUPPORT
|
| 410 | if(Si3218x_General_Configuration.bom_option == BO_DCDC_LCQC_5W
|
| 411 | || Si3218x_General_Configuration.bom_option == BO_DCDC_LCCB
|
| 412 | || Si3218x_General_Configuration.bom_option == BO_DCDC_LCCB110
|
| 413 | || Si3218x_General_Configuration.bom_option == BO_DCDC_BUCK_BOOST)
|
| 414 | {
|
| 415 | *patch = &(SI3218X_PATCH_A);
|
| 416 | }
|
| 417 | else
|
| 418 | {
|
| 419 | DEBUG_PRINT(pProslic, "%sChannel %d : Invalid Patch\n", LOGPRINT_PREFIX,
|
| 420 | pProslic->channel);
|
| 421 | pProslic->channelEnable = 0;
|
| 422 | pProslic->error = RC_INVALID_PATCH;
|
| 423 | return RC_INVALID_PATCH;
|
| 424 | }
|
| 425 | #else
|
| 426 | SILABS_UNREFERENCED_PARAMETER(pProslic);
|
| 427 | *patch = &(SI3218X_PATCH_A_DEFAULT);
|
| 428 | #endif
|
| 429 |
|
| 430 | return RC_NONE;
|
| 431 | }
|
| 432 |
|
| 433 | /*
|
| 434 | ** Function: Si3218x_GenParamUpdate
|
| 435 | **
|
| 436 | ** Update general parameters
|
| 437 | **
|
| 438 | ** Input Parameters:
|
| 439 | ** pProslic: pointer to PROSLIC object array
|
| 440 | ** fault: error code
|
| 441 | **
|
| 442 | ** Return:
|
| 443 | ** error code
|
| 444 | */
|
| 445 |
|
| 446 | int Si3218x_GenParamUpdate(proslicChanType_ptr pProslic,initSeqType seq)
|
| 447 | {
|
| 448 | ramData ram_data;
|
| 449 | uInt8 data;
|
| 450 |
|
| 451 | switch(seq)
|
| 452 | {
|
| 453 | case INIT_SEQ_PRE_CAL:
|
| 454 | /*
|
| 455 | ** Force pwrsave off and disable AUTO-tracking - set to user configured state after cal
|
| 456 | */
|
| 457 | WriteReg(pProHW, pProslic->channel,SI3218X_REG_ENHANCE,0);
|
| 458 | WriteReg(pProHW, pProslic->channel,SI3218X_REG_AUTO,0x2F);
|
| 459 |
|
| 460 | /*
|
| 461 | ** General Parameter Updates
|
| 462 | */
|
| 463 |
|
| 464 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_P_TH_HVIC,
|
| 465 | Si3218x_General_Configuration.p_th_hvic);
|
| 466 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_COEF_P_HVIC,
|
| 467 | Si3218x_General_Configuration.coef_p_hvic);
|
| 468 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_BAT_HYST,
|
| 469 | Si3218x_General_Configuration.bat_hyst);
|
| 470 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VBATH_EXPECT,
|
| 471 | Si3218x_General_Configuration.vbath_expect);
|
| 472 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VBATR_EXPECT,
|
| 473 | Si3218x_General_Configuration.vbatr_expect);
|
| 474 |
|
| 475 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PWRSAVE_TIMER,
|
| 476 | Si3218x_General_Configuration.pwrsave_timer);
|
| 477 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_OFFHOOK_THRESH,
|
| 478 | Si3218x_General_Configuration.pwrsave_ofhk_thresh);
|
| 479 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VBAT_TRACK_MIN,
|
| 480 | Si3218x_General_Configuration.vbat_track_min);
|
| 481 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VBAT_TRACK_MIN_RNG,
|
| 482 | Si3218x_General_Configuration.vbat_track_min_rng);
|
| 483 |
|
| 484 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_THERM_DBI,
|
| 485 | Si3218x_General_Configuration.therm_dbi);
|
| 486 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VOV_DCDC_SLOPE,
|
| 487 | Si3218x_General_Configuration.vov_dcdc_slope);
|
| 488 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VOV_DCDC_OS,
|
| 489 | Si3218x_General_Configuration.vov_dcdc_os);
|
| 490 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VOV_RING_BAT_MAX,
|
| 491 | Si3218x_General_Configuration.vov_ring_bat_max);
|
| 492 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_VERR,
|
| 493 | Si3218x_General_Configuration.dcdc_verr);
|
| 494 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_VERR_HYST,
|
| 495 | Si3218x_General_Configuration.dcdc_verr_hyst);
|
| 496 |
|
| 497 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PD_UVLO,
|
| 498 | Si3218x_General_Configuration.pd_uvlo);
|
| 499 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PD_OVLO,
|
| 500 | Si3218x_General_Configuration.pd_ovlo);
|
| 501 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PD_OCLO,
|
| 502 | Si3218x_General_Configuration.pd_oclo);
|
| 503 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PD_SWDRV,
|
| 504 | Si3218x_General_Configuration.pd_swdrv);
|
| 505 |
|
| 506 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_UVPOL,
|
| 507 | Si3218x_General_Configuration.dcdc_uvpol);
|
| 508 |
|
| 509 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_RNGTYPE,
|
| 510 | Si3218x_General_Configuration.dcdc_rngtype);
|
| 511 |
|
| 512 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_ANA_TOFF,
|
| 513 | Si3218x_General_Configuration.dcdc_ana_toff);
|
| 514 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_ANA_TONMIN,
|
| 515 | Si3218x_General_Configuration.dcdc_ana_tonmin);
|
| 516 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_ANA_TONMAX,
|
| 517 | Si3218x_General_Configuration.dcdc_ana_tonmax);
|
| 518 |
|
| 519 |
|
| 520 | /*
|
| 521 | ** Hardcoded RAM
|
| 522 | */
|
| 523 |
|
| 524 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_OITHRESH_LO,
|
| 525 | GCONF.i_oithresh_lo);
|
| 526 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_OITHRESH_HI,
|
| 527 | GCONF.i_oithresh_hi);
|
| 528 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_OVTHRESH,GCONF.v_ovthresh);
|
| 529 |
|
| 530 | ram_data = (GCONF.v_uvthresh > UVTHRESH_OFFS)?(GCONF.v_uvthresh -
|
| 531 | UVTHRESH_OFFS)/UVTHRESH_SCALE:0L;
|
| 532 | ram_data *= BIT20LSB;
|
| 533 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_UVTHRESH,ram_data);
|
| 534 |
|
| 535 | ram_data = (GCONF.v_uvhyst > UVHYST_OFFS)?(GCONF.v_uvhyst -
|
| 536 | UVHYST_OFFS)/UVHYST_SCALE:0L;
|
| 537 | ram_data *= BIT20LSB;
|
| 538 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_UVHYST,ram_data);
|
| 539 |
|
| 540 | /* Set default audio gain based on PM bom */
|
| 541 | if(Si3218x_General_Configuration.pm_bom == BO_PM_BOM)
|
| 542 | {
|
| 543 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_SCALE_KAUDIO,BOM_KAUDIO_PM);
|
| 544 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_AC_ADC_GAIN,BOM_AC_ADC_GAIN_PM);
|
| 545 | }
|
| 546 | else
|
| 547 | {
|
| 548 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_SCALE_KAUDIO,BOM_KAUDIO_NO_PM);
|
| 549 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_AC_ADC_GAIN,
|
| 550 | BOM_AC_ADC_GAIN_NO_PM);
|
| 551 | }
|
| 552 |
|
| 553 | /*
|
| 554 | ** Hardcoded changes to default settings
|
| 555 | */
|
| 556 | data = ReadReg(pProHW, pProslic->channel,SI3218X_REG_GPIO_CFG1);
|
| 557 | data &= 0xF9; /* Clear DIR for GPIO 1&2 */
|
| 558 | data |= 0x60; /* Set ANA mode for GPIO 1&2 */
|
| 559 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_GPIO_CFG1,
|
| 560 | data); /* coarse sensors analog mode */
|
| 561 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_PDN,
|
| 562 | 0x80); /* madc powered in open state */
|
| 563 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_A1_1,
|
| 564 | 0x71EB851L); /* Fix HPF corner */
|
| 565 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_REF_OSC,
|
| 566 | 0x200000L); /* PLL freerun workaround */
|
| 567 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ILOOPLPF,
|
| 568 | 0x4EDDB9L); /* 20pps pulse dialing enhancement */
|
| 569 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ILONGLPF,
|
| 570 | 0x806D6L); /* 20pps pulse dialing enhancement */
|
| 571 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VDIFFLPF,
|
| 572 | 0x10038DL); /* 20pps pulse dialing enhancement */
|
| 573 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_VREF_CTRL,0x0L);
|
| 574 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VCM_TH,0x106240L);
|
| 575 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VCMLPF,0x10059FL);
|
| 576 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_CM_SPEEDUP_TIMER,0x0F0000);
|
| 577 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VCM_HYST,0x206280L);
|
| 578 |
|
| 579 | /* Prevent Ref Osc from powering down in PLL Freerun mode (pd_ref_osc) */
|
| 580 | ram_data = ReadRAM(pProHW, pProslic->channel,SI3218X_RAM_PWRSAVE_CTRL_LO);
|
| 581 | WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PWRSAVE_CTRL_LO,
|
| 582 | ram_data&0x07FFFFFFL); /* clear b27 */
|
| 583 | break;
|
| 584 |
|
| 585 |
|
| 586 | case INIT_SEQ_POST_CAL:
|
| 587 | WriteReg(pProHW, pProslic->channel,SI3218X_REG_ENHANCE,
|
| 588 | Si3218x_General_Configuration.enhance&0x1F);
|
| 589 | WriteReg(pProHW, pProslic->channel,SI3218X_REG_AUTO,
|
| 590 | Si3218x_General_Configuration.auto_reg);
|
| 591 | if(Si3218x_General_Configuration.zcal_en)
|
| 592 | {
|
| 593 | WriteReg(pProHW,pProslic->channel, SI3218X_REG_ZCAL_EN, 0x04);
|
| 594 | }
|
| 595 | break;
|
| 596 |
|
| 597 | default:
|
| 598 | break;
|
| 599 | }
|
| 600 | return RC_NONE;
|
| 601 | }
|
| 602 |
|
| 603 | /*
|
| 604 | ** Function: Si3218x_Init_with_Options
|
| 605 | **
|
| 606 | ** Description:
|
| 607 | ** - probe SPI to establish daisy chain length
|
| 608 | ** - load patch
|
| 609 | ** - initialize general parameters
|
| 610 | ** - calibrate madc
|
| 611 | ** - bring up DC/DC converters
|
| 612 | ** - calibrate everything except madc & lb
|
| 613 | **
|
| 614 | ** Input Parameters:
|
| 615 | ** pProslic: pointer to PROSLIC object array
|
| 616 | ** fault: error code
|
| 617 | **
|
| 618 | ** Return:
|
| 619 | ** error code
|
| 620 | */
|
| 621 |
|
| 622 | int Si3218x_Init_with_Options (proslicChanType_ptr *pProslic, int size,
|
| 623 | initOptionsType init_opt)
|
| 624 | {
|
| 625 | /*
|
| 626 | ** This function will initialize the chipRev and chipType members in pProslic
|
| 627 | ** as well as load the initialization structures.
|
| 628 | */
|
| 629 |
|
| 630 | uInt8 data;
|
| 631 | uInt8 calSetup[] = {0x00, 0x00, 0x01, 0x80}; /* CALR0-CALR3 */
|
| 632 | int k, device_count;
|
| 633 | const proslicPatch *patch;
|
| 634 | uInt8 status;
|
| 635 |
|
| 636 | LOGPRINT("%s(%d) size = %d init_opt = %d\n", __FUNCTION__, __LINE__, size,
|
| 637 | init_opt);
|
| 638 | /*
|
| 639 | **
|
| 640 | ** First qualify general parameters by identifying valid device key. This
|
| 641 | ** will prevent inadvertent use of other device's preset files, which could
|
| 642 | ** lead to improper initialization and high current states.
|
| 643 | */
|
| 644 |
|
| 645 | data = Si3218x_General_Configuration.device_key;
|
| 646 |
|
| 647 | if((data < DEVICE_KEY_MIN)||(data > DEVICE_KEY_MAX))
|
| 648 | {
|
| 649 | pProslic[0]->error = RC_INVALID_GEN_PARAM;
|
| 650 | return pProslic[0]->error;
|
| 651 | }
|
| 652 |
|
| 653 | /* reset error code */
|
| 654 | for(k = 0; k < size; k++)
|
| 655 | {
|
| 656 | pProslic[k]->error = RC_NONE;
|
| 657 | }
|
| 658 |
|
| 659 | if( (init_opt == INIT_REINIT) || (init_opt == INIT_SOFTRESET) )
|
| 660 | {
|
| 661 | ProSLIC_ReInit_helper(pProslic, size, init_opt, SI3218X_CHAN_PER_DEVICE);
|
| 662 |
|
| 663 | /* for single channel devices, we need do a full restore.. */
|
| 664 | if(init_opt == INIT_REINIT)
|
| 665 | {
|
| 666 | init_opt = 0;
|
| 667 | }
|
| 668 | }
|
| 669 |
|
| 670 | if( init_opt != INIT_REINIT )
|
| 671 | {
|
| 672 | if( (SiVoice_IdentifyChannels(pProslic, size, &device_count, NULL) != RC_NONE)
|
| 673 | ||(device_count == 0) )
|
| 674 | {
|
| 675 | DEBUG_PRINT(*pProslic, "%s: failed to detect any ProSLICs\n", LOGPRINT_PREFIX);
|
| 676 | return RC_SPI_FAIL;
|
| 677 | }
|
| 678 |
|
| 679 | /*
|
| 680 | ** Probe each channel and enable all channels that respond
|
| 681 | */
|
| 682 | for (k=0; k<size; k++)
|
| 683 | {
|
| 684 | if ((pProslic[k]->channelEnable)
|
| 685 | &&(pProslic[k]->channelType == PROSLIC))
|
| 686 | {
|
| 687 | if ( (ProSLIC_VerifyMasterStat(pProslic[k]) != RC_NONE)
|
| 688 | || (ProSLIC_VerifyControlInterface(pProslic[k]) != RC_NONE) )
|
| 689 | {
|
| 690 | pProslic[k]->channelEnable = 0;
|
| 691 | pProslic[k]->error = RC_SPI_FAIL;
|
| 692 | DEBUG_PRINT(*pProslic, "%s: SPI communications or PCLK/FS failure\n", LOGPRINT_PREFIX);
|
| 693 | return pProslic[k]->error; /* Halt init if SPI fail */
|
| 694 | }
|
| 695 | }
|
| 696 | }
|
| 697 | } /* init_opt !REINIT */
|
| 698 |
|
| 699 |
|
| 700 | if( (init_opt != INIT_NO_PATCH_LOAD ) && (init_opt != INIT_REINIT) )
|
| 701 | {
|
| 702 | /*
|
| 703 | ** Load patch (load on every channel since single channel device)
|
| 704 | */
|
| 705 | for (k=0; k<size; k++)
|
| 706 | {
|
| 707 | if ((pProslic[k]->channelEnable)&&(pProslic[k]->channelType == PROSLIC))
|
| 708 | {
|
| 709 |
|
| 710 | /* Select Patch*/
|
| 711 | if (pProslic[k]->deviceId->chipRev == SI3218X_REVA )
|
| 712 | {
|
| 713 | status = (uInt8) Si3218x_SelectPatch(pProslic[k],&patch);
|
| 714 | }
|
| 715 | else
|
| 716 | {
|
| 717 | DEBUG_PRINT(pProslic[k], "%sChannel %d : Unsupported Device Revision (%d)\n",
|
| 718 | LOGPRINT_PREFIX, pProslic[k]->channel,pProslic[k]->deviceId->chipRev );
|
| 719 | pProslic[k]->channelEnable = 0;
|
| 720 | pProslic[k]->error = RC_UNSUPPORTED_DEVICE_REV;
|
| 721 | return RC_UNSUPPORTED_DEVICE_REV;
|
| 722 | }
|
| 723 |
|
| 724 | data = 1; /* Use this as a flag to see if we need to load the patch */
|
| 725 | /* If the patch doesn't match, we need to do a full init, change settings */
|
| 726 | if(init_opt == INIT_SOFTRESET)
|
| 727 | {
|
| 728 | ramData patchData;
|
| 729 | patchData = pProslic[k]->ReadRAMX(pProslic[k]->pProHWX, pProslic[k]->channel,
|
| 730 | PROSLIC_RAM_PATCHID);
|
| 731 |
|
| 732 | if( patchData == patch->patchSerial)
|
| 733 | {
|
| 734 | data = 0;
|
| 735 | }
|
| 736 | else
|
| 737 | {
|
| 738 | init_opt = INIT_NO_OPT;
|
| 739 | }
|
| 740 | } /* SOFTRESET */
|
| 741 |
|
| 742 | /* Load Patch */
|
| 743 | if(status == RC_NONE)
|
| 744 | {
|
| 745 | if(data == 1)
|
| 746 | {
|
| 747 | Si3218x_LoadPatch(pProslic[k],patch);
|
| 748 | #ifndef DISABLE_VERIFY_PATCH
|
| 749 | /* Optional Patch Verification */
|
| 750 | data = (uInt8)Si3218x_VerifyPatch(pProslic[k],patch);
|
| 751 | if (data != RC_NONE)
|
| 752 | {
|
| 753 | DEBUG_PRINT(pProslic[k], "%sChannel %d : Patch verification failed (%d)\n",
|
| 754 | LOGPRINT_PREFIX, k, data);
|
| 755 | pProslic[k]->channelEnable=0;
|
| 756 | pProslic[k]->error = RC_PATCH_ERR;
|
| 757 | return data;
|
| 758 | }
|
| 759 | #endif
|
| 760 | }
|
| 761 | }
|
| 762 | else
|
| 763 | {
|
| 764 | return status;
|
| 765 | }
|
| 766 | } /* channel == PROSLIC */
|
| 767 | } /* for all channles */
|
| 768 | }/* init_opt - need to reload patch */
|
| 769 |
|
| 770 | /*
|
| 771 | ** Load general parameters - includes all BOM dependencies
|
| 772 | */
|
| 773 | if(init_opt != INIT_SOFTRESET)
|
| 774 | {
|
| 775 | for (k=0; k<size; k++)
|
| 776 | {
|
| 777 | if ((pProslic[k]->channelEnable)&&(pProslic[k]->channelType == PROSLIC))
|
| 778 | {
|
| 779 | Si3218x_GenParamUpdate(pProslic[k],INIT_SEQ_PRE_CAL);
|
| 780 | }
|
| 781 |
|
| 782 | pProslic[k]->WriteRAMX(pProslic[k]->pProHWX,pProslic[k]->channel,
|
| 783 | SI3218X_RAM_IRING_LIM,SI3218X_IRING_LIM_MAX);
|
| 784 | }
|
| 785 | }
|
| 786 |
|
| 787 | if((init_opt != INIT_NO_CAL)
|
| 788 | && (init_opt != INIT_SOFTRESET)) /* Must recal on single channel devices */
|
| 789 | {
|
| 790 | /*
|
| 791 | ** Calibrate (madc offset)
|
| 792 | */
|
| 793 | ProSLIC_Calibrate(pProslic,size,calSetup,TIMEOUT_MADC_CAL);
|
| 794 | }/* init_opt */
|
| 795 |
|
| 796 | /*
|
| 797 | ** Bring up DC/DC converters sequentially to minimize
|
| 798 | ** peak power demand on VDC
|
| 799 | */
|
| 800 | for (k=0; k<size; k++)
|
| 801 | {
|
| 802 | if ((pProslic[k]->channelEnable)&&(pProslic[k]->channelType == PROSLIC))
|
| 803 | {
|
| 804 | pProslic[k]->error = Si3218x_PowerUpConverter(pProslic[k]);
|
| 805 | }
|
| 806 | }
|
| 807 |
|
| 808 | if((init_opt != INIT_NO_CAL) && (init_opt != INIT_SOFTRESET))
|
| 809 | {
|
| 810 | /*
|
| 811 | ** Calibrate remaining cals (except madc, lb)
|
| 812 | */
|
| 813 | calSetup[1] = SI3218X_CAL_STD_CALR1;
|
| 814 | calSetup[2] = SI3218X_CAL_STD_CALR2;
|
| 815 |
|
| 816 | ProSLIC_Calibrate(pProslic,size,calSetup,TIMEOUT_GEN_CAL);
|
| 817 | }
|
| 818 |
|
| 819 | /*
|
| 820 | ** Apply post calibration general parameters
|
| 821 | */
|
| 822 | if(init_opt != INIT_SOFTRESET)
|
| 823 | {
|
| 824 | for (k=0; k<size; k++)
|
| 825 | {
|
| 826 |
|
| 827 | if ((pProslic[k]->channelEnable)&&(pProslic[k]->channelType == PROSLIC))
|
| 828 | {
|
| 829 | Si3218x_GenParamUpdate(pProslic[k],INIT_SEQ_POST_CAL);
|
| 830 | }
|
| 831 | }
|
| 832 | }
|
| 833 |
|
| 834 | /* Restore linefeed state after initialization for REINIT/SOFTRESET */
|
| 835 | if( (init_opt == INIT_REINIT) || (init_opt == INIT_SOFTRESET) )
|
| 836 | {
|
| 837 | for(k = 0; k < size; k++)
|
| 838 | {
|
| 839 | pProslic[k]->WriteRegX(pProslic[k]->pProHWX,pProslic[k]->channel,
|
| 840 | SI3218X_REG_LINEFEED,pProslic[k]->scratch);
|
| 841 | }
|
| 842 | }
|
| 843 |
|
| 844 | /*
|
| 845 | ** If any channel incurred a non-fatal error, return
|
| 846 | ** RC_NON_FATAL_INIT_ERR to trigger user to read each channel's
|
| 847 | ** error status
|
| 848 | */
|
| 849 | for (k=0; k<size; k++)
|
| 850 | {
|
| 851 | if(pProslic[k]->error != RC_NONE)
|
| 852 | {
|
| 853 | return RC_NON_FATAL_INIT_ERR;
|
| 854 | }
|
| 855 | }
|
| 856 |
|
| 857 | return RC_NONE;
|
| 858 | }
|
| 859 |
|
| 860 | /*
|
| 861 | ** Function: Si3218x_EnableInterrupts
|
| 862 | **
|
| 863 | ** Description:
|
| 864 | ** Enables interrupts
|
| 865 | **
|
| 866 | ** Input Parameters:
|
| 867 | ** pProslic: pointer to PROSLIC channel obj
|
| 868 | **
|
| 869 | ** Returns:
|
| 870 | ** 0
|
| 871 | */
|
| 872 |
|
| 873 | int Si3218x_EnableInterrupts (proslicChanType_ptr pProslic)
|
| 874 | {
|
| 875 | uInt8 i;
|
| 876 | #ifdef GCI_MODE
|
| 877 | uInt8 data;
|
| 878 | #endif
|
| 879 | /* Clear pending interrupts first */
|
| 880 | for(i = SI3218X_REG_IRQ1; i < SI3218X_REG_IRQ4; i++)
|
| 881 | {
|
| 882 | #ifdef GCI_MODE
|
| 883 | data = ReadReg(pProHW,pProslic->channel, i);
|
| 884 | WriteReg(pProHW,pProslic->channel,i,data); /*clear interrupts (gci only)*/
|
| 885 | #else
|
| 886 | (void)ReadReg(pProHW,pProslic->channel, i);
|
| 887 | #endif
|
| 888 |
|
| 889 | }
|
| 890 |
|
| 891 | WriteReg (pProHW,pProslic->channel,SI3218X_REG_IRQEN1,
|
| 892 | Si3218x_General_Configuration.irqen1);
|
| 893 | WriteReg (pProHW,pProslic->channel,SI3218X_REG_IRQEN2,
|
| 894 | Si3218x_General_Configuration.irqen2);
|
| 895 | WriteReg (pProHW,pProslic->channel,SI3218X_REG_IRQEN3,
|
| 896 | Si3218x_General_Configuration.irqen3);
|
| 897 | WriteReg (pProHW,pProslic->channel,SI3218X_REG_IRQEN4,
|
| 898 | Si3218x_General_Configuration.irqen4);
|
| 899 |
|
| 900 | return RC_NONE;
|
| 901 | }
|
| 902 |
|
| 903 | /*
|
| 904 | **
|
| 905 | ** PROSLIC CONFIGURATION FUNCTIONS
|
| 906 | **
|
| 907 | */
|
| 908 |
|
| 909 | /*
|
| 910 | ** Function: Si3218x_RingSetup
|
| 911 | **
|
| 912 | ** Description:
|
| 913 | ** configure ringing
|
| 914 | **
|
| 915 | ** Input Parameters:
|
| 916 | ** pProslic: pointer to PROSLIC channel obj
|
| 917 | ** preset: ring preset
|
| 918 | **
|
| 919 | ** Returns:
|
| 920 | ** 0
|
| 921 | */
|
| 922 |
|
| 923 | #ifndef DISABLE_RING_SETUP
|
| 924 | int Si3218x_RingSetup (proslicChanType *pProslic, int preset)
|
| 925 | {
|
| 926 |
|
| 927 | if(pProslic->channelType != PROSLIC)
|
| 928 | {
|
| 929 | return RC_CHANNEL_TYPE_ERR;
|
| 930 | }
|
| 931 |
|
| 932 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RTPER,
|
| 933 | Si3218x_Ring_Presets[preset].rtper);
|
| 934 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RINGFR,
|
| 935 | Si3218x_Ring_Presets[preset].freq);
|
| 936 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RINGAMP,
|
| 937 | Si3218x_Ring_Presets[preset].amp);
|
| 938 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RINGPHAS,
|
| 939 | Si3218x_Ring_Presets[preset].phas);
|
| 940 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RINGOF,
|
| 941 | Si3218x_Ring_Presets[preset].offset);
|
| 942 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_RING,
|
| 943 | Si3218x_Ring_Presets[preset].slope_ring);
|
| 944 |
|
| 945 | if(Si3218x_Ring_Presets[preset].iring_lim > SI3218X_IRING_LIM_MAX)
|
| 946 | {
|
| 947 | Si3218x_Ring_Presets[preset].iring_lim = SI3218X_IRING_LIM_MAX;
|
| 948 | }
|
| 949 |
|
| 950 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_IRING_LIM,
|
| 951 | Si3218x_Ring_Presets[preset].iring_lim);
|
| 952 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RTACTH,
|
| 953 | Si3218x_Ring_Presets[preset].rtacth);
|
| 954 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RTDCTH,
|
| 955 | Si3218x_Ring_Presets[preset].rtdcth);
|
| 956 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RTACDB,
|
| 957 | Si3218x_Ring_Presets[preset].rtacdb);
|
| 958 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RTDCDB,
|
| 959 | Si3218x_Ring_Presets[preset].rtdcdb);
|
| 960 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VOV_RING_BAT,
|
| 961 | Si3218x_Ring_Presets[preset].vov_ring_bat);
|
| 962 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VOV_RING_GND,
|
| 963 | Si3218x_Ring_Presets[preset].vov_ring_gnd);
|
| 964 |
|
| 965 | #ifndef NOCLAMP_VBATR
|
| 966 | /* Always limit VBATR_EXPECT to the general configuration maximum */
|
| 967 | if(Si3218x_Ring_Presets[preset].vbatr_expect >
|
| 968 | Si3218x_General_Configuration.vbatr_expect)
|
| 969 | {
|
| 970 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VBATR_EXPECT,
|
| 971 | Si3218x_General_Configuration.vbatr_expect);
|
| 972 | DEBUG_PRINT(pProslic,
|
| 973 | "%sRingSetup : VBATR_EXPECT : Clamped to Gen Conf Limit\n",LOGPRINT_PREFIX);
|
| 974 | }
|
| 975 | else
|
| 976 | {
|
| 977 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VBATR_EXPECT,
|
| 978 | Si3218x_Ring_Presets[preset].vbatr_expect);
|
| 979 | }
|
| 980 |
|
| 981 | #else
|
| 982 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VBATR_EXPECT,
|
| 983 | Si3218x_Ring_Presets[preset].vbatr_expect);
|
| 984 | #endif
|
| 985 |
|
| 986 |
|
| 987 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGTALO,
|
| 988 | Si3218x_Ring_Presets[preset].talo);
|
| 989 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGTAHI,
|
| 990 | Si3218x_Ring_Presets[preset].tahi);
|
| 991 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGTILO,
|
| 992 | Si3218x_Ring_Presets[preset].tilo);
|
| 993 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGTIHI,
|
| 994 | Si3218x_Ring_Presets[preset].tihi);
|
| 995 |
|
| 996 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VBAT_TRACK_MIN_RNG,
|
| 997 | Si3218x_Ring_Presets[preset].dcdc_vref_min_rng);
|
| 998 |
|
| 999 | /*
|
| 1000 | ** LPR Handler
|
| 1001 | **
|
| 1002 | ** If USERSTAT == 0x01, adjust RINGCON and clear USERSTAT
|
| 1003 | */
|
| 1004 | if (Si3218x_Ring_Presets[preset].userstat == 0x01)
|
| 1005 | {
|
| 1006 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGCON,
|
| 1007 | (0x80|Si3218x_Ring_Presets[preset].ringcon) & ~(0x40));
|
| 1008 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_USERSTAT,0x00);
|
| 1009 | }
|
| 1010 | else
|
| 1011 | {
|
| 1012 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGCON,
|
| 1013 | Si3218x_Ring_Presets[preset].ringcon);
|
| 1014 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_USERSTAT,
|
| 1015 | Si3218x_Ring_Presets[preset].userstat);
|
| 1016 | }
|
| 1017 |
|
| 1018 |
|
| 1019 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VCM_RING,
|
| 1020 | Si3218x_Ring_Presets[preset].vcm_ring);
|
| 1021 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VCM_RING_FIXED,
|
| 1022 | Si3218x_Ring_Presets[preset].vcm_ring_fixed);
|
| 1023 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_DELTA_VCM,
|
| 1024 | Si3218x_Ring_Presets[preset].delta_vcm);
|
| 1025 |
|
| 1026 |
|
| 1027 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_DCDC_RNGTYPE,
|
| 1028 | Si3218x_Ring_Presets[preset].dcdc_rngtype);
|
| 1029 |
|
| 1030 |
|
| 1031 | /*
|
| 1032 | ** If multi bom supported **AND** a buck boost converter
|
| 1033 | ** is being used, force dcdc_rngtype to be fixed.
|
| 1034 | */
|
| 1035 | #ifdef SIVOICE_MULTI_BOM_SUPPORT
|
| 1036 | #define DCDC_RNGTYPE_BKBT 0L
|
| 1037 | /* Automatically adjust DCDC_RNGTYPE */
|
| 1038 | if(Si3218x_General_Configuration.bom_option == BO_DCDC_BUCK_BOOST)
|
| 1039 | {
|
| 1040 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_DCDC_RNGTYPE,DCDC_RNGTYPE_BKBT);
|
| 1041 | }
|
| 1042 | #endif
|
| 1043 |
|
| 1044 |
|
| 1045 | return RC_NONE;
|
| 1046 | }
|
| 1047 | #endif
|
| 1048 |
|
| 1049 | /*
|
| 1050 | ** Function: PROSLIC_ZsynthSetup
|
| 1051 | **
|
| 1052 | ** Description:
|
| 1053 | ** configure impedance synthesis
|
| 1054 | */
|
| 1055 |
|
| 1056 | #ifndef DISABLE_ZSYNTH_SETUP
|
| 1057 | int Si3218x_ZsynthSetup (proslicChanType *pProslic, int preset)
|
| 1058 | {
|
| 1059 | uInt8 lf;
|
| 1060 | uInt8 cal_en = 0;
|
| 1061 | uInt16 timer = 500;
|
| 1062 |
|
| 1063 | if(pProslic->channelType != PROSLIC)
|
| 1064 | {
|
| 1065 | return RC_CHANNEL_TYPE_ERR;
|
| 1066 | }
|
| 1067 |
|
| 1068 | lf = ReadReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED);
|
| 1069 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,0);
|
| 1070 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C0,
|
| 1071 | Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c0);
|
| 1072 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C1,
|
| 1073 | Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c1);
|
| 1074 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C2,
|
| 1075 | Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c2);
|
| 1076 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C3,
|
| 1077 | Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c3);
|
| 1078 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C0,
|
| 1079 | Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c0);
|
| 1080 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C1,
|
| 1081 | Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c1);
|
| 1082 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C2,
|
| 1083 | Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c2);
|
| 1084 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C3,
|
| 1085 | Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c3);
|
| 1086 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C2,
|
| 1087 | Si3218x_Impedance_Presets[preset].hybrid.ecfir_c2);
|
| 1088 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C3,
|
| 1089 | Si3218x_Impedance_Presets[preset].hybrid.ecfir_c3);
|
| 1090 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C4,
|
| 1091 | Si3218x_Impedance_Presets[preset].hybrid.ecfir_c4);
|
| 1092 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C5,
|
| 1093 | Si3218x_Impedance_Presets[preset].hybrid.ecfir_c5);
|
| 1094 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C6,
|
| 1095 | Si3218x_Impedance_Presets[preset].hybrid.ecfir_c6);
|
| 1096 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C7,
|
| 1097 | Si3218x_Impedance_Presets[preset].hybrid.ecfir_c7);
|
| 1098 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C8,
|
| 1099 | Si3218x_Impedance_Presets[preset].hybrid.ecfir_c8);
|
| 1100 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C9,
|
| 1101 | Si3218x_Impedance_Presets[preset].hybrid.ecfir_c9);
|
| 1102 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECIIR_B0,
|
| 1103 | Si3218x_Impedance_Presets[preset].hybrid.ecfir_b0);
|
| 1104 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECIIR_B1,
|
| 1105 | Si3218x_Impedance_Presets[preset].hybrid.ecfir_b1);
|
| 1106 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECIIR_A1,
|
| 1107 | Si3218x_Impedance_Presets[preset].hybrid.ecfir_a1);
|
| 1108 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECIIR_A2,
|
| 1109 | Si3218x_Impedance_Presets[preset].hybrid.ecfir_a2);
|
| 1110 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ZSYNTH_A1,
|
| 1111 | Si3218x_Impedance_Presets[preset].zsynth.zsynth_a1);
|
| 1112 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ZSYNTH_A2,
|
| 1113 | Si3218x_Impedance_Presets[preset].zsynth.zsynth_a2);
|
| 1114 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ZSYNTH_B1,
|
| 1115 | Si3218x_Impedance_Presets[preset].zsynth.zsynth_b1);
|
| 1116 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ZSYNTH_B0,
|
| 1117 | Si3218x_Impedance_Presets[preset].zsynth.zsynth_b0);
|
| 1118 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ZSYNTH_B2,
|
| 1119 | Si3218x_Impedance_Presets[preset].zsynth.zsynth_b2);
|
| 1120 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_RA,
|
| 1121 | Si3218x_Impedance_Presets[preset].zsynth.ra);
|
| 1122 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACGAIN,
|
| 1123 | Si3218x_Impedance_Presets[preset].txgain);
|
| 1124 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN_SAVE,
|
| 1125 | Si3218x_Impedance_Presets[preset].rxgain);
|
| 1126 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN,
|
| 1127 | Si3218x_Impedance_Presets[preset].rxgain);
|
| 1128 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B0_1,
|
| 1129 | Si3218x_Impedance_Presets[preset].rxachpf_b0_1);
|
| 1130 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B1_1,
|
| 1131 | Si3218x_Impedance_Presets[preset].rxachpf_b1_1);
|
| 1132 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_A1_1,
|
| 1133 | Si3218x_Impedance_Presets[preset].rxachpf_a1_1);
|
| 1134 |
|
| 1135 | /*
|
| 1136 | ** Scale based on desired gain plan
|
| 1137 | */
|
| 1138 | Si3218x_dbgSetTXGain(pProslic,Si3218x_Impedance_Presets[preset].txgain_db,
|
| 1139 | preset,TXACGAIN_SEL);
|
| 1140 | Si3218x_dbgSetRXGain(pProslic,Si3218x_Impedance_Presets[preset].rxgain_db,
|
| 1141 | preset,RXACGAIN_SEL);
|
| 1142 | Si3218x_TXAudioGainSetup(pProslic,TXACGAIN_SEL);
|
| 1143 | Si3218x_RXAudioGainSetup(pProslic,RXACGAIN_SEL);
|
| 1144 |
|
| 1145 | /*
|
| 1146 | ** Perform Zcal in case OHT used (eg. no offhook event to trigger auto Zcal)
|
| 1147 | */
|
| 1148 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_CALR0,0x00);
|
| 1149 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_CALR1,0x40);
|
| 1150 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_CALR2,0x00);
|
| 1151 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_CALR3,0x80); /* start cal */
|
| 1152 |
|
| 1153 | /* Wait for zcal to finish */
|
| 1154 | do
|
| 1155 | {
|
| 1156 | cal_en = ReadReg(pProHW,pProslic->channel,SI3218X_REG_CALR3);
|
| 1157 | Delay(pProTimer,1);
|
| 1158 | timer--;
|
| 1159 | }
|
| 1160 | while((cal_en&0x80)&&(timer>0));
|
| 1161 |
|
| 1162 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,lf);
|
| 1163 |
|
| 1164 | if(timer > 0)
|
| 1165 | {
|
| 1166 | return RC_NONE;
|
| 1167 | }
|
| 1168 | else
|
| 1169 | {
|
| 1170 | return RC_CAL_TIMEOUT;
|
| 1171 | }
|
| 1172 | }
|
| 1173 | #endif
|
| 1174 |
|
| 1175 | /*
|
| 1176 | ** Function: PROSLIC_AudioGainSetup
|
| 1177 | **
|
| 1178 | ** Description:
|
| 1179 | ** configure audio gains
|
| 1180 | */
|
| 1181 | int Si3218x_TXAudioGainSetup (proslicChanType *pProslic, int preset)
|
| 1182 | {
|
| 1183 |
|
| 1184 | if(pProslic->channelType != PROSLIC)
|
| 1185 | {
|
| 1186 | return RC_CHANNEL_TYPE_ERR;
|
| 1187 | }
|
| 1188 |
|
| 1189 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACGAIN,
|
| 1190 | Si3218x_audioGain_Presets[preset].acgain);
|
| 1191 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C0,
|
| 1192 | Si3218x_audioGain_Presets[preset].aceq_c0);
|
| 1193 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C1,
|
| 1194 | Si3218x_audioGain_Presets[preset].aceq_c1);
|
| 1195 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C2,
|
| 1196 | Si3218x_audioGain_Presets[preset].aceq_c2);
|
| 1197 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C3,
|
| 1198 | Si3218x_audioGain_Presets[preset].aceq_c3);
|
| 1199 |
|
| 1200 | return RC_NONE;
|
| 1201 | }
|
| 1202 |
|
| 1203 | /*
|
| 1204 | ** Function: PROSLIC_AudioGainSetup
|
| 1205 | **
|
| 1206 | ** Description:
|
| 1207 | ** configure audio gains
|
| 1208 | */
|
| 1209 |
|
| 1210 | int Si3218x_RXAudioGainSetup (proslicChanType *pProslic, int preset)
|
| 1211 | {
|
| 1212 |
|
| 1213 | if(pProslic->channelType != PROSLIC)
|
| 1214 | {
|
| 1215 | return RC_CHANNEL_TYPE_ERR;
|
| 1216 | }
|
| 1217 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN_SAVE,
|
| 1218 | Si3218x_audioGain_Presets[preset].acgain);
|
| 1219 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN,
|
| 1220 | Si3218x_audioGain_Presets[preset].acgain);
|
| 1221 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C0,
|
| 1222 | Si3218x_audioGain_Presets[preset].aceq_c0);
|
| 1223 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C1,
|
| 1224 | Si3218x_audioGain_Presets[preset].aceq_c1);
|
| 1225 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C2,
|
| 1226 | Si3218x_audioGain_Presets[preset].aceq_c2);
|
| 1227 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C3,
|
| 1228 | Si3218x_audioGain_Presets[preset].aceq_c3);
|
| 1229 |
|
| 1230 | return RC_NONE;
|
| 1231 | }
|
| 1232 |
|
| 1233 |
|
| 1234 | /*
|
| 1235 | ** Function: PROSLIC_AudioGainScale
|
| 1236 | **
|
| 1237 | ** Description:
|
| 1238 | ** Multiply path gain by passed value for PGA and EQ scale (no reference to dB,
|
| 1239 | ** multiply by a scale factor)
|
| 1240 | */
|
| 1241 | int Si3218x_AudioGainScale (proslicChanType *pProslic, int preset,
|
| 1242 | uInt32 pga_scale, uInt32 eq_scale,int rx_tx_sel)
|
| 1243 | {
|
| 1244 |
|
| 1245 | if(rx_tx_sel == TXACGAIN_SEL)
|
| 1246 | {
|
| 1247 | Si3218x_audioGain_Presets[TXACGAIN_SEL].acgain =
|
| 1248 | (Si3218x_Impedance_Presets[preset].txgain/1000)*pga_scale;
|
| 1249 | if (Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c0 & 0x10000000L)
|
| 1250 | {
|
| 1251 | Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c0 |= 0xf0000000L;
|
| 1252 | }
|
| 1253 | if (Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c1 & 0x10000000L)
|
| 1254 | {
|
| 1255 | Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c1 |= 0xf0000000L;
|
| 1256 | }
|
| 1257 | if (Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c2 & 0x10000000L)
|
| 1258 | {
|
| 1259 | Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c2 |= 0xf0000000L;
|
| 1260 | }
|
| 1261 | if (Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c3 & 0x10000000L)
|
| 1262 | {
|
| 1263 | Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c3 |= 0xf0000000L;
|
| 1264 | }
|
| 1265 | Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c0 = ((int32)
|
| 1266 | Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c0/1000)*eq_scale;
|
| 1267 | Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c1 = ((int32)
|
| 1268 | Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c1/1000)*eq_scale;
|
| 1269 | Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c2 = ((int32)
|
| 1270 | Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c2/1000)*eq_scale;
|
| 1271 | Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c3 = ((int32)
|
| 1272 | Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c3/1000)*eq_scale;
|
| 1273 |
|
| 1274 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACGAIN,
|
| 1275 | Si3218x_audioGain_Presets[TXACGAIN_SEL].acgain);
|
| 1276 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C0,
|
| 1277 | Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c0);
|
| 1278 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C1,
|
| 1279 | Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c1);
|
| 1280 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C2,
|
| 1281 | Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c2);
|
| 1282 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C3,
|
| 1283 | Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c3);
|
| 1284 | }
|
| 1285 | else
|
| 1286 | {
|
| 1287 | Si3218x_audioGain_Presets[RXACGAIN_SEL].acgain =
|
| 1288 | (Si3218x_Impedance_Presets[preset].rxgain/1000)*pga_scale;
|
| 1289 | if (Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c0 & 0x10000000L)
|
| 1290 | {
|
| 1291 | Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c0 |= 0xf0000000L;
|
| 1292 | }
|
| 1293 | if (Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c1 & 0x10000000L)
|
| 1294 | {
|
| 1295 | Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c1 |= 0xf0000000L;
|
| 1296 | }
|
| 1297 | if (Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c2 & 0x10000000L)
|
| 1298 | {
|
| 1299 | Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c2 |= 0xf0000000L;
|
| 1300 | }
|
| 1301 | if (Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c3 & 0x10000000L)
|
| 1302 | {
|
| 1303 | Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c3 |= 0xf0000000L;
|
| 1304 | }
|
| 1305 | Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c0 = ((int32)
|
| 1306 | Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c0/1000)*eq_scale;
|
| 1307 | Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c1 = ((int32)
|
| 1308 | Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c1/1000)*eq_scale;
|
| 1309 | Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c2 = ((int32)
|
| 1310 | Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c2/1000)*eq_scale;
|
| 1311 | Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c3 = ((int32)
|
| 1312 | Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c3/1000)*eq_scale;
|
| 1313 |
|
| 1314 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN_SAVE,
|
| 1315 | Si3218x_audioGain_Presets[RXACGAIN_SEL].acgain);
|
| 1316 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN,
|
| 1317 | Si3218x_audioGain_Presets[RXACGAIN_SEL].acgain);
|
| 1318 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C0,
|
| 1319 | Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c0);
|
| 1320 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C1,
|
| 1321 | Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c1);
|
| 1322 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C2,
|
| 1323 | Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c2);
|
| 1324 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C3,
|
| 1325 | Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c3);
|
| 1326 | }
|
| 1327 | return 0;
|
| 1328 | }
|
| 1329 | int Si3218x_TXAudioGainScale (proslicChanType *pProslic, int preset,
|
| 1330 | uInt32 pga_scale, uInt32 eq_scale)
|
| 1331 | {
|
| 1332 | return Si3218x_AudioGainScale(pProslic,preset,pga_scale,eq_scale,TXACGAIN_SEL);
|
| 1333 | }
|
| 1334 | int Si3218x_RXAudioGainScale (proslicChanType *pProslic, int preset,
|
| 1335 | uInt32 pga_scale, uInt32 eq_scale)
|
| 1336 | {
|
| 1337 | return Si3218x_AudioGainScale(pProslic,preset,pga_scale,eq_scale,RXACGAIN_SEL);
|
| 1338 | }
|
| 1339 |
|
| 1340 |
|
| 1341 | /*
|
| 1342 | ** Function: PROSLIC_DCFeedSetup
|
| 1343 | **
|
| 1344 | ** Description:
|
| 1345 | ** configure dc feed
|
| 1346 | */
|
| 1347 |
|
| 1348 | #ifndef DISABLE_DCFEED_SETUP
|
| 1349 | int Si3218x_DCFeedSetupCfg (proslicChanType *pProslic, Si3218x_DCfeed_Cfg *cfg,
|
| 1350 | int preset)
|
| 1351 | {
|
| 1352 | uInt8 lf;
|
| 1353 |
|
| 1354 | if(pProslic->channelType != PROSLIC)
|
| 1355 | {
|
| 1356 | return RC_CHANNEL_TYPE_ERR;
|
| 1357 | }
|
| 1358 | lf = ReadReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED);
|
| 1359 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,0);
|
| 1360 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_VLIM,
|
| 1361 | cfg[preset].slope_vlim);
|
| 1362 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_RFEED,
|
| 1363 | cfg[preset].slope_rfeed);
|
| 1364 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_ILIM,
|
| 1365 | cfg[preset].slope_ilim);
|
| 1366 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_DELTA1,cfg[preset].delta1);
|
| 1367 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_DELTA2,cfg[preset].delta2);
|
| 1368 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_V_VLIM,cfg[preset].v_vlim);
|
| 1369 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_V_RFEED,cfg[preset].v_rfeed);
|
| 1370 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_V_ILIM,cfg[preset].v_ilim);
|
| 1371 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_CONST_RFEED,
|
| 1372 | cfg[preset].const_rfeed);
|
| 1373 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_CONST_ILIM,
|
| 1374 | cfg[preset].const_ilim);
|
| 1375 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_I_VLIM,cfg[preset].i_vlim);
|
| 1376 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRONHK,cfg[preset].lcronhk);
|
| 1377 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCROFFHK,cfg[preset].lcroffhk);
|
| 1378 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRDBI,cfg[preset].lcrdbi);
|
| 1379 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LONGHITH,cfg[preset].longhith);
|
| 1380 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LONGLOTH,cfg[preset].longloth);
|
| 1381 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LONGDBI,cfg[preset].longdbi);
|
| 1382 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRMASK,cfg[preset].lcrmask);
|
| 1383 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRMASK_POLREV,
|
| 1384 | cfg[preset].lcrmask_polrev);
|
| 1385 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRMASK_STATE,
|
| 1386 | cfg[preset].lcrmask_state);
|
| 1387 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRMASK_LINECAP,
|
| 1388 | cfg[preset].lcrmask_linecap);
|
| 1389 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VCM_OH,cfg[preset].vcm_oh);
|
| 1390 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VOV_BAT,cfg[preset].vov_bat);
|
| 1391 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VOV_GND,cfg[preset].vov_gnd);
|
| 1392 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,lf);
|
| 1393 |
|
| 1394 | return RC_NONE;
|
| 1395 | }
|
| 1396 |
|
| 1397 | #endif
|
| 1398 |
|
| 1399 | /*
|
| 1400 | ** Function: PROSLIC_PulseMeterSetup
|
| 1401 | **
|
| 1402 | ** Description:
|
| 1403 | ** configure pulse metering
|
| 1404 | */
|
| 1405 |
|
| 1406 | #ifndef DISABLE_PULSE_SETUP
|
| 1407 | int Si3218x_PulseMeterSetup (proslicChanType *pProslic, int preset)
|
| 1408 | {
|
| 1409 | uInt8 reg;
|
| 1410 |
|
| 1411 | if(pProslic->channelType != PROSLIC)
|
| 1412 | {
|
| 1413 | return RC_CHANNEL_TYPE_ERR;
|
| 1414 | }
|
| 1415 |
|
| 1416 | else
|
| 1417 | {
|
| 1418 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PM_AMP_THRESH,
|
| 1419 | Si3218x_PulseMeter_Presets[preset].pm_amp_thresh);
|
| 1420 | reg = (Si3218x_PulseMeter_Presets[preset].pmFreq<<1)|
|
| 1421 | (Si3218x_PulseMeter_Presets[preset].pmAuto<<3);
|
| 1422 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PM_ACTIVE,
|
| 1423 | Si3218x_PulseMeter_Presets[preset].pmActive);
|
| 1424 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PM_INACTIVE,
|
| 1425 | Si3218x_PulseMeter_Presets[preset].pmInactive);
|
| 1426 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_PMCON,reg);
|
| 1427 | return RC_NONE;
|
| 1428 | }
|
| 1429 |
|
| 1430 | }
|
| 1431 | #endif
|
| 1432 |
|
| 1433 | /*
|
| 1434 | ** Function: PROSLIC_PCMSetup
|
| 1435 | **
|
| 1436 | ** Description:
|
| 1437 | ** configure pcm
|
| 1438 | */
|
| 1439 |
|
| 1440 | #ifndef DISABLE_PCM_SETUP
|
| 1441 | int Si3218x_PCMSetup(proslicChanType *pProslic, int preset)
|
| 1442 | {
|
| 1443 | uInt8 regTemp;
|
| 1444 | uInt8 pmEn;
|
| 1445 |
|
| 1446 | if(pProslic->channelType != PROSLIC)
|
| 1447 | {
|
| 1448 | return RC_CHANNEL_TYPE_ERR;
|
| 1449 | }
|
| 1450 |
|
| 1451 | pmEn = ReadReg(pProHW,pProslic->channel,
|
| 1452 | SI3218X_REG_PMCON) & 0x01; /* PM/wideband lockout */
|
| 1453 | if (Si3218x_PCM_Presets[preset].widebandEn && pmEn)
|
| 1454 | {
|
| 1455 | #ifdef ENABLE_DEBUG
|
| 1456 | LOGPRINT ("%s Wideband Mode is not supported while Pulse Metering is enabled.\n",
|
| 1457 | LOGPRINT_PREFIX);
|
| 1458 | #endif
|
| 1459 | }
|
| 1460 | else if (Si3218x_PCM_Presets[preset].widebandEn && !pmEn)
|
| 1461 | {
|
| 1462 | /* TXIIR settings */
|
| 1463 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_1,0x3538E80L);
|
| 1464 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_1,0x3538E80L);
|
| 1465 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_1,0x1AA9100L);
|
| 1466 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_2,0x216D100L);
|
| 1467 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_2,0x2505400L);
|
| 1468 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B2_2,0x216D100L);
|
| 1469 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_2,0x2CB8100L);
|
| 1470 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A2_2,0x1D7FA500L);
|
| 1471 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_3,0x2CD9B00L);
|
| 1472 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_3,0x1276D00L);
|
| 1473 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B2_3,0x2CD9B00L);
|
| 1474 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_3,0x2335300L);
|
| 1475 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A2_3,0x19D5F700L);
|
| 1476 | /* RXIIR settings */
|
| 1477 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_1,0x6A71D00L);
|
| 1478 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_1,0x6A71D00L);
|
| 1479 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_1,0x1AA9100L);
|
| 1480 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_2,0x216D100L);
|
| 1481 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_2,0x2505400L);
|
| 1482 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B2_2,0x216D100L);
|
| 1483 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_2,0x2CB8100L);
|
| 1484 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A2_2,0x1D7FA500L);
|
| 1485 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_3,0x2CD9B00L);
|
| 1486 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_3,0x1276D00L);
|
| 1487 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B2_3,0x2CD9B00L);
|
| 1488 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_3,0x2335300L);
|
| 1489 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A2_3,0x19D5F700L);
|
| 1490 | /*
|
| 1491 | ** RXHPF
|
| 1492 | ** Note: Calling ProSLIC_ZsynthSetup() will overwrite some
|
| 1493 | ** of these values. ProSLIC_PCMSetup() should always
|
| 1494 | ** be called after loading coefficients when using
|
| 1495 | ** wideband mode
|
| 1496 | */
|
| 1497 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B0_1,0x7CFF900L);
|
| 1498 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B1_1,0x18300700L);
|
| 1499 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_A1_1,0x79FF201L);
|
| 1500 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B0_2,0x7CEDA1DL);
|
| 1501 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B1_2,0x106320D4L);
|
| 1502 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B2_2,0x7CEDA1DL);
|
| 1503 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_A1_2,0xF9A910FL);
|
| 1504 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_A2_2,0x185FFDA8L);
|
| 1505 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_GAIN,0x08000000L);
|
| 1506 | /* TXHPF */
|
| 1507 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_B0_1,0x0C7FF4CEL);
|
| 1508 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_B1_1,0x13800B32L);
|
| 1509 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_A1_1,0x079FF201L);
|
| 1510 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_B0_2,0x030FDD10L);
|
| 1511 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_B1_2,0x19E0996CL);
|
| 1512 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_B2_2,0x030FDD10L);
|
| 1513 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_A1_2,0x0F9A910FL);
|
| 1514 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_A2_2,0x185FFDA8L);
|
| 1515 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_GAIN,0x0CD30000L);
|
| 1516 |
|
| 1517 | regTemp = ReadReg(pProHW,pProslic->channel,SI3218X_REG_DIGCON);
|
| 1518 | #ifndef DISABLE_HPF_WIDEBAND
|
| 1519 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_DIGCON,
|
| 1520 | regTemp&~(0xC)); /* Enable HPF */
|
| 1521 | #else
|
| 1522 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_DIGCON,
|
| 1523 | regTemp|(0xC)); /* Disable HPF */
|
| 1524 | #endif
|
| 1525 | regTemp = ReadReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE);
|
| 1526 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE,regTemp|1);
|
| 1527 | }
|
| 1528 | else
|
| 1529 | {
|
| 1530 | regTemp = ReadReg(pProHW,pProslic->channel,SI3218X_REG_DIGCON);
|
| 1531 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_DIGCON,regTemp&~(0xC));
|
| 1532 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_1,0x3538E80L);
|
| 1533 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_1,0x3538E80L);
|
| 1534 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_1,0x1AA9100L);
|
| 1535 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_2,0x216D100L);
|
| 1536 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_2,0x2505400L);
|
| 1537 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B2_2,0x216D100L);
|
| 1538 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_2,0x2CB8100L);
|
| 1539 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A2_2,0x1D7FA500L);
|
| 1540 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_3,0x2CD9B00L);
|
| 1541 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_3,0x1276D00L);
|
| 1542 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B2_3,0x2CD9B00L);
|
| 1543 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_3,0x2335300L);
|
| 1544 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A2_3,0x19D5F700L);
|
| 1545 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_1,0x6A71D00L);
|
| 1546 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_1,0x6A71D00L);
|
| 1547 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_1,0x1AA9100L);
|
| 1548 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_2,0x216D100L);
|
| 1549 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_2,0x2505400L);
|
| 1550 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B2_2,0x216D100L);
|
| 1551 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_2,0x2CB8100L);
|
| 1552 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A2_2,0x1D7FA500L);
|
| 1553 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_3,0x2CD9B00L);
|
| 1554 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_3,0x1276D00L);
|
| 1555 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B2_3,0x2CD9B00L);
|
| 1556 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_3,0x2335300L);
|
| 1557 | WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A2_3,0x19D5F700L);
|
| 1558 | regTemp = ReadReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE);
|
| 1559 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE,regTemp&~(1));
|
| 1560 | }
|
| 1561 | regTemp = Si3218x_PCM_Presets[preset].pcmFormat;
|
| 1562 | regTemp |= Si3218x_PCM_Presets[preset].pcm_tri << 5;
|
| 1563 | regTemp |= Si3218x_PCM_Presets[preset].alaw_inv << 2;
|
| 1564 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_PCMMODE,regTemp);
|
| 1565 | regTemp = ReadReg(pProHW,pProslic->channel,SI3218X_REG_PCMTXHI);
|
| 1566 | regTemp &= 3;
|
| 1567 | regTemp |= Si3218x_PCM_Presets[preset].tx_edge<<4;
|
| 1568 | WriteReg(pProHW,pProslic->channel,SI3218X_REG_PCMTXHI,regTemp);
|
| 1569 |
|
| 1570 | return RC_NONE;
|
| 1571 | }
|
| 1572 | #endif
|
| 1573 |
|
| 1574 | /*
|
| 1575 | **
|
| 1576 | ** PROSLIC CONTROL FUNCTIONS
|
| 1577 | **
|
| 1578 | */
|
| 1579 |
|
| 1580 | /*
|
| 1581 |
|
| 1582 | ** Function: PROSLIC_dbgSetDCFeed
|
| 1583 | **
|
| 1584 | ** Description:
|
| 1585 | ** provisionally function for setting up
|
| 1586 | ** dcfeed given desired open circuit voltage
|
| 1587 | ** and loop current.
|
| 1588 | */
|
| 1589 |
|
| 1590 | int Si3218x_dbgSetDCFeed (proslicChanType *pProslic, uInt32 v_vlim_val,
|
| 1591 | uInt32 i_ilim_val, int32 preset)
|
| 1592 | {
|
| 1593 | #ifndef DISABLE_DCFEED_SETUP
|
| 1594 | /* Note: * needs more descriptive return codes in the event of an out of range argument */
|
| 1595 | uInt16 vslope = 160;
|
| 1596 | uInt16 rslope = 720;
|
| 1597 | uInt32 vscale1 = 1386;
|
| 1598 | uInt32 vscale2 =
|
| 1599 | 1422; /* 1386x1422 = 1970892 broken down to minimize trunc err */
|
| 1600 | uInt32 iscale1 = 913;
|
| 1601 | uInt32 iscale2 = 334; /* 913x334 = 304942 */
|
| 1602 | uInt32 i_rfeed_val, v_rfeed_val, const_rfeed_val, i_vlim_val, const_ilim_val,
|
| 1603 | v_ilim_val;
|
| 1604 | int32 signedVal;
|
| 1605 | /* Set Linefeed to open state before modifying DC Feed */
|
| 1606 |
|
| 1607 | /* Assumptions must be made to minimize computations. This limits the
|
| 1608 | ** range of available settings, but should be more than adequate for
|
| 1609 | ** short loop applications.
|
| 1610 | **
|
| 1611 | ** Assumtions:
|
| 1612 | **
|
| 1613 | ** SLOPE_VLIM => 160ohms
|
| 1614 | ** SLOPE_RFEED => 720ohms
|
| 1615 | ** I_RFEED => 3*I_ILIM/4
|
| 1616 | **
|
| 1617 | ** With these assumptions, the DC Feed parameters now become
|
| 1618 | **
|
| 1619 | ** Inputs: V_VLIM, I_ILIM
|
| 1620 | ** Constants: SLOPE_VLIM, SLOPE_ILIM, SLOPE_RFEED, SLOPE_DELTA1, SLOPE_DELTA2
|
| 1621 | ** Outputs: V_RFEED, V_ILIM, I_VLIM, CONST_RFEED, CONST_ILIM
|
| 1622 | **
|
| 1623 | */
|
| 1624 |
|
| 1625 | if(pProslic->channelType != PROSLIC)
|
| 1626 | {
|
| 1627 | return RC_CHANNEL_TYPE_ERR;
|
| 1628 | }
|
| 1629 |
|
| 1630 | /* Validate arguments */
|
| 1631 | if((i_ilim_val < 15)||(i_ilim_val > 45))
|
| 1632 | {
|
| 1633 | return 1; /* need error code */
|
| 1634 | }
|
| 1635 | if((v_vlim_val < 30)||(v_vlim_val > 52))
|
| 1636 | {
|
| 1637 | return 1; /* need error code */
|
| 1638 | }
|
| 1639 |
|
| 1640 | /* Calculate voltages in mV and currents in uA */
|
| 1641 | v_vlim_val *= 1000;
|
| 1642 | i_ilim_val *= 1000;
|
| 1643 |
|
| 1644 | /* I_RFEED */
|
| 1645 | i_rfeed_val = (3*i_ilim_val)/4;
|
| 1646 |
|
| 1647 | /* V_RFEED */
|
| 1648 | v_rfeed_val = v_vlim_val - (i_rfeed_val*vslope)/1000;
|
| 1649 |
|
| 1650 | /* V_ILIM */
|
| 1651 | v_ilim_val = v_rfeed_val - (rslope*(i_ilim_val - i_rfeed_val))/1000;
|
| 1652 |
|
| 1653 | /* I_VLIM */
|
| 1654 | i_vlim_val = (v_vlim_val*1000)/4903;
|
| 1655 |
|
| 1656 | /* CONST_RFEED */
|
| 1657 | signedVal = v_rfeed_val * (i_ilim_val - i_rfeed_val);
|
| 1658 | signedVal /= (v_rfeed_val - v_ilim_val);
|
| 1659 | signedVal = i_rfeed_val + signedVal;
|
| 1660 |
|
| 1661 | /* signedVal in uA here */
|
| 1662 | signedVal *= iscale1;
|
| 1663 | signedVal /= 100;
|
| 1664 | signedVal *= iscale2;
|
| 1665 | signedVal /= 10;
|
| 1666 |
|
| 1667 | if(signedVal < 0)
|
| 1668 | {
|
| 1669 | const_rfeed_val = (signedVal)+ (1L<<29);
|
| 1670 | }
|
| 1671 | else
|
| 1672 | {
|
| 1673 | const_rfeed_val = signedVal & 0x1FFFFFFF;
|
| 1674 | }
|
| 1675 |
|
| 1676 | /* CONST_ILIM */
|
| 1677 | const_ilim_val = i_ilim_val;
|
| 1678 |
|
| 1679 | /* compute RAM values */
|
| 1680 | v_vlim_val *= vscale1;
|
| 1681 | v_vlim_val /= 100;
|
| 1682 | v_vlim_val *= vscale2;
|
| 1683 | v_vlim_val /= 10;
|
| 1684 |
|
| 1685 | v_rfeed_val *= vscale1;
|
| 1686 | v_rfeed_val /= 100;
|
| 1687 | v_rfeed_val *= vscale2;
|
| 1688 | v_rfeed_val /= 10;
|
| 1689 |
|
| 1690 | v_ilim_val *= vscale1;
|
| 1691 | v_ilim_val /= 100;
|
| 1692 | v_ilim_val *= vscale2;
|
| 1693 | v_ilim_val /= 10;
|
| 1694 |
|
| 1695 | const_ilim_val *= iscale1;
|
| 1696 | const_ilim_val /= 100;
|
| 1697 | const_ilim_val *= iscale2;
|
| 1698 | const_ilim_val /= 10;
|
| 1699 |
|
| 1700 | i_vlim_val *= iscale1;
|
| 1701 | i_vlim_val /= 100;
|
| 1702 | i_vlim_val *= iscale2;
|
| 1703 | i_vlim_val /= 10;
|
| 1704 |
|
| 1705 | Si3218x_DCfeed_Presets[preset].slope_vlim = 0x18842BD7L;
|
| 1706 | Si3218x_DCfeed_Presets[preset].slope_rfeed = 0x1E8886DEL;
|
| 1707 | Si3218x_DCfeed_Presets[preset].slope_ilim = 0x40A0E0L;
|
| 1708 | Si3218x_DCfeed_Presets[preset].delta1 = 0x1EABA1BFL;
|
| 1709 | Si3218x_DCfeed_Presets[preset].delta2 = 0x1EF744EAL;
|
| 1710 | Si3218x_DCfeed_Presets[preset].v_vlim = v_vlim_val;
|
| 1711 | Si3218x_DCfeed_Presets[preset].v_rfeed = v_rfeed_val;
|
| 1712 | Si3218x_DCfeed_Presets[preset].v_ilim = v_ilim_val;
|
| 1713 | Si3218x_DCfeed_Presets[preset].const_rfeed = const_rfeed_val;
|
| 1714 | Si3218x_DCfeed_Presets[preset].const_ilim = const_ilim_val;
|
| 1715 | Si3218x_DCfeed_Presets[preset].i_vlim = i_vlim_val;
|
| 1716 |
|
| 1717 | return RC_NONE;
|
| 1718 | #else
|
| 1719 | SILABS_UNREFERENCED_PARAMETER(pProslic);
|
| 1720 | SILABS_UNREFERENCED_PARAMETER(preset);
|
| 1721 | SILABS_UNREFERENCED_PARAMETER(v_vlim_val);
|
| 1722 | SILABS_UNREFERENCED_PARAMETER(i_ilim_val);
|
| 1723 | return RC_IGNORE;
|
| 1724 | #endif
|
| 1725 | }
|
| 1726 |
|
| 1727 | /*
|
| 1728 | ** Function: PROSLIC_dbgSetDCFeedVopen
|
| 1729 | **
|
| 1730 | ** Description:
|
| 1731 | ** provisionally function for setting up
|
| 1732 | ** dcfeed given desired open circuit voltage.
|
| 1733 | ** Entry I_ILIM value will be used.
|
| 1734 | */
|
| 1735 | int Si3218x_dbgSetDCFeedVopen (proslicChanType *pProslic, uInt32 v_vlim_val,
|
| 1736 | int32 preset)
|
| 1737 | {
|
| 1738 | #ifndef DISABLE_DCFEED_SETUP
|
| 1739 | uInt32 i_ilim_val;
|
| 1740 | uInt32 iscale1 = 913;
|
| 1741 | uInt32 iscale2 = 334; /* 913x334 = 304942 */
|
| 1742 |
|
| 1743 |
|
| 1744 | if(pProslic->channelType != PROSLIC)
|
| 1745 | {
|
| 1746 | return RC_CHANNEL_TYPE_ERR;
|
| 1747 | }
|
| 1748 |
|
| 1749 | /* Read present CONST_ILIM value */
|
| 1750 | i_ilim_val = Si3218x_DCfeed_Presets[preset].const_ilim;
|
| 1751 |
|
| 1752 |
|
| 1753 | i_ilim_val /= iscale2;
|
| 1754 | i_ilim_val /= iscale1;
|
| 1755 |
|
| 1756 | return Si3218x_dbgSetDCFeed(pProslic,v_vlim_val,i_ilim_val,preset);
|
| 1757 | #else
|
| 1758 | SILABS_UNREFERENCED_PARAMETER(pProslic);
|
| 1759 | SILABS_UNREFERENCED_PARAMETER(preset);
|
| 1760 | SILABS_UNREFERENCED_PARAMETER(v_vlim_val);
|
| 1761 | return RC_IGNORE;
|
| 1762 | #endif
|
| 1763 | }
|
| 1764 |
|
| 1765 | /*
|
| 1766 | ** Function: PROSLIC_dbgSetDCFeedIloop
|
| 1767 | **
|
| 1768 | ** Description:
|
| 1769 | ** provisionally function for setting up
|
| 1770 | ** dcfeed given desired loop current.
|
| 1771 | ** Entry V_VLIM value will be used.
|
| 1772 | */
|
| 1773 | int Si3218x_dbgSetDCFeedIloop (proslicChanType *pProslic, uInt32 i_ilim_val,
|
| 1774 | int32 preset)
|
| 1775 | {
|
| 1776 | #ifndef DISABLE_DCFEED_SETUP
|
| 1777 |
|
| 1778 | uInt32 v_vlim_val;
|
| 1779 | uInt32 vscale1 = 1386;
|
| 1780 | uInt32 vscale2 =
|
| 1781 | 1422; /* 1386x1422 = 1970892 broken down to minimize trunc err */
|
| 1782 |
|
| 1783 | if(pProslic->channelType != PROSLIC)
|
| 1784 | {
|
| 1785 | return RC_CHANNEL_TYPE_ERR;
|
| 1786 | }
|
| 1787 |
|
| 1788 | /* Read present V_VLIM value */
|
| 1789 | v_vlim_val = Si3218x_DCfeed_Presets[preset].v_vlim;
|
| 1790 |
|
| 1791 | v_vlim_val /= vscale2;
|
| 1792 | v_vlim_val /= vscale1;
|
| 1793 |
|
| 1794 | return Si3218x_dbgSetDCFeed(pProslic,v_vlim_val,i_ilim_val, preset);
|
| 1795 | #else
|
| 1796 | SILABS_UNREFERENCED_PARAMETER(pProslic);
|
| 1797 | SILABS_UNREFERENCED_PARAMETER(preset);
|
| 1798 | SILABS_UNREFERENCED_PARAMETER(i_ilim_val);
|
| 1799 | return RC_IGNORE;
|
| 1800 | #endif
|
| 1801 | }
|
| 1802 |
|
| 1803 | typedef struct
|
| 1804 | {
|
| 1805 | uInt8 freq;
|
| 1806 | ramData ringfr; /* trise scale for trap */
|
| 1807 | uInt32 ampScale;
|
| 1808 | } ProSLIC_SineRingFreqLookup;
|
| 1809 |
|
| 1810 | typedef struct
|
| 1811 | {
|
| 1812 | uInt8 freq;
|
| 1813 | ramData rtacth;
|
| 1814 | ramData rtper;
|
| 1815 | ramData rtdb;
|
| 1816 | } ProSLIC_SineRingtripLookup;
|
| 1817 |
|
| 1818 | typedef struct
|
| 1819 | {
|
| 1820 | uInt8 freq;
|
| 1821 | uInt16 cfVal[6];
|
| 1822 | } ProSLIC_TrapRingFreqLookup;
|
| 1823 |
|
| 1824 | typedef struct
|
| 1825 | {
|
| 1826 | uInt8 freq;
|
| 1827 | ramData rtper;
|
| 1828 | ramData rtdb;
|
| 1829 | uInt32 rtacth[6];
|
| 1830 | } ProSLIC_TrapRingtripLookup;
|
| 1831 |
|
| 1832 | static const ProSLIC_SineRingFreqLookup sineRingFreqTable[] =
|
| 1833 | /* Freq RINGFR, vScale */
|
| 1834 | {
|
| 1835 | {15, 0x7F6E930L, 18968L},
|
| 1836 | {16, 0x7F5A8E0L, 20234L},
|
| 1837 | {20, 0x7EFD9D5L, 25301L},
|
| 1838 | {22, 0x7EC770AL, 27843L},
|
| 1839 | {23, 0x7EAA6E2L, 29113L},
|
| 1840 | {25, 0x7E6C925L, 31649L},
|
| 1841 | {30, 0x7DBB96BL, 38014L},
|
| 1842 | {34, 0x7D34155L, 42270L}, /* Actually 33.33Hz */
|
| 1843 | {35, 0x7CEAD72L, 44397L},
|
| 1844 | {40, 0x7BFA887L, 50802L},
|
| 1845 | {45, 0x7AEAE74L, 57233L},
|
| 1846 | {50, 0x79BC384L, 63693L},
|
| 1847 | {0,0,0}
|
| 1848 | }; /* terminator */
|
| 1849 |
|
| 1850 | static const ProSLIC_SineRingtripLookup sineRingtripTable[] =
|
| 1851 | /* Freq rtacth */
|
| 1852 | {
|
| 1853 | {15, 11440000L, 0x6A000L, 0x4000L },
|
| 1854 | {16, 10810000L, 0x64000L, 0x4000L },
|
| 1855 | {20, 8690000L, 0x50000L, 0x8000L },
|
| 1856 | {22, 7835000L, 0x48000L, 0x8000L },
|
| 1857 | {23, 7622000L, 0x46000L, 0x8000L },
|
| 1858 | {25, 6980000L, 0x40000L, 0xA000L },
|
| 1859 | {30, 5900000L, 0x36000L, 0xA000L },
|
| 1860 | {34, 10490000L, 0x60000L, 0x6000L }, /* Actually 33.33 */
|
| 1861 | {35, 10060000L, 0x5C000L, 0x6000L },
|
| 1862 | {40, 8750000L, 0x50000L, 0x8000L },
|
| 1863 | {45, 7880000L, 0x48000L, 0x8000L },
|
| 1864 | {50, 7010000L, 0x40000L, 0xA000L },
|
| 1865 | {0,0L, 0L, 0L}
|
| 1866 | }; /* terminator */
|
| 1867 |
|
| 1868 | static const ProSLIC_TrapRingFreqLookup trapRingFreqTable[] =
|
| 1869 | /* Freq multCF11 multCF12 multCF13 multCF14 multCF15 multCF16*/
|
| 1870 | {
|
| 1871 | {15, {69,122, 163, 196, 222,244}},
|
| 1872 | {16, {65,115, 153, 184, 208,229}},
|
| 1873 | {20, {52,92, 122, 147, 167,183}},
|
| 1874 | {22, {47,83, 111, 134, 152,166}},
|
| 1875 | {23, {45,80, 107, 128, 145,159}},
|
| 1876 | {25, {42,73, 98, 118, 133,146}},
|
| 1877 | {30, {35,61, 82, 98, 111,122}},
|
| 1878 | {34, {31,55, 73, 88, 100,110}},
|
| 1879 | {35, {30,52, 70, 84, 95,104}},
|
| 1880 | {40, {26,46, 61, 73, 83,91}},
|
| 1881 | {45, {23,41, 54, 65, 74,81}},
|
| 1882 | {50, {21,37, 49, 59, 67,73}},
|
| 1883 | {0,{0L,0L,0L,0L}} /* terminator */
|
| 1884 | };
|
| 1885 |
|
| 1886 |
|
| 1887 | static const ProSLIC_TrapRingtripLookup trapRingtripTable[] =
|
| 1888 | /* Freq rtper rtdb rtacthCR11 rtacthCR12 rtacthCR13 rtacthCR14 rtacthCR15 rtacthCR16*/
|
| 1889 | {
|
| 1890 | {15, 0x6A000L, 0x4000L, {16214894L, 14369375L, 12933127L, 11793508L, 10874121L, 10121671L}},
|
| 1891 | {16, 0x64000L, 0x4000L, {15201463L, 13471289L, 12124806L, 11056414L, 10194489L, 9489067L}},
|
| 1892 | {20, 0x50000L, 0x6000L, {12161171L, 10777031L, 9699845L, 8845131L, 8155591L, 7591253L}},
|
| 1893 | {22, 0x48000L, 0x6000L, {11055610L, 9797301L, 8818041L, 8041028L, 7414174L, 6901139L}},
|
| 1894 | {23, 0x46000L, 0x6000L, {10574931L, 9371331L, 8434648L, 7691418L, 7091818L, 6601090L}},
|
| 1895 | {25, 0x40000L, 0x8000L, {9728937L, 8621625L, 7759876L, 7076105L, 6524473L, 6073003L}},
|
| 1896 | {30, 0x36000L, 0x8000L, {8107447L, 7184687L, 6466563L, 5896754L, 5437061L, 5060836L}},
|
| 1897 | {34, 0x60000L, 0x6000L, {7297432L, 6466865L, 5820489L, 5307609L, 4893844L, 4555208L}},
|
| 1898 | {35, 0x5C000L, 0x6000L, {6949240L, 6158303L, 5542769L, 5054361L, 4660338L, 4337859L}},
|
| 1899 | {40, 0x50000L, 0x6000L, {6080585L, 5388516L, 4849923L, 4422565L, 4077796L, 3795627L}},
|
| 1900 | {45, 0x48000L, 0x6000L, {5404965L, 4789792L, 4311042L, 3931169L, 3624707L, 3373890L}},
|
| 1901 | {50, 0x40000L, 0x8000L, {4864468L, 4310812L, 3879938L, 3538052L, 3262236L, 3036501L}},
|
| 1902 | {0,0x0L, 0x0L, {0L,0L,0L,0L}} /* terminator */
|
| 1903 | };
|
| 1904 |
|
| 1905 | /*
|
| 1906 | ** Function: PROSLIC_dbgRingingSetup
|
| 1907 | **
|
| 1908 | ** Description:
|
| 1909 | ** Provision function for setting up
|
| 1910 | ** Ring type, frequency, amplitude and dc offset.
|
| 1911 | ** Main use will be by peek/poke applications.
|
| 1912 | */
|
| 1913 | int Si3218x_dbgSetRinging (proslicChanType *pProslic,
|
| 1914 | ProSLIC_dbgRingCfg *ringCfg, int preset)
|
| 1915 | {
|
| 1916 | #ifndef DISABLE_RING_SETUP
|
| 1917 | int errVal,i=0;
|
| 1918 | uInt32 vScale = 1608872L; /* (2^28/170.25)*((100+4903)/4903) */
|
| 1919 | ramData dcdcVminTmp;
|
| 1920 |
|
| 1921 |
|
| 1922 | if(pProslic->channelType != PROSLIC)
|
| 1923 | {
|
| 1924 | return RC_CHANNEL_TYPE_ERR;
|
| 1925 | }
|
| 1926 |
|
| 1927 | errVal = RC_NONE;
|
| 1928 |
|
| 1929 | switch(ringCfg->ringtype)
|
| 1930 | {
|
| 1931 | case ProSLIC_RING_SINE:
|
| 1932 | i=0;
|
| 1933 | do
|
| 1934 | {
|
| 1935 | if(sineRingFreqTable[i].freq >= ringCfg->freq)
|
| 1936 | {
|
| 1937 | break;
|
| 1938 | }
|
| 1939 | i++;
|
| 1940 | }
|
| 1941 | while (sineRingFreqTable[i].freq);
|
| 1942 |
|
| 1943 | /* Set to maximum value if exceeding maximum value from table */
|
| 1944 | if(sineRingFreqTable[i].freq == 0)
|
| 1945 | {
|
| 1946 | i--;
|
| 1947 | errVal = RC_RING_V_LIMITED;
|
| 1948 | }
|
| 1949 |
|
| 1950 | /* Update RINGFR RINGAMP, RINGOFFSET, and RINGCON */
|
| 1951 | Si3218x_Ring_Presets[preset].freq = sineRingFreqTable[i].ringfr;
|
| 1952 | Si3218x_Ring_Presets[preset].amp = ringCfg->amp * sineRingFreqTable[i].ampScale;
|
| 1953 | Si3218x_Ring_Presets[preset].offset = ringCfg->offset * vScale;
|
| 1954 | Si3218x_Ring_Presets[preset].phas = 0L;
|
| 1955 |
|
| 1956 | /* Don't alter anything in RINGCON other than clearing the TRAP bit */
|
| 1957 | Si3218x_Ring_Presets[preset].ringcon &= 0xFE;
|
| 1958 |
|
| 1959 | Si3218x_Ring_Presets[preset].rtper = sineRingtripTable[i].rtper;
|
| 1960 | Si3218x_Ring_Presets[preset].rtacdb = sineRingtripTable[i].rtdb;
|
| 1961 | Si3218x_Ring_Presets[preset].rtdcdb = sineRingtripTable[i].rtdb;
|
| 1962 | Si3218x_Ring_Presets[preset].rtdcth = 0xFFFFFFFL;
|
| 1963 | Si3218x_Ring_Presets[preset].rtacth = sineRingtripTable[i].rtacth;
|
| 1964 | break;
|
| 1965 |
|
| 1966 | case ProSLIC_RING_TRAP_CF11:
|
| 1967 | case ProSLIC_RING_TRAP_CF12:
|
| 1968 | case ProSLIC_RING_TRAP_CF13:
|
| 1969 | case ProSLIC_RING_TRAP_CF14:
|
| 1970 | case ProSLIC_RING_TRAP_CF15:
|
| 1971 | case ProSLIC_RING_TRAP_CF16:
|
| 1972 | i=0;
|
| 1973 | do
|
| 1974 | {
|
| 1975 | if(trapRingFreqTable[i].freq >= ringCfg->freq)
|
| 1976 | {
|
| 1977 | break;
|
| 1978 | }
|
| 1979 | i++;
|
| 1980 | }
|
| 1981 | while (trapRingFreqTable[i].freq);
|
| 1982 |
|
| 1983 | /* Set to maximum value if exceeding maximum value from table */
|
| 1984 | if(trapRingFreqTable[i].freq == 0)
|
| 1985 | {
|
| 1986 | i--;
|
| 1987 | errVal = RC_RING_V_LIMITED;
|
| 1988 | }
|
| 1989 |
|
| 1990 | /* Update RINGFR RINGAMP, RINGOFFSET, and RINGCON */
|
| 1991 | Si3218x_Ring_Presets[preset].amp = ringCfg->amp * vScale;
|
| 1992 | Si3218x_Ring_Presets[preset].freq =
|
| 1993 | Si3218x_Ring_Presets[preset].amp/trapRingFreqTable[i].cfVal[ringCfg->ringtype];
|
| 1994 | Si3218x_Ring_Presets[preset].offset = ringCfg->offset * vScale;
|
| 1995 | Si3218x_Ring_Presets[preset].phas = 262144000L/trapRingFreqTable[i].freq;
|
| 1996 |
|
| 1997 | /* Don't alter anything in RINGCON other than setting the TRAP bit */
|
| 1998 | Si3218x_Ring_Presets[preset].ringcon |= 0x01;
|
| 1999 |
|
| 2000 | /* RTPER and debouce timers */
|
| 2001 | Si3218x_Ring_Presets[preset].rtper = trapRingtripTable[i].rtper;
|
| 2002 | Si3218x_Ring_Presets[preset].rtacdb = trapRingtripTable[i].rtdb;
|
| 2003 | Si3218x_Ring_Presets[preset].rtdcdb = trapRingtripTable[i].rtdb;
|
| 2004 |
|
| 2005 |
|
| 2006 | Si3218x_Ring_Presets[preset].rtdcth = 0xFFFFFFFL;
|
| 2007 | Si3218x_Ring_Presets[preset].rtacth =
|
| 2008 | trapRingtripTable[i].rtacth[ringCfg->ringtype];
|
| 2009 |
|
| 2010 |
|
| 2011 | break;
|
| 2012 | }
|
| 2013 |
|
| 2014 | /*
|
| 2015 | ** DCDC tracking sluggish under light load at higher ring freq.
|
| 2016 | ** Reduce tracking depth above 40Hz. This should have no effect
|
| 2017 | ** if using the Buck-Boost architecture.
|
| 2018 | */
|
| 2019 | if((sineRingFreqTable[i].freq >= 40)
|
| 2020 | ||(Si3218x_General_Configuration.bom_option == BO_DCDC_BUCK_BOOST))
|
| 2021 | {
|
| 2022 | dcdcVminTmp = ringCfg->amp + ringCfg->offset;
|
| 2023 | dcdcVminTmp *= 1000;
|
| 2024 | dcdcVminTmp *= SCALE_V_MADC;
|
| 2025 | Si3218x_Ring_Presets[preset].dcdc_vref_min_rng = dcdcVminTmp;
|
| 2026 | }
|
| 2027 | else
|
| 2028 | {
|
| 2029 | Si3218x_Ring_Presets[preset].dcdc_vref_min_rng = 0x1800000L;
|
| 2030 | }
|
| 2031 |
|
| 2032 | return errVal;
|
| 2033 | #else
|
| 2034 | SILABS_UNREFERENCED_PARAMETER(pProslic);
|
| 2035 | SILABS_UNREFERENCED_PARAMETER(preset);
|
| 2036 | SILABS_UNREFERENCED_PARAMETER(ringCfg);
|
| 2037 | return RC_IGNORE;
|
| 2038 | #endif
|
| 2039 | }
|
| 2040 |
|
| 2041 |
|
| 2042 | typedef struct
|
| 2043 | {
|
| 2044 | int32 gain;
|
| 2045 | uInt32 scale;
|
| 2046 | } ProSLIC_GainScaleLookup;
|
| 2047 |
|
| 2048 | #ifndef ENABLE_HIRES_GAIN
|
| 2049 | static int Si3218x_dbgSetGain (proslicChanType *pProslic, int32 gain,
|
| 2050 | int impedance_preset, int tx_rx_sel)
|
| 2051 | {
|
| 2052 | int errVal = 0;
|
| 2053 | int32 i;
|
| 2054 | int32 gain_pga, gain_eq;
|
| 2055 | const ProSLIC_GainScaleLookup gainScaleTable[]
|
| 2056 | = /* gain, scale=10^(gain/20) */
|
| 2057 | {
|
| 2058 | {-30, 32},
|
| 2059 | {-29, 35},
|
| 2060 | {-28, 40},
|
| 2061 | {-27, 45},
|
| 2062 | {-26, 50},
|
| 2063 | {-25, 56},
|
| 2064 | {-24, 63},
|
| 2065 | {-23, 71},
|
| 2066 | {-22, 79},
|
| 2067 | {-21, 89},
|
| 2068 | {-20, 100},
|
| 2069 | {-19, 112},
|
| 2070 | {-18, 126},
|
| 2071 | {-17, 141},
|
| 2072 | {-16, 158},
|
| 2073 | {-15, 178},
|
| 2074 | {-14, 200},
|
| 2075 | {-13, 224},
|
| 2076 | {-12, 251},
|
| 2077 | {-11, 282},
|
| 2078 | {-10, 316},
|
| 2079 | {-9, 355},
|
| 2080 | {-8, 398},
|
| 2081 | {-7, 447},
|
| 2082 | {-6, 501},
|
| 2083 | {-5, 562},
|
| 2084 | {-4, 631},
|
| 2085 | {-3, 708},
|
| 2086 | {-2, 794},
|
| 2087 | {-1, 891},
|
| 2088 | {0, 1000},
|
| 2089 | {1, 1122},
|
| 2090 | {2, 1259},
|
| 2091 | {3, 1413},
|
| 2092 | {4, 1585},
|
| 2093 | {5, 1778},
|
| 2094 | {6, 1995},
|
| 2095 | {0xff,0} /* terminator */
|
| 2096 | };
|
| 2097 |
|
| 2098 | SILABS_UNREFERENCED_PARAMETER(pProslic);
|
| 2099 |
|
| 2100 | /* Test against max gain */
|
| 2101 | if (gain > PROSLIC_EXTENDED_GAIN_MAX)
|
| 2102 | {
|
| 2103 | errVal = RC_GAIN_OUT_OF_RANGE;
|
| 2104 | DEBUG_PRINT(pProslic, "%sdbgSetGain: Gain %d out of range\n", LOGPRINT_PREFIX,
|
| 2105 | (int)gain);
|
| 2106 | gain = PROSLIC_EXTENDED_GAIN_MAX; /* Clamp to maximum */
|
| 2107 | }
|
| 2108 |
|
| 2109 | /* Test against min gain */
|
| 2110 | if (gain < PROSLIC_GAIN_MIN)
|
| 2111 | {
|
| 2112 | errVal = RC_GAIN_OUT_OF_RANGE;
|
| 2113 | DEBUG_PRINT(pProslic, "%sdbgSetGain: Gain %d out of range\n", LOGPRINT_PREFIX,
|
| 2114 | (int)gain);
|
| 2115 | gain = PROSLIC_GAIN_MIN; /* Clamp to minimum */
|
| 2116 | }
|
| 2117 |
|
| 2118 | /* Distribute gain */
|
| 2119 | if(gain == 0)
|
| 2120 | {
|
| 2121 | gain_pga = 0;
|
| 2122 | gain_eq = 0;
|
| 2123 | }
|
| 2124 | else if(gain > PROSLIC_GAIN_MAX)
|
| 2125 | {
|
| 2126 | if(tx_rx_sel == TXACGAIN_SEL)
|
| 2127 | {
|
| 2128 | gain_pga = PROSLIC_GAIN_MAX;
|
| 2129 | gain_eq = gain - PROSLIC_GAIN_MAX;
|
| 2130 | }
|
| 2131 | else
|
| 2132 | {
|
| 2133 | gain_pga = gain - PROSLIC_GAIN_MAX;
|
| 2134 | gain_eq = PROSLIC_GAIN_MAX;
|
| 2135 | }
|
| 2136 | }
|
| 2137 | else if(gain > 0)
|
| 2138 | {
|
| 2139 | if(tx_rx_sel == TXACGAIN_SEL)
|
| 2140 | {
|
| 2141 | gain_pga = gain;
|
| 2142 | gain_eq = 0;
|
| 2143 | }
|
| 2144 | else
|
| 2145 | {
|
| 2146 | gain_pga = 0;
|
| 2147 | gain_eq = gain;
|
| 2148 | }
|
| 2149 | }
|
| 2150 | else
|
| 2151 | {
|
| 2152 | if(tx_rx_sel == TXACGAIN_SEL)
|
| 2153 | {
|
| 2154 | gain_pga = 0;
|
| 2155 | gain_eq = gain;
|
| 2156 | }
|
| 2157 | else
|
| 2158 | {
|
| 2159 | gain_pga = gain;
|
| 2160 | gain_eq = 0;
|
| 2161 | }
|
| 2162 |
|
| 2163 | }
|
| 2164 |
|
| 2165 |
|
| 2166 | /*
|
| 2167 | ** Lookup PGA Appropriate PGA Gain
|
| 2168 | */
|
| 2169 | i=0;
|
| 2170 | do
|
| 2171 | {
|
| 2172 | if(gainScaleTable[i].gain >= gain_pga) /* was gain_1 */
|
| 2173 | {
|
| 2174 | break;
|
| 2175 | }
|
| 2176 | i++;
|
| 2177 | }
|
| 2178 | while (gainScaleTable[i].gain!=0xff);
|
| 2179 |
|
| 2180 | /* Set to maximum value if exceeding maximum value from table */
|
| 2181 | if(gainScaleTable[i].gain == 0xff)
|
| 2182 | {
|
| 2183 | i--;
|
| 2184 | errVal = RC_GAIN_DELTA_TOO_LARGE;
|
| 2185 | }
|
| 2186 |
|
| 2187 | if(tx_rx_sel == TXACGAIN_SEL)
|
| 2188 | {
|
| 2189 | Si3218x_audioGain_Presets[0].acgain =
|
| 2190 | (Si3218x_Impedance_Presets[impedance_preset].txgain/1000)
|
| 2191 | *gainScaleTable[i].scale;
|
| 2192 | }
|
| 2193 | else
|
| 2194 | {
|
| 2195 | Si3218x_audioGain_Presets[1].acgain =
|
| 2196 | (Si3218x_Impedance_Presets[impedance_preset].rxgain/1000)
|
| 2197 | *gainScaleTable[i].scale;
|
| 2198 | }
|
| 2199 |
|
| 2200 |
|
| 2201 | /*
|
| 2202 | ** Lookup EQ Gain
|
| 2203 | */
|
| 2204 | i=0;
|
| 2205 | do
|
| 2206 | {
|
| 2207 | if(gainScaleTable[i].gain >= gain_eq) /* was gain_2 */
|
| 2208 | {
|
| 2209 | break;
|
| 2210 | }
|
| 2211 | i++;
|
| 2212 | }
|
| 2213 | while (gainScaleTable[i].gain!=0xff);
|
| 2214 |
|
| 2215 | /* Set to maximum value if exceeding maximum value from table */
|
| 2216 | if(gainScaleTable[i].gain == 0xff)
|
| 2217 | {
|
| 2218 | i--;
|
| 2219 | errVal = RC_GAIN_DELTA_TOO_LARGE;
|
| 2220 | }
|
| 2221 |
|
| 2222 | if(tx_rx_sel == TXACGAIN_SEL)
|
| 2223 | {
|
| 2224 | /*sign extend negative numbers*/
|
| 2225 | if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0 & 0x10000000L)
|
| 2226 | {
|
| 2227 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0 |= 0xf0000000L;
|
| 2228 | }
|
| 2229 | if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1 & 0x10000000L)
|
| 2230 | {
|
| 2231 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1 |= 0xf0000000L;
|
| 2232 | }
|
| 2233 | if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2 & 0x10000000L)
|
| 2234 | {
|
| 2235 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2 |= 0xf0000000L;
|
| 2236 | }
|
| 2237 | if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3 & 0x10000000L)
|
| 2238 | {
|
| 2239 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3 |= 0xf0000000L;
|
| 2240 | }
|
| 2241 |
|
| 2242 | Si3218x_audioGain_Presets[0].aceq_c0 = ((int32)
|
| 2243 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0/1000)
|
| 2244 | *gainScaleTable[i].scale;
|
| 2245 | Si3218x_audioGain_Presets[0].aceq_c1 = ((int32)
|
| 2246 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1/1000)
|
| 2247 | *gainScaleTable[i].scale;
|
| 2248 | Si3218x_audioGain_Presets[0].aceq_c2 = ((int32)
|
| 2249 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2/1000)
|
| 2250 | *gainScaleTable[i].scale;
|
| 2251 | Si3218x_audioGain_Presets[0].aceq_c3 = ((int32)
|
| 2252 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3/1000)
|
| 2253 | *gainScaleTable[i].scale;
|
| 2254 | }
|
| 2255 | else
|
| 2256 | {
|
| 2257 | /*sign extend negative numbers*/
|
| 2258 | if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0 & 0x10000000L)
|
| 2259 | {
|
| 2260 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0 |= 0xf0000000L;
|
| 2261 | }
|
| 2262 | if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1 & 0x10000000L)
|
| 2263 | {
|
| 2264 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1 |= 0xf0000000L;
|
| 2265 | }
|
| 2266 | if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2 & 0x10000000L)
|
| 2267 | {
|
| 2268 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2 |= 0xf0000000L;
|
| 2269 | }
|
| 2270 | if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3 & 0x10000000L)
|
| 2271 | {
|
| 2272 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3 |= 0xf0000000L;
|
| 2273 | }
|
| 2274 |
|
| 2275 | Si3218x_audioGain_Presets[1].aceq_c0 = ((int32)
|
| 2276 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0/1000)
|
| 2277 | *gainScaleTable[i].scale;
|
| 2278 | Si3218x_audioGain_Presets[1].aceq_c1 = ((int32)
|
| 2279 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1/1000)
|
| 2280 | *gainScaleTable[i].scale;
|
| 2281 | Si3218x_audioGain_Presets[1].aceq_c2 = ((int32)
|
| 2282 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2/1000)
|
| 2283 | *gainScaleTable[i].scale;
|
| 2284 | Si3218x_audioGain_Presets[1].aceq_c3 = ((int32)
|
| 2285 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3/1000)
|
| 2286 | *gainScaleTable[i].scale;
|
| 2287 | }
|
| 2288 |
|
| 2289 |
|
| 2290 | return errVal;
|
| 2291 | }
|
| 2292 | #else /* ENABLE_HIRES_GAIN */
|
| 2293 | /*
|
| 2294 | ** Function: Si3218x_dbgSetGainHiRes()
|
| 2295 | **
|
| 2296 | ** Description:
|
| 2297 | ** Provision function for setting up
|
| 2298 | ** TX and RX gain with 0.1dB resolution instead
|
| 2299 | ** of 1.0dB resolution
|
| 2300 | */
|
| 2301 | static int Si3218x_dbgSetGainHiRes (proslicChanType *pProslic, int32 gain,
|
| 2302 | int impedance_preset, int tx_rx_sel)
|
| 2303 | {
|
| 2304 | int errVal = 0;
|
| 2305 | int32 i;
|
| 2306 | int32 coarseGainIndex, fineGainIndex;
|
| 2307 | int32 gain_pga, gain_eq;
|
| 2308 | int32 coarseGain, fineGain;
|
| 2309 | int32 tmp;
|
| 2310 | const ProSLIC_GainScaleLookup coarseGainScaleTable[]
|
| 2311 | = /* gain, scale=10^(gain/20) */
|
| 2312 | {
|
| 2313 | {-30, 32},
|
| 2314 | {-29, 35},
|
| 2315 | {-28, 40},
|
| 2316 | {-27, 45},
|
| 2317 | {-26, 50},
|
| 2318 | {-25, 56},
|
| 2319 | {-24, 63},
|
| 2320 | {-23, 71},
|
| 2321 | {-22, 79},
|
| 2322 | {-21, 89},
|
| 2323 | {-20, 100},
|
| 2324 | {-19, 112},
|
| 2325 | {-18, 126},
|
| 2326 | {-17, 141},
|
| 2327 | {-16, 158},
|
| 2328 | {-15, 178},
|
| 2329 | {-14, 200},
|
| 2330 | {-13, 224},
|
| 2331 | {-12, 251},
|
| 2332 | {-11, 282},
|
| 2333 | {-10, 316},
|
| 2334 | {-9, 355},
|
| 2335 | {-8, 398},
|
| 2336 | {-7, 447},
|
| 2337 | {-6, 501},
|
| 2338 | {-5, 562},
|
| 2339 | {-4, 631},
|
| 2340 | {-3, 708},
|
| 2341 | {-2, 794},
|
| 2342 | {-1, 891},
|
| 2343 | {0, 1000},
|
| 2344 | {1, 1122},
|
| 2345 | {2, 1259},
|
| 2346 | {3, 1413},
|
| 2347 | {4, 1585},
|
| 2348 | {5, 1778},
|
| 2349 | {6, 1995},
|
| 2350 | {0xff,0} /* terminator */
|
| 2351 | };
|
| 2352 |
|
| 2353 | const ProSLIC_GainScaleLookup fineGainScaleTable[]
|
| 2354 | = /* gain, scale=10^(gain/20) */
|
| 2355 | {
|
| 2356 | {-9, 902},
|
| 2357 | {-8, 912},
|
| 2358 | {-7, 923},
|
| 2359 | {-6, 933},
|
| 2360 | {-5, 944},
|
| 2361 | {-4, 955},
|
| 2362 | {-3, 966},
|
| 2363 | {-2, 977},
|
| 2364 | {-1, 989},
|
| 2365 | {0, 1000},
|
| 2366 | {1, 1012},
|
| 2367 | {2, 1023},
|
| 2368 | {3, 1035},
|
| 2369 | {4, 1047},
|
| 2370 | {5, 1059},
|
| 2371 | {6, 1072},
|
| 2372 | {7, 1084},
|
| 2373 | {8, 1096},
|
| 2374 | {9, 1109},
|
| 2375 | {0xff,0} /* terminator */
|
| 2376 | };
|
| 2377 |
|
| 2378 | SILABS_UNREFERENCED_PARAMETER(pProslic);
|
| 2379 |
|
| 2380 | /* Test against max gain */
|
| 2381 | if (gain > (PROSLIC_GAIN_MAX*10L))
|
| 2382 | {
|
| 2383 | errVal = RC_GAIN_OUT_OF_RANGE;
|
| 2384 | DEBUG_PRINT(pProslic, "%sdbgSetGain: Gain %d dB*10 out of range\n",
|
| 2385 | LOGPRINT_PREFIX, gain);
|
| 2386 | gain = (PROSLIC_GAIN_MAX*10L); /* Clamp to maximum */
|
| 2387 | }
|
| 2388 |
|
| 2389 | /* Test against min gain */
|
| 2390 | if (gain < (PROSLIC_GAIN_MIN*10L))
|
| 2391 | {
|
| 2392 | errVal = RC_GAIN_OUT_OF_RANGE;
|
| 2393 | DEBUG_PRINT(pProslic, "%sdbgSetGain: Gain %d dB*10 out of range\n",
|
| 2394 | LOGPRINT_PREFIX, gain);
|
| 2395 | gain = (PROSLIC_GAIN_MIN*10); /* Clamp to minimum */
|
| 2396 | }
|
| 2397 |
|
| 2398 | /* Distribute gain */
|
| 2399 | coarseGain = gain/10L;
|
| 2400 | fineGain = gain - (coarseGain*10L);
|
| 2401 |
|
| 2402 | /* Distribute coarseGain */
|
| 2403 | if(coarseGain == 0)
|
| 2404 | {
|
| 2405 | gain_pga = 0;
|
| 2406 | gain_eq = 0;
|
| 2407 | }
|
| 2408 | else if(coarseGain > 0)
|
| 2409 | {
|
| 2410 | if(tx_rx_sel == TXACGAIN_SEL)
|
| 2411 | {
|
| 2412 | gain_pga = coarseGain;
|
| 2413 | gain_eq = 0;
|
| 2414 | }
|
| 2415 | else
|
| 2416 | {
|
| 2417 | gain_pga = 0;
|
| 2418 | gain_eq = coarseGain;
|
| 2419 | }
|
| 2420 | }
|
| 2421 | else
|
| 2422 | {
|
| 2423 | if(tx_rx_sel == TXACGAIN_SEL)
|
| 2424 | {
|
| 2425 | gain_pga = 0;
|
| 2426 | gain_eq = coarseGain;
|
| 2427 | }
|
| 2428 | else
|
| 2429 | {
|
| 2430 | gain_pga = coarseGain;
|
| 2431 | gain_eq = 0;
|
| 2432 | }
|
| 2433 | }
|
| 2434 |
|
| 2435 | /*
|
| 2436 | ** Lookup PGA Appopriate PGA Gain
|
| 2437 | */
|
| 2438 | i=0;
|
| 2439 | do
|
| 2440 | {
|
| 2441 | if(coarseGainScaleTable[i].gain >= gain_pga)
|
| 2442 | {
|
| 2443 | break;
|
| 2444 | }
|
| 2445 | i++;
|
| 2446 | }
|
| 2447 | while (coarseGainScaleTable[i].gain!=0xff);
|
| 2448 |
|
| 2449 | /* Set to maximum value if exceeding maximum value from table */
|
| 2450 | if(coarseGainScaleTable[i].gain == 0xff)
|
| 2451 | {
|
| 2452 | i--;
|
| 2453 | errVal = RC_GAIN_DELTA_TOO_LARGE;
|
| 2454 | }
|
| 2455 |
|
| 2456 | coarseGainIndex = i; /* Store coarse index */
|
| 2457 |
|
| 2458 | /* Find fineGain */
|
| 2459 | i = 0;
|
| 2460 | do
|
| 2461 | {
|
| 2462 | if(fineGainScaleTable[i].gain >= fineGain)
|
| 2463 | {
|
| 2464 | break;
|
| 2465 | }
|
| 2466 | i++;
|
| 2467 | }
|
| 2468 | while (fineGainScaleTable[i].gain!=0xff);
|
| 2469 |
|
| 2470 | /* Set to maximum value if exceeding maximum value from table */
|
| 2471 | if(fineGainScaleTable[i].gain == 0xff)
|
| 2472 | {
|
| 2473 | i--;
|
| 2474 | errVal = RC_GAIN_DELTA_TOO_LARGE;
|
| 2475 | }
|
| 2476 |
|
| 2477 | fineGainIndex = i;
|
| 2478 |
|
| 2479 | if(tx_rx_sel == TXACGAIN_SEL)
|
| 2480 | {
|
| 2481 | Si3218x_audioGain_Presets[0].acgain = ((
|
| 2482 | Si3218x_Impedance_Presets[impedance_preset].txgain/1000L)
|
| 2483 | *coarseGainScaleTable[coarseGainIndex].scale);
|
| 2484 | }
|
| 2485 | else
|
| 2486 | {
|
| 2487 | Si3218x_audioGain_Presets[1].acgain = ((
|
| 2488 | Si3218x_Impedance_Presets[impedance_preset].rxgain/1000L)
|
| 2489 | * coarseGainScaleTable[coarseGainIndex].scale)/1000L
|
| 2490 | * fineGainScaleTable[fineGainIndex].scale;
|
| 2491 | }
|
| 2492 |
|
| 2493 | /*
|
| 2494 | ** Lookup EQ Gain
|
| 2495 | */
|
| 2496 | i=0;
|
| 2497 | do
|
| 2498 | {
|
| 2499 | if(coarseGainScaleTable[i].gain >= gain_eq)
|
| 2500 | {
|
| 2501 | break;
|
| 2502 | }
|
| 2503 | i++;
|
| 2504 | }
|
| 2505 | while (coarseGainScaleTable[i].gain!=0xff);
|
| 2506 |
|
| 2507 | /* Set to maximum value if exceeding maximum value from table */
|
| 2508 | if(coarseGainScaleTable[i].gain == 0xff)
|
| 2509 | {
|
| 2510 | i--;
|
| 2511 | errVal = RC_GAIN_DELTA_TOO_LARGE;
|
| 2512 | }
|
| 2513 |
|
| 2514 | coarseGainIndex = i; /* Store coarse index */
|
| 2515 |
|
| 2516 | if(tx_rx_sel == TXACGAIN_SEL)
|
| 2517 | {
|
| 2518 | /*sign extend negative numbers*/
|
| 2519 | if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0 & 0x10000000L)
|
| 2520 | {
|
| 2521 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0 |= 0xf0000000L;
|
| 2522 | }
|
| 2523 | if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1 & 0x10000000L)
|
| 2524 | {
|
| 2525 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1 |= 0xf0000000L;
|
| 2526 | }
|
| 2527 | if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2 & 0x10000000L)
|
| 2528 | {
|
| 2529 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2 |= 0xf0000000L;
|
| 2530 | }
|
| 2531 | if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3 & 0x10000000L)
|
| 2532 | {
|
| 2533 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3 |= 0xf0000000L;
|
| 2534 | }
|
| 2535 |
|
| 2536 | tmp = (((int32)
|
| 2537 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0/1000L)
|
| 2538 | *coarseGainScaleTable[coarseGainIndex].scale);
|
| 2539 | tmp = tmp / (int32)1000L;
|
| 2540 | tmp = tmp * (int32)fineGainScaleTable[fineGainIndex].scale;
|
| 2541 | Si3218x_audioGain_Presets[0].aceq_c0 = tmp;
|
| 2542 |
|
| 2543 | tmp = (((int32)
|
| 2544 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1/1000L)
|
| 2545 | *coarseGainScaleTable[coarseGainIndex].scale);
|
| 2546 | tmp = tmp / (int32)1000L;
|
| 2547 | tmp = tmp * (int32)fineGainScaleTable[fineGainIndex].scale;
|
| 2548 | Si3218x_audioGain_Presets[0].aceq_c1 = tmp;
|
| 2549 |
|
| 2550 | tmp = (((int32)
|
| 2551 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2/1000L)
|
| 2552 | *coarseGainScaleTable[coarseGainIndex].scale);
|
| 2553 | tmp = tmp / (int32)1000L;
|
| 2554 | tmp = tmp * (int32)fineGainScaleTable[fineGainIndex].scale;
|
| 2555 | Si3218x_audioGain_Presets[0].aceq_c2 = tmp;
|
| 2556 |
|
| 2557 | tmp = (((int32)
|
| 2558 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3/1000L)
|
| 2559 | *coarseGainScaleTable[coarseGainIndex].scale);
|
| 2560 | tmp = tmp / (int32)1000L;
|
| 2561 | tmp = tmp * (int32)fineGainScaleTable[fineGainIndex].scale;
|
| 2562 | Si3218x_audioGain_Presets[0].aceq_c3 = tmp;
|
| 2563 | }
|
| 2564 | else
|
| 2565 | {
|
| 2566 | /*sign extend negative numbers*/
|
| 2567 | if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0 & 0x10000000L)
|
| 2568 | {
|
| 2569 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0 |= 0xf0000000L;
|
| 2570 | }
|
| 2571 | if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1 & 0x10000000L)
|
| 2572 | {
|
| 2573 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1 |= 0xf0000000L;
|
| 2574 | }
|
| 2575 | if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2 & 0x10000000L)
|
| 2576 | {
|
| 2577 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2 |= 0xf0000000L;
|
| 2578 | }
|
| 2579 | if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3 & 0x10000000L)
|
| 2580 | {
|
| 2581 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3 |= 0xf0000000L;
|
| 2582 | }
|
| 2583 |
|
| 2584 | Si3218x_audioGain_Presets[1].aceq_c0 = ((int32)
|
| 2585 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0/1000)
|
| 2586 | *coarseGainScaleTable[i].scale;
|
| 2587 | Si3218x_audioGain_Presets[1].aceq_c1 = ((int32)
|
| 2588 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1/1000)
|
| 2589 | * coarseGainScaleTable[i].scale;
|
| 2590 | Si3218x_audioGain_Presets[1].aceq_c2 = ((int32)
|
| 2591 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2/1000)
|
| 2592 | * coarseGainScaleTable[i].scale;
|
| 2593 | Si3218x_audioGain_Presets[1].aceq_c3 = ((int32)
|
| 2594 | Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3/1000)
|
| 2595 | * coarseGainScaleTable[i].scale;
|
| 2596 | }
|
| 2597 |
|
| 2598 | return errVal;
|
| 2599 | }
|
| 2600 | #endif /* ENABLE_HIRES_GAIN */
|
| 2601 |
|
| 2602 | /*
|
| 2603 | ** Function: PROSLIC_dbgSetTXGain
|
| 2604 | **
|
| 2605 | ** Description:
|
| 2606 | ** Provision function for setting up
|
| 2607 | ** TX gain
|
| 2608 | */
|
| 2609 |
|
| 2610 | int Si3218x_dbgSetTXGain (proslicChanType *pProslic, int32 gain,
|
| 2611 | int impedance_preset, int audio_gain_preset)
|
| 2612 | {
|
| 2613 | SILABS_UNREFERENCED_PARAMETER(audio_gain_preset);
|
| 2614 | #ifdef ENABLE_HIRES_GAIN
|
| 2615 | return Si3218x_dbgSetGainHiRes(pProslic,gain,impedance_preset,TXACGAIN_SEL);
|
| 2616 | #else
|
| 2617 | return Si3218x_dbgSetGain(pProslic,gain,impedance_preset,TXACGAIN_SEL);
|
| 2618 | #endif
|
| 2619 | }
|
| 2620 |
|
| 2621 | /*
|
| 2622 | ** Function: PROSLIC_dbgSetRXGain
|
| 2623 | **
|
| 2624 | ** Description:
|
| 2625 | ** Provision function for setting up
|
| 2626 | ** RX gain
|
| 2627 | */
|
| 2628 | int Si3218x_dbgSetRXGain (proslicChanType *pProslic, int32 gain,
|
| 2629 | int impedance_preset, int audio_gain_preset)
|
| 2630 | {
|
| 2631 | SILABS_UNREFERENCED_PARAMETER(audio_gain_preset);
|
| 2632 | #ifdef ENABLE_HIRES_GAIN
|
| 2633 | return Si3218x_dbgSetGainHiRes(pProslic,gain,impedance_preset,RXACGAIN_SEL);
|
| 2634 | #else
|
| 2635 | return Si3218x_dbgSetGain(pProslic,gain,impedance_preset,RXACGAIN_SEL);
|
| 2636 | #endif
|
| 2637 | }
|
| 2638 |
|
| 2639 | /*
|
| 2640 | ** Function: Si3218x_GetRAMScale
|
| 2641 | **
|
| 2642 | ** Description:
|
| 2643 | ** Read scale factor for passed RAM location
|
| 2644 | **
|
| 2645 | ** Return Value:
|
| 2646 | ** int32 scale
|
| 2647 | */
|
| 2648 | static int32 Si3218x_GetRAMScale(uInt16 addr)
|
| 2649 | {
|
| 2650 | int32 scale;
|
| 2651 |
|
| 2652 | switch(addr)
|
| 2653 | {
|
| 2654 | case SI3218X_RAM_MADC_ILOOP:
|
| 2655 | case SI3218X_RAM_MADC_ITIP:
|
| 2656 | case SI3218X_RAM_MADC_IRING:
|
| 2657 | case SI3218X_RAM_MADC_ILONG:
|
| 2658 | scale = SCALE_I_MADC;
|
| 2659 | break;
|
| 2660 |
|
| 2661 | case SI3218X_RAM_MADC_VTIPC:
|
| 2662 | case SI3218X_RAM_MADC_VRINGC:
|
| 2663 | case SI3218X_RAM_MADC_VBAT:
|
| 2664 | case SI3218X_RAM_MADC_VDC:
|
| 2665 | case SI3218X_RAM_MADC_VDC_OS:
|
| 2666 | case SI3218X_RAM_MADC_VLONG:
|
| 2667 | case SI3218X_RAM_VDIFF_SENSE:
|
| 2668 | case SI3218X_RAM_VDIFF_FILT:
|
| 2669 | case SI3218X_RAM_VDIFF_COARSE:
|
| 2670 | case SI3218X_RAM_VTIP:
|
| 2671 | case SI3218X_RAM_VRING:
|
| 2672 | scale = SCALE_V_MADC;
|
| 2673 | break;
|
| 2674 |
|
| 2675 | default:
|
| 2676 | scale = 1;
|
| 2677 | break;
|
| 2678 | }
|
| 2679 |
|
| 2680 | return scale;
|
| 2681 | }
|
| 2682 |
|
| 2683 | /*
|
| 2684 | ** Function: Si3218x_ReadMADCScaled
|
| 2685 | **
|
| 2686 | ** Description:
|
| 2687 | ** Read MADC (or other sensed voltages/currents) and
|
| 2688 | ** return scaled value in int32 format.
|
| 2689 | **
|
| 2690 | ** Return Value:
|
| 2691 | ** int32 voltage in mV or
|
| 2692 | ** int32 current in uA
|
| 2693 | */
|
| 2694 | int32 Si3218x_ReadMADCScaled(proslicChanType_ptr pProslic,uInt16 addr,
|
| 2695 | int32 scale)
|
| 2696 | {
|
| 2697 | int32 data;
|
| 2698 |
|
| 2699 | /*
|
| 2700 | ** Read 29-bit RAM and sign extend to 32-bits
|
| 2701 | */
|
| 2702 | data = ReadRAM(pProHW,pProslic->channel,addr);
|
| 2703 | if(data & 0x10000000L)
|
| 2704 | {
|
| 2705 | data |= 0xF0000000L;
|
| 2706 | }
|
| 2707 |
|
| 2708 | /*
|
| 2709 | ** Scale to provided value, or use defaults if scale = 0
|
| 2710 | */
|
| 2711 | if(scale == 0)
|
| 2712 | {
|
| 2713 | scale = Si3218x_GetRAMScale(addr);
|
| 2714 | }
|
| 2715 |
|
| 2716 | data /= scale;
|
| 2717 |
|
| 2718 | return data;
|
| 2719 | }
|
| 2720 |
|
| 2721 | /*
|
| 2722 | ** Function: Si3218x_LineMonitor
|
| 2723 | **
|
| 2724 | ** Description:
|
| 2725 | ** Monitor line voltages and currents
|
| 2726 | */
|
| 2727 | int Si3218x_LineMonitor(proslicChanType *pProslic, proslicMonitorType *monitor)
|
| 2728 | {
|
| 2729 |
|
| 2730 | if(pProslic->channelType != PROSLIC)
|
| 2731 | {
|
| 2732 | return RC_CHANNEL_TYPE_ERR;
|
| 2733 | }
|
| 2734 |
|
| 2735 | if(pProslic->channelEnable)
|
| 2736 | {
|
| 2737 | monitor->vtr = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_VDIFF_FILT);
|
| 2738 | if(monitor->vtr & 0x10000000L)
|
| 2739 | {
|
| 2740 | monitor->vtr |= 0xf0000000L;
|
| 2741 | }
|
| 2742 | monitor->vtr /= SCALE_V_MADC;
|
| 2743 |
|
| 2744 | monitor->vtip = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_VTIP);
|
| 2745 | if(monitor->vtip & 0x10000000L)
|
| 2746 | {
|
| 2747 | monitor->vtip |= 0xf0000000L;
|
| 2748 | }
|
| 2749 | monitor->vtip /= SCALE_V_MADC;
|
| 2750 |
|
| 2751 | monitor->vring = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_VRING);
|
| 2752 | if(monitor->vring & 0x10000000L)
|
| 2753 | {
|
| 2754 | monitor->vring |= 0xf0000000L;
|
| 2755 | }
|
| 2756 | monitor->vring /= SCALE_V_MADC;
|
| 2757 |
|
| 2758 | monitor->vlong = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_VLONG);
|
| 2759 | if(monitor->vlong & 0x10000000L)
|
| 2760 | {
|
| 2761 | monitor->vlong |= 0xf0000000L;
|
| 2762 | }
|
| 2763 | monitor->vlong /= SCALE_V_MADC;
|
| 2764 |
|
| 2765 | monitor->vbat = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_VBAT);
|
| 2766 | if(monitor->vbat & 0x10000000L)
|
| 2767 | {
|
| 2768 | monitor->vbat |= 0xf0000000L;
|
| 2769 | }
|
| 2770 | monitor->vbat /= SCALE_V_MADC;
|
| 2771 |
|
| 2772 | monitor->vdc = 0; /* Si3218x has no SVDC */
|
| 2773 |
|
| 2774 | monitor->itr = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_ILOOP);
|
| 2775 | if(monitor->itr & 0x10000000L)
|
| 2776 | {
|
| 2777 | monitor->itr |= 0xf0000000L;
|
| 2778 | }
|
| 2779 | monitor->itr /= SCALE_I_MADC;
|
| 2780 |
|
| 2781 | monitor->itip = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_ITIP);
|
| 2782 | if(monitor->itip & 0x10000000L)
|
| 2783 | {
|
| 2784 | monitor->itip |= 0xf0000000L;
|
| 2785 | }
|
| 2786 | monitor->itip /= SCALE_I_MADC;
|
| 2787 |
|
| 2788 | monitor->iring = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_IRING);
|
| 2789 | if(monitor->iring & 0x10000000L)
|
| 2790 | {
|
| 2791 | monitor->iring |= 0xf0000000L;
|
| 2792 | }
|
| 2793 | monitor->iring /= SCALE_I_MADC;
|
| 2794 |
|
| 2795 | monitor->ilong = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_ILONG);
|
| 2796 | if(monitor->ilong & 0x10000000L)
|
| 2797 | {
|
| 2798 | monitor->ilong |= 0xf0000000L;
|
| 2799 | }
|
| 2800 | monitor->ilong /= SCALE_I_MADC;
|
| 2801 |
|
| 2802 | monitor->p_hvic = ReadRAM(pProHW,pProslic->channel,
|
| 2803 | SI3218X_RAM_P_Q1_D); /* P_HVIC_LPF */
|
| 2804 | if(monitor->p_hvic & 0x10000000L)
|
| 2805 | {
|
| 2806 | monitor->p_hvic |= 0xf0000000L;
|
| 2807 | }
|
| 2808 | monitor->p_hvic /= SCALE_P_MADC;
|
| 2809 | }
|
| 2810 |
|
| 2811 | return RC_NONE;
|
| 2812 | }
|
| 2813 |
|
| 2814 | /*
|
| 2815 | ** Function: Si3218x_PSTNCheck
|
| 2816 | **
|
| 2817 | ** Description:
|
| 2818 | ** Continuous monitoring of longitudinal current.
|
| 2819 | ** If an average of N samples exceed avgThresh or a
|
| 2820 | ** single sample exceeds singleThresh, the linefeed
|
| 2821 | ** is forced into the open state.
|
| 2822 | **
|
| 2823 | ** This protects the port from connecting to a live
|
| 2824 | ** pstn line (faster than power alarm).
|
| 2825 | **
|
| 2826 | */
|
| 2827 | int Si3218x_PSTNCheck (proslicChanType *pProslic,
|
| 2828 | proslicPSTNCheckObjType *pPSTNCheck)
|
| 2829 | {
|
| 2830 | uInt8 i;
|
| 2831 |
|
| 2832 | if( (pProslic->channelType != PROSLIC)
|
| 2833 | || (pPSTNCheck->samples == 0) )
|
| 2834 | {
|
| 2835 | return RC_NONE; /* Ignore DAA channels */
|
| 2836 | }
|
| 2837 |
|
| 2838 | /* Adjust buffer index */
|
| 2839 | if(pPSTNCheck->count >= pPSTNCheck->samples)
|
| 2840 | {
|
| 2841 | pPSTNCheck->buffFull = TRUE;
|
| 2842 | pPSTNCheck->count = 0; /* reset buffer ptr */
|
| 2843 | }
|
| 2844 |
|
| 2845 | /* Read next sample */
|
| 2846 | pPSTNCheck->ilong[pPSTNCheck->count] = ReadRAM(pProHW,pProslic->channel,
|
| 2847 | SI3218X_RAM_MADC_ILONG);
|
| 2848 | if(pPSTNCheck->ilong[pPSTNCheck->count] & 0x10000000L)
|
| 2849 | {
|
| 2850 | pPSTNCheck->ilong[pPSTNCheck->count] |= 0xf0000000L;
|
| 2851 | }
|
| 2852 | pPSTNCheck->ilong[pPSTNCheck->count] /= SCALE_I_MADC;
|
| 2853 |
|
| 2854 | /* Monitor magnitude only */
|
| 2855 | if(pPSTNCheck->ilong[pPSTNCheck->count] < 0)
|
| 2856 | {
|
| 2857 | pPSTNCheck->ilong[pPSTNCheck->count] = -pPSTNCheck->ilong[pPSTNCheck->count];
|
| 2858 | }
|
| 2859 |
|
| 2860 | /* Quickly test for single measurement violation */
|
| 2861 | if(pPSTNCheck->ilong[pPSTNCheck->count] > pPSTNCheck->singleThresh)
|
| 2862 | {
|
| 2863 | return RC_PSTN_CHECK_SINGLE_FAIL; /* fail */
|
| 2864 | }
|
| 2865 |
|
| 2866 | /* Average once buffer is full */
|
| 2867 | if(pPSTNCheck->buffFull == TRUE)
|
| 2868 | {
|
| 2869 | pPSTNCheck->avgIlong = 0;
|
| 2870 | for(i=0; i<pPSTNCheck->samples; i++)
|
| 2871 | {
|
| 2872 | pPSTNCheck->avgIlong += pPSTNCheck->ilong[i];
|
| 2873 | }
|
| 2874 | pPSTNCheck->avgIlong /= pPSTNCheck->samples;
|
| 2875 |
|
| 2876 | if(pPSTNCheck->avgIlong > pPSTNCheck->avgThresh)
|
| 2877 | {
|
| 2878 | /* reinit obj and return fail */
|
| 2879 | pPSTNCheck->count = 0;
|
| 2880 | pPSTNCheck->buffFull = FALSE;
|
| 2881 | return RC_PSTN_CHECK_AVG_FAIL;
|
| 2882 | }
|
| 2883 | else
|
| 2884 | {
|
| 2885 | pPSTNCheck->count++;
|
| 2886 | return RC_NONE;
|
| 2887 | }
|
| 2888 | }
|
| 2889 | else
|
| 2890 | {
|
| 2891 | pPSTNCheck->count++;
|
| 2892 | return RC_NONE;
|
| 2893 | }
|
| 2894 | }
|
| 2895 |
|
| 2896 | #ifdef PSTN_DET_ENABLE
|
| 2897 | /*
|
| 2898 | ** Function: abs_int32
|
| 2899 | **
|
| 2900 | ** Description:
|
| 2901 | ** abs implementation for int32 type
|
| 2902 | */
|
| 2903 | static int32 abs_int32(int32 a)
|
| 2904 | {
|
| 2905 | if(a < 0)
|
| 2906 | {
|
| 2907 | return -1*a;
|
| 2908 | }
|
| 2909 | return a;
|
| 2910 | }
|
| 2911 |
|
| 2912 | /*
|
| 2913 | ** Function: Si3218x_DiffPSTNCheck
|
| 2914 | **
|
| 2915 | ** Description:
|
| 2916 | ** Monitor for excessive longitudinal current, which
|
| 2917 | ** would be present if a live pstn line was connected
|
| 2918 | ** to the port.
|
| 2919 | **
|
| 2920 | ** Returns:
|
| 2921 | ** RC_NONE - test in progress
|
| 2922 | ** RC_COMPLETE_NO_ERR - test complete, no alarms or errors
|
| 2923 | ** RC_POWER_ALARM_HVIC - test interrupted by HVIC power alarm
|
| 2924 | ** RC_
|
| 2925 | **
|
| 2926 | */
|
| 2927 |
|
| 2928 | int Si3218x_DiffPSTNCheck (proslicChanType *pProslic,
|
| 2929 | proslicDiffPSTNCheckObjType *pPSTNCheck)
|
| 2930 | {
|
| 2931 | uInt8 loop_status;
|
| 2932 | int i;
|
| 2933 |
|
| 2934 | if(pProslic->channelType != PROSLIC)
|
| 2935 | {
|
| 2936 | return RC_CHANNEL_TYPE_ERR; /* Ignore DAA channels */
|
| 2937 | }
|
| 2938 |
|
| 2939 |
|
| 2940 | switch(pPSTNCheck->pState.stage)
|
| 2941 | {
|
| 2942 | case 0:
|
| 2943 | /* Optional OPEN foreign voltage measurement - only execute if LCS = 0 */
|
| 2944 | /* Disable low power mode */
|
| 2945 | pPSTNCheck->enhanceRegSave = ReadReg(pProHW,pProslic->channel, PROSLIC_REG_ENHANCE);
|
| 2946 | WriteReg(pProHW,pProslic->channel, PROSLIC_REG_ENHANCE,
|
| 2947 | pPSTNCheck->enhanceRegSave&0x07); /* Disable powersave */
|
| 2948 | pPSTNCheck->vdiff1_avg = 0;
|
| 2949 | pPSTNCheck->vdiff2_avg = 0;
|
| 2950 | pPSTNCheck->iloop1_avg = 0;
|
| 2951 | pPSTNCheck->iloop2_avg = 0;
|
| 2952 | pPSTNCheck->return_status = RC_COMPLETE_NO_ERR;
|
| 2953 | /* Do OPEN state hazardous voltage measurement if enabled and ONHOOK */
|
| 2954 | Si3218x_ReadHookStatus(pProslic,&loop_status);
|
| 2955 | if((loop_status == PROSLIC_ONHOOK)&&(pPSTNCheck->femf_enable == 1))
|
| 2956 | {
|
| 2957 | pPSTNCheck->pState.stage++;
|
| 2958 | }
|
| 2959 | else
|
| 2960 | {
|
| 2961 | pPSTNCheck->pState.stage = 10;
|
| 2962 | }
|
| 2963 |
|
| 2964 | return RC_NONE;
|
| 2965 |
|
| 2966 | case 1:
|
| 2967 | /* Change linefeed to OPEN state for HAZV measurement, setup coarse sensors */
|
| 2968 | pPSTNCheck->lfstate_entry = ReadReg(pProHW,pProslic->channel, PROSLIC_REG_LINEFEED);
|
| 2969 | ProSLIC_SetLinefeedStatus(pProslic,LF_OPEN);
|
| 2970 | pPSTNCheck->pState.stage++;
|
| 2971 | return RC_NONE;
|
| 2972 |
|
| 2973 | case 2:
|
| 2974 | /* Settle */
|
| 2975 | ProSLIC_PSTN_delay_poll(&(pPSTNCheck->pState), PSTN_DET_OPEN_FEMF_SETTLE);
|
| 2976 | return RC_NONE;
|
| 2977 |
|
| 2978 | case 3:
|
| 2979 | /* Measure HAZV */
|
| 2980 | pPSTNCheck->vdiff_open = Si3218x_ReadMADCScaled(pProslic,SI3218X_RAM_VDIFF_COARSE,0);
|
| 2981 | DEBUG_PRINT(pProslic, "%sDiff PSTN : Vopen = %d mV\n", LOGPRINT_PREFIX,
|
| 2982 | pPSTNCheck->vdiff_open);
|
| 2983 |
|
| 2984 | /* Stop PSTN check if differential voltage > max_femf_vopen present */
|
| 2985 | if(abs_int32(pPSTNCheck->vdiff_open) > pPSTNCheck->max_femf_vopen)
|
| 2986 | {
|
| 2987 | pPSTNCheck->pState.stage = 70;
|
| 2988 | pPSTNCheck->return_status = RC_PSTN_OPEN_FEMF;
|
| 2989 | }
|
| 2990 | else
|
| 2991 | {
|
| 2992 | pPSTNCheck->pState.stage = 10;
|
| 2993 | }
|
| 2994 | return 0;
|
| 2995 |
|
| 2996 | case 10:
|
| 2997 | /* Load first DC feed preset */
|
| 2998 | ProSLIC_DCFeedSetup(pProslic,pPSTNCheck->dcfPreset1);
|
| 2999 | ProSLIC_SetLinefeedStatus(pProslic,LF_FWD_ACTIVE);
|
| 3000 | pPSTNCheck->pState.stage++;
|
| 3001 | return RC_NONE;
|
| 3002 |
|
| 3003 | case 11:
|
| 3004 | /* Settle */
|
| 3005 | ProSLIC_PSTN_delay_poll(&(pPSTNCheck->pState), PSTN_DET_DIFF_IV1_SETTLE);
|
| 3006 | return RC_NONE;
|
| 3007 |
|
| 3008 | case 12:
|
| 3009 | /* Measure VDIFF and ILOOP, switch to 2nd DCFEED setup */
|
| 3010 | pPSTNCheck->vdiff1[pPSTNCheck->pState.sampleIterations] =
|
| 3011 | Si3218x_ReadMADCScaled(pProslic,SI3218X_RAM_VDIFF_FILT,0);
|
| 3012 | pPSTNCheck->iloop1[pPSTNCheck->pState.sampleIterations] =
|
| 3013 | Si3218x_ReadMADCScaled(pProslic,SI3218X_RAM_MADC_ILOOP,0);
|
| 3014 | #ifdef ENABLE_DEBUG
|
| 3015 | if ( DEBUG_ENABLED(pProslic) )
|
| 3016 | {
|
| 3017 | LOGPRINT("%sDiff PSTN: Vdiff1[%d] = %d mV\n", LOGPRINT_PREFIX,
|
| 3018 | pPSTNCheck->pState.sampleIterations,
|
| 3019 | pPSTNCheck->vdiff1[pPSTNCheck->pState.sampleIterations]);
|
| 3020 | LOGPRINT("%sDiff PSTN: Iloop1[%d] = %d uA\n", LOGPRINT_PREFIX,
|
| 3021 | pPSTNCheck->pState.sampleIterations,
|
| 3022 | pPSTNCheck->iloop1[pPSTNCheck->pState.sampleIterations]);
|
| 3023 | }
|
| 3024 | #endif
|
| 3025 | pPSTNCheck->pState.sampleIterations++;
|
| 3026 | if(pPSTNCheck->pState.sampleIterations >= pPSTNCheck->samples)
|
| 3027 | {
|
| 3028 | ProSLIC_DCFeedSetup(pProslic,pPSTNCheck->dcfPreset2);
|
| 3029 | pPSTNCheck->pState.stage++;
|
| 3030 | pPSTNCheck->pState.sampleIterations = 0;
|
| 3031 | }
|
| 3032 | return RC_NONE;
|
| 3033 |
|
| 3034 | case 13:
|
| 3035 | /* Settle feed 500ms */
|
| 3036 | ProSLIC_PSTN_delay_poll(&(pPSTNCheck->pState), PSTN_DET_DIFF_IV2_SETTLE);
|
| 3037 | return RC_NONE;
|
| 3038 |
|
| 3039 | case 14:
|
| 3040 | /* Measure VDIFF and ILOOP*/
|
| 3041 | pPSTNCheck->vdiff2[pPSTNCheck->pState.sampleIterations] =
|
| 3042 | Si3218x_ReadMADCScaled(pProslic,SI3218X_RAM_VDIFF_FILT,0);
|
| 3043 | pPSTNCheck->iloop2[pPSTNCheck->pState.sampleIterations] =
|
| 3044 | Si3218x_ReadMADCScaled(pProslic,SI3218X_RAM_MADC_ILOOP,0);
|
| 3045 | #ifdef ENABLE_DEBUG
|
| 3046 | if ( DEBUG_ENABLED(pProslic) )
|
| 3047 | {
|
| 3048 | LOGPRINT("%sDiff PSTN: Vdiff2[%d] = %d mV\n", LOGPRINT_PREFIX,
|
| 3049 | pPSTNCheck->pState.sampleIterations,
|
| 3050 | pPSTNCheck->vdiff2[pPSTNCheck->pState.sampleIterations]);
|
| 3051 | LOGPRINT("%sDiff PSTN: Iloop2[%d] = %d uA\n", LOGPRINT_PREFIX,
|
| 3052 | pPSTNCheck->pState.sampleIterations,
|
| 3053 | pPSTNCheck->iloop2[pPSTNCheck->pState.sampleIterations]);
|
| 3054 | }
|
| 3055 | #endif
|
| 3056 | pPSTNCheck->pState.sampleIterations++;
|
| 3057 | if(pPSTNCheck->pState.sampleIterations >= pPSTNCheck->samples)
|
| 3058 | {
|
| 3059 | /* Compute averages */
|
| 3060 | for (i=0; i<pPSTNCheck->samples; i++)
|
| 3061 | {
|
| 3062 | pPSTNCheck->vdiff1_avg += pPSTNCheck->vdiff1[i];
|
| 3063 | pPSTNCheck->iloop1_avg += pPSTNCheck->iloop1[i];
|
| 3064 | pPSTNCheck->vdiff2_avg += pPSTNCheck->vdiff2[i];
|
| 3065 | pPSTNCheck->iloop2_avg += pPSTNCheck->iloop2[i];
|
| 3066 | }
|
| 3067 |
|
| 3068 | pPSTNCheck->vdiff1_avg /= pPSTNCheck->samples;
|
| 3069 | pPSTNCheck->iloop1_avg /= pPSTNCheck->samples;
|
| 3070 | pPSTNCheck->vdiff2_avg /= pPSTNCheck->samples;
|
| 3071 | pPSTNCheck->iloop2_avg /= pPSTNCheck->samples;
|
| 3072 |
|
| 3073 | /* Force small (probably offset) currents to minimum value */
|
| 3074 | if(abs_int32(pPSTNCheck->iloop1_avg) < PSTN_DET_MIN_ILOOP)
|
| 3075 | {
|
| 3076 | pPSTNCheck->iloop1_avg = PSTN_DET_MIN_ILOOP;
|
| 3077 | }
|
| 3078 | if(abs_int32(pPSTNCheck->iloop2_avg) < PSTN_DET_MIN_ILOOP)
|
| 3079 | {
|
| 3080 | pPSTNCheck->iloop2_avg = PSTN_DET_MIN_ILOOP;
|
| 3081 | }
|
| 3082 |
|
| 3083 | /* Calculate measured loop impedance */
|
| 3084 | pPSTNCheck->rl1 = abs_int32((
|
| 3085 | pPSTNCheck->vdiff1_avg*1000L)/pPSTNCheck->iloop1_avg);
|
| 3086 | pPSTNCheck->rl2 = abs_int32((
|
| 3087 | pPSTNCheck->vdiff2_avg*1000L)/pPSTNCheck->iloop2_avg);
|
| 3088 |
|
| 3089 | /* Force non-zero loop resistance */
|
| 3090 | if(pPSTNCheck->rl1 == 0)
|
| 3091 | {
|
| 3092 | pPSTNCheck->rl1 = 1;
|
| 3093 | }
|
| 3094 | if(pPSTNCheck->rl2 == 0)
|
| 3095 | {
|
| 3096 | pPSTNCheck->rl2 = 1;
|
| 3097 | }
|
| 3098 |
|
| 3099 | /* Qualify loop impedances */
|
| 3100 | pPSTNCheck->rl_ratio = (pPSTNCheck->rl1*1000L)/pPSTNCheck->rl2;
|
| 3101 | #ifdef ENABLE_DEBUG
|
| 3102 | if ( DEBUG_ENABLED(pProslic) )
|
| 3103 | {
|
| 3104 | const char fmt_string[] = "%sDiffPSTN: %s = %d %s\n";
|
| 3105 | LOGPRINT(fmt_string, LOGPRINT_PREFIX, "VDIFF1", pPSTNCheck->vdiff1_avg, "mV");
|
| 3106 | LOGPRINT(fmt_string, LOGPRINT_PREFIX, "ILOOP1",pPSTNCheck->iloop1_avg, "uA");
|
| 3107 | LOGPRINT(fmt_string, LOGPRINT_PREFIX, "VDIFF2",pPSTNCheck->vdiff2_avg, "mV");
|
| 3108 | LOGPRINT(fmt_string, LOGPRINT_PREFIX, "ILOOP2",pPSTNCheck->iloop2_avg, "uA");
|
| 3109 | LOGPRINT(fmt_string, LOGPRINT_PREFIX, "RL1",pPSTNCheck->rl1, "ohm");
|
| 3110 | LOGPRINT(fmt_string, LOGPRINT_PREFIX, "RL2",pPSTNCheck->rl2, "ohm");
|
| 3111 | LOGPRINT(fmt_string, LOGPRINT_PREFIX, "RL_Ratio",pPSTNCheck->rl_ratio, " ");
|
| 3112 | }
|
| 3113 | #endif
|
| 3114 |
|
| 3115 | /* Restore */
|
| 3116 | pPSTNCheck->pState.sampleIterations = 0;
|
| 3117 | pPSTNCheck->pState.stage = 70;
|
| 3118 | }
|
| 3119 | return RC_NONE;
|
| 3120 |
|
| 3121 | case 70: /* Reset test state, restore entry conditions */
|
| 3122 | ProSLIC_DCFeedSetup(pProslic,pPSTNCheck->entryDCFeedPreset);
|
| 3123 | ProSLIC_SetLinefeedStatus(pProslic,pPSTNCheck->lfstate_entry);
|
| 3124 | WriteReg(pProHW,pProslic->channel,PROSLIC_REG_ENHANCE, pPSTNCheck->enhanceRegSave);
|
| 3125 | pPSTNCheck->pState.stage = 0;
|
| 3126 | pPSTNCheck->pState.waitIterations = 0;
|
| 3127 | pPSTNCheck->pState.sampleIterations = 0;
|
| 3128 | return pPSTNCheck->return_status;
|
| 3129 |
|
| 3130 | }
|
| 3131 | return RC_NONE;
|
| 3132 | }
|
| 3133 |
|
| 3134 | #endif
|
| 3135 |
|