/*------------------------------------------------------------------------------ Copyright 2018 Sony Semiconductor Solutions Corporation Last Updated : 2018/12/13 Modification ID : e402a4dcb0e51a00c34b174334c082c1211eebf1 ------------------------------------------------------------------------------*/ #include "sony_demod_atsc.h" #include "sony_demod_atsc_monitor.h" #include /*------------------------------------------------------------------------------ Definitions ------------------------------------------------------------------------------*/ /* Wait time */ #define WAITCOMMANDRESPONSE_POLL_INTERVAL_MS (10) /**< Wait Response Polling Interval (in ms). */ #define WAITCPUIDLE_TIMEOUT_MS (1000) /**< Wait for CPU idle (in ms). */ /*------------------------------------------------------------------------------ Structs ------------------------------------------------------------------------------*/ /** @brief Command data for ATSC demodulator core. */ typedef struct { uint8_t data[6]; /**< Command Parameters */ } sony_demod_atsc_cmd_t; /*------------------------------------------------------------------------------ Static Function Prototypes ------------------------------------------------------------------------------*/ /** @brief Configure the demodulator from Sleep to Active for ATSC. */ static sony_result_t SLtoAA(sony_demod_t * pDemod); /** @brief Configure the demodulator from Active ATSC to Active ATSC. Used for changing channel parameters. */ static sony_result_t AAtoAA(sony_demod_t * pDemod); /** @brief Configure the demodulator from Active ATSC to Sleep. */ static sony_result_t AAtoSL(sony_demod_t * pDemod); /** @brief Send Command to ATSC demodulator. */ static sony_result_t sendCommand (sony_demod_t *pDemod, const sony_demod_atsc_cmd_t *pCmd); /** @brief Get Response Data from ATSC demodulator. */ static sony_result_t readResponse (sony_demod_t *pDemod, sony_demod_atsc_cmd_t *pResp, uint8_t cmdId); /** @brief Demodulation Abort function. */ static sony_result_t demodAbort (sony_demod_t * pDemod); /** @brief Continuous writing function. */ static sony_result_t slaveRWriteMultiRegisters (sony_demod_t * pDemod, uint8_t bank, uint8_t registerAddress, const uint8_t* pData, uint8_t size); /*------------------------------------------------------------------------------ Functions ------------------------------------------------------------------------------*/ sony_result_t sony_demod_atsc_Tune (sony_demod_t * pDemod, sony_atsc_tune_param_t * pTuneParam) { sony_result_t result = SONY_RESULT_OK; SONY_TRACE_ENTER ("sony_demod_atsc_Tune"); if ((!pDemod) || (!pTuneParam)) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } if ((pDemod->state == SONY_DEMOD_STATE_ACTIVE) && (pDemod->system == SONY_DTV_SYSTEM_ATSC)) { /* Demodulator Active and set to ATSC mode */ result = AAtoAA(pDemod); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } } else if ((pDemod->state == SONY_DEMOD_STATE_ACTIVE) && (pDemod->system != SONY_DTV_SYSTEM_ATSC)) { /* Demodulator Active but not ATSC mode */ result = sony_demod_Sleep(pDemod); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } pDemod->system = SONY_DTV_SYSTEM_ATSC; pDemod->bandwidth = SONY_DTV_BW_6_MHZ; result = SLtoAA (pDemod); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } } else if (pDemod->state == SONY_DEMOD_STATE_SLEEP) { /* Demodulator in Sleep mode */ pDemod->system = SONY_DTV_SYSTEM_ATSC; pDemod->bandwidth = SONY_DTV_BW_6_MHZ; result = SLtoAA (pDemod); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } } else { SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE); } /* Update demodulator state */ pDemod->state = SONY_DEMOD_STATE_ACTIVE; SONY_TRACE_RETURN (SONY_RESULT_OK); } sony_result_t sony_demod_atsc_TuneEnd (sony_demod_t * pDemod) { sony_result_t result = SONY_RESULT_OK; SONY_TRACE_ENTER ("sony_demod_atsc_TuneEnd"); if (!pDemod) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) { /* This api is accepted in ACTIVE state only */ SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE); } if (pDemod->system != SONY_DTV_SYSTEM_ATSC) { /* Not ATSC */ SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE); } result = sony_demod_atsc_SoftReset(pDemod); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } /* Enable TS output */ result = sony_demod_SetStreamOutput (pDemod, 1); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } printf("demod enable ts output \n"); SONY_TRACE_RETURN (SONY_RESULT_OK); } sony_result_t sony_demod_atsc_SoftReset (sony_demod_t * pDemod) { sony_result_t result = SONY_RESULT_OK; sony_demod_atsc_cmd_t cmd; SONY_TRACE_ENTER ("sony_demod_atsc_SoftReset"); if (!pDemod) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) { /* This api is accepted in ACTIVE state only */ SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE); } if (pDemod->system != SONY_DTV_SYSTEM_ATSC) { /* Not ATSC */ SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE); } /* Abort Demodulation */ result = demodAbort (pDemod); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } /* Start FAT Command * byte0:COMMANDID_STARTFAT 0xB3 * byte1:Demod Mode * :8VSB (0x10) * :64QAM (0x11) * :256QAM (0x12) * :AUTO (0x16) * byte2:Signal Check OFF * :SIGNALCHK_ON (0x00) * :SIGNALCHK_OFF (0x04) * byte3:Reserved(0x00) * byte4:Reserved(0x00) * byte5:Reserved(0x00) */ cmd.data[0] = 0xB3; cmd.data[1] = 0x10; /* 8VSB Mode */ if (pDemod->atscAutoSignalCheckOff) { cmd.data[2] = 0x04; /* During Scanning Signal Check Off */ } else { cmd.data[2] = 0x00; /* During Scanning Signal Check On */ } cmd.data[3] = 0; cmd.data[4] = 0; cmd.data[5] = 0; /* Send Command */ result = sendCommand (pDemod, &cmd); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } /* Get Response */ result = readResponse (pDemod, &cmd, 0xB3); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } /* Update Current Internal CPU State */ pDemod->atscCPUState = SONY_DEMOD_ATSC_CPU_STATE_BUSY; SONY_TRACE_RETURN (SONY_RESULT_OK); } sony_result_t sony_demod_atsc_Sleep (sony_demod_t * pDemod) { sony_result_t result = SONY_RESULT_OK; SONY_TRACE_ENTER ("sony_demod_atsc_Sleep"); if (!pDemod) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } if ((pDemod->state != SONY_DEMOD_STATE_SLEEP) && (pDemod->state != SONY_DEMOD_STATE_ACTIVE)) { /* This api is accepted in Sleep and Active states only */ SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE); } result = AAtoSL (pDemod); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } SONY_TRACE_RETURN (SONY_RESULT_OK); } sony_result_t sony_demod_atsc_CheckDemodLock (sony_demod_t * pDemod, sony_demod_lock_result_t * pLock) { sony_result_t result = SONY_RESULT_OK; uint8_t vqlock = 0; uint8_t tslock = 0; uint8_t agclock = 0; uint8_t unlockDetected = 0; SONY_TRACE_ENTER ("sony_demod_atsc_CheckDemodLock"); if (!pDemod || !pLock) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) { /* This api is accepted in Active state only */ SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE); } *pLock = SONY_DEMOD_LOCK_RESULT_NOTDETECT; result = sony_demod_atsc_monitor_SyncStat (pDemod, &vqlock, &agclock, &tslock, &unlockDetected); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } if (pDemod->atscUnlockDetection) { if (unlockDetected) { *pLock = SONY_DEMOD_LOCK_RESULT_UNLOCKED; SONY_TRACE_RETURN (SONY_RESULT_OK); } } else { /* the result of unlockDetect should be ignored */ unlockDetected = 0; } if (vqlock) { *pLock = SONY_DEMOD_LOCK_RESULT_LOCKED; SONY_TRACE_RETURN (SONY_RESULT_OK); } SONY_TRACE_RETURN (SONY_RESULT_OK); } sony_result_t sony_demod_atsc_CheckTSLock (sony_demod_t * pDemod, sony_demod_lock_result_t * pLock) { sony_result_t result = SONY_RESULT_OK; uint8_t vqlock = 0; uint8_t tslock = 0; uint8_t agclock = 0; uint8_t unlockDetected = 0; SONY_TRACE_ENTER ("sony_demod_atsc_CheckTSLock"); if (!pDemod || !pLock) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) { /* This api is accepted in Active state only */ SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE); } *pLock = SONY_DEMOD_LOCK_RESULT_NOTDETECT; result = sony_demod_atsc_monitor_SyncStat (pDemod, &vqlock, &agclock, &tslock, &unlockDetected); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } //PR_TUN("dbg_pr vqlock=%d, agclock=%d, tslock=%d, unlockDetected=%d\n",vqlock, agclock, tslock, unlockDetected); if (tslock) { *pLock = SONY_DEMOD_LOCK_RESULT_LOCKED; SONY_TRACE_RETURN (SONY_RESULT_OK); } if (pDemod->atscUnlockDetection) { if (unlockDetected) { *pLock = SONY_DEMOD_LOCK_RESULT_UNLOCKED; SONY_TRACE_RETURN (SONY_RESULT_OK); } } else { /* the result of unlockDetect should be ignored */ unlockDetected = 0; } SONY_TRACE_RETURN (SONY_RESULT_OK); } sony_result_t sony_demod_atsc_SlaveRWriteRegister (sony_demod_t * pDemod, uint8_t bank, uint8_t registerAddress, uint8_t value, uint8_t bitMask) { sony_result_t result = SONY_RESULT_OK; sony_demod_atsc_cmd_t cmd; SONY_TRACE_ENTER ("sony_demod_atsc_SlaveRWriteRegister"); if (!pDemod) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } if ((pDemod->state != SONY_DEMOD_STATE_SLEEP) && (pDemod->state != SONY_DEMOD_STATE_ACTIVE)) { /* This api is accepted in Sleep or Active state only */ SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE); } if (pDemod->atscCPUState != SONY_DEMOD_ATSC_CPU_STATE_IDLE) { /* This api is accepted in CPU Idle State */ SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE); } /* Write Register Command * byte0:COMMANDID_WRITE_REG 0xC5 * byte1:Bank * byte2:SubAddress * byte3:Write Data * byte4:Mask * byte5:Reserved(0x00) */ cmd.data[0] = 0xC5; cmd.data[1] = bank; cmd.data[2] = registerAddress; cmd.data[3] = value; cmd.data[4] = bitMask; cmd.data[5] = 0; /* Send Command */ result = sendCommand(pDemod, &cmd); if (result != SONY_RESULT_OK){ SONY_TRACE_RETURN (result); } /* Get Response */ result = readResponse(pDemod, &cmd, 0xC5); if (result != SONY_RESULT_OK){ SONY_TRACE_RETURN (result); } SONY_TRACE_RETURN (result); } sony_result_t sony_demod_atsc_SlaveRReadRegister (sony_demod_t * pDemod, uint8_t bank, uint8_t registerAddress, uint8_t * pValue) { sony_result_t result = SONY_RESULT_OK; sony_demod_atsc_cmd_t cmd; SONY_TRACE_ENTER ("sony_demod_atsc_SlaveRReadRegister"); if (!pDemod || !pValue) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } if ((pDemod->state != SONY_DEMOD_STATE_SLEEP) && (pDemod->state != SONY_DEMOD_STATE_ACTIVE)) { /* This api is accepted in Sleep or Active state only */ SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE); } if (pDemod->atscCPUState != SONY_DEMOD_ATSC_CPU_STATE_IDLE) { /* This api is accepted in CPU Idle State */ SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE); } /* * Read Register Command * byte0:COMMANDID_READ_REG 0xC6 * byte1:Bank * byte2:SubAddress * byte3:Reserved(0x00) * byte4:Reserved(0x00) * byte5:Reserved(0x00) */ cmd.data[0] = 0xC6; cmd.data[1] = bank; cmd.data[2] = registerAddress; cmd.data[3] = 0; cmd.data[4] = 0; cmd.data[5] = 0; /* Send Command */ result = sendCommand (pDemod, &cmd); if (result != SONY_RESULT_OK){ SONY_TRACE_RETURN (result); } /* Get Response */ result = readResponse (pDemod, &cmd, 0xC6); if (result != SONY_RESULT_OK){ SONY_TRACE_RETURN (result); } *pValue = cmd.data[1]; SONY_TRACE_RETURN (result); } /*------------------------------------------------------------------------------ Static Functions ------------------------------------------------------------------------------*/ static sony_result_t SLtoAA(sony_demod_t * pDemod) { sony_result_t result = SONY_RESULT_OK; SONY_TRACE_ENTER ("SLtoAA"); if (!pDemod) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } /* Configure TS clock Mode and Frequency */ result = sony_demod_SetTSClockModeAndFreq (pDemod, SONY_DTV_SYSTEM_ATSC); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } /* Set SLV-X Bank : 0x00 */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVX, 0x00, 0x00) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* Set demod mode */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVX, 0x17, 0x0F) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* Set SLV-T Bank : 0x00 */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x00) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* Set TS/TLV mode */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0xA9, 0x00) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* Enable demod clock */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x2C, 0x01) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* TADC setting */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x4B, 0x74) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* TADC setting */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x49, 0x00) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* TADC setting */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVX, 0x18, 0x00) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } result = demodAbort (pDemod); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } /* IF Frequency Setting */ { uint8_t data[4]; data[0] = (uint8_t) ( pDemod->iffreqConfig.configATSC & 0xFF); data[1] = (uint8_t) ((pDemod->iffreqConfig.configATSC >> 8) & 0xFF); data[2] = (uint8_t) ((pDemod->iffreqConfig.configATSC >> 16) & 0xFF); data[3] = (uint8_t) ((pDemod->iffreqConfig.configATSC >> 24) & 0xFF); /* * slave Bank Addr Bit Default Value Name * ---------------------------------------------------------------------------------- * A3h A1h [7:0] 8'h4F user define vsb_DRPSPA_LOENGEN_EXT_FIXED_FREQ[7:0] * A3h A2h [7:0] 8'hC2 user define vsb_DRPSPA_LOENGEN_EXT_FIXED_FREQ[15:8] * A3h A3h [7:0] 8'hF6 user define vsb_DRPSPA_LOENGEN_EXT_FIXED_FREQ[23:16] * A3h A4h [7:0] 8'h24 user define vsb_DRPSPA_LOENGEN_EXT_FIXED_FREQ[31:24] */ result = slaveRWriteMultiRegisters (pDemod, 0xA3, 0xA1, data, sizeof(data)); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } } /* ASCOT Setting */ if (pDemod->tunerOptimize == SONY_DEMOD_TUNER_OPTIMIZE_SONYSILICON) { /* ASCOT setting ON * slave Bank Addr Bit Default Value Name * --------------------------------------------------------------------------------- * A0h 13h [1:0] 8'h03 8'h03 vsb_gdeq_on */ result = sony_demod_atsc_SlaveRWriteRegister (pDemod, 0xA0, 0x13, 0x03, 0x03); if (result != SONY_RESULT_OK){ SONY_TRACE_RETURN (result); } } else { /* ASCOT setting OFF * slave Bank Addr Bit Default Value Name * ---------------------------------------------------------------------------------- * A0h 13h [1:0] 8'h03 8'h00 vsb_gdeq_on */ result = sony_demod_atsc_SlaveRWriteRegister (pDemod, 0xA0, 0x13, 0x00, 0x03); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } } if (pDemod->tunerOptimize == SONY_DEMOD_TUNER_OPTIMIZE_SONYSILICON) { /* Filter Setting * slave Bank Addr Bit Default Value Name * -------------------------------------------------------------------------------- * 06h A0h [7:0] 8'h31 8'h31 OHI_GDEQ_COEF01 * 06h A1h [7:0] 8'hA5 8'hA5 OHI_GDEQ_COEF02 * 06h A2h [7:0] 8'h2E 8'h2E OHI_GDEQ_COEF11 * 06h A3h [7:0] 8'h9F 8'h9F OHI_GDEQ_COEF12 * 06h A4h [7:0] 8'h2B 8'h2B OHI_GDEQ_COEF21 * 06h A5h [7:0] 8'h99 8'h99 OHI_GDEQ_COEF22 * 06h A6h [7:0] 8'h00 8'h00 OHI_GDEQ_COEF31 * 06h A7h [7:0] 8'hCD 8'hCD OHI_GDEQ_COEF32 * 06h A8h [7:0] 8'h00 8'h00 OHI_GDEQ_COEF41 * 06h A9h [7:0] 8'hCD 8'hCD OHI_GDEQ_COEF42 * 06h AAh [7:0] 8'h00 8'h00 OHI_GDEQ_COEF51 * 06h ABh [7:0] 8'h00 8'h00 OHI_GDEQ_COEF52 * 06h ACh [7:0] 8'h2B 8'h2B OHI_GDEQ_COEF61 * 06h ADh [7:0] 8'h9D 8'h9D OHI_GDEQ_COEF62 */ const uint8_t data[] = { 0x31, 0xA5, 0x2E, 0x9F, 0x2B, 0x99, 0x00, 0xCD, 0x00, 0xCD, 0x00, 0x00, 0x2B, 0x9D }; result = slaveRWriteMultiRegisters (pDemod, 0x06, 0xA0, data, sizeof(data)); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } } /* ATSC1.0 initial setting */ { uint8_t noSignalThresh[3]; uint8_t signalThresh[3]; /* * slave Bank Addr Bit Default Value Name * ----------------------------------------------------------------------- * A0h 6Fh [7:0] 8'h37 8'h61 dagca_no_signal_thresh[7:0] * A0h 70h [7:0] 8'h2e 8'hFB dagca_no_signal_thresh[15:8] * A0h 71h [7:0] 8'h66 8'h7F dagca_no_signal_thresh[23:16] * 09h 80h [7:0] 8'hAE 8'h61 OHI_DAGCA_NOSIG_THRESH[7:0] * 09h 81h [7:0] 8'h37 8'hFB OHI_DAGCA_NOSIG_THRESH[15:8] * 09h 82h [7:0] 8'h61 8'h7F OHI_DAGCA_NOSIG_THRESH[23:16] * A0h 73h [7:0] 8'hFC 8'h26 dagca_signal_thresh[7:0] * A0h 74h [7:0] 8'hA2 8'h49 dagca_signal_thresh[15:8] * A0h 75h [7:0] 8'h5C 8'h7C dagca_signal_thresh[23:16] * 09h 83h [7:0] 8'hAE 8'h26 OHI_DAGCA_SIG_THRESH[7:0] * 09h 84h [7:0] 8'h27 8'h49 OHI_DAGCA_SIG_THRESH[15:8] * 09h 85h [7:0] 8'h61 8'h7C OHI_DAGCA_SIG_THRESH[23:16] * 06h 71h [2:0] 8'h00 8'h05 OHI_CONST_SEL[2:0] */ noSignalThresh[0] = (uint8_t)(pDemod->atscNoSignalThresh & 0xFF); noSignalThresh[1] = (uint8_t)((pDemod->atscNoSignalThresh >> 8) & 0xFF); noSignalThresh[2] = (uint8_t)((pDemod->atscNoSignalThresh >> 16) & 0xFF); signalThresh[0] = (uint8_t)(pDemod->atscSignalThresh & 0xFF); signalThresh[1] = (uint8_t)((pDemod->atscSignalThresh >> 8) & 0xFF); signalThresh[2] = (uint8_t)((pDemod->atscSignalThresh >> 16) & 0xFF); result = slaveRWriteMultiRegisters (pDemod, 0xA0, 0x6F, noSignalThresh, sizeof(noSignalThresh)); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } result = slaveRWriteMultiRegisters (pDemod, 0x09, 0x80, noSignalThresh, sizeof(noSignalThresh)); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } result = slaveRWriteMultiRegisters (pDemod, 0xA0, 0x73, signalThresh, sizeof(signalThresh)); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } result = slaveRWriteMultiRegisters (pDemod, 0x09, 0x83, signalThresh, sizeof(signalThresh)); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } result = sony_demod_atsc_SlaveRWriteRegister (pDemod, 0x06, 0x71, 0x05, 0x07); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } } /* Spectrum Inversion Setting * RF signal spectrum | tuner spectrum sense | Setting * | (pDemod->confSense) | (from Demod View) * -------------------+--------------------------+--------- * Normal | not same as RF(Normal) | 1B (Normal) * Invert | not same as RF(Normal) | 0B (Invert) * Normal | same as RF(Invert) | 0B (Invert) * Invert | same as RF(Invert) | 1B (Normal) * slave Bank Addr Bit Default Value Name *------------------------------------------------------------------------------------------ * A3h A0h [4] 8'h1B 8'h** vsb_DRPSPA_LOENGEN_POSSHIFT */ if (pDemod->rfSpectrumSense == pDemod->confSense){ result = sony_demod_atsc_SlaveRWriteRegister (pDemod, 0xA3, 0xA0, 0x10, 0x10); if (result != SONY_RESULT_OK){ SONY_TRACE_RETURN (result); } } else { result = sony_demod_atsc_SlaveRWriteRegister (pDemod, 0xA3, 0xA0, 0x00, 0x10); if (result != SONY_RESULT_OK){ SONY_TRACE_RETURN (result); } } /* Set SLV-T Bank : 0x00 */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x00) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* Disable HiZ Setting 1 (TAGC, SAGC(Hi-Z), TSVALID, TSSYNC, TSCLK) */ if (sony_i2c_SetRegisterBits (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x80, 0x08, 0x1F) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* Disable HiZ Setting 2 */ result = sony_demod_SetTSDataPinHiZ (pDemod, 0); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } SONY_TRACE_RETURN (result); } static sony_result_t AAtoAA(sony_demod_t * pDemod) { sony_result_t result = SONY_RESULT_OK; SONY_TRACE_ENTER ("AAtoAA"); if (!pDemod) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } /* Disable TS output */ result = sony_demod_SetStreamOutput (pDemod, 0); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } SONY_TRACE_RETURN (SONY_RESULT_OK); } static sony_result_t AAtoSL(sony_demod_t * pDemod) { sony_result_t result = SONY_RESULT_OK; SONY_TRACE_ENTER ("AAtoSL"); if (!pDemod) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } /* Disable TS output */ result = sony_demod_SetStreamOutput (pDemod, 0); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } /* Set SLV-T Bank : 0x00 */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x00) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* Enable Hi-Z setting 1 (TAGC, SAGC, TSVALID, TSSYNC, TSCLK) */ if (sony_i2c_SetRegisterBits (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x80, 0x1F, 0x1F) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* Enable Hi-Z setting 2 */ result = sony_demod_SetTSDataPinHiZ (pDemod, 1); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } result = demodAbort (pDemod); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (result); } /* Set SLV-T Bank : 0x00 */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x00) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* Cancel ATSC1 setting * slave Bank Addr Bit Default Value Name * ---------------------------------------------------------------------------------- * 00h D3h [0] 8'h00 8'h00 OTSRATECTRLOFF */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0xD3, 0x00) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* Set SLV-X Bank : 0x00 */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVX, 0x00, 0x00) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* TADC setting */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVX, 0x18, 0x01) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* TADC setting */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x49, 0x33) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* TADC setting */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x4B, 0x21) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* Disable demodulator clock */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0x2C, 0x00) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* Set tstlv mode to default */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVT, 0xA9, 0x00) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* Set demodulator mode to default */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVX, 0x17, 0x01) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } SONY_TRACE_RETURN (SONY_RESULT_OK); } static sony_result_t sendCommand (sony_demod_t *pDemod, const sony_demod_atsc_cmd_t *pCmd) { sony_result_t result = SONY_RESULT_OK; SONY_TRACE_ENTER ("sendCommand"); if ((!pDemod) || (!pDemod->pI2c) || (!pCmd)){ SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } /* Write data to 0x0A register */ result = pDemod->pI2c->WriteRegister (pDemod->pI2c, pDemod->i2cAddressSLVR, 0x0A, pCmd->data, sizeof(pCmd->data)); if (result != SONY_RESULT_OK){ SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } SONY_TRACE_RETURN (result); } static sony_result_t readResponse (sony_demod_t *pDemod, sony_demod_atsc_cmd_t *pResp, uint8_t cmdId) { sony_result_t result = SONY_RESULT_OK; uint32_t waitTime = 0; SONY_TRACE_ENTER ("readResponse"); if ((!pDemod) || (!pDemod->pI2c) || (!pResp)){ SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } for (;;) { /* Read data to 0x0A register */ result = pDemod->pI2c->ReadRegister (pDemod->pI2c, pDemod->i2cAddressSLVR, 0x0A, pResp->data, sizeof(pResp->data)); if (result != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } if (pResp->data[0] == 0x00) { /* Waiting... */ SONY_SLEEP (WAITCOMMANDRESPONSE_POLL_INTERVAL_MS); waitTime += WAITCOMMANDRESPONSE_POLL_INTERVAL_MS; } else { if (pResp->data[5] == cmdId) { break; } else { SONY_TRACE_RETURN (SONY_RESULT_ERROR_HW_STATE); } } if (waitTime >= WAITCPUIDLE_TIMEOUT_MS) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_TIMEOUT); } } /* Check Response Status */ if ((pResp->data[0] & 0x3F) == 0x30) { SONY_TRACE_RETURN (SONY_RESULT_OK); } else { SONY_TRACE_RETURN (SONY_RESULT_ERROR_OTHER); } } static sony_result_t slaveRWriteMultiRegisters (sony_demod_t * pDemod, uint8_t bank, uint8_t registerAddress, const uint8_t* pData, uint8_t size) { uint8_t wtimes = 0; sony_result_t result = SONY_RESULT_OK; SONY_TRACE_ENTER ("slaveRWriteMultiRegisters"); if (!pDemod || !pData ) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } for (wtimes = 0; wtimes < size; wtimes++) { result = sony_demod_atsc_SlaveRWriteRegister (pDemod, bank, registerAddress + wtimes, *(pData + wtimes), 0xFF); if (result != SONY_RESULT_OK){ SONY_TRACE_RETURN (result); } } SONY_TRACE_RETURN (SONY_RESULT_OK); } static sony_result_t demodAbort (sony_demod_t * pDemod) { if (!pDemod){ SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG); } SONY_TRACE_ENTER ("demodAbort"); /* Set SLV-R Bank : 0x01 */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVR, 0x00, 0x01) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* Abort Current Demodulation * slave Bank Addr Bit Value Name * ------------------------------------------------------------------------------------- * 01h 48h [0] 1'b1 OCPUWAKEUP */ if (pDemod->pI2c->WriteOneRegister (pDemod->pI2c, pDemod->i2cAddressSLVR, 0x48, 0x01) != SONY_RESULT_OK) { SONY_TRACE_RETURN (SONY_RESULT_ERROR_I2C); } /* Update Current Internal CPU State */ pDemod->atscCPUState = SONY_DEMOD_ATSC_CPU_STATE_IDLE; SONY_TRACE_RETURN (SONY_RESULT_OK); }