diff options
Diffstat (limited to 'api/standard.c')
-rw-r--r-- | api/standard.c | 4093 |
1 files changed, 4093 insertions, 0 deletions
diff --git a/api/standard.c b/api/standard.c new file mode 100644 index 0000000..bcbe2fc --- /dev/null +++ b/api/standard.c @@ -0,0 +1,4093 @@ +#include "standard.h" +#include "cmd.h" +#include "user.h" + + +#include "firmware.h" + +#ifndef Firmware_FORMAT_VER1 +#define Firmware_FORMAT_VER1 1 +#define Firmware_FORMAT_VER2 0 +#endif + +#if (Firmware_FORMAT_VER1 == 2) && (Firmware_FORMAT_VER2 == 0) +static Byte* Firmware_partitions = Firmware_new_partitions; +#endif + +#if (Firmware_FORMAT_VER1 > 2) || ((Firmware_FORMAT_VER1 == 2) && (Firmware_FORMAT_VER2 > 0)) +#error API version too old. Please update API version. +#endif + +#define Standard_MAX_BIT 8 +#define Standard_MAX_CLOCK 12 +#define Standard_MAX_BAND 3 + + +Byte Chip2_I2c_address = User_I2C_ADDRESS; + +const Byte Standard_bitMask[Standard_MAX_BIT] = { + 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF +}; + +const ClockTable Standard_clockTable[Standard_MAX_CLOCK] = +{ + { 20480, 20480000 }, /** FPGA */ + { 16384, 20480000 }, /** 16.38MHz */ + { 20480, 20480000 }, /** 20.48MHz */ + { 36000, 20250000 }, /** 36.00MHz */ + { 30000, 20156250 }, /** 30.00MHz */ + { 26000, 20583333 }, /** 26.00MHz */ + { 28000, 20416667 }, /** 28.00MHz */ + { 32000, 20500000 }, /** 32.00MHz */ + { 34000, 20187500 }, /** 34.00MHz */ + { 24000, 20500000 }, /** 24.00MHz */ + { 22000, 20625000 }, /** 22.00MHz */ + { 12000, 20250000 } /** 12.00MHz */ +}; + +const BandTable Standard_bandTable[Standard_MAX_BAND] = +{ + { 174000, 230000 }, /** VHF */ + { 350000, 900000 }, /** UHF */ + { 1670000, 1680000 } /** L-BAND */ +}; + +/** local functions */ + +#if User_USE_DRIVER +Dword Standard_getDriver ( + IN Demodulator* demodulator, + OUT Handle* handle +) { + Dword error = Error_NO_ERROR; + TCHAR registry1[100] = TEXT("\\Drivers\\SDCARD\\ClientDrivers\\Custom\\MANF-0296-CARDID-5347-FUNC-1"); + TCHAR registry2[100] = TEXT("\\Drivers\\SDCARD\\ClientDrivers\\Custom\\MANF-03BE-CARDID-0001-FUNC-1"); + TCHAR name[256]; + TCHAR shortBuffer[32]; + DWORD len = 16; + DWORD i; + HKEY hKey, hSubKey; + DWORD size; + + /** Open the HKLM\Drivers\Active key in registry */ + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Drivers\\Active"), 0, 0, &hKey) == ERROR_SUCCESS) { + /** Get subkeys count */ + if (RegQueryInfoKey(hKey, NULL, NULL, NULL, &i, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { + /** Browse subkeys in reverse order (pluggable cards are not at the beginning of the list !) */ + while (i) { + i--; + /** Select the subkey */ + size = sizeof(shortBuffer); + if (RegEnumKeyEx(hKey, i, shortBuffer, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { + /** Open the subkey */ + shortBuffer[sizeof(shortBuffer)-1] = '\0'; + _stprintf(name, TEXT("Drivers\\Active\\%s"), shortBuffer); + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, name, 0, 0, &hSubKey) == ERROR_SUCCESS) { + size = sizeof(name); + if (RegQueryValueEx(hSubKey, TEXT("Key"), NULL, NULL, (LPBYTE) name, &size) == ERROR_SUCCESS) { + if ((_tcsncmp(name, registry1, _tcsclen(registry1)) == 0) || (_tcsncmp(name, registry2, _tcsclen(registry2)) == 0)) { + /** This is the good PnPID, now get the serial com in the "Name" value */ + size = len; + if (RegQueryValueEx(hSubKey, TEXT("Name"), NULL, NULL, (LPBYTE) name, &size) == ERROR_SUCCESS) { + /** Found ! */ + RegCloseKey(hSubKey); + RegCloseKey(hKey); + /** OK */ + goto exit; + } + } + } + + /** Close the subkey */ + RegCloseKey(hSubKey); + } + } + } + } + } + /** Close the key */ + RegCloseKey(hKey); + +exit : + *handle = CreateFile (name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + + return (error); +} +#endif + +Dword Standard_divider ( + IN Demodulator* demodulator, + IN Dword a, + IN Dword b, + IN Dword x +) { + Dword answer = 0; + Dword c = 0; + Dword i = 0; + + if (a > b) { + c = a / b; + a = a - c * b; + } + + for (i = 0; i < x; i++) { + if (a >= b) { + answer += 1; + a-=b; + } + a <<= 1; + answer <<= 1; + } + + answer = (c << (Long) x) + answer; + + return (answer); +} + + +Dword Standard_computeCrystal ( + IN Demodulator* demodulator, + IN Long crystalFrequency, /** Crystal frequency (Hz) */ + OUT Dword* crystal +) { + Dword error = Error_NO_ERROR; + + *crystal = (Long) Standard_divider (demodulator, (Dword) crystalFrequency, 1000000ul, 19ul); + + return (error); +} + + +Dword Standard_computeAdc ( + IN Demodulator* demodulator, + IN Long adcFrequency, /** ADC frequency (Hz) */ + OUT Dword* adc +) +{ + Dword error = Error_NO_ERROR; + + *adc = (Long) Standard_divider (demodulator, (Dword) adcFrequency, 1000000ul, 19ul); + + return (error); +} + + +Dword Standard_computeFcw ( + IN Demodulator* demodulator, + IN Long adcFrequency, /** ADC frequency (Hz) */ + IN Long ifFrequency, /** IF frequency (Hz) */ + IN Bool inversion, /** RF spectrum inversion */ + OUT Dword* fcw +) { + Dword error = Error_NO_ERROR; + Long ifFreq; + Long adcFreq; + Long adcFreqHalf; + Long adcFreqSample; + Long invBfs; + Long controlWord; + Byte adcMultiplier; + + adcFreq = adcFrequency; + ifFreq = ifFrequency; + adcFreqHalf = adcFreq / 2; + + if (inversion == True) + ifFreq = -1 * ifFreq; + + adcFreqSample = ifFreq; + + if (adcFreqSample >= 0) + invBfs = 1; + else { + invBfs = -1; + adcFreqSample = adcFreqSample * -1; + } + + while (adcFreqSample > adcFreqHalf) + adcFreqSample = adcFreqSample - adcFreq; + + /** Sample, spectrum at positive frequency */ + if(adcFreqSample >= 0) + invBfs = invBfs * -1; + else { + invBfs = invBfs * 1; + adcFreqSample = adcFreqSample * (-1); /** Absolute value */ + } + + controlWord = (Long) Standard_divider (demodulator, (Dword) adcFreqSample, (Dword) adcFreq, 23ul); + + if (invBfs == -1) { + controlWord *= -1; + } + + /** Get ADC multiplier */ + error = Standard_readRegister (demodulator, 0, Processor_OFDM, adcx2, &adcMultiplier); + if (error) goto exit; + + if (adcMultiplier == 1) { + controlWord /= 2; + } + + *fcw = controlWord & 0x7FFFFF; + +exit : + return (error); +} + + +Dword Standard_programFcw ( + IN Demodulator* demodulator, + IN Byte chip, + IN Long shift, /** Hz */ + IN Dword adcFrequency /** Hz */ +) +{ + Dword error = Error_NO_ERROR; + Dword fcw; + Long fcwShift; + Byte temp0; + Byte temp1; + Byte temp2; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + /** Get shift freq */ + fcwShift = (shift * 8 * 1024 + (Long) adcFrequency / (2 * 1024)) / (Long) adcFrequency * 1024; + + fcw = (Dword) ((Long) ganymede->fcw + fcwShift); + + temp0 = (Byte) (fcw & 0x000000FF); + temp1 = (Byte) ((fcw & 0x0000FF00) >> 8); + temp2 = (Byte) ((fcw & 0x007F0000) >> 16); + + error = Standard_writeRegister (demodulator, chip, Processor_OFDM, p_reg_bfs_fcw_7_0, temp0); + if (error) goto exit; + error = Standard_writeRegister (demodulator, chip, Processor_OFDM, p_reg_bfs_fcw_15_8, temp1); + if (error) goto exit; + error = Standard_writeRegister (demodulator, chip, Processor_OFDM, p_reg_bfs_fcw_22_16, temp2); + if (error) goto exit; + +exit : + return (error); +} + + +Dword Standard_maskDcaOutput ( + IN Demodulator* demodulator +) { + Dword error = Error_NO_ERROR; + Byte i; + Bool dcaValid = False; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if ((ganymede->chipNumber > 1) && (ganymede->architecture == Architecture_DCA)) + dcaValid = True; + + if (dcaValid == True) { + for (i = 0; i < ganymede->chipNumber; i++) { + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, p_reg_dca_upper_out_en, reg_dca_upper_out_en_pos, reg_dca_upper_out_en_len, 0); + if (error) goto exit; + } + User_delay (demodulator, 5); + } + +exit : + return (error); +} + + +Dword Standard_sendCommand ( + IN Demodulator* demodulator, + OUT Word command, + IN Byte chip, + IN Processor processor, + IN Dword writeBufferLength, + IN Byte* writeBuffer, + IN Dword readBufferLength, + OUT Byte* readBuffer +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER +#else + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->cmdDescription->sendCommand != NULL) { + error = ganymede->cmdDescription->sendCommand (demodulator, command, chip, processor, writeBufferLength, writeBuffer, readBufferLength, readBuffer); + } +#endif + return (error); +} + + +Dword Standard_selectBandwidth ( + IN Demodulator* demodulator, + IN Byte chip, + IN Word bandwidth, /** KHz */ + IN Dword adcFrequency /** Hz, ex: 20480000 */ +) { + Dword error = Error_NO_ERROR; + Dword coeff1_2048Nu; + Dword coeff1_4096Nu; + Dword coeff1_8191Nu; + Dword coeff1_8192Nu; + Dword coeff1_8193Nu; + Dword coeff2_2k; + Dword coeff2_4k; + Dword coeff2_8k; + Word bfsfcw_fftindex_ratio; + Word fftindex_bfsfcw_ratio; + + Byte temp0; + Byte temp1; + Byte temp2; + Byte temp3; + Byte buffer[36]; + Byte bw; + Byte adcMultiplier; + Ganymede* ganymede; + + if (bandwidth == 5000) + bw = 3; + else if (bandwidth == 6000) + bw = 0; + else if (bandwidth == 7000) + bw = 1; + else if (bandwidth == 8000) + bw = 2; + else { + error = Error_INVALID_BW; + goto exit; + } + + ganymede = (Ganymede*) demodulator; + + error = Standard_writeRegisterBits (demodulator, chip, Processor_OFDM, g_reg_bw, reg_bw_pos, reg_bw_len, bw); + if (error) goto exit; + + /** Program CFOE */ + if (adcFrequency == 20156250) { + if (bandwidth == 5000) { + coeff1_2048Nu = 0x02449b5c; + coeff1_4096Nu = 0x01224dae; + coeff1_8191Nu = 0x00912b60; + coeff1_8192Nu = 0x009126d7; + coeff1_8193Nu = 0x0091224e; + coeff2_2k = 0x01224dae; + coeff2_4k = 0x009126d7; + coeff2_8k = 0x0048936b; + bfsfcw_fftindex_ratio = 0x0387; + fftindex_bfsfcw_ratio = 0x0122; + } else if (bandwidth == 6000) { + coeff1_2048Nu = 0x02b8ba6e; + coeff1_4096Nu = 0x015c5d37; + coeff1_8191Nu = 0x00ae340d; + coeff1_8192Nu = 0x00ae2e9b; + coeff1_8193Nu = 0x00ae292a; + coeff2_2k = 0x015c5d37; + coeff2_4k = 0x00ae2e9b; + coeff2_8k = 0x0057174e; + bfsfcw_fftindex_ratio = 0x02f1; + fftindex_bfsfcw_ratio = 0x015c; + } else if (bandwidth == 7000) { + coeff1_2048Nu = 0x032cd980; + coeff1_4096Nu = 0x01966cc0; + coeff1_8191Nu = 0x00cb3cba; + coeff1_8192Nu = 0x00cb3660; + coeff1_8193Nu = 0x00cb3007; + coeff2_2k = 0x01966cc0; + coeff2_4k = 0x00cb3660; + coeff2_8k = 0x00659b30; + bfsfcw_fftindex_ratio = 0x0285; + fftindex_bfsfcw_ratio = 0x0196; + } else if (bandwidth == 8000) { + coeff1_2048Nu = 0x03a0f893; + coeff1_4096Nu = 0x01d07c49; + coeff1_8191Nu = 0x00e84567; + coeff1_8192Nu = 0x00e83e25; + coeff1_8193Nu = 0x00e836e3; + coeff2_2k = 0x01d07c49; + coeff2_4k = 0x00e83e25; + coeff2_8k = 0x00741f12; + bfsfcw_fftindex_ratio = 0x0234; + fftindex_bfsfcw_ratio = 0x01d0; + } else { + error = Error_INVALID_BW; + goto exit; + } + } else if (adcFrequency == 20187500) { + if (bandwidth == 5000) { + coeff1_2048Nu = 0x0243b546; + coeff1_4096Nu = 0x0121daa3; + coeff1_8191Nu = 0x0090f1d9; + coeff1_8192Nu = 0x0090ed51; + coeff1_8193Nu = 0x0090e8ca; + coeff2_2k = 0x0121daa3; + coeff2_4k = 0x0090ed51; + coeff2_8k = 0x004876a9; + bfsfcw_fftindex_ratio = 0x0388; + fftindex_bfsfcw_ratio = 0x0122; + } else if (bandwidth == 6000) { + coeff1_2048Nu = 0x02b7a654; + coeff1_4096Nu = 0x015bd32a; + coeff1_8191Nu = 0x00adef04; + coeff1_8192Nu = 0x00ade995; + coeff1_8193Nu = 0x00ade426; + coeff2_2k = 0x015bd32a; + coeff2_4k = 0x00ade995; + coeff2_8k = 0x0056f4ca; + bfsfcw_fftindex_ratio = 0x02f2; + fftindex_bfsfcw_ratio = 0x015c; + } else if (bandwidth == 7000) { + coeff1_2048Nu = 0x032b9761; + coeff1_4096Nu = 0x0195cbb1; + coeff1_8191Nu = 0x00caec30; + coeff1_8192Nu = 0x00cae5d8; + coeff1_8193Nu = 0x00cadf81; + coeff2_2k = 0x0195cbb1; + coeff2_4k = 0x00cae5d8; + coeff2_8k = 0x006572ec; + bfsfcw_fftindex_ratio = 0x0286; + fftindex_bfsfcw_ratio = 0x0196; + } else if (bandwidth == 8000) { + coeff1_2048Nu = 0x039f886f; + coeff1_4096Nu = 0x01cfc438; + coeff1_8191Nu = 0x00e7e95b; + coeff1_8192Nu = 0x00e7e21c; + coeff1_8193Nu = 0x00e7dadd; + coeff2_2k = 0x01cfc438; + coeff2_4k = 0x00e7e21c; + coeff2_8k = 0x0073f10e; + bfsfcw_fftindex_ratio = 0x0235; + fftindex_bfsfcw_ratio = 0x01d0; + } else { + error = Error_INVALID_BW; + goto exit; + } + } else if (adcFrequency == 20250000) { + if (bandwidth == 5000) { + coeff1_2048Nu = 0x0241eb3b; + coeff1_4096Nu = 0x0120f59e; + coeff1_8191Nu = 0x00907f53; + coeff1_8192Nu = 0x00907acf; + coeff1_8193Nu = 0x0090764b; + coeff2_2k = 0x0120f59e; + coeff2_4k = 0x00907acf; + coeff2_8k = 0x00483d67; + bfsfcw_fftindex_ratio = 0x038b; + fftindex_bfsfcw_ratio = 0x0121; + } else if (bandwidth == 6000) { + coeff1_2048Nu = 0x02b580ad; + coeff1_4096Nu = 0x015ac057; + coeff1_8191Nu = 0x00ad6597; + coeff1_8192Nu = 0x00ad602b; + coeff1_8193Nu = 0x00ad5ac1; + coeff2_2k = 0x015ac057; + coeff2_4k = 0x00ad602b; + coeff2_8k = 0x0056b016; + bfsfcw_fftindex_ratio = 0x02f4; + fftindex_bfsfcw_ratio = 0x015b; + } else if (bandwidth == 7000) { + coeff1_2048Nu = 0x03291620; + coeff1_4096Nu = 0x01948b10; + coeff1_8191Nu = 0x00ca4bda; + coeff1_8192Nu = 0x00ca4588; + coeff1_8193Nu = 0x00ca3f36; + coeff2_2k = 0x01948b10; + coeff2_4k = 0x00ca4588; + coeff2_8k = 0x006522c4; + bfsfcw_fftindex_ratio = 0x0288; + fftindex_bfsfcw_ratio = 0x0195; + } else if (bandwidth == 8000) { + coeff1_2048Nu = 0x039cab92; + coeff1_4096Nu = 0x01ce55c9; + coeff1_8191Nu = 0x00e7321e; + coeff1_8192Nu = 0x00e72ae4; + coeff1_8193Nu = 0x00e723ab; + coeff2_2k = 0x01ce55c9; + coeff2_4k = 0x00e72ae4; + coeff2_8k = 0x00739572; + bfsfcw_fftindex_ratio = 0x0237; + fftindex_bfsfcw_ratio = 0x01ce; + } else { + error = Error_INVALID_BW; + goto exit; + } + } else if (adcFrequency == 20583333) { + if (bandwidth == 5000) { + coeff1_2048Nu = 0x02388f54; + coeff1_4096Nu = 0x011c47aa; + coeff1_8191Nu = 0x008e2846; + coeff1_8192Nu = 0x008e23d5; + coeff1_8193Nu = 0x008e1f64; + coeff2_2k = 0x011c47aa; + coeff2_4k = 0x008e23d5; + coeff2_8k = 0x004711ea; + bfsfcw_fftindex_ratio = 0x039a; + fftindex_bfsfcw_ratio = 0x011c; + } else if (bandwidth == 6000) { + coeff1_2048Nu = 0x02aa4598; + coeff1_4096Nu = 0x015522cc; + coeff1_8191Nu = 0x00aa96bb; + coeff1_8192Nu = 0x00aa9166; + coeff1_8193Nu = 0x00aa8c12; + coeff2_2k = 0x015522cc; + coeff2_4k = 0x00aa9166; + coeff2_8k = 0x005548b3; + bfsfcw_fftindex_ratio = 0x0300; + fftindex_bfsfcw_ratio = 0x0155; + } else if (bandwidth == 7000) { + coeff1_2048Nu = 0x031bfbdc; + coeff1_4096Nu = 0x018dfdee; + coeff1_8191Nu = 0x00c7052f; + coeff1_8192Nu = 0x00c6fef7; + coeff1_8193Nu = 0x00c6f8bf; + coeff2_2k = 0x018dfdee; + coeff2_4k = 0x00c6fef7; + coeff2_8k = 0x00637f7b; + bfsfcw_fftindex_ratio = 0x0293; + fftindex_bfsfcw_ratio = 0x018e; + } else if (bandwidth == 8000) { + coeff1_2048Nu = 0x038db21f; + coeff1_4096Nu = 0x01c6d910; + coeff1_8191Nu = 0x00e373a3; + coeff1_8192Nu = 0x00e36c88; + coeff1_8193Nu = 0x00e3656d; + coeff2_2k = 0x01c6d910; + coeff2_4k = 0x00e36c88; + coeff2_8k = 0x0071b644; + bfsfcw_fftindex_ratio = 0x0240; + fftindex_bfsfcw_ratio = 0x01c7; + } else { + error = Error_INVALID_BW; + goto exit; + } + } else if (adcFrequency == 20416667) { + if (bandwidth == 5000) { + coeff1_2048Nu = 0x023d337f; + coeff1_4096Nu = 0x011e99c0; + coeff1_8191Nu = 0x008f515a; + coeff1_8192Nu = 0x008f4ce0; + coeff1_8193Nu = 0x008f4865; + coeff2_2k = 0x011e99c0; + coeff2_4k = 0x008f4ce0; + coeff2_8k = 0x0047a670; + bfsfcw_fftindex_ratio = 0x0393; + fftindex_bfsfcw_ratio = 0x011f; + } else if (bandwidth == 6000) { + coeff1_2048Nu = 0x02afd765; + coeff1_4096Nu = 0x0157ebb3; + coeff1_8191Nu = 0x00abfb39; + coeff1_8192Nu = 0x00abf5d9; + coeff1_8193Nu = 0x00abf07a; + coeff2_2k = 0x0157ebb3; + coeff2_4k = 0x00abf5d9; + coeff2_8k = 0x0055faed; + bfsfcw_fftindex_ratio = 0x02fa; + fftindex_bfsfcw_ratio = 0x0158; + } else if (bandwidth == 7000) { + coeff1_2048Nu = 0x03227b4b; + coeff1_4096Nu = 0x01913da6; + coeff1_8191Nu = 0x00c8a518; + coeff1_8192Nu = 0x00c89ed3; + coeff1_8193Nu = 0x00c8988e; + coeff2_2k = 0x01913da6; + coeff2_4k = 0x00c89ed3; + coeff2_8k = 0x00644f69; + bfsfcw_fftindex_ratio = 0x028d; + fftindex_bfsfcw_ratio = 0x0191; + } else if (bandwidth == 8000) { + coeff1_2048Nu = 0x03951f32; + coeff1_4096Nu = 0x01ca8f99; + coeff1_8191Nu = 0x00e54ef7; + coeff1_8192Nu = 0x00e547cc; + coeff1_8193Nu = 0x00e540a2; + coeff2_2k = 0x01ca8f99; + coeff2_4k = 0x00e547cc; + coeff2_8k = 0x0072a3e6; + bfsfcw_fftindex_ratio = 0x023c; + fftindex_bfsfcw_ratio = 0x01cb; + } else { + error = Error_INVALID_BW; + goto exit; + } + } else if (adcFrequency == 20480000) { + if (bandwidth == 5000) { + coeff1_2048Nu = 0x023b6db7; + coeff1_4096Nu = 0x011db6db; + coeff1_8191Nu = 0x008edfe5; + coeff1_8192Nu = 0x008edb6e; + coeff1_8193Nu = 0x008ed6f7; + coeff2_2k = 0x011db6db; + coeff2_4k = 0x008edb6e; + coeff2_8k = 0x00476db7; + bfsfcw_fftindex_ratio = 0x0396; + fftindex_bfsfcw_ratio = 0x011e; + } else if (bandwidth == 6000) { + coeff1_2048Nu = 0x02adb6db; + coeff1_4096Nu = 0x0156db6e; + coeff1_8191Nu = 0x00ab7312; + coeff1_8192Nu = 0x00ab6db7; + coeff1_8193Nu = 0x00ab685c; + coeff2_2k = 0x0156db6e; + coeff2_4k = 0x00ab6db7; + coeff2_8k = 0x0055b6db; + bfsfcw_fftindex_ratio = 0x02fd; + fftindex_bfsfcw_ratio = 0x0157; + } else if (bandwidth == 7000) { + coeff1_2048Nu = 0x03200000; + coeff1_4096Nu = 0x01900000; + coeff1_8191Nu = 0x00c80640; + coeff1_8192Nu = 0x00c80000; + coeff1_8193Nu = 0x00c7f9c0; + coeff2_2k = 0x01900000; + coeff2_4k = 0x00c80000; + coeff2_8k = 0x00640000; + bfsfcw_fftindex_ratio = 0x028f; + fftindex_bfsfcw_ratio = 0x0190; + } else if (bandwidth == 8000) { + coeff1_2048Nu = 0x03924925; + coeff1_4096Nu = 0x01c92492; + coeff1_8191Nu = 0x00e4996e; + coeff1_8192Nu = 0x00e49249; + coeff1_8193Nu = 0x00e48b25; + coeff2_2k = 0x01c92492; + coeff2_4k = 0x00e49249; + coeff2_8k = 0x00724925; + bfsfcw_fftindex_ratio = 0x023d; + fftindex_bfsfcw_ratio = 0x01c9; + } else { + error = Error_INVALID_BW; + goto exit; + } + } else if (adcFrequency == 20500000) { + if (bandwidth == 5000) { + coeff1_2048Nu = 0x023adeff; + coeff1_4096Nu = 0x011d6f80; + coeff1_8191Nu = 0x008ebc36; + coeff1_8192Nu = 0x008eb7c0; + coeff1_8193Nu = 0x008eb34a; + coeff2_2k = 0x011d6f80; + coeff2_4k = 0x008eb7c0; + coeff2_8k = 0x00475be0; + bfsfcw_fftindex_ratio = 0x0396; + fftindex_bfsfcw_ratio = 0x011d; + } else if (bandwidth == 6000) { + coeff1_2048Nu = 0x02ad0b99; + coeff1_4096Nu = 0x015685cc; + coeff1_8191Nu = 0x00ab4840; + coeff1_8192Nu = 0x00ab42e6; + coeff1_8193Nu = 0x00ab3d8c; + coeff2_2k = 0x015685cc; + coeff2_4k = 0x00ab42e6; + coeff2_8k = 0x0055a173; + bfsfcw_fftindex_ratio = 0x02fd; + fftindex_bfsfcw_ratio = 0x0157; + } else if (bandwidth == 7000) { + coeff1_2048Nu = 0x031f3832; + coeff1_4096Nu = 0x018f9c19; + coeff1_8191Nu = 0x00c7d44b; + coeff1_8192Nu = 0x00c7ce0c; + coeff1_8193Nu = 0x00c7c7ce; + coeff2_2k = 0x018f9c19; + coeff2_4k = 0x00c7ce0c; + coeff2_8k = 0x0063e706; + bfsfcw_fftindex_ratio = 0x0290; + fftindex_bfsfcw_ratio = 0x0190; + } else if (bandwidth == 8000) { + coeff1_2048Nu = 0x039164cb; + coeff1_4096Nu = 0x01c8b266; + coeff1_8191Nu = 0x00e46056; + coeff1_8192Nu = 0x00e45933; + coeff1_8193Nu = 0x00e45210; + coeff2_2k = 0x01c8b266; + coeff2_4k = 0x00e45933; + coeff2_8k = 0x00722c99; + bfsfcw_fftindex_ratio = 0x023e; + fftindex_bfsfcw_ratio = 0x01c9; + } else { + error = Error_INVALID_BW; + goto exit; + } + } else if (adcFrequency == 20625000) { + if (bandwidth == 5000) { + coeff1_2048Nu = 0x02376948; + coeff1_4096Nu = 0x011bb4a4; + coeff1_8191Nu = 0x008ddec1; + coeff1_8192Nu = 0x008dda52; + coeff1_8193Nu = 0x008dd5e3; + coeff2_2k = 0x011bb4a4; + coeff2_4k = 0x008dda52; + coeff2_8k = 0x0046ed29; + bfsfcw_fftindex_ratio = 0x039c; + fftindex_bfsfcw_ratio = 0x011c; + } else if (bandwidth == 6000) { + coeff1_2048Nu = 0x02a8e4bd; + coeff1_4096Nu = 0x0154725e; + coeff1_8191Nu = 0x00aa3e81; + coeff1_8192Nu = 0x00aa392f; + coeff1_8193Nu = 0x00aa33de; + coeff2_2k = 0x0154725e; + coeff2_4k = 0x00aa392f; + coeff2_8k = 0x00551c98; + bfsfcw_fftindex_ratio = 0x0302; + fftindex_bfsfcw_ratio = 0x0154; + } else if (bandwidth == 7000) { + coeff1_2048Nu = 0x031a6032; + coeff1_4096Nu = 0x018d3019; + coeff1_8191Nu = 0x00c69e41; + coeff1_8192Nu = 0x00c6980c; + coeff1_8193Nu = 0x00c691d8; + coeff2_2k = 0x018d3019; + coeff2_4k = 0x00c6980c; + coeff2_8k = 0x00634c06; + bfsfcw_fftindex_ratio = 0x0294; + fftindex_bfsfcw_ratio = 0x018d; + } else if (bandwidth == 8000) { + coeff1_2048Nu = 0x038bdba6; + coeff1_4096Nu = 0x01c5edd3; + coeff1_8191Nu = 0x00e2fe02; + coeff1_8192Nu = 0x00e2f6ea; + coeff1_8193Nu = 0x00e2efd2; + coeff2_2k = 0x01c5edd3; + coeff2_4k = 0x00e2f6ea; + coeff2_8k = 0x00717b75; + bfsfcw_fftindex_ratio = 0x0242; + fftindex_bfsfcw_ratio = 0x01c6; + } else { + error = Error_INVALID_BW; + goto exit; + } + } else { + error = Error_INVALID_XTAL_FREQ; + goto exit; + } + + + /** Get ADC multiplier */ + error = Standard_readRegister (demodulator, 0, Processor_OFDM, adcx2, &adcMultiplier); + if (error) goto exit; + + if (adcMultiplier == 1) { + coeff1_2048Nu /= 2; + coeff1_4096Nu /= 2; + coeff1_8191Nu /= 2; + coeff1_8192Nu /= 2; + coeff1_8193Nu /= 2 ; + coeff2_2k /= 2; + coeff2_4k /= 2; + coeff2_8k /= 2; + } + + /** Write coeff1_2048Nu */ + /** Get Byte0 */ + temp0 = (Byte) (coeff1_2048Nu & 0x000000FF); + /** Get Byte1 */ + temp1 = (Byte) ((coeff1_2048Nu & 0x0000FF00) >> 8); + /** Get Byte2 */ + temp2 = (Byte) ((coeff1_2048Nu & 0x00FF0000) >> 16); + /** Get Byte3 */ + temp3 = (Byte) ((coeff1_2048Nu & 0x03000000) >> 24); + + /** Gig endian to make 8051 happy */ + buffer[cfoe_NS_2048_coeff1_25_24 - cfoe_NS_2048_coeff1_25_24] = temp3; + buffer[cfoe_NS_2048_coeff1_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2; + buffer[cfoe_NS_2048_coeff1_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1; + buffer[cfoe_NS_2048_coeff1_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0; + + /** Write coeff2_2k */ + /** Get Byte0 */ + temp0 = (Byte) ((coeff2_2k & 0x000000FF)); + /** Get Byte1 */ + temp1 = (Byte) ((coeff2_2k & 0x0000FF00) >> 8); + /** Get Byte2 */ + temp2 = (Byte) ((coeff2_2k & 0x00FF0000) >> 16); + /** Get Byte3 */ + temp3 = (Byte) ((coeff2_2k & 0x01000000) >> 24); + + /** Gig endian to make 8051 happy */ + buffer[cfoe_NS_2k_coeff2_24 - cfoe_NS_2048_coeff1_25_24] = temp3; + buffer[cfoe_NS_2k_coeff2_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2; + buffer[cfoe_NS_2k_coeff2_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1; + buffer[cfoe_NS_2k_coeff2_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0; + + /** Write coeff1_8191Nu */ + /** Get Byte0 */ + temp0 = (Byte) ((coeff1_8191Nu & 0x000000FF)); + /** Get Byte1 */ + temp1 = (Byte) ((coeff1_8191Nu & 0x0000FF00) >> 8); + /** Get Byte2 */ + temp2 = (Byte) ((coeff1_8191Nu & 0x00FFC000) >> 16); + /** Get Byte3 */ + temp3 = (Byte) ((coeff1_8191Nu & 0x03000000) >> 24); + + /** Big endian to make 8051 happy */ + buffer[cfoe_NS_8191_coeff1_25_24 - cfoe_NS_2048_coeff1_25_24] = temp3; + buffer[cfoe_NS_8191_coeff1_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2; + buffer[cfoe_NS_8191_coeff1_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1; + buffer[cfoe_NS_8191_coeff1_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0; + + /** Write coeff1_8192Nu */ + /** Get Byte0 */ + temp0 = (Byte) (coeff1_8192Nu & 0x000000FF); + /** Get Byte1 */ + temp1 = (Byte) ((coeff1_8192Nu & 0x0000FF00) >> 8); + /** Get Byte2 */ + temp2 = (Byte) ((coeff1_8192Nu & 0x00FFC000) >> 16); + /** Get Byte3 */ + temp3 = (Byte) ((coeff1_8192Nu & 0x03000000) >> 24); + + /** Gig endian to make 8051 happy */ + buffer[cfoe_NS_8192_coeff1_25_24 - cfoe_NS_2048_coeff1_25_24] = temp3; + buffer[cfoe_NS_8192_coeff1_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2; + buffer[cfoe_NS_8192_coeff1_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1; + buffer[cfoe_NS_8192_coeff1_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0; + + /** Write coeff1_8193Nu */ + /** Get Byte0 */ + temp0 = (Byte) ((coeff1_8193Nu & 0x000000FF)); + /** Get Byte1 */ + temp1 = (Byte) ((coeff1_8193Nu & 0x0000FF00) >> 8); + /** Get Byte2 */ + temp2 = (Byte) ((coeff1_8193Nu & 0x00FFC000) >> 16); + /** Get Byte3 */ + temp3 = (Byte) ((coeff1_8193Nu & 0x03000000) >> 24); + + /** Big endian to make 8051 happy */ + buffer[cfoe_NS_8193_coeff1_25_24 - cfoe_NS_2048_coeff1_25_24] = temp3; + buffer[cfoe_NS_8193_coeff1_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2; + buffer[cfoe_NS_8193_coeff1_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1; + buffer[cfoe_NS_8193_coeff1_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0; + + /** Write coeff2_8k */ + /** Get Byte0 */ + temp0 = (Byte) ((coeff2_8k & 0x000000FF)); + /** Get Byte1 */ + temp1 = (Byte) ((coeff2_8k & 0x0000FF00) >> 8); + /** Get Byte2 */ + temp2 = (Byte) ((coeff2_8k & 0x00FF0000) >> 16); + /** Get Byte3 */ + temp3 = (Byte) ((coeff2_8k & 0x01000000) >> 24); + + /** Big endian to make 8051 happy */ + buffer[cfoe_NS_8k_coeff2_24 - cfoe_NS_2048_coeff1_25_24] = temp3; + buffer[cfoe_NS_8k_coeff2_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2; + buffer[cfoe_NS_8k_coeff2_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1; + buffer[cfoe_NS_8k_coeff2_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0; + + /** Write coeff1_4096Nu */ + /** Get Byte0 */ + temp0 = (Byte) (coeff1_4096Nu & 0x000000FF); + /** Get Byte1 */ + temp1 = (Byte) ((coeff1_4096Nu & 0x0000FF00) >> 8); + /** Get Byte2 */ + temp2 = (Byte) ((coeff1_4096Nu & 0x00FF0000) >> 16); + /** Get Byte3[1:0] */ + /** Bit[7:2] will be written soon and so don't have to care them */ + temp3 = (Byte) ((coeff1_4096Nu & 0x03000000) >> 24); + + /** Big endian to make 8051 happy */ + buffer[cfoe_NS_4096_coeff1_25_24 - cfoe_NS_2048_coeff1_25_24] = temp3; + buffer[cfoe_NS_4096_coeff1_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2; + buffer[cfoe_NS_4096_coeff1_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1; + buffer[cfoe_NS_4096_coeff1_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0; + + /** Write coeff2_4k */ + /** Get Byte0 */ + temp0 = (Byte) ((coeff2_4k & 0x000000FF)); + /** Get Byte1 */ + temp1 = (Byte) ((coeff2_4k & 0x0000FF00) >> 8); + /** Get Byte2 */ + temp2 = (Byte) ((coeff2_4k & 0x00FF0000) >> 16); + /** Get Byte3 */ + temp3 = (Byte) ((coeff2_4k & 0x01000000) >> 24); + + /** Big endian to make 8051 happy */ + buffer[cfoe_NS_4k_coeff2_24 - cfoe_NS_2048_coeff1_25_24] = temp3; + buffer[cfoe_NS_4k_coeff2_23_16 - cfoe_NS_2048_coeff1_25_24] = temp2; + buffer[cfoe_NS_4k_coeff2_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1; + buffer[cfoe_NS_4k_coeff2_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0; + + /** Get Byte0 */ + temp0 = (Byte) (bfsfcw_fftindex_ratio & 0x00FF); + /** Get Byte1 */ + temp1 = (Byte) ((bfsfcw_fftindex_ratio & 0xFF00) >> 8); + + /** Big endian to make 8051 happy */ + buffer[bfsfcw_fftindex_ratio_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1; + buffer[bfsfcw_fftindex_ratio_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0; + + /** Get Byte0 */ + temp0 = (Byte) (fftindex_bfsfcw_ratio & 0x00FF); + /** Get Byte1 */ + temp1 = (Byte) ((fftindex_bfsfcw_ratio & 0xFF00) >> 8); + + /** Big endian to make 8051 happy */ + buffer[fftindex_bfsfcw_ratio_15_8 - cfoe_NS_2048_coeff1_25_24] = temp1; + buffer[fftindex_bfsfcw_ratio_7_0 - cfoe_NS_2048_coeff1_25_24] = temp0; + + error = Standard_writeRegisters (demodulator, chip, Processor_OFDM, cfoe_NS_2048_coeff1_25_24, 36, buffer); + if (error) goto exit; + +exit : + return (error); +} + + +Dword Standard_setFrequency ( + IN Demodulator* demodulator, + IN Byte chip, + IN Dword frequency +) { + Dword error = Error_NO_ERROR; + Byte band; + Byte i; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + /** Clear easy mode flag first */ + error = Standard_writeRegister (demodulator, chip, Processor_OFDM, Training_Mode, 0x00); + if (error) goto exit; + + /** Clear empty_channel_status lock flag */ + error = Standard_writeRegister (demodulator, chip, Processor_OFDM, empty_channel_status, 0x00); + if (error) goto exit; + + /** Clear MPEG2 lock flag */ + error = Standard_writeRegisterBits (demodulator, chip, Processor_OFDM, r_mp2if_sync_byte_locked, mp2if_sync_byte_locked_pos, mp2if_sync_byte_locked_len, 0x00); + if (error) goto exit; + + /** Determine frequency band */ + band = 0xFF; + for (i = 0; i < Standard_MAX_BAND; i++) { + if ((frequency >= Standard_bandTable[i].minimum) && (frequency <= Standard_bandTable[i].maximum)) { + band = i; + break; + } + } + error = Standard_writeRegister (demodulator, chip, Processor_OFDM, FreBand, band); + if (error) goto exit; + + if (ganymede->tunerDescription->setTuner != NULL) { + if ((ganymede->busId != Bus_I2M) && (ganymede->busId != Bus_I2U)) { + if (ganymede->chipNumber > 1 && chip == 0) { + error = ganymede->tunerDescription->setTuner (demodulator, chip, ganymede->bandwidth[chip], frequency + 100); + if (error) goto exit; + } else if (ganymede->chipNumber > 1 && chip == 1) { + error = ganymede->tunerDescription->setTuner (demodulator, chip, ganymede->bandwidth[chip], frequency - 100); + if (error) goto exit; + } else { + error = ganymede->tunerDescription->setTuner (demodulator, chip, ganymede->bandwidth[chip], frequency); + if (error) goto exit; + } + } + } + + /** Trigger ofsm */ + error = Standard_writeRegister (demodulator, chip, Processor_OFDM, trigger_ofsm, 0); + if (error) goto exit; + + ganymede->frequency[chip] = frequency; + +exit : + return (error); +} + + +Dword Standard_loadFirmware ( + IN Demodulator* demodulator, + IN Byte* firmwareCodes, + IN Segment* firmwareSegments, + IN Byte* firmwarePartitions +) { + Dword error = Error_NO_ERROR; + Dword beginPartition; + Dword endPartition; + Dword version; + Dword firmwareLength; + Byte* firmwareCodesPointer; + Word command; + Dword i; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + /** Set I2C master clock speed. */ + error = Standard_writeRegister (demodulator, 0, Processor_LINK, p_reg_one_cycle_counter_tuner, User_I2C_SPEED); + if (error) goto exit; + + firmwareCodesPointer = firmwareCodes; + + if ((ganymede->tunerDescription->tunerId == 0x23 || ganymede->tunerDescription->tunerId == 0x2D) && + firmwarePartitions[0] == firmwarePartitions[1]) { + beginPartition = firmwarePartitions[0]; + endPartition = firmwarePartitions[0] + firmwarePartitions[1]; + + for (i = 0; i < beginPartition; i++) { + firmwareLength = firmwareSegments[i].segmentLength; + firmwareCodesPointer += firmwareLength; + } + } else { + beginPartition = 0; + endPartition = firmwarePartitions[0]; + } + + for (i = beginPartition; i < endPartition; i++) { + firmwareLength = firmwareSegments[i].segmentLength; + if (firmwareSegments[i].segmentType == 0) { + /** Dwonload firmware */ + error = Standard_sendCommand (demodulator, Command_FW_DOWNLOAD_BEGIN, 0, Processor_LINK, 0, NULL, 0, NULL); + if (error) goto exit; + if (ganymede->cmdDescription->loadFirmware != NULL) { + error = ganymede->cmdDescription->loadFirmware (demodulator, firmwareLength, firmwareCodesPointer); + } + if (error) goto exit; + error = Standard_sendCommand (demodulator, Command_FW_DOWNLOAD_END, 0, Processor_LINK, 0, NULL, 0, NULL); + if (error) goto exit; + } else if (firmwareSegments[i].segmentType == 1) { + /** Copy firmware */ + error = Standard_sendCommand (demodulator, Command_SCATTER_WRITE, 0, Processor_LINK, firmwareLength, firmwareCodesPointer, 0, NULL); + if (error) goto exit; + } else { + /** Direct write firmware */ + command = (Word) (firmwareCodesPointer[0] << 8) + (Word) firmwareCodesPointer[1]; + error = Standard_sendCommand (demodulator, command, 0, Processor_LINK, firmwareLength - 2, firmwareCodesPointer + 2, 0, NULL); + if (error) goto exit; + } + firmwareCodesPointer += firmwareLength; + } + + /** Boot */ + error = Standard_sendCommand (demodulator, Command_BOOT, 0, Processor_LINK, 0, NULL, 0, NULL); + if (error) goto exit; + + User_delay (demodulator, 10); + + /** Check if firmware is running */ + version = 0; + error = Standard_getFirmwareVersion (demodulator, Processor_LINK, &version); + if (error) goto exit; + if (version == 0) + error = Error_BOOT_FAIL; + +exit : + return (error); +} + + +Dword Standard_loadScript ( + IN Demodulator* demodulator, + IN StreamType streamType, + IN Word* scriptSets, + IN ValueSet* scripts, + IN Word* tunerScriptSets, + IN ValueSet* tunerScripts +) { + Dword error = Error_NO_ERROR; + Word beginScript; + Word endScript; + Byte i, value1 = 0, value2 = 0, supportRelay = 0, chipNumber = 0, bufferLens = 1; + Word j; + Byte buffer[20] = {0,}; + Dword tunerAddr, tunerAddrTemp; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + + /** Querry SupportRelayCommandWrite **/ + error = Standard_readRegister (demodulator, 0, Processor_OFDM, 0x004D, &supportRelay); + if (error) goto exit; + + if (supportRelay && ganymede->chipNumber == 2) + chipNumber = 1; + else + chipNumber = ganymede->chipNumber; + + /** Enable RelayCommandWrite **/ + if (supportRelay) { + error = Standard_writeRegister (demodulator, 0, Processor_OFDM, 0x004E, 1); + if (error) goto exit; + } + + if ((scriptSets[0] != 0) && (scripts != NULL)) { + beginScript = 0; + endScript = scriptSets[0]; + + for (i = 0; i < chipNumber; i++) { + /** Load OFSM init script */ + for (j = beginScript; j < endScript; j++) { + tunerAddr = tunerAddrTemp = scripts[j].address; + buffer[0] = scripts[j].value; + + while (j < endScript && bufferLens < 20) { + tunerAddrTemp += 1; + if (tunerAddrTemp != scripts[j+1].address) + break; + + buffer[bufferLens] = scripts[j+1].value; + bufferLens ++; + j ++; + } + + error = Standard_writeRegisters (demodulator, i, Processor_OFDM, tunerAddr, bufferLens, buffer); + if (error) goto exit; + bufferLens = 1; + } + } + } + + + /** Distinguish chip type */ + error = Standard_readRegister (demodulator, 0, Processor_LINK, 0x1222, &value1); + if (error) goto exit; + + error = Standard_readRegister (demodulator, 0, Processor_LINK, 0x384F, &value2); + if (error) goto exit; + + if ((tunerScriptSets[0] != 0) && (tunerScripts != NULL)) { + if (tunerScriptSets[1] == tunerScriptSets[0] && !(value1 == 0xF8 && value2 == 0xEA)) { + beginScript = tunerScriptSets[0]; + endScript = tunerScriptSets[0] + tunerScriptSets[1]; + } else { + beginScript = 0; + endScript = tunerScriptSets[0]; + } + + for (i = 0; i < chipNumber; i++) { + /** Load tuner init script */ + for (j = beginScript; j < endScript; j++) { + tunerAddr = tunerAddrTemp = tunerScripts[j].address; + buffer[0] = tunerScripts[j].value; + + while (j < endScript && bufferLens < 20) { + tunerAddrTemp += 1; + if (tunerAddrTemp != tunerScripts[j+1].address) + break; + + buffer[bufferLens] = tunerScripts[j+1].value; + bufferLens ++; + j ++; + } + + error = Standard_writeRegisters (demodulator, i, Processor_OFDM, tunerAddr, bufferLens, buffer); + if (error) goto exit; + bufferLens = 1; + } + } + } + + /** Disable RelayCommandWrite **/ + if (supportRelay) { + error = Standard_writeRegister (demodulator, 0, Processor_OFDM, 0x004E, 0); + if (error) goto exit; + } + +exit : + return (error); +} + +/** end of local functions */ + +Dword Standard_writeRegister ( + IN Demodulator* demodulator, + IN Byte chip, + IN Processor processor, + IN Dword registerAddress, + IN Byte value +) { + return (Standard_writeRegisters (demodulator, chip, processor, registerAddress, 1, &value)); +} + + +Dword Standard_writeRegisters ( + IN Demodulator* demodulator, + IN Byte chip, + IN Processor processor, + IN Dword registerAddress, + IN Byte bufferLength, + IN Byte* buffer +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + WriteRegistersRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.chip = chip; + request.processor = processor; + request.registerAddress = registerAddress; + request.bufferLength = bufferLength; + User_memoryCopy (demodulator, request.buffer, buffer, bufferLength); + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_WRITEREGISTERS, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Byte registerAddressLength; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (processor == Processor_LINK) { + if (registerAddress > 0x000000FF) { + registerAddressLength = 2; + } else { + registerAddressLength = 1; + } + } else { + registerAddressLength = 2; + } + if (ganymede->cmdDescription->writeRegisters != NULL) { + error = ganymede->cmdDescription->writeRegisters (demodulator, chip, processor, registerAddress, registerAddressLength, bufferLength, buffer); + } +#endif + + return (error); +} + + +Dword Standard_writeTunerRegisters ( + IN Demodulator* demodulator, + IN Byte chip, + IN Word registerAddress, + IN Byte bufferLength, + IN Byte* buffer +) { + Dword error = Error_NO_ERROR; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->cmdDescription->writeTunerRegisters != NULL) { + error = ganymede->cmdDescription->writeTunerRegisters (demodulator, chip, ganymede->tunerDescription->tunerAddress, registerAddress, ganymede->tunerDescription->registerAddressLength, bufferLength, buffer); + } + return (error); +} + + +Dword Standard_writeGenericRegisters ( + IN Demodulator* demodulator, + IN Byte chip, + IN Byte interfaceIndex, + IN Byte slaveAddress, + IN Byte bufferLength, + IN Byte* buffer +) { + Byte writeBuffer[256]; + Byte i; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + writeBuffer[0] = bufferLength; + writeBuffer[1] = interfaceIndex; + writeBuffer[2] = slaveAddress; + + for (i = 0; i < bufferLength; i++) { + writeBuffer[3 + i] = buffer[i]; + } + return (Standard_sendCommand (demodulator, Command_GENERIC_WRITE, chip, Processor_LINK, bufferLength + 3, writeBuffer, 0, NULL)); +} + + +Dword Standard_writeEepromValues ( + IN Demodulator* demodulator, + IN Byte chip, + IN Word registerAddress, + IN Byte bufferLength, + IN Byte* buffer +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + WriteEepromValuesRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.chip = chip; + request.registerAddress = registerAddress; + request.bufferLength = bufferLength; + User_memoryCopy (demodulator, request.buffer, buffer, bufferLength); + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_WRITEEEPROMVALUES, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Byte eepromAddress; + Byte registerAddressLength; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + /** Read EEPROM address. */ + /*error = ganymede->cmdDescription.readRegisters (demodulator, chip, Processor_LINK, 0xBFF0, 1, &eepromAddress); + if (error) goto exit; + */ + eepromAddress = 0x01; + + /** Read EEPROM valid length of register. */ + /*error = ganymede->cmdDescription.readRegisters (demodulator, chip, Processor_LINK, 0xBFF1, 1, ®isterAddressLength); + if (error) goto exit; + */ + registerAddressLength = 0x01; + + if (ganymede->cmdDescription->writeEepromValues != NULL) { + error = ganymede->cmdDescription->writeEepromValues (demodulator, chip, eepromAddress, registerAddress, registerAddressLength, bufferLength, buffer); + } + +#endif + + return (error); +} + + +Dword Standard_writeRegisterBits ( + IN Demodulator* demodulator, + IN Byte chip, + IN Processor processor, + IN Dword registerAddress, + IN Byte position, + IN Byte length, + IN Byte value +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + WriteRegisterBitsRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.chip = chip; + request.processor = processor; + request.registerAddress = registerAddress; + request.position = position; + request.length = length; + request.value = value; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_WRITEREGISTERBITS, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Byte registerAddressLength; + Ganymede* ganymede; + Byte temp; + + ganymede = (Ganymede*) demodulator; + + if (processor == Processor_LINK) { + if (registerAddress > 0x000000FF) { + registerAddressLength = 2; + } else { + registerAddressLength = 1; + } + } else { + registerAddressLength = 2; + } + if (length == 8) { + if (ganymede->cmdDescription->writeRegisters != NULL) { + error = ganymede->cmdDescription->writeRegisters (demodulator, chip, processor, registerAddress, registerAddressLength, 1, &value); + } + } else { + if (ganymede->cmdDescription->readRegisters != NULL) { + error = ganymede->cmdDescription->readRegisters (demodulator, chip, processor, registerAddress, registerAddressLength, 1, &temp); + if (error) goto exit; + } + + temp = REG_CREATE (value, temp, position, length); + + if (ganymede->cmdDescription->writeRegisters != NULL) { + error = ganymede->cmdDescription->writeRegisters (demodulator, chip, processor, registerAddress, registerAddressLength, 1, &temp); + if (error) goto exit; + } + } +exit: +#endif + + return (error); +} + + +Dword Standard_readRegister ( + IN Demodulator* demodulator, + IN Byte chip, + IN Processor processor, + IN Dword registerAddress, + OUT Byte* value +) { + return (Standard_readRegisters (demodulator, chip, processor, registerAddress, 1, value)); +} + + +Dword Standard_readRegisters ( + IN Demodulator* demodulator, + IN Byte chip, + IN Processor processor, + IN Dword registerAddress, + IN Byte bufferLength, + OUT Byte* buffer +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + ReadRegistersRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.chip = chip; + request.processor = processor; + request.registerAddress = registerAddress; + request.bufferLength = bufferLength; + request.buffer = buffer; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_READREGISTERS, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Byte registerAddressLength; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (processor == Processor_LINK) { + if (registerAddress > 0x000000FF) { + registerAddressLength = 2; + } else { + registerAddressLength = 1; + } + } else { + registerAddressLength = 2; + } + if (ganymede->cmdDescription->readRegisters != NULL) { + error = ganymede->cmdDescription->readRegisters (demodulator, chip, processor, registerAddress, registerAddressLength, bufferLength, buffer); + } +#endif + + return (error); +} + + +Dword Standard_readTunerRegisters ( + IN Demodulator* demodulator, + IN Byte chip, + IN Word registerAddress, + IN Byte bufferLength, + IN Byte* buffer +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + ReadTunerRegistersRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.chip = chip; + request.registerAddress = registerAddress; + request.bufferLength = bufferLength; + request.buffer = buffer; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_READTUNERREGISTERS, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->cmdDescription->readTunerRegisters != NULL) { + error = ganymede->cmdDescription->readTunerRegisters (demodulator, chip, ganymede->tunerDescription->tunerAddress, registerAddress, ganymede->tunerDescription->registerAddressLength, bufferLength, buffer); + } +#endif + + return (error); +} + + +Dword Standard_readGenericRegisters ( + IN Demodulator* demodulator, + IN Byte chip, + IN Byte interfaceIndex, + IN Byte slaveAddress, + IN Byte bufferLength, + IN Byte* buffer +) { + Byte writeBuffer[3]; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + writeBuffer[0] = bufferLength; + writeBuffer[1] = interfaceIndex; + writeBuffer[2] = slaveAddress; + + return (Standard_sendCommand (demodulator, Command_GENERIC_READ, chip, Processor_LINK, 3, writeBuffer, bufferLength, buffer)); +} + + +Dword Standard_readEepromValues ( + IN Demodulator* demodulator, + IN Byte chip, + IN Word registerAddress, + IN Byte bufferLength, + OUT Byte* buffer +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + ReadEepromValuesRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.chip = chip; + request.registerAddress = registerAddress; + request.bufferLength = bufferLength; + request.buffer = buffer; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_READEEPROMVALUES, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Byte eepromAddress; + Byte registerAddressLength; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + /** Read EEPROM address. */ + /*error = ganymede->cmdDescription.readRegisters (demodulator, chip, Processor_LINK, 0xBFF0, 1, &eepromAddress); + if (error) goto exit; + */ + eepromAddress = 0x01; + + /** Read EEPROM valid length of register. */ + /*error = ganymede->cmdDescription.readRegisters (demodulator, chip, Processor_LINK, 0xBFF1, 1, ®isterAddressLength); + if (error) goto exit; + */ + registerAddressLength = 0x01; + + if (ganymede->cmdDescription->readEepromValues != NULL) { + error = ganymede->cmdDescription->readEepromValues (demodulator, chip, eepromAddress, registerAddress, registerAddressLength, bufferLength, buffer); + } + +#endif + + return (error); +} + + +Dword Standard_readRegisterBits ( + IN Demodulator* demodulator, + IN Byte chip, + IN Processor processor, + IN Dword registerAddress, + IN Byte position, + IN Byte length, + OUT Byte* value +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + ReadRegisterBitsRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.chip = chip; + request.processor = processor; + request.registerAddress = registerAddress; + request.position = position; + request.length = length; + request.value = value; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_READREGISTERBITS, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Byte temp = 0; + Byte registerAddressLength; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (processor == Processor_LINK) { + if (registerAddress > 0x000000FF) { + registerAddressLength = 2; + } else { + registerAddressLength = 1; + } + } else { + registerAddressLength = 2; + } + if (ganymede->cmdDescription->readRegisters != NULL) { + error = ganymede->cmdDescription->readRegisters (demodulator, chip, processor, registerAddress, registerAddressLength, 1, &temp); + } + if (error) goto exit; + + if (length == 8) { + *value = temp; + } else { + temp = REG_GET (temp, position, length); + *value = temp; + } + +#endif + +exit : + return (error); +} + + +Dword Standard_getHardwareVersion ( + IN Demodulator* demodulator, + OUT Dword* version +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER +#else + Byte hwVer0; + Byte hwVer1; + + error = Standard_readRegister (demodulator, 0, Processor_OFDM, 0xFFF0, &hwVer0); + if (error) goto exit; + error = Standard_readRegister (demodulator, 0, Processor_OFDM, 0xFFF1, &hwVer1); + if (error) goto exit; + + /** HW Version = HWVer + Top_Ver */ + *version = (Dword) (hwVer1 << 8) + (Dword) hwVer0; + +exit : +#endif + + return (error); +} + + +Dword Standard_getFirmwareVersion ( + IN Demodulator* demodulator, + IN Processor processor, + OUT Dword* version +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + GetFirmwareVersionRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.processor = processor; + request.version = version; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_GETFIRMWAREVERSION, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Byte writeBuffer[1] = {0,}; + Byte readBuffer[4] = {0,}; + Byte value = 0; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if ((ganymede->busId == Bus_I2M) || (ganymede->busId == Bus_I2U)) { + *version = 0xFFFFFFFF; + goto exit; + } + + /** Check chip version */ + error = Standard_readRegister (demodulator, 0, Processor_LINK, 0x1222, &value); + if (error) goto exit; + + if (value == 0xF8 || User_MAX_PKT_SIZE > 9) { + writeBuffer[0] = 1; + error = Standard_sendCommand (demodulator, Command_QUERYINFO, 0, processor, 1, writeBuffer, 4, readBuffer); + if (error) goto exit; + } else { + error = Standard_sendCommand (demodulator, Command_FW_DOWNLOAD_END, 0, Processor_LINK, 0, NULL, 0, NULL); + if (error == 0x01000009) { /* Boot code*/ + readBuffer[0] = readBuffer[1] = readBuffer[2] = readBuffer[3] = 0; + error = 0; + } else if (error = 0x010000FA) { /* Firmware code*/ + if (processor == Processor_LINK) + { + error = Standard_readRegisters (demodulator, 0, Processor_LINK, 0x83E9, 1, readBuffer); + if (error) goto exit; + + error = Standard_readRegisters (demodulator, 0, Processor_LINK, 0x83EA, 1, readBuffer + 1); + if (error) goto exit; + + error = Standard_readRegisters (demodulator, 0, Processor_LINK, 0x83EB, 1, readBuffer + 2); + if (error) goto exit; + + error = Standard_readRegisters (demodulator, 0, Processor_LINK, 0x83EC, 1, readBuffer + 3); + if (error) goto exit; + } + else + { + error = Standard_readRegisters (demodulator, 0, Processor_OFDM, 0x4191, 1, readBuffer); + if (error) goto exit; + + error = Standard_readRegisters (demodulator, 0, Processor_OFDM, 0x4192, 1, readBuffer + 1); + if (error) goto exit; + + error = Standard_readRegisters (demodulator, 0, Processor_OFDM, 0x4193, 1, readBuffer + 2); + if (error) goto exit; + + error = Standard_readRegisters (demodulator, 0, Processor_OFDM, 0x4194, 1, readBuffer + 3); + if (error) goto exit; + } + } else /* error */ + goto exit; + } + + *version = (Dword) (((Dword) readBuffer[0] << 24) + ((Dword) readBuffer[1] << 16) + ((Dword) readBuffer[2] << 8) + (Dword) readBuffer[3]); + +exit : +#endif + + return (error); +} + + +Dword Standard_getPostVitBer ( + IN Demodulator* demodulator, + IN Byte chip, + OUT Dword* postErrorCount, /** 24 bits */ + OUT Dword* postBitCount, /** 16 bits */ + OUT Word* abortCount +) { + Dword error = Error_NO_ERROR; + Dword errorCount; + Dword bitCount; + Byte buffer[7]; + Word abort; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + *postErrorCount = 0; + *postBitCount = 0; + + error = Standard_readRegisters (demodulator, chip, Processor_OFDM, rsd_abort_packet_cnt_7_0, r_rsd_packet_unit_15_8 - rsd_abort_packet_cnt_7_0 + 1, buffer); + if (error) goto exit; + + abort = ((Word) buffer[rsd_abort_packet_cnt_15_8 - rsd_abort_packet_cnt_7_0] << 8) + buffer[rsd_abort_packet_cnt_7_0 - rsd_abort_packet_cnt_7_0]; + errorCount = ((Dword) buffer[rsd_bit_err_cnt_23_16 - rsd_abort_packet_cnt_7_0] << 16) + ((Dword) buffer[rsd_bit_err_cnt_15_8 - rsd_abort_packet_cnt_7_0] << 8) + buffer[rsd_bit_err_cnt_7_0 - rsd_abort_packet_cnt_7_0]; + bitCount = ((Dword) buffer[r_rsd_packet_unit_15_8 - rsd_abort_packet_cnt_7_0] << 8) + buffer[r_rsd_packet_unit_7_0 - rsd_abort_packet_cnt_7_0]; + if (bitCount == 0) { + /*error = Error_RSD_PKT_CNT_0;*/ + *postErrorCount = 1; + *postBitCount = 2; + *abortCount = 1000; + goto exit; + } + + *abortCount = abort; + bitCount = bitCount - (Dword)abort; + if (bitCount == 0) { + *postErrorCount = 1; + *postBitCount = 2; + } else { + *postErrorCount = errorCount - (Dword) abort * 8 * 8; + *postBitCount = bitCount * 204 * 8; + } + +exit : + return (error); +} + + +Dword Standard_getRfAgcGain ( + IN Demodulator* demodulator, + IN Byte chip, + OUT Byte* rfAgc +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER +#else + /** get rf_agc_control */ + error = Standard_readRegisterBits (demodulator, chip, Processor_OFDM, r_reg_aagc_rf_gain, reg_aagc_rf_gain_pos, reg_aagc_rf_gain_len, rfAgc); +#endif + + return (error); +} + + +Dword Standard_getIfAgcGain ( + IN Demodulator* demodulator, + IN Byte chip, + OUT Byte* ifAgc +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER +#else + /** get if_agc_control */ + error = Standard_readRegisterBits (demodulator, chip, Processor_OFDM, r_reg_aagc_if_gain, reg_aagc_if_gain_pos, reg_aagc_if_gain_len, ifAgc); +#endif + + return (error); +} + + +Dword Standard_getSignalQuality ( + IN Demodulator* demodulator, + IN Byte chip, + OUT Byte* quality +) { + Dword error = Error_NO_ERROR; + + error = Standard_readRegister (demodulator, chip, Processor_OFDM, signal_quality, quality); + return (error); +} + + +Dword Standard_getSignalStrength ( + IN Demodulator* demodulator, + IN Byte chip, + OUT Byte* strength +) { + Dword error = Error_NO_ERROR; + + error = Standard_readRegister (demodulator, chip, Processor_OFDM, signal_strength, strength); + return (error); +} + + +Dword Standard_getSignalStrengthDbm ( + IN Demodulator* demodulator, + IN Byte chip, + IN Long rfpullUpVolt_X10, /** RF pull up voltage multiplied by 10 */ + IN Long ifpullUpVolt_X10, /** IF pull up voltage multiplied by 10 */ + OUT Long* strengthDbm /** DBm */ +) +{ + Dword error = Error_NO_ERROR; + Byte temp; + + if ((rfpullUpVolt_X10 == 0) || (ifpullUpVolt_X10 == 0)) { + error = Error_INV_PULLUP_VOLT; + goto exit; + } + + error = Standard_readRegister (demodulator, chip, Processor_OFDM, est_rf_level_dbm, &temp); + if (error) goto exit; + + *strengthDbm = (Long) (temp * -1); + +exit : + return (error); +} + + +Dword Standard_loadIrTable ( + IN Demodulator* demodulator, + IN Word tableLength, + IN Byte* table +) { + Dword error = Error_NO_ERROR; + Byte baseHigh; + Byte baseLow; + Word registerBase; + Word i; + + error = Standard_readRegister (demodulator, 0, Processor_LINK, 0x417F, &baseHigh); + if (error) goto exit; + error = Standard_readRegister (demodulator, 0, Processor_LINK, 0x4180, &baseLow); + if (error) goto exit; + + registerBase = (Word) (baseHigh << 8) + (Word) baseLow; + + if (registerBase) { + for (i = 0; i < tableLength; i++) { + error = Standard_writeRegister (demodulator, 0, Processor_LINK, registerBase + i, table[i]); + if (error) goto exit; + } + } + +exit : + return (error); +} + + +Dword Standard_initialize ( + IN Demodulator* demodulator, + IN Byte chipNumber, + IN Word sawBandwidth, + IN StreamType streamType, + IN Architecture architecture +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + InitializeRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + ganymede->driver = NULL; + error = Standard_getDriver (demodulator, &ganymede->driver); + + if (ganymede->driver != NULL) { + request.chipNumber = chipNumber; + request.sawBandwidth = sawBandwidth; + request.streamType = streamType; + request.architecture = architecture; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_INITIALIZE, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Dword crystal = 0; + Dword adc = 0; + Dword fcw = 0; + Byte buffer[4]; + Dword version = 0; + Word* tunerScriptSets = NULL; + ValueSet* tunerScripts = NULL; + Byte i; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + ganymede->chipNumber = chipNumber; + ganymede->options = 0x0000; + ganymede->fcw = 0x00000000; + ganymede->frequency[0] = 642000; + ganymede->frequency[1] = 642000; + ganymede->initialized = False; + + + if (ganymede->busId == 0xFFFF) { + goto exit; + } + + if (ganymede->tunerDescription->tunerId == 0xFFFF) { + goto exit; + } + + error = Standard_getFirmwareVersion (demodulator, Processor_LINK, &version); + if (error) goto exit; + if (version != 0) { + ganymede->booted = True; + } else { + ganymede->booted = False; + } + + + ganymede->firmwareCodes = Firmware_codes; + ganymede->firmwareSegments = Firmware_segments; + ganymede->firmwarePartitions = Firmware_partitions; + ganymede->scriptSets = Firmware_scriptSets; + ganymede->scripts = Firmware_scripts; + + /** Set up by default tunerDescription */ /** releaseExternalRemove */ + tunerScriptSets = ganymede->tunerDescription->tunerScriptSets; + tunerScripts = ganymede->tunerDescription->tunerScript; + + + error = Standard_readRegisterBits (demodulator, 0, Processor_LINK, r_io_mux_pwron_clk_strap, io_mux_pwron_clk_strap_pos, io_mux_pwron_clk_strap_len, &i); + if (error) goto exit; + + ganymede->crystalFrequency = Standard_clockTable[i].crystalFrequency; + ganymede->adcFrequency = Standard_clockTable[i].adcFrequency; + + ganymede->dataReady = False; + + /** Write secondary I2C address to device */ + /** Enable or disable clock out for 2nd chip power saving */ + if (ganymede->chipNumber > 1) { + error = Standard_writeRegister (demodulator, 0, Processor_LINK, 0x417F, Chip2_I2c_address); + if (error) goto exit; + + error = Standard_writeRegister (demodulator, 0, Processor_LINK, p_reg_top_clkoen, 1); + if (error) goto exit; + } else { + error = Standard_writeRegister (demodulator, 0, Processor_LINK, 0x417F, 0x00); + if (error) goto exit; + + error = Standard_writeRegister (demodulator, 0, Processor_LINK, p_reg_top_clkoen, 0); + if (error) goto exit; + } + + /** Detect the HostA or HostB */ + error = Standard_readRegisterBits (demodulator, 0, Processor_LINK, r_io_mux_pwron_hosta, io_mux_pwron_hosta_pos, io_mux_pwron_hosta_len, &ganymede->hostInterface[0]); + if (error) goto exit; + + /** Load firmware */ + if (ganymede->firmwareCodes != NULL) { + if (ganymede->booted == False) { + error = Standard_loadFirmware (demodulator, ganymede->firmwareCodes, ganymede->firmwareSegments, ganymede->firmwarePartitions); + if (error) goto exit; + ganymede->booted = True; + } + } + + /** Set I2C master clock speed. */ + error = Standard_writeRegister (demodulator, 0, Processor_LINK, p_reg_one_cycle_counter_tuner, User_I2C_SPEED); + if (error) goto exit; + + + /** Set I2C master clock 100k in order to support tuner I2C. */ + error = Standard_writeRegister (demodulator, 0, Processor_LINK, p_reg_one_cycle_counter_tuner, 0x1a); + if (error) goto exit; + + /** Open tuner */ + for (i = 0; i < ganymede->chipNumber; i++) { + + /** Set 0xD827 to 0 as open drain for tuner i2c */ + error = Standard_writeRegister (demodulator, i , Processor_LINK, p_reg_top_padodpu, 0); + if (error) goto exit; + + /** Set 0xD829 to 0 as push pull for tuner AGC */ + error = Standard_writeRegister (demodulator, i , Processor_LINK, p_reg_top_agc_od, 0); + if (error) goto exit; + } + if (ganymede->tunerDescription->openTuner != NULL) { + if ((ganymede->busId != Bus_I2M) && (ganymede->busId != Bus_I2U)) { + for (i = 0; i < ganymede->chipNumber; i++) { + error = ganymede->tunerDescription->openTuner (demodulator, i); + if (error) goto exit; + } + } + } + for (i = 0; i < ganymede->chipNumber; i++) { + /** Tell firmware the type of tuner. */ + error = Standard_writeRegister (demodulator, i, Processor_LINK, p_reg_link_ofsm_dummy_15_8, (Byte) ganymede->tunerDescription->tunerId); + if (error) goto exit; + } + + /** Initialize OFDM */ + if (ganymede->booted == True) { + for (i = 0; i < ganymede->chipNumber; i++) { + /** Set read-update bit to 1 for constellation */ + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, p_reg_feq_read_update, reg_feq_read_update_pos, reg_feq_read_update_len, 1); + if (error) goto exit; + + /** Enable FEC Monitor */ + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, p_fec_vtb_rsd_mon_en, fec_vtb_rsd_mon_en_pos, fec_vtb_rsd_mon_en_len, 1); + if (error) goto exit; + } + + /** Compute ADC and load them to device */ + error = Standard_computeCrystal (demodulator, (Long) ganymede->crystalFrequency * 1000, &crystal); + if (error) goto exit; + + buffer[0] = (Byte) (crystal & 0x000000FF); + buffer[1] = (Byte) ((crystal & 0x0000FF00) >> 8); + buffer[2] = (Byte) ((crystal & 0x00FF0000) >> 16); + buffer[3] = (Byte) ((crystal & 0xFF000000) >> 24); + for (i = 0; i < ganymede->chipNumber; i++) { + error = Standard_writeRegisters (demodulator, i, Processor_OFDM, crystal_clk_7_0, 4, buffer); + if (error) goto exit; + } + + /** Compute ADC and load them to device */ + error = Standard_computeAdc (demodulator, (Long) ganymede->adcFrequency, &adc); + if (error) goto exit; + + buffer[0] = (Byte) (adc & 0x000000FF); + buffer[1] = (Byte) ((adc & 0x0000FF00) >> 8); + buffer[2] = (Byte) ((adc & 0x00FF0000) >> 16); + for (i = 0; i < ganymede->chipNumber; i++) { + error = Standard_writeRegisters (demodulator, i, Processor_OFDM, p_reg_f_adc_7_0, 3, buffer); + if (error) goto exit; + } + + /** Compute FCW and load them to device */ + error = Standard_computeFcw (demodulator, (Long) ganymede->adcFrequency, (Long) ganymede->tunerDescription->ifFrequency, ganymede->tunerDescription->inversion, &fcw); + if (error) goto exit; + ganymede->fcw = fcw; + + buffer[0] = (Byte) (fcw & 0x000000FF); + buffer[1] = (Byte) ((fcw & 0x0000FF00) >> 8); + buffer[2] = (Byte) ((fcw & 0x007F0000) >> 16); + for (i = 0; i < ganymede->chipNumber; i++) { + error = Standard_writeRegisters (demodulator, i, Processor_OFDM, bfs_fcw_7_0, bfs_fcw_22_16 - bfs_fcw_7_0 + 1, buffer); + if (error) goto exit; + } + } + + /** Load script */ + if (ganymede->scripts != NULL) { + error = Standard_loadScript (demodulator, streamType, ganymede->scriptSets, ganymede->scripts, tunerScriptSets, tunerScripts); + if (error) goto exit; + } + + /** Set the desired stream type */ + error = Standard_setStreamType (demodulator, streamType); + if (error) goto exit; + + /** Set the desired architecture type */ + error = Standard_setArchitecture (demodulator, architecture); + if (error) goto exit; + +#if User_USE_INTERRUPT + if (ganymede->busId == Bus_SDIO) { + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_sdioc_external_int_en, reg_sdioc_external_int_en_pos, reg_sdioc_external_int_en_len, 1); + if (error) goto exit; + } +#endif + + for (i = 0; i< ganymede->chipNumber; i++) { + + /** Set H/W MPEG2 locked detection **/ + error = Standard_writeRegister (demodulator, i, Processor_LINK, p_reg_top_lock3_out, 1); + if (error) goto exit; + + /** Set registers for driving power 0xD830 **/ + error = Standard_writeRegister (demodulator, i, Processor_LINK, p_reg_top_padmiscdr2, 1); + if (error) goto exit; + + /** Set registers for driving power 0xD831 **/ + error = Standard_writeRegister (demodulator, i, Processor_LINK, p_reg_top_padmiscdr4, 0); + if (error) goto exit; + + /** Set registers for driving power 0xD832 **/ + error = Standard_writeRegister (demodulator, i, Processor_LINK, p_reg_top_padmiscdr8, 0); + if (error) goto exit; + } + + ganymede->initialized = True; + +#endif +exit: + + return (error); +} + + +Dword Standard_finalize ( + IN Demodulator* demodulator +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + FinalizeRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_FINALIZE, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Byte i; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->tunerDescription->closeTuner != NULL) { + for (i = 0; i < ganymede->chipNumber; i++) { + error = ganymede->tunerDescription->closeTuner (demodulator, i); + } + } + +#endif + + return (error); +} + + +Dword Standard_isTpsLocked ( + IN Demodulator* demodulator, + IN Byte chip, + OUT Bool* locked +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER +#else + Byte temp; + + *locked = False; + + error = Standard_readRegisterBits (demodulator, chip, Processor_OFDM, p_fd_tpsd_lock, fd_tpsd_lock_pos, fd_tpsd_lock_len, &temp); + if (error) goto exit; + if (temp) *locked = True; + +exit : +#endif + + return (error); +} + + +Dword Standard_isMpeg2Locked ( + IN Demodulator* demodulator, + IN Byte chip, + OUT Bool* locked +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER +#else + Byte temp; + + *locked = False; + + error = Standard_readRegisterBits (demodulator, chip, Processor_OFDM, r_mp2if_sync_byte_locked, mp2if_sync_byte_locked_pos, mp2if_sync_byte_locked_len, &temp); + if (error) goto exit; + if (temp) *locked = True; + +exit : +#endif + + return (error); +} + + +Dword Standard_isLocked ( + IN Demodulator* demodulator, + IN Byte chip, + OUT Bool* locked +) { + Dword error = Error_NO_ERROR; + + Word emptyLoop = 0; + Word tpsLoop = 0; + Word mpeg2Loop = 0; + Byte channels[2]; + Byte begin; + Byte end; + Byte i; + Byte emptyChannel = 1; + Byte tpsLocked = 0; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + IsLockedRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.chip = chip; + request.locked = locked; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_ISLOCKED, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + + *locked = False; + + if (ganymede->architecture == Architecture_DCA) { + begin = 0; + end = ganymede->chipNumber; + } else { + begin = chip; + end = begin + 1; + } + + for (i = begin; i < end; i++) { + ganymede->statistic[i].signalPresented = False; + ganymede->statistic[i].signalLocked = False; + ganymede->statistic[i].signalQuality = 0; + ganymede->statistic[i].signalStrength = 0; + } + + channels[0] = 2; + channels[1] = 2; + while (emptyLoop < 40) { + for (i = begin; i < end; i++) { + error = Standard_readRegister (demodulator, i, Processor_OFDM, empty_channel_status, &channels[i]); + if (error) goto exit; + } + if ((channels[0] == 1) || (channels[1] == 1)) { + emptyChannel = 0; + break; + } + if ((channels[0] == 2) && (channels[1] == 2)) { + emptyChannel = 1; + goto exit; + } + User_delay (demodulator, 25); + emptyLoop++; + } + + if (emptyChannel == 1) goto exit; + + while (tpsLoop < 50) { + for (i = begin; i < end; i++) { + /** Empty channel */ + error = Standard_isTpsLocked (demodulator, i, &ganymede->statistic[i].signalPresented); + if (error) goto exit; + if (ganymede->statistic[i].signalPresented == True) { + tpsLocked = 1; + break; + } + } + + if (tpsLocked == 1) break; + + User_delay (demodulator, 25); + tpsLoop++; + } + + if (tpsLocked == 0) goto exit; + + while (mpeg2Loop < 40) { + if (ganymede->architecture == Architecture_DCA) { + error = Standard_isMpeg2Locked (demodulator, 0, &ganymede->statistic[0].signalLocked); + if (error) goto exit; + if (ganymede->statistic[0].signalLocked == True) { + for (i = begin; i < end; i++) { + ganymede->statistic[i].signalQuality = 80; + ganymede->statistic[i].signalStrength = 80; + } + *locked = True; + break; + } + } else { + error = Standard_isMpeg2Locked (demodulator, chip, &ganymede->statistic[chip].signalLocked); + if (error) goto exit; + if (ganymede->statistic[chip].signalLocked == True) { + ganymede->statistic[chip].signalQuality = 80; + ganymede->statistic[chip].signalStrength = 80; + *locked = True; + break; + } + } + User_delay (demodulator, 25); + mpeg2Loop++; + } + for (i = begin; i < end; i++) { + ganymede->statistic[i].signalQuality = 0; + ganymede->statistic[i].signalStrength = 20; + } + +exit: +#endif + + return (error); +} + + +Dword Standard_reset ( + IN Demodulator* demodulator +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER +#else + Byte value; + Byte i; + Byte j; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + for (i = 0; i < ganymede->chipNumber; i++) { + + /** Enable OFDM reset */ + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, I2C_reg_ofdm_rst_en, reg_ofdm_rst_en_pos, reg_ofdm_rst_en_len, 0x01); + if (error) goto exit; + + /** Start reset mechanism */ + value = 0x00; + error = Standard_writeRegisters (demodulator, i, Processor_OFDM, RESET_STATE, 1, &value); + if (error) goto exit; + + /** Clear ofdm reset */ + for (j = 0; j < 150; j++) { + error = Standard_readRegisterBits (demodulator, i, Processor_OFDM, I2C_reg_ofdm_rst, reg_ofdm_rst_pos, reg_ofdm_rst_len, &value); + if (error) goto exit; + if (value) break; + User_delay (demodulator, 10); + } + + if (j == 150) { + error = Error_RESET_TIMEOUT; + goto exit; + } + + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, I2C_reg_ofdm_rst, reg_ofdm_rst_pos, reg_ofdm_rst_len, 0); + if (error) goto exit; + + /** Disable OFDM reset */ + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, I2C_reg_ofdm_rst_en, reg_ofdm_rst_en_pos, reg_ofdm_rst_en_len, 0x00); + if (error) goto exit; + } + +exit : +#endif + + return (error); +} + + +Dword Standard_getChannelModulation ( + IN Demodulator* demodulator, + IN Byte chip, + OUT ChannelModulation* channelModulation +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + GetChannelModulationRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.chip = chip; + request.channelModulation = channelModulation; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_GETCHANNELMODULATION, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Byte temp; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + /** Get constellation type */ + error = Standard_readRegisterBits (demodulator, chip, Processor_OFDM, g_reg_tpsd_const, reg_tpsd_const_pos, reg_tpsd_const_len, &temp); + if (error) goto exit; + channelModulation->constellation = (Constellation) temp; + + /** Get TPS hierachy and alpha value */ + error = Standard_readRegisterBits (demodulator, chip, Processor_OFDM, g_reg_tpsd_hier, reg_tpsd_hier_pos, reg_tpsd_hier_len, &temp); + if (error) goto exit; + channelModulation->hierarchy = (Hierarchy)temp; + + /** Get high/low priority */ + error = Standard_readRegisterBits (demodulator, chip, Processor_OFDM, g_reg_dec_pri, reg_dec_pri_pos, reg_dec_pri_len, &temp); + if (error) goto exit; + if (temp) + channelModulation->priority = Priority_HIGH; + else + channelModulation->priority = Priority_LOW; + + /** Get high code rate */ + error = Standard_readRegisterBits (demodulator, chip, Processor_OFDM, g_reg_tpsd_hpcr, reg_tpsd_hpcr_pos, reg_tpsd_hpcr_len, &temp); + if (error) goto exit; + channelModulation->highCodeRate = (CodeRate) temp; + + /** Get low code rate */ + error = Standard_readRegisterBits (demodulator, chip, Processor_OFDM, g_reg_tpsd_lpcr, reg_tpsd_lpcr_pos, reg_tpsd_lpcr_len, &temp); + if (error) goto exit; + channelModulation->lowCodeRate = (CodeRate) temp; + + /** Get guard interval */ + error = Standard_readRegisterBits (demodulator, chip, Processor_OFDM, g_reg_tpsd_gi, reg_tpsd_gi_pos, reg_tpsd_gi_len, &temp); + if (error) goto exit; + channelModulation->interval = (Interval) temp; + + /** Get FFT mode */ + error = Standard_readRegisterBits (demodulator, chip, Processor_OFDM, g_reg_tpsd_txmod, reg_tpsd_txmod_pos, reg_tpsd_txmod_len, &temp); + if (error) goto exit; + channelModulation->transmissionMode = (TransmissionModes) temp; + + /** Get bandwidth */ + error = Standard_readRegisterBits (demodulator, chip, Processor_OFDM, g_reg_bw, reg_bw_pos, reg_bw_len, &temp); + if (error) goto exit; + channelModulation->bandwidth = (Bandwidth) temp; + + /** Get frequency */ + channelModulation->frequency = ganymede->frequency[chip]; + +exit : +#endif + + return (error); +} + + + +Dword Standard_acquireChannel ( + IN Demodulator* demodulator, + IN Byte chip, + IN Word bandwidth, + IN Dword frequency +) { + Dword error = Error_NO_ERROR; + + Byte begin; + Byte end; + Byte i; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + AcquireChannelRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.chip = chip; + request.frequency = frequency; + request.bandwidth = bandwidth; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_ACQUIRECHANNEL, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->architecture == Architecture_DCA) { + begin = 0; + end = ganymede->chipNumber; + } else { + begin = chip; + end = begin + 1; + } + + + for (i = begin; i < end; i++) { + error = Standard_selectBandwidth (demodulator, i, bandwidth, ganymede->adcFrequency); + if (error) goto exit; + ganymede->bandwidth[i] = bandwidth; + } + + error = Standard_maskDcaOutput (demodulator); + if (error) goto exit; + + /** Set frequency */ + for (i = begin; i < end; i++) { + error = Standard_setFrequency (demodulator, i, frequency); + if (error) goto exit; + } + +exit : +#endif + + return (error); +} + + +Dword Standard_setStreamType ( + IN Demodulator* demodulator, + IN StreamType streamType +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + SetStreamTypeRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.streamType = streamType; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_SETSTREAMTYPE, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Dword warning = Error_NO_ERROR; + Ganymede* ganymede; + Byte i; + + ganymede = (Ganymede*) demodulator; + + /** Enable DVB-T interrupt if next stream type is StreamType_DVBT_DATAGRAM */ + if (streamType == StreamType_DVBT_DATAGRAM) { + for (i = 0; i < ganymede->chipNumber; i++) { + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_dvbt_inten, reg_dvbt_inten_pos, reg_dvbt_inten_len, 1); + if (error) goto exit; + if ((ganymede->busId == Bus_USB) || (ganymede->busId == Bus_USB11)) { + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, p_reg_mpeg_full_speed, reg_mpeg_full_speed_pos, reg_mpeg_full_speed_len, 0); + if (error) goto exit; + } else { + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, p_reg_mpeg_full_speed, reg_mpeg_full_speed_pos, reg_mpeg_full_speed_len, 1); + if (error) goto exit; + } + } + } + + /** Enable DVB-T mode */ + for (i = 0; i < ganymede->chipNumber; i++) { + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_dvbt_en, reg_dvbt_en_pos, reg_dvbt_en_len, 1); + if (error) goto exit; + } + + + /** Enter sub mode */ + switch (streamType) { + case StreamType_DVBT_DATAGRAM : + if ((ganymede->busId == Bus_USB) || (ganymede->busId == Bus_USB11)) { + error = Standard_writeRegisterBits (demodulator, 0, Processor_OFDM, p_mp2if_mpeg_ser_mode, mp2if_mpeg_ser_mode_pos, mp2if_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, 0, Processor_OFDM, p_mp2if_mpeg_par_mode, mp2if_mpeg_par_mode_pos, mp2if_mpeg_par_mode_len, 0); + if (error) goto exit; + /** Fix current leakage */ + if (ganymede->chipNumber > 1) { + if (ganymede->hostInterface[0]) { + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_top_hostb_mpeg_ser_mode, reg_top_hostb_mpeg_ser_mode_pos, reg_top_hostb_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_top_hostb_mpeg_par_mode, reg_top_hostb_mpeg_par_mode_pos, reg_top_hostb_mpeg_par_mode_len, 1); + if (error) goto exit; + } else { + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_top_hosta_mpeg_ser_mode, reg_top_hosta_mpeg_ser_mode_pos, reg_top_hosta_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_top_hosta_mpeg_par_mode, reg_top_hosta_mpeg_par_mode_pos, reg_top_hosta_mpeg_par_mode_len, 1); + if (error) goto exit; + } + } else { + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_top_hosta_mpeg_ser_mode, reg_top_hosta_mpeg_ser_mode_pos, reg_top_hosta_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_top_hosta_mpeg_par_mode, reg_top_hosta_mpeg_par_mode_pos, reg_top_hosta_mpeg_par_mode_len, 1); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_top_hostb_mpeg_ser_mode, reg_top_hostb_mpeg_ser_mode_pos, reg_top_hostb_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_top_hostb_mpeg_par_mode, reg_top_hostb_mpeg_par_mode_pos, reg_top_hostb_mpeg_par_mode_len, 1); + if (error) goto exit; + } + } else { + error = Standard_writeRegisterBits (demodulator, 0, Processor_OFDM, p_mp2if_mpeg_ser_mode, mp2if_mpeg_ser_mode_pos, mp2if_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, 0, Processor_OFDM, p_mp2if_mpeg_par_mode, mp2if_mpeg_par_mode_pos, mp2if_mpeg_par_mode_len, 0); + if (error) goto exit; + + /** Fix current leakage */ + if (ganymede->chipNumber > 1) { + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_top_hosta_mpeg_ser_mode, reg_top_hosta_mpeg_ser_mode_pos, reg_top_hosta_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_top_hosta_mpeg_par_mode, reg_top_hosta_mpeg_par_mode_pos, reg_top_hosta_mpeg_par_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_top_hostb_mpeg_ser_mode, reg_top_hostb_mpeg_ser_mode_pos, reg_top_hostb_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_top_hostb_mpeg_par_mode, reg_top_hostb_mpeg_par_mode_pos, reg_top_hostb_mpeg_par_mode_len, 0); + if (error) goto exit; + } else { + if (ganymede->hostInterface[0]) { + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_top_hostb_mpeg_ser_mode, reg_top_hostb_mpeg_ser_mode_pos, reg_top_hostb_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_top_hostb_mpeg_par_mode, reg_top_hostb_mpeg_par_mode_pos, reg_top_hostb_mpeg_par_mode_len, 1); + if (error) goto exit; + } else { + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_top_hosta_mpeg_ser_mode, reg_top_hosta_mpeg_ser_mode_pos, reg_top_hosta_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_top_hosta_mpeg_par_mode, reg_top_hosta_mpeg_par_mode_pos, reg_top_hosta_mpeg_par_mode_len, 1); + if (error) goto exit; + } + } + } + break; + case StreamType_DVBT_PARALLEL : + for (i = 0; i < ganymede->chipNumber; i++) { + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, p_mp2if_mpeg_ser_mode, mp2if_mpeg_ser_mode_pos, mp2if_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, p_mp2if_mpeg_par_mode, mp2if_mpeg_par_mode_pos, mp2if_mpeg_par_mode_len, 1); + if (error) goto exit; + + if (i == 0) { + if (ganymede->hostInterface[0]) { + /** HostA interface is enabled */ + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_top_hosta_mpeg_ser_mode, reg_top_hosta_mpeg_ser_mode_pos, reg_top_hosta_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_top_hosta_mpeg_par_mode, reg_top_hosta_mpeg_par_mode_pos, reg_top_hosta_mpeg_par_mode_len, 1); + if (error) goto exit; + } else { + /** HostB interface is enabled */ + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_top_hostb_mpeg_ser_mode, reg_top_hostb_mpeg_ser_mode_pos, reg_top_hostb_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_top_hostb_mpeg_par_mode, reg_top_hostb_mpeg_par_mode_pos, reg_top_hostb_mpeg_par_mode_len, 1); + if (error) goto exit; + } + } else { + /** HostA interface is enabled */ + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_top_hosta_mpeg_ser_mode, reg_top_hosta_mpeg_ser_mode_pos, reg_top_hosta_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_top_hosta_mpeg_par_mode, reg_top_hosta_mpeg_par_mode_pos, reg_top_hosta_mpeg_par_mode_len, 1); + if (error) goto exit; + } + } + break; + case StreamType_DVBT_SERIAL : + for (i = 0; i < ganymede->chipNumber; i++) { + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, p_mp2if_mpeg_ser_mode, mp2if_mpeg_ser_mode_pos, mp2if_mpeg_ser_mode_len, 1); + if (error) goto exit; + + if (i == 0) { + if (ganymede->hostInterface[0]) { + /** HostA interface is enabled */ + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_top_hosta_mpeg_ser_mode, reg_top_hosta_mpeg_ser_mode_pos, reg_top_hosta_mpeg_ser_mode_len, 1); + if (error) goto exit; + } else { + /** HostB interface is enabled */ + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_top_hostb_mpeg_ser_mode, reg_top_hostb_mpeg_ser_mode_pos, reg_top_hostb_mpeg_ser_mode_len, 1); + if (error) goto exit; + } + } else { + /** HostA interface is enabled */ + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_top_hosta_mpeg_ser_mode, reg_top_hosta_mpeg_ser_mode_pos, reg_top_hosta_mpeg_ser_mode_len, 1); + if (error) goto exit; + } + } + break; + } + error = User_mpegConfig (demodulator); + + ganymede->streamType = streamType; + +exit : +#endif + + return (error); +} + + +Dword Standard_setArchitecture ( + IN Demodulator* demodulator, + IN Architecture architecture +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + SetArchitectureRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.architecture = architecture; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_SETARCHITECTURE, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Word frameSize; + Byte packetSize; + Byte buffer[2]; + Byte standAlone[2]; + Byte upperChip[2]; + Byte upperHost[2]; + Byte lowerChip[2]; + Byte lowerHost[2]; + Byte dcaEnable[2]; + Byte phaseLatch[2]; + Byte fpgaLatch[2]; + Byte i; + Bool pipValid = False; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (architecture == Architecture_DCA) { + for (i = 0; i < ganymede->chipNumber; i++) { + standAlone[i] = 0; + upperChip[i] = 0; + upperHost[i] = 0; + lowerChip[i] = 0; + lowerHost[i] = 0; + dcaEnable[i] = 1; + phaseLatch[i] = 0; + fpgaLatch[i] = 0; + } + if (ganymede->chipNumber == 1) { + standAlone[0] = 1; + dcaEnable[0] = 0; + } else { + upperChip[ganymede->chipNumber - 1] = 1; + upperHost[0] = 1; + lowerChip[0] = 1; + lowerHost[ganymede->chipNumber - 1] = 1; + phaseLatch[0] = 1; + phaseLatch[ganymede->chipNumber - 1] = 1; + fpgaLatch[0] = 0x77; + fpgaLatch[ganymede->chipNumber - 1] = 0x77; + } + } else { + for (i = 0; i < ganymede->chipNumber; i++) { + standAlone[i] = 1; + upperChip[i] = 0; + upperHost[i] = 0; + lowerChip[i] = 0; + lowerHost[i] = 0; + dcaEnable[i] = 0; + phaseLatch[i] = 0; + fpgaLatch[i] = 0; + } + } + + if (ganymede->initialized == True) { + error = Standard_maskDcaOutput (demodulator); + if (error) goto exit; + } + + /** Set upper chip first in order to avoid I/O conflict */ + for (i = ganymede->chipNumber; i > 0; i--) { + /** Set dca_upper_chip */ + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_OFDM, p_reg_dca_upper_chip, reg_dca_upper_chip_pos, reg_dca_upper_chip_len, upperChip[i - 1]); + if (error) goto exit; + if (i == 1) { + if ((ganymede->busId == Bus_USB) || (ganymede->busId == Bus_USB11)) { + if (ganymede->hostInterface[0]) { + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hosta_dca_upper, reg_top_hosta_dca_upper_pos, reg_top_hosta_dca_upper_len, upperHost[i - 1]); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hostb_dca_upper, reg_top_hostb_dca_upper_pos, reg_top_hostb_dca_upper_len, 0); + if (error) goto exit; + } else { + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hostb_dca_upper, reg_top_hostb_dca_upper_pos, reg_top_hostb_dca_upper_len, upperHost[i - 1]); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hosta_dca_upper, reg_top_hosta_dca_upper_pos, reg_top_hosta_dca_upper_len, 0); + if (error) goto exit; + } + } else { + if (ganymede->hostInterface[0]) { + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hostb_dca_upper, reg_top_hostb_dca_upper_pos, reg_top_hostb_dca_upper_len, upperHost[i - 1]); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hosta_dca_upper, reg_top_hosta_dca_upper_pos, reg_top_hosta_dca_upper_len, 0); + if (error) goto exit; + } else { + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hosta_dca_upper, reg_top_hosta_dca_upper_pos, reg_top_hosta_dca_upper_len, upperHost[i - 1]); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hostb_dca_upper, reg_top_hostb_dca_upper_pos, reg_top_hostb_dca_upper_len, 0); + if (error) goto exit; + } + } + } else { + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hostb_dca_upper, reg_top_hostb_dca_upper_pos, reg_top_hostb_dca_upper_len, upperHost[i - 1]); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hosta_dca_upper, reg_top_hosta_dca_upper_pos, reg_top_hosta_dca_upper_len, 0); + if (error) goto exit; + } + + /** Set dca_lower_chip */ + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_OFDM, p_reg_dca_lower_chip, reg_dca_lower_chip_pos, reg_dca_lower_chip_len, lowerChip[i - 1]); + if (error) goto exit; + if (i == 1) { + if ((ganymede->busId == Bus_USB) || (ganymede->busId == Bus_USB11)) { + if (ganymede->hostInterface[0]) { + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hosta_dca_lower, reg_top_hosta_dca_lower_pos, reg_top_hosta_dca_lower_len, lowerHost[i - 1]); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hostb_dca_lower, reg_top_hostb_dca_lower_pos, reg_top_hostb_dca_lower_len, 0); + if (error) goto exit; + } else { + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hostb_dca_lower, reg_top_hostb_dca_lower_pos, reg_top_hostb_dca_lower_len, lowerHost[i - 1]); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hosta_dca_lower, reg_top_hosta_dca_lower_pos, reg_top_hosta_dca_lower_len, 0); + if (error) goto exit; + } + } else { + if (ganymede->hostInterface[0]) { + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hostb_dca_lower, reg_top_hostb_dca_lower_pos, reg_top_hostb_dca_lower_len, lowerHost[i - 1]); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hosta_dca_lower, reg_top_hosta_dca_lower_pos, reg_top_hosta_dca_lower_len, 0); + if (error) goto exit; + } else { + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hosta_dca_lower, reg_top_hosta_dca_lower_pos, reg_top_hosta_dca_lower_len, lowerHost[i - 1]); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hostb_dca_lower, reg_top_hostb_dca_lower_pos, reg_top_hostb_dca_lower_len, 0); + if (error) goto exit; + } + } + } else { + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hostb_dca_lower, reg_top_hostb_dca_lower_pos, reg_top_hostb_dca_lower_len, lowerHost[i - 1]); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_top_hosta_dca_lower, reg_top_hosta_dca_lower_pos, reg_top_hosta_dca_lower_len, 0); + if (error) goto exit; + } + + /** Set phase latch */ + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_OFDM, p_reg_dca_platch, reg_dca_platch_pos, reg_dca_platch_len, phaseLatch[i - 1]); + if (error) goto exit; + + /** Set fpga latch */ + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_OFDM, p_reg_dca_fpga_latch, reg_dca_fpga_latch_pos, reg_dca_fpga_latch_len, fpgaLatch[i - 1]); + if (error) goto exit; + } + + for (i = 0; i < ganymede->chipNumber; i++) { + /** Set stand alone */ + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, p_reg_dca_stand_alone, reg_dca_stand_alone_pos, reg_dca_stand_alone_len, standAlone[i]); + if (error) goto exit; + + /** Set DCA enable */ + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, p_reg_dca_en, reg_dca_en_pos, reg_dca_en_len, dcaEnable[i]); + if (error) goto exit; + } + + if (ganymede->initialized == True) { + for (i = 0; i < ganymede->chipNumber; i++) { + error = Standard_writeRegister (demodulator, i, Processor_OFDM, trigger_ofsm, 0); + if (error) goto exit; + } + } + + + if ((ganymede->busId == Bus_USB) || (ganymede->busId == Bus_USB11)) { + frameSize = User_USB20_FRAME_SIZE_DW; + packetSize = (Byte) (User_USB20_MAX_PACKET_SIZE / 4); + + if (ganymede->busId == Bus_USB11) { + frameSize = User_USB11_FRAME_SIZE_DW; + packetSize = (Byte) (User_USB11_MAX_PACKET_SIZE / 4); + } + + if ((ganymede->chipNumber > 1) && (architecture == Architecture_PIP)) + pipValid = True; + + /** Reset EP4 */ + error = Standard_writeRegisterBits (demodulator, 0, Processor_OFDM, p_reg_mp2_sw_rst, reg_mp2_sw_rst_pos, reg_mp2_sw_rst_len, 1); + if (error) goto exit; + + /** Reset EP5 */ + error = Standard_writeRegisterBits (demodulator, 0, Processor_OFDM, p_reg_mp2if2_sw_rst, reg_mp2if2_sw_rst_pos, reg_mp2if2_sw_rst_len, 1); + if (error) goto exit; + + /** Disable EP4 */ + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_ep4_tx_en, reg_ep4_tx_en_pos, reg_ep4_tx_en_len, 0); + if (error) goto exit; + + /** Disable EP5 */ + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_ep5_tx_en, reg_ep5_tx_en_pos, reg_ep5_tx_en_len, 0); + if (error) goto exit; + + /** Disable EP4 NAK */ + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_ep4_tx_nak, reg_ep4_tx_nak_pos, reg_ep4_tx_nak_len, 0); + if (error) goto exit; + + /** Disable EP5 NAK */ + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_ep5_tx_nak, reg_ep5_tx_nak_pos, reg_ep5_tx_nak_len, 0); + if (error) goto exit; + + /** Enable EP4 */ + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_ep4_tx_en, reg_ep4_tx_en_pos, reg_ep4_tx_en_len, 1); + if (error) goto exit; + + /** Set EP4 transfer length */ + buffer[p_reg_ep4_tx_len_7_0 - p_reg_ep4_tx_len_7_0] = (Byte) frameSize; + buffer[p_reg_ep4_tx_len_15_8 - p_reg_ep4_tx_len_7_0] = (Byte) (frameSize >> 8); + error = Standard_writeRegisters (demodulator, 0, Processor_LINK, p_reg_ep4_tx_len_7_0, 2, buffer); + + /** Set EP4 packet size */ + error = Standard_writeRegister (demodulator, 0, Processor_LINK, p_reg_ep4_max_pkt, packetSize); + if (error) goto exit; + + if (pipValid == True) { + /** Enable EP5 */ + error = Standard_writeRegisterBits (demodulator, 0, Processor_LINK, p_reg_ep5_tx_en, reg_ep5_tx_en_pos, reg_ep5_tx_en_len, 1); + if (error) goto exit; + + /** Set EP5 transfer length */ + buffer[p_reg_ep5_tx_len_7_0 - p_reg_ep5_tx_len_7_0] = (Byte) frameSize; + buffer[p_reg_ep5_tx_len_15_8 - p_reg_ep5_tx_len_7_0] = (Byte) (frameSize >> 8); + error = Standard_writeRegisters (demodulator, 0, Processor_LINK, p_reg_ep5_tx_len_7_0, 2, buffer); + + /** Set EP5 packet size */ + error = Standard_writeRegister (demodulator, 0, Processor_LINK, p_reg_ep5_max_pkt, packetSize); + if (error) goto exit; + } + + + /** Disable 15 SER/PAR mode */ + error = Standard_writeRegisterBits (demodulator, 0, Processor_OFDM, p_mp2if_mpeg_ser_mode, mp2if_mpeg_ser_mode_pos, mp2if_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, 0, Processor_OFDM, p_mp2if_mpeg_par_mode, mp2if_mpeg_par_mode_pos, mp2if_mpeg_par_mode_len, 0); + if (error) goto exit; + + if (pipValid == True) { + /** Enable mp2if2 */ + error = Standard_writeRegisterBits (demodulator, 0, Processor_OFDM, p_reg_mp2if2_en, reg_mp2if2_en_pos, reg_mp2if2_en_len, 1); + if (error) goto exit; + + for (i = 1; i < ganymede->chipNumber; i++) { + /** Enable serial mode */ + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, p_mp2if_mpeg_ser_mode, mp2if_mpeg_ser_mode_pos, mp2if_mpeg_ser_mode_len, 1); + if (error) goto exit; + + /** Enable HostB serial */ + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_top_hostb_mpeg_ser_mode, reg_top_hostb_mpeg_ser_mode_pos, reg_top_hostb_mpeg_ser_mode_len, 1); + if (error) goto exit; + } + + /** Enable tsis */ + error = Standard_writeRegisterBits (demodulator, 0, Processor_OFDM, p_reg_tsis_en, reg_tsis_en_pos, reg_tsis_en_len, 1); + if (error) goto exit; + } else { + /** Disable mp2if2 */ + error = Standard_writeRegisterBits (demodulator, 0, Processor_OFDM, p_reg_mp2if2_en, reg_mp2if2_en_pos, reg_mp2if2_en_len, 0); + if (error) goto exit; + + for (i = 1; i < ganymede->chipNumber; i++) { + /** Disable serial mode */ + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, p_mp2if_mpeg_ser_mode, mp2if_mpeg_ser_mode_pos, mp2if_mpeg_ser_mode_len, 0); + if (error) goto exit; + + /** Disable HostB serial */ + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_top_hostb_mpeg_ser_mode, reg_top_hostb_mpeg_ser_mode_pos, reg_top_hostb_mpeg_ser_mode_len, 0); + if (error) goto exit; + } + + /** Disable tsis */ + error = Standard_writeRegisterBits (demodulator, 0, Processor_OFDM, p_reg_tsis_en, reg_tsis_en_pos, reg_tsis_en_len, 0); + if (error) goto exit; + } + + /** Negate EP4 reset */ + error = Standard_writeRegisterBits (demodulator, 0, Processor_OFDM, p_reg_mp2_sw_rst, reg_mp2_sw_rst_pos, reg_mp2_sw_rst_len, 0); + if (error) goto exit; + + /** Negate EP5 reset */ + error = Standard_writeRegisterBits (demodulator, 0, Processor_OFDM, p_reg_mp2if2_sw_rst, reg_mp2if2_sw_rst_pos, reg_mp2if2_sw_rst_len, 0); + if (error) goto exit; + + if (pipValid == True) { + /** Split 15 PSB to 1K + 1K and enable flow control */ + error = Standard_writeRegisterBits (demodulator, 0, Processor_OFDM, p_reg_mp2if2_half_psb, reg_mp2if2_half_psb_pos, reg_mp2if2_half_psb_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, 0, Processor_OFDM, p_reg_mp2if_stop_en, reg_mp2if_stop_en_pos, reg_mp2if_stop_en_len, 1); + if (error) goto exit; + + for (i = 1; i < ganymede->chipNumber; i++) { + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, p_reg_mpeg_full_speed, reg_mpeg_full_speed_pos, reg_mpeg_full_speed_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, p_reg_mp2if_stop_en, reg_mp2if_stop_en_pos, reg_mp2if_stop_en_len, 0); + if (error) goto exit; + } + } + } + + ganymede->architecture = architecture; + +exit: +#endif + + return (error); +} + + +Dword Standard_setViterbiRange ( + IN Demodulator* demodulator, + IN Byte chip, + IN Byte superFrameCount, + IN Word packetUnit +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + SetStatisticRangeRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.chip = chip; + request.superFrameCount = superFrameCount; + request.packetUnit = packetUnit; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_SETSTATISTICRANGE, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Byte temp0; + Byte temp1; + + /** Set super frame count */ + error = Standard_writeRegister (demodulator, chip, Processor_OFDM, qnt_vbc_sframe_num, superFrameCount); + if (error) goto exit; + + /** Set packet unit. */ + temp0 = (Byte) packetUnit; + temp1 = (Byte) (packetUnit >> 8); + error = Standard_writeRegisters (demodulator, chip, Processor_OFDM, rsd_packet_unit_7_0, 1, &temp0); + if (error) goto exit; + error = Standard_writeRegisters (demodulator, chip, Processor_OFDM, rsd_packet_unit_15_8, 1, &temp1); + if (error) goto exit; + +exit: +#endif + + return (error); +} + + +Dword Standard_getViterbiRange ( + IN Demodulator* demodulator, + IN Byte chip, + IN Byte* frameCount, + IN Word* packetUnit +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + GetStatisticRangeRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.chip = chip; + request.superFrameCount = superFrameCount; + request.packetUnit = packetUnit; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_GETSTATISTICRANGE, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Byte temp0; + Byte temp1; + + /** Get super frame count */ + error = Standard_readRegister (demodulator, chip, Processor_OFDM, qnt_vbc_sframe_num, frameCount); + if (error) goto exit; + + /** Get packet unit. */ + error = Standard_readRegisters (demodulator, chip, Processor_OFDM, r_rsd_packet_unit_7_0, 1, &temp0); + if (error) goto exit; + error = Standard_readRegisters (demodulator, chip, Processor_OFDM, r_rsd_packet_unit_15_8, 1, &temp1); + if (error) goto exit; + *packetUnit = (Word) (temp1 << 8) + (Word) temp0; + +exit: +#endif + + return (error); +} + + +Dword Standard_getStatistic ( + IN Demodulator* demodulator, + IN Byte chip, + OUT Statistic* statistic +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + GetStatisticRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.chip = chip; + request.statistic = statistic; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_GETSTATISTIC, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Ganymede* ganymede; + Byte quality; + Byte strength; + Byte buffer[2]; + + ganymede = (Ganymede*) demodulator; + + /** Get statistic by stream type */ + error = Standard_readRegisters (demodulator, chip, Processor_OFDM, tpsd_lock, mpeg_lock - tpsd_lock + 1, buffer); + if (error) goto exit; + + if (buffer[tpsd_lock - tpsd_lock]) + ganymede->statistic[chip].signalPresented = True; + else + ganymede->statistic[chip].signalPresented = False; + + if (buffer[mpeg_lock - tpsd_lock]) + ganymede->statistic[chip].signalLocked = True; + else + ganymede->statistic[chip].signalLocked = False; + + error = Standard_getSignalQuality (demodulator, chip, &quality); + if (error) goto exit; + + ganymede->statistic[chip].signalQuality = quality; + + error = Standard_getSignalStrength (demodulator, chip, &strength); + if (error) goto exit; + + ganymede->statistic[chip].signalStrength = strength; + + *statistic = ganymede->statistic[chip]; + +exit : +#endif + + return (error); +} + + +Dword Standard_getInterrupts ( + IN Demodulator* demodulator, + OUT Interrupts* interrupts +) { + Dword error = Error_NO_ERROR; + Ganymede* ganymede; + Byte value = 0; + + ganymede = (Ganymede*) demodulator; + + /** Get interrupts by stream type */ + + + *interrupts = Interrupt_NONE; + + /** Read the interrupts register to determine the type of interrupts. */ + error = Standard_readRegister (demodulator, 0, Processor_LINK, r_link_ofsm_dvbt_int, &value); + if (error) goto exit; + + if (value & 0x04) { + ganymede->dataReady = True; + *interrupts |= Interrupt_DVBT; + } + +exit: + return (error); +} + + +Dword Standard_clearInterrupt ( + IN Demodulator* demodulator, + IN Interrupt interrupt +) { + Dword error = Error_NO_ERROR; + Ganymede* ganymede; + Byte value = 0; + + ganymede = (Ganymede*) demodulator; + + /** Clear interrupt by stream type */ + + //error = ganymede->dvbtStandardDescription.clearInterrupt (demodulator, interrupt); + value = (Byte) interrupt; + + /** Clear the specific interrupt. */ + error = Standard_writeRegister (demodulator, 0, Processor_LINK, p_reg_dvbt_intsts, value); + + return (error); +} + + +Dword Standard_getDataLength ( + IN Demodulator* demodulator, + OUT Dword* dataLength, + OUT Bool* valid /** used in DVBH mode */ +) { + Dword error = Error_NO_ERROR; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + /** Get data length by stream type */ + switch (ganymede->burstSize) { + case BurstSize_1024 : + *dataLength = 1024; + break; + case BurstSize_2048 : + *dataLength = 2048; + break; + case BurstSize_4096 : + *dataLength = 4096; + break; + } + *valid = True; + + return (error); +} + + +Dword Standard_getData ( + IN Demodulator* demodulator, + IN Dword bufferLength, + OUT Byte* buffer +) { + Dword error = Error_NO_ERROR; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + /** Get data by stream type */ + + //error = ganymede->dvbtStandardDescription.getData (demodulator, bufferLength, buffer); + + if (bufferLength == 0) { + error = Error_INVALID_DATA_LENGTH; + goto exit; + } + + + /** IP datagram is locate in a special register 0xF00000 */ + error = ganymede->cmdDescription->receiveData (demodulator, 0xF00000, bufferLength, buffer); + if (error) goto exit; + + ganymede->dataReady = False; + +exit: + return (error); +} + + +/** combine Standard_getLength and Standard_getData */ +Dword Standard_getDatagram ( + IN Demodulator* demodulator, + OUT Dword* bufferLength, + OUT Byte* buffer +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + GetDatagramRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.bufferLength = bufferLength; + request.buffer = buffer; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_GETDATAGRAM, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Ganymede* ganymede; + Dword length = 0; + Byte value; + Bool ready = False; + + ganymede = (Ganymede*) demodulator; + + /** Get datagram by stream type */ + + //error = ganymede->dvbtStandardDescription.getDatagram (demodulator, bufferLength, buffer); + +#if User_USE_INTERRUPT +#else + + error = Standard_readRegisterBits (demodulator, 0, Processor_LINK, r_link_ofsm_ip_valid, link_ofsm_ip_valid_pos, link_ofsm_ip_valid_len, &value); + if (error) goto exit; + + if (value) { + ganymede->dataReady = True; + } + if (ganymede->dataReady == False) { + *bufferLength = 0; + error = Error_NOT_READY; + goto exit; + } +#endif + switch (ganymede->burstSize) { + case BurstSize_1024 : + length = 1024; + break; + case BurstSize_2048 : + length = 2048; + break; + case BurstSize_4096 : + length = 4096; + break; + } + if (*bufferLength >= length) { + //error = Dvbt_getData (demodulator, length, (Byte*) buffer); + //if (error) goto exit; + + if (bufferLength == 0) { + error = Error_INVALID_DATA_LENGTH; + goto exit; + } + + + /** IP datagram is locate in a special register 0xF00000 */ + error = ganymede->cmdDescription->receiveData (demodulator, 0xF00000, length, buffer); + if (error) goto exit; + + *bufferLength = length; + + ganymede->dataReady = False; + + *bufferLength = length; + } else { + error = Error_BUFFER_INSUFFICIENT; + } + + +exit: +#endif + + return (error); +} + + +/** get ir raw code (4 bytes) */ +Dword Standard_getIrCode ( + IN Demodulator* demodulator, + OUT Dword* code +) { + Dword error = Error_NO_ERROR; + Byte readBuffer[4]; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + error = Standard_sendCommand (demodulator, Command_IR_GET, 0, Processor_LINK, 0, NULL, 4, readBuffer); + if (error) goto exit; + + *code = (Dword) ((readBuffer[0] << 24) + (readBuffer[1] << 16) + (readBuffer[2] << 8) + readBuffer[3]); + +exit : + return (error); +} + + +Dword Standard_reboot ( + IN Demodulator* demodulator +) { + Dword error = Error_NO_ERROR; + Dword version; + Byte i; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + error = Standard_getFirmwareVersion (demodulator, Processor_LINK, &version); + if (error) goto exit; + if (version == 0xFFFFFFFF) goto exit; /** I2M and I2U */ + if (version != 0) { + for (i = ganymede->chipNumber; i > 0; i--) { + error = ganymede->cmdDescription->reboot (demodulator, i - 1); + User_delay (demodulator, 1); + if (error) goto exit; + } + + if ((ganymede->busId == Bus_USB) || (ganymede->busId == Bus_USB11)) goto exit; + + User_delay (demodulator, 10); + + version = 1; + for (i = 0; i < 30; i++) { + error = Standard_getFirmwareVersion (demodulator, Processor_LINK, &version); + if (error == Error_NO_ERROR) break; + User_delay (demodulator, 10); + } + if (error) goto exit; + if (version != 0) + error = Error_REBOOT_FAIL; + } + for (i = ganymede->chipNumber; i > 0; i--) { + error = Standard_writeRegisterBits (demodulator, i - 1, Processor_LINK, p_reg_p_dmb_sw_reset, reg_p_dmb_sw_reset_pos, reg_p_dmb_sw_reset_len, 1); + if (error) goto exit; + } + + ganymede->booted = False; + +exit : + return (error); +} + + +Dword Standard_controlPowerSaving ( + IN Demodulator* demodulator, + IN Byte chip, + IN Byte control +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + ControlPowerSavingRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.chip = chip; + request.control = control; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_CONTROLPOWERSAVING, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Byte temp; + Byte begin; + Byte end; + Byte i; + Byte j; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->architecture == Architecture_DCA) { + begin = 0; + end = ganymede->chipNumber; + } else { + begin = chip; + end = begin + 1; + } + + if (control) { + /** Power up case */ + if ((ganymede->busId == Bus_USB) || (ganymede->busId == Bus_USB11)) { + for (i = begin; i < end; i++) { + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, p_reg_afe_mem0, 3, 1, 0); + if (error) goto exit; + } + } else { /** TS, SPI, and SDIO case */ + /** not implemented yet */ + } + + /** Fixed current leakage */ + switch (ganymede->busId) { + case Bus_SPI : + case Bus_SDIO : + case Bus_USB : + case Bus_USB11 : + if (ganymede->chipNumber > 1) { + for (i = 1; i < ganymede->chipNumber; i++) { + /** Disable HostA parallel */ + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_top_hosta_mpeg_ser_mode, reg_top_hosta_mpeg_ser_mode_pos, reg_top_hosta_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_top_hosta_mpeg_par_mode, reg_top_hosta_mpeg_par_mode_pos, reg_top_hosta_mpeg_par_mode_len, 0); + if (error) goto exit; + } + } + break; + } + } else { + /** Power down case */ + if ((ganymede->busId == Bus_USB) || (ganymede->busId == Bus_USB11)) { + for (i = begin; i < end; i++) { + error = Standard_writeRegister (demodulator, i, Processor_OFDM, suspend_flag, 1); + if (error) goto exit; + error = Standard_writeRegister (demodulator, i, Processor_OFDM, trigger_ofsm, 0); + if (error) goto exit; + + for (j = 0; j < 150; j++) { + error = Standard_readRegister (demodulator, i, Processor_OFDM, suspend_flag, &temp); + if (error) goto exit; + if (!temp) break; + User_delay (demodulator, 10); + } + error = Standard_writeRegisterBits (demodulator, i, Processor_OFDM, p_reg_afe_mem0, 3, 1, 1); + if (error) goto exit; + } + } else { /** TS SPI SDIO */ + /** not implemented yet */ + } + + /** Fixed current leakage */ + switch (ganymede->busId) { + case Bus_SPI : + case Bus_SDIO : + case Bus_USB : + case Bus_USB11 : + if (ganymede->chipNumber > 1) { + for (i = 1; i < ganymede->chipNumber; i++) { + /** Enable HostA parallel */ + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_top_hosta_mpeg_ser_mode, reg_top_hosta_mpeg_ser_mode_pos, reg_top_hosta_mpeg_ser_mode_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_top_hosta_mpeg_par_mode, reg_top_hosta_mpeg_par_mode_pos, reg_top_hosta_mpeg_par_mode_len, 1); + if (error) goto exit; + } + } + break; + } + } + +exit : +#endif + + return (error); +} + + +Dword Standard_controlTunerPowerSaving ( + IN Demodulator* demodulator, + IN Byte control +) { + Dword error = Error_NO_ERROR; + + if (control) { + error = Standard_writeRegister (demodulator, 0, Processor_LINK, p_reg_top_gpioh7_en, 1); + if (error) goto exit; + + error = Standard_writeRegister (demodulator, 0, Processor_LINK, p_reg_top_gpioh7_on, 1); + if (error) goto exit; + + error = Standard_writeRegister (demodulator, 0, Processor_LINK, p_reg_top_gpioh7_o, 1); + if (error) goto exit; + } else { + error = Standard_writeRegister (demodulator, 0, Processor_LINK, p_reg_top_gpioh7_en, 1); + if (error) goto exit; + + error = Standard_writeRegister (demodulator, 0, Processor_LINK, p_reg_top_gpioh7_on, 1); + if (error) goto exit; + + error = Standard_writeRegister (demodulator, 0, Processor_LINK, p_reg_top_gpioh7_o, 0); + if (error) goto exit; + } + +exit: + return (error); +} + + +Dword Standard_controlPidFilter ( + IN Demodulator* demodulator, + IN Byte chip, + IN Byte control +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + ControlPidFilterRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.chip = chip; + request.control = control; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_CONTROLPIDFILTER, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + error = Standard_writeRegisterBits (demodulator, chip, Processor_OFDM, p_mp2if_pid_en, mp2if_pid_en_pos, mp2if_pid_en_len, control); +#endif + + return (error); +} + + +Dword Standard_resetPidFilter ( + IN Demodulator* demodulator, + IN Byte chip +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER +#else + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + error = Standard_writeRegisterBits (demodulator, chip, Processor_OFDM, p_mp2if_pid_rst, mp2if_pid_rst_pos, mp2if_pid_rst_len, 1); + if (error) goto exit; + +exit : +#endif + + return (error); +} + + +Dword Standard_addPidToFilter ( + IN Demodulator* demodulator, + IN Byte chip, + IN Byte index, + IN Pid pid +) { + Dword error = Error_NO_ERROR; + +#if User_USE_DRIVER + DWORD number; + BOOL result; + AddPidRequest request; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + if (ganymede->driver != NULL) { + request.chip = chip; + request.pid = pid; + result = DeviceIoControl ( + ganymede->driver, + IOCTL_AFA_DEMOD_ADDPID, + &request, + sizeof (request), + NULL, + 0, + &number, + NULL + ); + error = request.error; + } else { + error = Error_DRIVER_INVALID; + } +#else + Byte writeBuffer[2]; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + /** Enable pid filter */ + error = Standard_writeRegisterBits (demodulator, chip, Processor_OFDM, p_mp2if_pid_en, mp2if_pid_en_pos, mp2if_pid_en_len, 1); + if (error) goto exit; + + writeBuffer[0] = (Byte) pid.value; + writeBuffer[1] = (Byte) (pid.value >> 8); + + error = Standard_writeRegisters (demodulator, chip, Processor_OFDM, p_mp2if_pid_dat_l, 2, writeBuffer); + if (error) goto exit; + + error = Standard_writeRegisterBits (demodulator, chip, Processor_OFDM, p_mp2if_pid_index_en, mp2if_pid_index_en_pos, mp2if_pid_index_en_len, 1); + if (error) goto exit; + + error = Standard_writeRegister (demodulator, chip, Processor_OFDM, p_mp2if_pid_index, index); + if (error) goto exit; + +exit : +#endif + + return (error); +} + + +Dword Standard_setBurstSize ( + IN Demodulator* demodulator, + IN BurstSize burstSize +) { + Dword error = Error_NO_ERROR; + Byte i; + Ganymede* ganymede; + + ganymede = (Ganymede*) demodulator; + + + if (burstSize == BurstSize_4096) { + error = Error_NOT_SUPPORT; + goto exit; + } + + + switch (burstSize) { + case BurstSize_1024 : + for (i = 0; i < ganymede->chipNumber; i++) { + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_dvbt_path, reg_dvbt_path_pos, reg_dvbt_path_len, 1); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_dvbt_bufsize, reg_dvbt_bufsize_pos, reg_dvbt_bufsize_len, 1); + if (error) goto exit; + } + ganymede->burstSize = BurstSize_1024; + break; + case BurstSize_2048 : + for (i = 0; i < ganymede->chipNumber; i++) { + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_dvbt_path, reg_dvbt_path_pos, reg_dvbt_path_len, 1); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_dvbt_bufsize, reg_dvbt_bufsize_pos, reg_dvbt_bufsize_len, 0); + if (error) goto exit; + } + ganymede->burstSize = BurstSize_2048; + + break; + case BurstSize_4096 : + for (i = 0; i < ganymede->chipNumber; i++) { + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_dvbt_path, reg_dvbt_path_pos, reg_dvbt_path_len, 0); + if (error) goto exit; + error = Standard_writeRegisterBits (demodulator, i, Processor_LINK, p_reg_dvbt_bufsize, reg_dvbt_bufsize_pos, reg_dvbt_bufsize_len, 1); + if (error) goto exit; + } + ganymede->burstSize = BurstSize_4096; + break; + } + +exit : + return (error); +} + + +Dword Standard_getBurstSize ( + IN Demodulator* demodulator, + IN BurstSize* burstSize +) { + Dword error = Error_NO_ERROR; + Byte path; + Byte size; + + error = Standard_readRegisterBits (demodulator, 0, Processor_LINK, p_reg_dvbt_path, reg_dvbt_path_pos, reg_dvbt_path_len, &path); + if (error) goto exit; + error = Standard_readRegisterBits (demodulator, 0, Processor_LINK, p_reg_dvbt_bufsize, reg_dvbt_bufsize_pos, reg_dvbt_bufsize_len, &size); + if (error) goto exit; + + if (path) { + if (size) { + *burstSize = BurstSize_1024; + } else { + *burstSize = BurstSize_2048; + } + } else { + if (size) { + *burstSize = BurstSize_4096; + } else { + *burstSize = BurstSize_2048; + } + } + +exit : + return (error); +} |