Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

545 lines
14 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Philips Semiconductors-CSU 1999
  4. // All rights are reserved. Reproduction in whole or in part is prohibited
  5. // without the written consent of the copyright owner.
  6. //
  7. // Philips reserves the right to make changes without notice at any time.
  8. // Philips makes no warranty, expressed, implied or statutory, including but
  9. // not limited to any implied warranty of merchantibility or fitness for any
  10. // particular purpose, or that the use will not infringe any third party
  11. // patent, copyright or trademark. Philips must not be liable for any loss
  12. // or damage arising from its use.
  13. //
  14. // VSB2.CPP
  15. // Class CVSB2Demod Implementation
  16. //////////////////////////////////////////////////////////////////////////////
  17. #include "philtune.h"
  18. #include "vsb2.h"
  19. UCHAR Vsb2InitArray[] =
  20. { 0x00, 0x00, 0x00, 0x00, 0x00,
  21. 0x01, 0x20, 0x0E, 0x04, 0x80,
  22. 0x00, 0x00, 0x00, 0x44 ,0x24,
  23. 0x00, 0x80, 0x02, 0x80, 0x00,
  24. 0xCA, 0xFC, 0x96, 0x66, 0x22,
  25. 0x2F, 0x00, 0xFC, 0x96, 0x66,
  26. 0x00, 0x00, 0x00, 0x00, 0x00,
  27. 0x00, 0x20, 0x00, 0x40, 0x00,
  28. 0x60, 0x00, 0x00, 0x00, 0x00,
  29. 0x02, 0x00, 0x04, 0x38, 0x00,
  30. 0x00, 0x00, 0x00, 0x00};
  31. /*
  32. * CVSB2Demod()
  33. * Input :
  34. * Output:
  35. * Description: CVSB2Demod Constructor.
  36. */
  37. CVSB2Demod::CVSB2Demod(CI2CScript *p_I2CScript, BoardInfoType *p_BoardInfo, NTSTATUS *p_Status)
  38. :CVSBDemod(p_I2CScript, p_BoardInfo, p_Status)
  39. {
  40. Initialize();
  41. }
  42. /*
  43. * ~CVSB2Demod()
  44. * Input :
  45. * Output:
  46. * Description: CVSB2Demod Destructor.
  47. */
  48. CVSB2Demod::~CVSB2Demod()
  49. {
  50. }
  51. #if 0
  52. /*
  53. * operator new
  54. * Purpose: CVSB2Demod class overrides operator new.
  55. *
  56. * Inputs : UINT uiSize : size of the object to be placed
  57. *
  58. * Outputs: PVOID : pointer of the CVSB2Demod class object
  59. * Author : MM
  60. */
  61. PVOID CVSB2Demod::operator new(UINT uiSize)
  62. {
  63. if (uiSize != sizeof(CVSB2Demod))
  64. {
  65. _DbgPrintF( DEBUGLVL_ERROR,("CVSB2Demod: operator new() fails\n"));
  66. return(NULL);
  67. }
  68. return (AllocateFixedMemory(uiSize));
  69. }
  70. /*
  71. * operator delete
  72. * Purpose: CVSB2Demod class overrides operator delete
  73. *
  74. * Inputs : PVOID p_Buffer : pointer to object being deleted
  75. *
  76. * Outputs:
  77. * Author : MM
  78. */
  79. void CVSB2Demod::operator delete(PVOID p_Object)
  80. {
  81. if(p_Object != NULL)
  82. FreeFixedMemory(p_Object);
  83. _DbgPrintF( DEBUGLVL_VERBOSE,("CVSB2Demod: operator delete() succeeds\n"));
  84. }
  85. #endif
  86. /*
  87. * Initialize()
  88. * Input :
  89. * Output: TRUE - if initialization data can be written to I2C
  90. * FALSE - if there is an I2C error
  91. * Description: Initialize.
  92. */
  93. BOOL CVSB2Demod::Initialize()
  94. {
  95. m_uiMaxControlRegisterAddress = VSB2_CONTROL_SIZE - 1;
  96. //Mini: 2/18/2000
  97. // Adding a check to see if the version status register exists, this indicates
  98. // that its verison N1E or higher
  99. UCHAR ucStatus[VSB2_STATUS_SIZE+1];
  100. ucStatus[VSB2_STATUS_SIZE] = 0;
  101. Read(ucStatus, VSB2_STATUS_SIZE+1, 0);
  102. if(ucStatus != 0)
  103. m_uiMaxStatusRegisterAddress = VSB2_STATUS_SIZE;
  104. else
  105. m_uiMaxStatusRegisterAddress = VSB2_STATUS_SIZE - 1;
  106. return TRUE;
  107. // return (InitVSB());
  108. }
  109. /*
  110. * InitVSB()
  111. * Input :
  112. * Output: TRUE - if initialization data can be written to I2C
  113. * FALSE - if there is an I2C error
  114. * Description: Initialize the VSB chip with default values.
  115. */
  116. BOOL CVSB2Demod::InitVSB()
  117. {
  118. BOOL bResult;
  119. MemoryCopy(m_ucControlReg, Vsb2InitArray, sizeof(Vsb2InitArray));
  120. // Write I2C sequence to chip
  121. bResult = m_pI2CScript->WriteSeq(VSB_I2C_ADDRESS, Vsb2InitArray,
  122. sizeof Vsb2InitArray);
  123. if (bResult)
  124. {
  125. _DbgPrintF( DEBUGLVL_VERBOSE,("CVSB2Demod: Demodulator Init PASSED !!! ------------ \n"));
  126. }
  127. else
  128. {
  129. _DbgPrintF( DEBUGLVL_ERROR,("CVSB2Demod: Demodulator Init FAILED !!! ------------ \n"));
  130. }
  131. // return (bResult & bResult1);
  132. return bResult;
  133. }
  134. /*
  135. * GetStatus()
  136. * Input : PVsbStatusType p_Status : pointer to Status structure
  137. * Output: TRUE - if status can be read from I2C
  138. * FALSE - if there is an I2C error
  139. * Description: Get chip status.
  140. */
  141. BOOL CVSB2Demod::GetStatus(PVsbStatusType p_Status)
  142. {
  143. BOOL bResult;
  144. UINT uiNumCoeff;
  145. UINT uiLength;
  146. UCHAR ucStatus[VSB2_STATUS_SIZE+1];
  147. Vsb2StatusType AllStatus;
  148. if(GetStatus(&AllStatus))
  149. {
  150. MemoryCopy(p_Status, &AllStatus.Status, sizeof(VsbStatusType));
  151. return TRUE;
  152. }
  153. else
  154. return FALSE;
  155. }
  156. /*
  157. * GetStatus()
  158. * Input : PVsb2StatusType p_Status : pointer to Status structure
  159. * Output: TRUE - if status can be read from I2C
  160. * FALSE - if there is an I2C error
  161. * Description: Get chip status.
  162. */
  163. BOOL CVSB2Demod::GetStatus(PVsb2StatusType p_Status)
  164. {
  165. BOOL bResult;
  166. UINT uiNumCoeff;
  167. UINT uiLength;
  168. UCHAR ucStatus[VSB2_STATUS_SIZE+1];
  169. m_RegisterLock.Lock();
  170. RegisterType Status;
  171. Status.uiAddress = 0;
  172. Status.uiLength = m_uiMaxStatusRegisterAddress+1; //VSB2_STATUS_SIZE
  173. Status.p_ucBuffer = ucStatus;
  174. if(ReadStatusReg(&Status, 1) == WDMMINI_NOERROR)
  175. bResult = TRUE;
  176. else
  177. bResult = FALSE;
  178. m_RegisterLock.Unlock();
  179. if(bResult == TRUE)
  180. {
  181. p_Status->Status.bFrontEndLock = (ucStatus[VSB_REG_STATE] & 0x4) >> 2;
  182. p_Status->Status.ucState = ucStatus[VSB_REG_STATE] & 0x3;
  183. p_Status->Status.bEqualizerLock =
  184. ((ucStatus[VSB_REG_STATE] & 0x7) == 0x7) ? 1 : 0;
  185. p_Status->Status.uiMse =
  186. ((UINT(ucStatus[VSB2_REG_MSE_1]) << 8) & 0xff00) |
  187. (UINT(ucStatus[VSB2_REG_MSE_2]) & 0xff);
  188. p_Status->Status.ucCarrierOffset =
  189. UCHAR(ucStatus[VSB2_REG_CARRIER_OFFSET]) & 0xff;
  190. p_Status->Status.uiSegmentErrorRate =
  191. ((UINT(ucStatus[VSB2_REG_SER_1]) << 8) & 0xff00) |
  192. (UINT(ucStatus[VSB2_REG_SER_2]) & 0xff);
  193. p_Status->bCorrelatorError =
  194. (ucStatus[VSB2_REG_CORRELATOR] & 0x2) >> 1;
  195. p_Status->bCorrelatorFull =
  196. ucStatus[VSB2_REG_CORRELATOR] & 0x1;
  197. }
  198. // _DbgPrintF( DEBUGLVL_TERSE,("CPhilipsWDMTuner:VSB status = %x %x %x %x\n",m_8VSBStatus[0], m_8VSBStatus[1],
  199. // m_8VSBStatus[2], m_8VSBStatus[3]));
  200. return(bResult);
  201. }
  202. /*
  203. * EnableCoefficients()
  204. * Input: UCHAR ucEnable
  205. * Output :
  206. * Description: Set the enable coefficients register
  207. */
  208. BOOL CVSB2Demod::EnableCoefficients(UCHAR ucEnable)
  209. {
  210. _DbgPrintF( DEBUGLVL_VERBOSE,("CVSB2Demod::EnableCoefficients()\n"));
  211. /* if(ucEnable & CORRELATOR_ID)
  212. {
  213. if(!EnableCorrelatorRead())
  214. return FALSE;
  215. if(!WaitForCorrelatorFull())
  216. return FALSE;
  217. }
  218. */
  219. m_ucControlReg[VSB2_REG_COEFFICIENT_ENABLE] |= ucEnable;
  220. if(Write(m_ucControlReg, (VSB2_REG_COEFFICIENT_ENABLE + 1), 0)== WDMMINI_NOERROR)
  221. return TRUE;
  222. else
  223. return FALSE;
  224. }
  225. /*
  226. * DisableCoefficients()
  227. * Input:
  228. * Output :
  229. * Description: Disable coefficient read/write
  230. */
  231. BOOL CVSB2Demod::DisableCoefficients(UINT ucEnable)
  232. {
  233. _DbgPrintF( DEBUGLVL_VERBOSE,("CVSB2Demod::DisableCoefficients()\n"));
  234. // m_ucControlReg[VSB2_REG_COEFFICIENT_ENABLE] = 0;
  235. m_ucControlReg[VSB2_REG_COEFFICIENT_ENABLE] &= (~ucEnable);
  236. if(Write(m_ucControlReg, (VSB2_REG_COEFFICIENT_ENABLE + 1), 0)!= WDMMINI_NOERROR)
  237. return FALSE;
  238. else
  239. return TRUE;
  240. }
  241. /*
  242. * DisableCoefficients()
  243. * Input:
  244. * Output :
  245. * Description: Disable coefficient read/write
  246. */
  247. BOOL CVSB2Demod::DisableCoefficients()
  248. {
  249. _DbgPrintF( DEBUGLVL_VERBOSE,("CVSB2Demod::DisableCoefficients()\n"));
  250. m_ucControlReg[VSB2_REG_COEFFICIENT_ENABLE] = 0;
  251. if(Write(m_ucControlReg, (VSB2_REG_COEFFICIENT_ENABLE + 1), 0)!= WDMMINI_NOERROR)
  252. return FALSE;
  253. else
  254. return TRUE;
  255. }
  256. BOOL CVSB2Demod::EnableCorrelatorRead()
  257. {
  258. // Reset correlator ?????
  259. // m_ucControlReg[VSB2_CTRL_REG_CORRELATOR] |= 0x08;
  260. // if(Write(m_ucControlReg, (VSB2_CTRL_REG_CORRELATOR + 1), 0) != WDMMINI_NOERROR)
  261. // return FALSE;
  262. // should I set the correlator length too based on the length passed in
  263. // property set . I don't think so as there will be no information on the
  264. // start and end
  265. // Clear reset and Set correlator fill flag
  266. // m_ucControlReg[VSB2_CTRL_REG_CORRELATOR] &= 0xF7;
  267. m_ucControlReg[VSB2_CTRL_REG_CORRELATOR] |= 0x10;
  268. if(Write(m_ucControlReg, (VSB2_CTRL_REG_CORRELATOR + 1), 0)!= WDMMINI_NOERROR)
  269. return FALSE;
  270. return TRUE;
  271. }
  272. BOOL CVSB2Demod::WaitForCorrelatorFull()
  273. {
  274. UCHAR ucStatus[10];
  275. UINT uiTimeout = 100;
  276. while(uiTimeout)
  277. {
  278. if(Read(ucStatus, sizeof(ucStatus), 0)!= WDMMINI_NOERROR)
  279. return FALSE;
  280. if(ucStatus[VSB2_REG_CORRELATOR] & 0xFE)
  281. break;
  282. // Delay of 100ms
  283. Delay(100000);
  284. uiTimeout--;
  285. }
  286. // Disable Correlator FILL
  287. m_ucControlReg[VSB2_CTRL_REG_CORRELATOR] &= 0xEF;
  288. Write(m_ucControlReg, (VSB2_CTRL_REG_CORRELATOR + 1), 0);
  289. if(uiTimeout == 0)
  290. return FALSE;
  291. return TRUE;
  292. }
  293. /*
  294. * CoeffIDToAddress()
  295. * Input: UINT uiID - ID
  296. * UINT *p_uiAddress - The address pointer
  297. * Output : TRUE: If ID can be translated
  298. * FALSE: IF ID does not exist
  299. * Description: Translate coefficient ID to address
  300. */
  301. BOOL CVSB2Demod::CoeffIDToAddress(UINT uiID, UINT *p_uiAddress,
  302. UINT uiRegisterType)
  303. {
  304. _DbgPrintF( DEBUGLVL_VERBOSE,("CVSB2Demod::CoeffIDToAddress()\n"));
  305. if(uiRegisterType == WRITE_REGISTERS)
  306. {
  307. switch(uiID)
  308. {
  309. case EQUALIZER_ID:
  310. *p_uiAddress = VSB2_CTRL_REG_EQUALIZER_COEFF;
  311. break;
  312. case EQUALIZER_CLUSTER_ID:
  313. *p_uiAddress = VSB2_CTRL_REG_EQUALIZER_CLUSTER_COEFF;
  314. break;
  315. case SYNC_ENHANCER_ID:
  316. *p_uiAddress = VSB2_CTRL_REG_SYNC_ENHANCER_COEFF;
  317. break;
  318. case NTSC_COCHANNEL_REJECTION_ID:
  319. *p_uiAddress = VSB2_CTRL_REG_COCHANNEL_REJECTION_COEFF;
  320. break;
  321. default:
  322. *p_uiAddress = 0;
  323. return FALSE;
  324. }
  325. }
  326. else
  327. {
  328. switch(uiID)
  329. {
  330. case EQUALIZER_ID:
  331. *p_uiAddress = VSB2_STATUS_REG_EQUALIZER_COEFF;
  332. break;
  333. case EQUALIZER_CLUSTER_ID:
  334. *p_uiAddress = VSB2_STATUS_REG_EQUALIZER_CLUSTER_COEFF;
  335. break;
  336. case SYNC_ENHANCER_ID:
  337. *p_uiAddress = VSB2_STATUS_REG_SYNC_ENHANCER_COEFF;
  338. break;
  339. case NTSC_COCHANNEL_REJECTION_ID:
  340. *p_uiAddress = VSB2_STATUS_REG_COCHANNEL_REJECTION_COEFF;
  341. break;
  342. case CORRELATOR_ID:
  343. *p_uiAddress = VSB2_REG_CORRELATOR_COEFF;
  344. break;
  345. default:
  346. *p_uiAddress = 0;
  347. return FALSE;
  348. }
  349. }
  350. return TRUE;
  351. }
  352. /*
  353. * SetOutputMode()
  354. * Input:
  355. * Output :
  356. * Description: Set The output mode (Normal/Diagnostic/ITU656/Serialized input)
  357. */
  358. BOOL CVSB2Demod::SetOutputMode(UINT uiOutputMode)
  359. {
  360. RegisterType Control;
  361. UCHAR ucOutput;
  362. UCHAR ucMask;
  363. ucOutput = m_ucControlReg[VSB2_REG_TS_OUT_1] & VSB2_TS_OUT_MODE_MASK;
  364. ucOutput |= (uiOutputMode << 2); // shifted by 2 bits
  365. Control.uiAddress = VSB2_REG_TS_OUT_1;
  366. Control.uiLength = 1;
  367. Control.p_ucBuffer = &ucOutput;
  368. // Reset chip
  369. if(SetControlRegister(&Control, 1) != WDMMINI_NOERROR)
  370. return FALSE;
  371. return TRUE;
  372. }
  373. /*
  374. * GetOutputMode()
  375. * Input:
  376. * Output :
  377. * Description: Get The output mode (Normal/Diagnostic/ITU656/Serialized input)
  378. */
  379. BOOL CVSB2Demod::GetOutputMode(UINT *p_uiOutputMode)
  380. {
  381. RegisterType Control;
  382. UCHAR ucOutput;
  383. UCHAR ucMask;
  384. ucOutput = m_ucControlReg[VSB2_REG_TS_OUT_1] & (~VSB2_TS_OUT_MODE_MASK);
  385. ucOutput >>= 2 ; // sifted by 2 bits
  386. *p_uiOutputMode = (UINT)(ucOutput & 0x3); // mask of all bits but the 2 LSBs
  387. return TRUE;
  388. }
  389. /*
  390. * SetDiagMode()
  391. * Input: ULONG ulMode - Diagnostic mode(enumeration VSBDIAGTYPE)
  392. * Output :
  393. * Description: Set The diag mode
  394. */
  395. BOOL CVSB2Demod::SetDiagMode(VSBDIAGTYPE ulMode)
  396. {
  397. RegisterType Control;
  398. UCHAR ucOutput;
  399. UCHAR ucMask;
  400. if((((LONG)ulMode >= EQUALIZER_OUT) && (ulMode <= TRELLIS_DEC_DIAG_OUT)) ||
  401. ((ulMode >= TRELLIS_DEC_OUT) && (ulMode <= SRC_OUT)))
  402. {
  403. ucOutput = UCHAR(ulMode);
  404. Control.uiAddress = VSB2_REG_DIAG_SELECT;
  405. Control.uiLength = 1;
  406. Control.p_ucBuffer = &ucOutput;
  407. // Reset chip
  408. if(SetControlRegister(&Control, 1) != WDMMINI_NOERROR)
  409. return FALSE;
  410. return TRUE;
  411. }
  412. else
  413. return FALSE;
  414. }
  415. /*
  416. * GetDiagMode()
  417. * Input: ULONG *p_ulMode - pointer to diagnostic mode
  418. * Output : Diagnostic mode (enumeration VSBDIAGTYPE)
  419. * Description: Get The Diag mode
  420. */
  421. BOOL CVSB2Demod::GetDiagMode(ULONG *p_ulMode)
  422. {
  423. RegisterType Control;
  424. UCHAR ucOutput;
  425. UCHAR ucMask;
  426. *p_ulMode = (UINT)(m_ucControlReg[VSB2_REG_DIAG_SELECT]) &
  427. (~VSB2_DIAG_MODE_MASK);
  428. return TRUE;
  429. }
  430. /*
  431. * GetDiagSpeed()
  432. * Input: ULONG ulType - Diagnostic type
  433. * Output : Diagnostic speed
  434. * Description: Get The Diagnostic data speed
  435. */
  436. ULONG CVSB2Demod::GetDiagSpeed(ULONG ulType)
  437. {
  438. RegisterType Control;
  439. UCHAR ucOutput;
  440. UCHAR ucMask;
  441. ULONG ulSpeed;
  442. switch(ulType)
  443. {
  444. case EQUALIZER_OUT:
  445. case CR_ERROR:
  446. case TR_ERROR:
  447. case EQUALIZER_IN:
  448. case TRELLIS_DEC_DIAG_OUT:
  449. case SYNC_ENHANCER_REAL_IN:
  450. ulSpeed = TENPOINT76MHZ;
  451. break;
  452. case TRELLIS_DEC_OUT:
  453. case REED_SOLOMON_DIAG_OUT:
  454. ulSpeed = TWOPOINT69MHZ;
  455. break;
  456. case SRC_OUT:
  457. ulSpeed = TWENTYONEPOINT52MHZ;
  458. break;
  459. default:
  460. ulSpeed = 0;
  461. break;
  462. }
  463. return ulSpeed;
  464. }