/*------------------------------------------------------------------------------ Copyright 2018 Sony Semiconductor Solutions Corporation Last Updated : 2018/08/30 Modification ID : 902dae58eb5249e028ccc5d7f60bb66cca9b43a9 ------------------------------------------------------------------------------*/ #include "sony_integ_atsc.h" #include "sony_demod_atsc_monitor.h" #include /*------------------------------------------------------------------------------ Static Function Prototypes ------------------------------------------------------------------------------*/ /** @brief Waits for demodulator lock, polling ::sony_demod_atsc_monitor_SyncStat at 10ms intervals. Called as part of the Tune process. */ static sony_result_t atsc_WaitVQLock (sony_integ_t * pInteg); #define PR_DTUN printf /*------------------------------------------------------------------------------ Functions ------------------------------------------------------------------------------*/ sony_result_t sony_integ_atsc_Tune (sony_integ_t * pInteg, sony_atsc_tune_param_t * pTuneParam) { sony_result_t result; SONY_TRACE_ENTER ("sony_integ_atsc_Tune"); if ((!pInteg) || (!pTuneParam) || (!pInteg->pDemod)) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } if ((pInteg->pDemod->state != SONY_DEMOD_STATE_SLEEP) && (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE)) { /* This api is accepted in Sleep and Active states only */ SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE); } //PR_TUN("dbg_pr [%s,%d] freq=%d\n",__FUNCTION__,__LINE__,pTuneParam->centerFreqKHz); /* Tune the demodulator */ result = sony_demod_atsc_Tune (pInteg->pDemod, pTuneParam); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } if ((pInteg->pTuner) && (pInteg->pTuner->TerrCableTune)) { /* Enable the I2C repeater */ result = sony_demod_I2cRepeaterEnable (pInteg->pDemod, 0x01); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } PR_DTUN("dbg_pr [%s,%d] sony_demod_I2cRepeaterEnable 1\n",__FUNCTION__,__LINE__); /* Tune the RF part */ result = pInteg->pTuner->TerrCableTune (pInteg->pTuner, pTuneParam->centerFreqKHz, SONY_DTV_SYSTEM_ATSC, SONY_DTV_BW_6_MHZ); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } PR_DTUN("dbg_pr [%s,%d] TerrCableTune \n",__FUNCTION__,__LINE__); /* Disable the I2C repeater */ result = sony_demod_I2cRepeaterEnable (pInteg->pDemod, 0x00); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } PR_DTUN("dbg_pr [%s,%d] sony_demod_I2cRepeaterEnable 0\n",__FUNCTION__,__LINE__); } result = sony_demod_atsc_TuneEnd(pInteg->pDemod); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } PR_DTUN("dbg_pr [%s,%d] sony_demod_atsc_TuneEnd ,scanmode=%d \n",__FUNCTION__,__LINE__,pInteg->pDemod->scanMode); if (!pInteg->pDemod->scanMode) { result = sony_integ_atsc_WaitTSLock(pInteg); if (result != SONY_RESULT_OK) { PR_DTUN("dbg_pr [%s,%d] result=%d\n",__FUNCTION__,__LINE__,result); // 5 SONY_TRACE_RETURN (result); } } else { result = atsc_WaitVQLock(pInteg); if (result != SONY_RESULT_OK) { PR_DTUN("dbg_pr [%s,%d] \n",__FUNCTION__,__LINE__); SONY_TRACE_RETURN (result); } } SONY_TRACE_RETURN (SONY_RESULT_OK); } sony_result_t sony_integ_atsc_Scan (sony_integ_t * pInteg, sony_integ_atsc_scan_param_t * pScanParam, sony_integ_atsc_scan_callback_t callBack) { sony_result_t result = SONY_RESULT_OK; sony_integ_atsc_scan_result_t scanResult; SONY_TRACE_ENTER ("sony_integ_atsc_Scan"); if ((!pInteg) || (!pScanParam) || (!callBack) || (!pInteg->pDemod)) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } if ((pInteg->pDemod->state != SONY_DEMOD_STATE_SLEEP) && (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE)) { /* This api is accepted in Sleep and Active states only */ SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE); } /* Ensure the scan parameters are valid. */ if (pScanParam->endFrequencyKHz < pScanParam->startFrequencyKHz) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } if (pScanParam->stepFrequencyKHz == 0) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } /* Set the start frequency */ scanResult.centerFreqKHz = pScanParam->startFrequencyKHz; scanResult.tuneResult = SONY_RESULT_OK; scanResult.tuneParam.centerFreqKHz = pScanParam->startFrequencyKHz; /* Set scan mode enabled */ result = sony_demod_terr_cable_SetScanMode(pInteg->pDemod, SONY_DTV_SYSTEM_ATSC, 0x01); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } /* Scan routine */ while (scanResult.centerFreqKHz <= pScanParam->endFrequencyKHz) { scanResult.tuneParam.centerFreqKHz = scanResult.centerFreqKHz; scanResult.tuneResult = sony_integ_atsc_Tune(pInteg, &scanResult.tuneParam); switch (scanResult.tuneResult) { /* Channel found, callback to application */ case SONY_RESULT_OK: callBack (pInteg, &scanResult, pScanParam); break; case SONY_RESULT_ERROR_UNLOCK: case SONY_RESULT_ERROR_TIMEOUT: /* Channel not found, callback to application for progress updates */ callBack (pInteg, &scanResult, pScanParam); break; default: /* Serious error occurred -> cancel operation. */ sony_demod_terr_cable_SetScanMode(pInteg->pDemod, SONY_DTV_SYSTEM_ATSC, 0x00); SONY_TRACE_RETURN (scanResult.tuneResult); } scanResult.centerFreqKHz += pScanParam->stepFrequencyKHz; /* Check cancellation. */ result = sony_integ_CheckCancellation (pInteg); if (result != SONY_RESULT_OK) { sony_demod_terr_cable_SetScanMode(pInteg->pDemod, SONY_DTV_SYSTEM_ATSC, 0x00); SONY_TRACE_RETURN (result); } } /* Clear scan mode */ result = sony_demod_terr_cable_SetScanMode(pInteg->pDemod, SONY_DTV_SYSTEM_ATSC, 0x00); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } SONY_TRACE_RETURN (result); } sony_result_t sony_integ_atsc_WaitTSLock (sony_integ_t * pInteg) { sony_result_t result = SONY_RESULT_OK; sony_demod_lock_result_t lock = SONY_DEMOD_LOCK_RESULT_NOTDETECT; sony_stopwatch_t timer; uint8_t continueWait = 1; uint32_t elapsed = 0; /*uint32_t waitTimeOut = 0;*/ SONY_TRACE_ENTER ("sony_integ_atsc_WaitTSLock"); if ((!pInteg) || (!pInteg->pDemod)) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } if (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE) { /* This api is accepted in Active state only */ SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE); } /* Wait for TS lock */ result = sony_stopwatch_start (&timer); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } for (;;) { result = sony_stopwatch_elapsed(&timer, &elapsed); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } if (elapsed >= SONY_ATSC_WAIT_TS_LOCK) { continueWait = 0; } result = sony_demod_atsc_CheckTSLock (pInteg->pDemod, &lock); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } switch (lock) { case SONY_DEMOD_LOCK_RESULT_LOCKED: SONY_TRACE_RETURN (SONY_RESULT_OK); case SONY_DEMOD_LOCK_RESULT_UNLOCKED: SONY_TRACE_RETURN (SONY_RESULT_ERROR_UNLOCK); default: /* continue waiting... */ break; } /* Check cancellation. */ result = sony_integ_CheckCancellation (pInteg); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } if (continueWait) { result = sony_stopwatch_sleep (&timer, SONY_ATSC_WAIT_LOCK_INTERVAL); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } } else { result = SONY_RESULT_ERROR_TIMEOUT; break; } } SONY_TRACE_RETURN (result); } sony_result_t sony_integ_atsc_monitor_RFLevel (sony_integ_t * pInteg, int32_t * pRFLeveldB) { sony_result_t result = SONY_RESULT_OK; SONY_TRACE_ENTER ("sony_integ_atsc_WaitTSLock"); if ((!pInteg) || (!pInteg->pDemod) || (!pRFLeveldB)) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } if (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE) { /* This api is accepted in Active state only */ SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE); } if (pInteg->pDemod->system != SONY_DTV_SYSTEM_ATSC) { /* Not ATSC */ SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE); } if (!pInteg->pTuner) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT); } if (pInteg->pTuner->rfLevelFuncTerr == SONY_TUNER_RFLEVEL_FUNC_READ && pInteg->pTuner->ReadRFLevel) { /* Enable the I2C repeater */ result = sony_demod_I2cRepeaterEnable (pInteg->pDemod, 0x01); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } result = pInteg->pTuner->ReadRFLevel (pInteg->pTuner, pRFLeveldB); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } /* Disable the I2C repeater */ result = sony_demod_I2cRepeaterEnable (pInteg->pDemod, 0x00); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } } else if (pInteg->pTuner->rfLevelFuncTerr == SONY_TUNER_RFLEVEL_FUNC_CALCFROMAGC && pInteg->pTuner->CalcRFLevelFromAGC) { uint32_t ifAgc; result = sony_demod_atsc_monitor_IFAGCOut (pInteg->pDemod, &ifAgc); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } result = pInteg->pTuner->CalcRFLevelFromAGC (pInteg->pTuner, ifAgc, pRFLeveldB); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } } else { SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT); } /* dBm * 100 -> dBm * 1000 */ *pRFLeveldB *= 10; SONY_TRACE_RETURN (SONY_RESULT_OK); } /*------------------------------------------------------------------------------ Static Functions ------------------------------------------------------------------------------*/ static sony_result_t atsc_WaitVQLock (sony_integ_t * pInteg) { sony_result_t result = SONY_RESULT_OK; sony_demod_lock_result_t lock = SONY_DEMOD_LOCK_RESULT_NOTDETECT; sony_stopwatch_t timer; uint8_t continueWait = 1; uint32_t elapsed = 0; uint32_t waitTimeOut = 0; SONY_TRACE_ENTER ("atsc_WaitVQLock"); if ((!pInteg) || (!pInteg->pDemod)) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } if (pInteg->pDemod->state != SONY_DEMOD_STATE_ACTIVE) { /* This api is accepted in ACTIVE state only */ SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE); } waitTimeOut = SONY_ATSC_WAIT_DEMOD_LOCK; /* Wait for demod lock */ result = sony_stopwatch_start (&timer); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } for (;;) { result = sony_stopwatch_elapsed(&timer, &elapsed); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } if (elapsed >= waitTimeOut) { continueWait = 0; } result = sony_demod_atsc_CheckDemodLock (pInteg->pDemod, &lock); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } switch (lock) { case SONY_DEMOD_LOCK_RESULT_LOCKED: SONY_TRACE_RETURN (SONY_RESULT_OK); case SONY_DEMOD_LOCK_RESULT_UNLOCKED: SONY_TRACE_RETURN (SONY_RESULT_ERROR_UNLOCK); default: /* continue waiting... */ break; } /* Check cancellation. */ result = sony_integ_CheckCancellation (pInteg); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } if (continueWait) { result = sony_stopwatch_sleep (&timer, SONY_ATSC_WAIT_LOCK_INTERVAL); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } } else { result = SONY_RESULT_ERROR_TIMEOUT; break; } } SONY_TRACE_RETURN (result); }