387 lines
13 KiB
C
Executable File
387 lines
13 KiB
C
Executable File
/*------------------------------------------------------------------------------
|
|
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 <stdio.h>
|
|
|
|
/*------------------------------------------------------------------------------
|
|
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);
|
|
}
|