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