提交SMOD ATSC IMX APP版本 V122

This commit is contained in:
2026-07-16 14:35:59 +08:00
commit 7601c270d5
485 changed files with 255032 additions and 0 deletions
+574
View File
@@ -0,0 +1,574 @@
/*------------------------------------------------------------------------------
Copyright 2012-2013 Sony Semiconductor Solutions Corporation
Last Updated : 2013/05/15
File Revision : 1.0.3.0
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Based on HORUS3A(CXD2832A) application note 1.1.2
------------------------------------------------------------------------------*/
#include "sony_horus3a.h"
/*------------------------------------------------------------------------------
Definitions of static functions
------------------------------------------------------------------------------*/
/**
@brief Configure the HORUS3A tuner from Power On to Power Save state.
*/
static sony_result_t Initialize(sony_horus3a_t *pTuner);
/**
@brief Configure the HORUS3A tuner to Active state.
*/
static sony_result_t Tune(sony_horus3a_t *pTuner, uint32_t frequencykHz,
sony_horus3a_tv_system_t tvSystem, uint32_t symbolRateksps);
/**
@brief Configure the HORUS3A tuner to Power Save state.
*/
static sony_result_t EnterPowerSave(sony_horus3a_t *pTuner);
/**
@brief Configure the HORUS3A tuner to go out from Power Save state.
*/
static sony_result_t LeavePowerSave(sony_horus3a_t *pTuner);
/*------------------------------------------------------------------------------
Implementation
------------------------------------------------------------------------------*/
sony_result_t sony_horus3a_Create(sony_horus3a_t *pTuner, uint32_t xtalFreqMHz,
uint8_t i2cAddress, sony_i2c_t *pI2c, uint32_t flags)
{
SONY_TRACE_ENTER("sony_horus3a_Create");
if((!pTuner) || (!pI2c)){
SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
}
if((xtalFreqMHz != 16) && (xtalFreqMHz != 24) && (xtalFreqMHz != 27)){
SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
}
pTuner->state = SONY_HORUS3A_STATE_UNKNOWN; /* Chip is not accessed for now */
pTuner->xtalFreqMHz = xtalFreqMHz;
pTuner->pI2c = pI2c;
pTuner->i2cAddress = i2cAddress;
pTuner->flags = flags;
pTuner->frequencykHz = 0;
pTuner->tvSystem = SONY_HORUS3A_TV_SYSTEM_UNKNOWN;
pTuner->symbolRateksps = 0;
pTuner->user = NULL;
SONY_TRACE_RETURN(SONY_RESULT_OK);
}
sony_result_t sony_horus3a_Initialize(sony_horus3a_t *pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER("sony_horus3a_Initialize");
if((!pTuner) || (!pTuner->pI2c)){
SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
}
/* Wait 4ms after power on */
SONY_SLEEP(4);
result = Initialize(pTuner);
if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(result); }
pTuner->state = SONY_HORUS3A_STATE_SLEEP;
pTuner->frequencykHz = 0;
pTuner->tvSystem = SONY_HORUS3A_TV_SYSTEM_UNKNOWN;
pTuner->symbolRateksps = 0;
SONY_TRACE_RETURN(SONY_RESULT_OK);
}
sony_result_t sony_horus3a_Tune(sony_horus3a_t *pTuner, uint32_t frequencykHz,
sony_horus3a_tv_system_t tvSystem, uint32_t symbolRateksps)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER("sony_horus3a_Tune");
if((!pTuner) || (!pTuner->pI2c)){
SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
}
if((pTuner->state != SONY_HORUS3A_STATE_SLEEP) && (pTuner->state != SONY_HORUS3A_STATE_ACTIVE)){
SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
}
/* Rough frequency range check */
if((frequencykHz < 500000) || (frequencykHz > 2500000)){
SONY_TRACE_RETURN(SONY_RESULT_ERROR_RANGE);
}
if(pTuner->state == SONY_HORUS3A_STATE_SLEEP){
result = LeavePowerSave(pTuner);
if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(result); }
}
result = Tune(pTuner, frequencykHz, tvSystem, symbolRateksps);
if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(result); }
pTuner->state = SONY_HORUS3A_STATE_ACTIVE;
/* pTuner->frequencykHz will be updated in Tune function */
pTuner->tvSystem = tvSystem;
pTuner->symbolRateksps = symbolRateksps;
SONY_TRACE_RETURN(SONY_RESULT_OK);
}
sony_result_t sony_horus3a_Sleep(sony_horus3a_t *pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER("sony_horus3a_Sleep");
if((!pTuner) || (!pTuner->pI2c)){
SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
}
if((pTuner->state != SONY_HORUS3A_STATE_SLEEP) && (pTuner->state != SONY_HORUS3A_STATE_ACTIVE)){
SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
}
result = EnterPowerSave(pTuner);
if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(result); }
pTuner->state = SONY_HORUS3A_STATE_SLEEP;
pTuner->frequencykHz = 0;
pTuner->tvSystem = SONY_HORUS3A_TV_SYSTEM_UNKNOWN;
pTuner->symbolRateksps = 0;
SONY_TRACE_RETURN(SONY_RESULT_OK);
}
sony_result_t sony_horus3a_SetGPO(sony_horus3a_t *pTuner, uint8_t output)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER("sony_horus3a_SetGPO");
if((!pTuner) || (!pTuner->pI2c)){
SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
}
/* Write GPIO[1:0] */
result = sony_i2c_SetRegisterBits(pTuner->pI2c, pTuner->i2cAddress, 0x2D, (uint8_t)(output ? 0x40 : 0x00), 0xC0);
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
SONY_TRACE_RETURN(SONY_RESULT_OK);
}
/*------------------------------------------------------------------------------
Implementation of static functions
------------------------------------------------------------------------------*/
static sony_result_t Initialize(sony_horus3a_t *pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER("Initialize");
if((!pTuner) || (!pTuner->pI2c)){
SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
}
/* IQ Generator disable */
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x2A, 0x79);
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
/* 0x06 - 0x08 */
{
uint8_t data[3];
/* REF_R = Xtal Frequency */
data[0] = (uint8_t)(pTuner->xtalFreqMHz);
/* FIN = Xtal Frequency */
data[1] = (uint8_t)(pTuner->xtalFreqMHz);
data[2] = 0x00;
result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x06, data, sizeof(data));
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
}
switch(pTuner->flags & SONY_HORUS3A_CONFIG_IQOUT_MASK){
case SONY_HORUS3A_CONFIG_IQOUT_DIFFERENTIAL:
/* IQ Out = Differential */
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x0A, 0x00);
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
break;
case SONY_HORUS3A_CONFIG_IQOUT_SINGLEEND:
/* IQ Out = Single Ended */
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x0A, 0x40);
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
break;
case SONY_HORUS3A_CONFIG_IQOUT_SINGLEEND_LOWGAIN:
/* IQ Out = Single Ended (Low Gain) */
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x0A, 0xC0);
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
break;
default:
SONY_TRACE_RETURN(SONY_RESULT_ERROR_OTHER);
}
{
uint8_t data = 0;
/* XOSC_SEL setting */
if(pTuner->flags & SONY_HORUS3A_CONFIG_EXT_REF){
data = 0x00;
}else{
switch(pTuner->xtalFreqMHz){
case 27:
data = 0x1F; break;
case 24:
data = 0x10; break;
case 16:
data = 0x0C; break;
default:
SONY_TRACE_RETURN(SONY_RESULT_ERROR_OTHER);
}
data <<= 2; /* XOSC_SEL is Bit[6:2] */
}
if(!(pTuner->flags & SONY_HORUS3A_CONFIG_REFOUT_OFF)){
/* REFOUT ON */
data |= 0x80;
}
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x0E, data);
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
}
/* Power save setting */
result = EnterPowerSave(pTuner);
if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(result); }
SONY_SLEEP(3); /* Wait 3ms */
SONY_TRACE_RETURN(SONY_RESULT_OK);
}
static sony_result_t Tune(sony_horus3a_t *pTuner, uint32_t frequencykHz,
sony_horus3a_tv_system_t tvSystem, uint32_t symbolRateksps)
{
sony_result_t result = SONY_RESULT_OK;
uint8_t mixdiv = 0;
uint8_t mdiv = 0;
uint32_t ms = 0;
uint8_t f_ctl = 0;
uint8_t g_ctl = 0;
uint8_t fc_lpf = 0;
SONY_TRACE_ENTER("Tune");
/* frequency should be X MHz (X : integer) */
frequencykHz = ((frequencykHz + 500) / 1000) * 1000;
switch(tvSystem){
case SONY_HORUS3A_STV_ISDBS:
if(frequencykHz <= 1100000){
mixdiv = 4;
mdiv = 1;
}else{
mixdiv = 2;
mdiv = 0;
}
break;
case SONY_HORUS3A_STV_DVBS:
case SONY_HORUS3A_STV_DVBS2:
if(frequencykHz <= 1155000){
mixdiv = 4;
mdiv = 1;
}else{
mixdiv = 2;
mdiv = 0;
}
break;
default:
SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG); /* Invalid system */
}
/* Assumed that fREF == 1MHz (1000kHz) */
ms = ((frequencykHz * mixdiv)/2 + 1000/2) / 1000; /* Round */
if(ms > 0x7FFF){ /* 15 bit */
SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG); /* Invalid frequency */
}
/* Setup RF tracking filter */
if(pTuner->flags & SONY_HORUS3A_CONFIG_LNA_ENABLE){
if(frequencykHz < 975000){
/* F_CTL=11100 G_CTL=001 */
f_ctl = 0x1C; g_ctl = 0x01;
}else if(frequencykHz < 1050000){
/* F_CTL=11000 G_CTL=010 */
f_ctl = 0x18; g_ctl = 0x02;
}else if(frequencykHz < 1150000){
/* F_CTL=10100 G_CTL=010 */
f_ctl = 0x14; g_ctl = 0x02;
}else if(frequencykHz < 1250000){
/* F_CTL=10000 G_CTL=011 */
f_ctl = 0x10; g_ctl = 0x03;
}else if(frequencykHz < 1350000){
/* F_CTL=01100 G_CTL=100 */
f_ctl = 0x0C; g_ctl = 0x04;
}else if(frequencykHz < 1450000){
/* F_CTL=01010 G_CTL=100 */
f_ctl = 0x0A; g_ctl = 0x04;
}else if(frequencykHz < 1600000){
/* F_CTL=00111 G_CTL=101 */
f_ctl = 0x07; g_ctl = 0x05;
}else if(frequencykHz < 1800000){
/* F_CTL=00100 G_CTL=110 */
f_ctl = 0x04; g_ctl = 0x06;
}else if(frequencykHz < 2000000){
/* F_CTL=00010 G_CTL=110 */
f_ctl = 0x02; g_ctl = 0x06;
}else{
/* F_CTL=00000 G_CTL=111 */
f_ctl = 0x00; g_ctl = 0x07;
}
}else{
if(frequencykHz < 975000){
/* F_CTL=11100 G_CTL=001 */
f_ctl = 0x1C; g_ctl = 0x01;
}else if(frequencykHz < 1050000){
/* F_CTL=11000 G_CTL=010 */
f_ctl = 0x18; g_ctl = 0x02;
}else if(frequencykHz < 1150000){
/* F_CTL=10100 G_CTL=010 */
f_ctl = 0x14; g_ctl = 0x02;
}else if(frequencykHz < 1250000){
/* F_CTL=10000 G_CTL=011 */
f_ctl = 0x10; g_ctl = 0x03;
}else if(frequencykHz < 1350000){
/* F_CTL=01100 G_CTL=100 */
f_ctl = 0x0C; g_ctl = 0x04;
}else if(frequencykHz < 1450000){
/* F_CTL=01010 G_CTL=100 */
f_ctl = 0x0A; g_ctl = 0x04;
}else if(frequencykHz < 1600000){
/* F_CTL=00111 G_CTL=101 */
f_ctl = 0x07; g_ctl = 0x05;
}else if(frequencykHz < 1800000){
/* F_CTL=00100 G_CTL=010 */
f_ctl = 0x04; g_ctl = 0x02;
}else if(frequencykHz < 2000000){
/* F_CTL=00010 G_CTL=001 */
f_ctl = 0x02; g_ctl = 0x01;
}else{
/* F_CTL=00000 G_CTL=000 */
f_ctl = 0x00; g_ctl = 0x00;
}
}
/* LPF cutoff frequency setting */
switch(tvSystem){
case SONY_HORUS3A_STV_ISDBS:
fc_lpf = 22; /* 22MHz */
break;
case SONY_HORUS3A_STV_DVBS:
/*
rolloff = 0.35
SR <= 4.3
fc_lpf = 5
4.3 < SR <= 10
fc_lpf = SR * (1 + rolloff) / 2 + SR / 2 = SR * 1.175 = SR * (47/40)
10 < SR
fc_lpf = SR * (1 + rolloff) / 2 + 5 = SR * 0.675 + 5 = SR * (27/40) + 5
NOTE: The result should be round up.
*/
if(symbolRateksps <= 4300){
fc_lpf = 5;
}else if(symbolRateksps <= 10000){
fc_lpf = (uint8_t)((symbolRateksps * 47 + (40000-1)) / 40000);
}else{
fc_lpf = (uint8_t)((symbolRateksps * 27 + (40000-1)) / 40000 + 5);
}
if(fc_lpf > 36){
fc_lpf = 36; /* 5 <= fc_lpf <= 36 is valid */
}
break;
case SONY_HORUS3A_STV_DVBS2:
/*
rolloff = 0.2
SR <= 4.5
fc_lpf = 5
4.5 < SR <= 10
fc_lpf = SR * (1 + rolloff) / 2 + SR / 2 = SR * 1.1 = SR * (11/10)
10 < SR
fc_lpf = SR * (1 + rolloff) / 2 + 5 = SR * 0.6 + 5 = SR * (3/5) + 5
NOTE: The result should be round up.
*/
if(symbolRateksps <= 4500){
fc_lpf = 5;
}else if(symbolRateksps <= 10000){
fc_lpf = (uint8_t)((symbolRateksps * 11 + (10000-1)) / 10000);
}else{
fc_lpf = (uint8_t)((symbolRateksps * 3 + (5000-1)) / 5000 + 5);
}
if(fc_lpf > 36){
fc_lpf = 36; /* 5 <= fc_lpf <= 36 is valid */
}
break;
default:
SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG); /* Invalid system */
}
/* 0x00 - 0x04 */
{
uint8_t data[5];
data[0] = (uint8_t)((ms >> 7) & 0xFF);
data[1] = (uint8_t)((ms << 1) & 0xFF);
data[2] = 0x00;
data[3] = 0x00;
data[4] = (uint8_t)(mdiv << 7);
result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x00, data, sizeof(data));
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
}
/* Write G_CTL, F_CTL */
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x09, (uint8_t)((g_ctl << 5) | f_ctl));
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
/* Write LPF cutoff frequency */
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x37, (uint8_t)(0x80 | (fc_lpf << 1)));
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
/* Start Calibration */
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x05, 0x80);
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
/* IQ Generator enable */
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x2A, 0x7B);
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
SONY_SLEEP(10);
/* Store tuned frequency to the struct */
pTuner->frequencykHz = ms * 2 * 1000 / mixdiv;
SONY_TRACE_RETURN(SONY_RESULT_OK);
}
static sony_result_t EnterPowerSave(sony_horus3a_t *pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER("EnterPowerSave");
if((!pTuner) || (!pTuner->pI2c)){
SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
}
/* IQ Generator disable */
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x2A, 0x79);
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
/* MDIV_EN = 0 */
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x29, 0x70);
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
/* VCO disable preparation */
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x28, 0x3E);
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
/* VCO buffer disable */
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x2A, 0x19);
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
/* VCO calibration disable */
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x1C, 0x00);
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
/* 0x11 - 0x12 */
{
uint8_t data[2];
if(pTuner->flags & SONY_HORUS3A_CONFIG_POWERSAVE_ENABLEXTAL){
/* Power save setting (xtal is not stopped) */
data[0] = 0xC0;
}else{
/* Power save setting (xtal is stopped) */
data[0] = 0x80;
}
if(pTuner->flags & SONY_HORUS3A_CONFIG_LNA_ENABLE){
if(pTuner->flags & SONY_HORUS3A_CONFIG_POWERSAVE_STOPLNA){
/* LNA is stopped */
data[1] = 0x23;
}else{
/* LNA is not stopped */
data[1] = 0x27;
}
}else{
/* LNA is Disabled */
data[1] = 0xA7;
}
result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x11, data, sizeof(data));
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
}
SONY_TRACE_RETURN(SONY_RESULT_OK);
}
static sony_result_t LeavePowerSave(sony_horus3a_t *pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER("LeavePowerSave");
if((!pTuner) || (!pTuner->pI2c)){
SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
}
/* 0x11 - 0x12 */
{
uint8_t data[2];
/* Disable power save */
data[0] = 0x00;
if(pTuner->flags & SONY_HORUS3A_CONFIG_LNA_ENABLE){
/* LNA is Enabled */
data[1] = 0x27;
}else{
/* LNA is Disabled */
data[1] = 0xA7;
}
result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x11, data, sizeof(data));
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
}
/* VCO buffer enable */
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x2A, 0x79);
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
/* VCO calibration enable */
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x1C, 0xC0);
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
/* MDIV_EN = 1 */
result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x29, 0x71);
if(result != SONY_RESULT_OK) { SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
if(!(pTuner->flags & SONY_HORUS3A_CONFIG_POWERSAVE_ENABLEXTAL)){
/* Wait Xtal stable */
SONY_SLEEP(5);
}
SONY_TRACE_RETURN(SONY_RESULT_OK);
}
+186
View File
@@ -0,0 +1,186 @@
/*------------------------------------------------------------------------------
Copyright 2012-2013 Sony Semiconductor Solutions Corporation
Last Updated : 2013/05/15
File Revision : 1.0.3.0
------------------------------------------------------------------------------*/
/**
@file sony_horus3a.h
This file provides the HORUS3A tuner control interface.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_HORUS3A_H
#define SONY_HORUS3A_H
#include "sony_common.h"
#include "sony_i2c.h"
/*------------------------------------------------------------------------------
Defines
------------------------------------------------------------------------------*/
/**
@brief Version of this driver.
*/
#define SONY_HORUS3A_VERSION "1.0.3.0"
/**
@brief Default I2C slave address of the HORUS3A tuner.
*/
#define SONY_HORUS3A_ADDRESS 0xC0
/*------------------------------------------------------------------------------
Enums
------------------------------------------------------------------------------*/
/**
@brief HORUS3A tuner state.
*/
typedef enum {
SONY_HORUS3A_STATE_UNKNOWN,
SONY_HORUS3A_STATE_SLEEP,
SONY_HORUS3A_STATE_ACTIVE
} sony_horus3a_state_t;
/**
@brief Satellite broadcasting system definitions supported by HORUS3A.
*/
typedef enum {
SONY_HORUS3A_TV_SYSTEM_UNKNOWN,
SONY_HORUS3A_STV_ISDBS, /**< ISDB-S */
SONY_HORUS3A_STV_DVBS, /**< DVB-S */
SONY_HORUS3A_STV_DVBS2 /**< DVB-S2 */
} sony_horus3a_tv_system_t;
/*------------------------------------------------------------------------------
Structs
------------------------------------------------------------------------------*/
/**
@brief The HORUS3A tuner definition which allows control of the HORUS3A tuner device
through the defined set of functions.
*/
typedef struct sony_horus3a_t {
uint32_t xtalFreqMHz; /**< Xtal frequency for HORUS3A in MHz. */
uint8_t i2cAddress; /**< I2C slave address of the HORUS3A tuner (8-bit form - 8'bxxxxxxx0) */
sony_i2c_t* pI2c; /**< I2C API instance. */
uint32_t flags; /**< ORed value of SONY_HORUS3A_CONFIG_XXXX */
/* For saving current setting */
sony_horus3a_state_t state; /**< The driver operating state. */
uint32_t frequencykHz; /**< Currently RF frequency(kHz) tuned. */
sony_horus3a_tv_system_t tvSystem; /**< Current broadcasting system tuned. */
uint32_t symbolRateksps; /**< Current symbol rate(ksym/s) tuned. */
void* user; /**< User defined data. */
} sony_horus3a_t;
/*
Config flag definitions. (ORed value should be set to flags argument of Create API.)
*/
/**
@brief REFOUT output Off
*/
#define SONY_HORUS3A_CONFIG_REFOUT_OFF 0x80000000
/**
@brief Keep Xtal enable in power save state.
Should be used for Xtal shared system.
Not only for the master HORUS3A which has Xtal, but also slave HORUS3A which receive the clock signal.
*/
#define SONY_HORUS3A_CONFIG_POWERSAVE_ENABLEXTAL 0x40000000
/**
@brief Use external Xtal
Should be used for slave HORUS3A in Xtal shared system.
*/
#define SONY_HORUS3A_CONFIG_EXT_REF 0x20000000
/**
@brief Internal LNA enable
*/
#define SONY_HORUS3A_CONFIG_LNA_ENABLE 0x10000000
/**
@brief Stop internal LNA in power save state.
This flag is ignored if SONY_HORUS3A_CONFIG_LNA_ENABLE is not used.
*/
#define SONY_HORUS3A_CONFIG_POWERSAVE_STOPLNA 0x08000000
/**
@name IQ output setting.
One of following value should be used.
*/
/**@{*/
#define SONY_HORUS3A_CONFIG_IQOUT_DIFFERENTIAL 0x00000000 /**< IQ Output is Differential */
#define SONY_HORUS3A_CONFIG_IQOUT_SINGLEEND 0x01000000 /**< IQ Output is Single-Ended (+4.4dB) */
#define SONY_HORUS3A_CONFIG_IQOUT_SINGLEEND_LOWGAIN 0x02000000 /**< IQ Output is Single-Ended (-2.4dB) */
#define SONY_HORUS3A_CONFIG_IQOUT_MASK 0x03000000 /**< DON'T set this value. (Internal use only) */
/**@}*/
/*------------------------------------------------------------------------------
APIs
------------------------------------------------------------------------------*/
/**
@brief Set up the HORUS3A tuner driver.
This MUST be called before calling sony_horus3a_Initialize.
@param pTuner Reference to memory allocated for the HORUS3A instance.
The create function will setup this HORUS3A instance.
@param xtalFreqMHz The frequency of the HORUS3A crystal.
@param i2cAddress The HORUS3A tuner I2C slave address in 8-bit form.
@param pI2c The I2C APIs that the HORUS3A driver will use as the I2C interface.
@param flags Configuration flags. It should be ORed value of SONY_HORUS3A_CONFIG_XXXX.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_horus3a_Create(sony_horus3a_t *pTuner, uint32_t xtalFreqMHz,
uint8_t i2cAddress, sony_i2c_t *pI2c, uint32_t flags);
/**
@brief Initialize the HORUS3A tuner.
This MUST be called before calling sony_horus3a_Tune.
@param pTuner The HORUS3A tuner instance.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_horus3a_Initialize(sony_horus3a_t *pTuner);
/**
@brief Tune to a given RF frequency with broadcasting system.
@param pTuner The HORUS3A tuner instance.
@param frequencykHz RF frequency to tune. (kHz)
@param tvSystem The type of broadcasting system to tune.
@param symbolRateksps Symbol rate to tune. (ksps)
@return SONY_RESULT_OK if tuner successfully tuned.
*/
sony_result_t sony_horus3a_Tune(sony_horus3a_t *pTuner, uint32_t frequencykHz,
sony_horus3a_tv_system_t tvSystem, uint32_t symbolRateksps);
/**
@brief Put the HORUS3A tuner into Sleep state.
From this state the tuner can be directly tuned by calling sony_horus3a_Tune.
@param pTuner The HORUS3A tuner instance.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_horus3a_Sleep(sony_horus3a_t *pTuner);
/**
@brief Write to GPO
@param pTuner The HORUS3A tuner instance.
@param output Output logic level, 0 = Low, 1 = High
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_horus3a_SetGPO(sony_horus3a_t *pTuner, uint8_t output);
#endif /* SONY_HORUS3A_H */
+273
View File
@@ -0,0 +1,273 @@
/*------------------------------------------------------------------------------
Copyright 2016-2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/07/05
Modification ID : c7c68d70868a4a9fb9e0f480d8b940e8a1e8f651
------------------------------------------------------------------------------*/
#include "sony_tuner_horus3a.h"
#include <string.h>
#include <stdlib.h>
/*------------------------------------------------------------------------------
Static Functions
------------------------------------------------------------------------------*/
static sony_result_t sony_tuner_horus3a_Initialize (sony_tuner_t * pTuner);
static sony_result_t sony_tuner_horus3a_Tune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
uint32_t symbolRateKSps);
static sony_result_t sony_tuner_horus3a_Sleep (sony_tuner_t * pTuner);
static sony_result_t sony_tuner_horus3a_Shutdown (sony_tuner_t * pTuner);
static sony_result_t sony_tuner_horus3a_CalcRFLevelFromAGC (sony_tuner_t * pTuner,
uint32_t agcValue,
int32_t * pRFLevel);
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
sony_result_t sony_tuner_horus3a_Create (sony_tuner_t * pTuner,
uint32_t xtalFreqMHz,
uint8_t i2cAddress,
sony_i2c_t * pI2c,
uint32_t configFlags,
sony_horus3a_t * pHorus3a)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_horus3a_Create");
if ((!pI2c) || (!pHorus3a) || (!pTuner)){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
memset (pTuner, 0, sizeof (sony_tuner_t)); /* Zero filled */
result = sony_horus3a_Create (pHorus3a, xtalFreqMHz, i2cAddress, pI2c, configFlags);
if (result != SONY_RESULT_OK){SONY_TRACE_RETURN (result);}
/* Populate / Initialize the sony_tuner_t structure */
pTuner->i2cAddress = i2cAddress;
pTuner->pI2c = pI2c;
pTuner->flags = configFlags;
pTuner->symbolRateKSpsForSpectrum = 45000;
pTuner->rfLevelFuncTerr = SONY_TUNER_RFLEVEL_FUNC_NOSUPPORT; /* Not supported for terrestrial */
pTuner->rfLevelFuncSat = SONY_TUNER_RFLEVEL_FUNC_CALCFROMAGC; /* Use CalcRFLevelFromAGC function for satellite */
pTuner->user = pHorus3a;
pTuner->Initialize = sony_tuner_horus3a_Initialize;
pTuner->TerrCableTune = NULL;
pTuner->SatTune = sony_tuner_horus3a_Tune;
pTuner->Shutdown = sony_tuner_horus3a_Shutdown;
pTuner->Sleep = sony_tuner_horus3a_Sleep;
pTuner->ReadRFLevel = NULL;
pTuner->CalcRFLevelFromAGC = sony_tuner_horus3a_CalcRFLevelFromAGC;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
sony_result_t sony_tuner_horus3a_SetGPO (sony_tuner_t * pTuner, uint8_t value)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_horus3a_SetGPO");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_horus3a_SetGPO (((sony_horus3a_t *) pTuner->user), value);
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_horus3a_Initialize (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
sony_horus3a_t * pHorus3a = NULL;
SONY_TRACE_ENTER ("sony_tuner_horus3a_Initialize");
if ((!pTuner) || (!pTuner->user)){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
pHorus3a = (sony_horus3a_t *)(pTuner->user);
result = sony_horus3a_Initialize (pHorus3a);
if (result != SONY_RESULT_OK){SONY_TRACE_RETURN (result);}
pTuner->frequencyKHz = 0;
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_horus3a_Tune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
uint32_t symbolRateKSps)
{
sony_result_t result = SONY_RESULT_OK;
sony_horus3a_t * pHorus3a = NULL;
sony_horus3a_tv_system_t satSystem = SONY_HORUS3A_STV_DVBS2;
SONY_TRACE_ENTER ("sony_tuner_horus3a_Tune");
if ((!pTuner) || (!pTuner->user)){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
pHorus3a = (sony_horus3a_t *)(pTuner->user);
switch(system)
{
case SONY_DTV_SYSTEM_DVBS:
satSystem = SONY_HORUS3A_STV_DVBS;
break;
case SONY_DTV_SYSTEM_DVBS2:
satSystem = SONY_HORUS3A_STV_DVBS2;
break;
case SONY_DTV_SYSTEM_ISDBS:
case SONY_DTV_SYSTEM_ISDBS3:
satSystem = SONY_HORUS3A_STV_ISDBS;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_horus3a_Tune (pHorus3a, centerFreqKHz, satSystem, symbolRateKSps);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
pTuner->frequencyKHz = pHorus3a->frequencykHz;
pTuner->system = system;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = symbolRateKSps;
/* Tuner stabillization time */
SONY_SLEEP (50);
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_horus3a_Sleep (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
sony_horus3a_t * pHorus3a = NULL;
SONY_TRACE_ENTER ("sony_tuner_horus3a_Sleep");
if ((!pTuner) || (!pTuner->user)){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
pHorus3a = (sony_horus3a_t *)(pTuner->user);
result = sony_horus3a_Sleep (pHorus3a);
if (result != SONY_RESULT_OK){SONY_TRACE_RETURN (result);}
pTuner->frequencyKHz = 0;
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_horus3a_Shutdown (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
sony_horus3a_t * pHorus3a = NULL;
SONY_TRACE_ENTER ("sony_tuner_horus3a_Shutdown");
if ((!pTuner) || (!pTuner->user)){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
pHorus3a = (sony_horus3a_t *)(pTuner->user);
result = sony_horus3a_Sleep (pHorus3a);
if (result != SONY_RESULT_OK){SONY_TRACE_RETURN (result);}
pTuner->frequencyKHz = 0;
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_horus3a_CalcRFLevelFromAGC (sony_tuner_t * pTuner,
uint32_t agcValue,
int32_t * pRFLevel)
{
int32_t tempA = 0;
uint8_t isNegative = 0;
uint32_t tempDiv = 0;
uint32_t tempQ = 0;
uint32_t tempR = 0;
SONY_TRACE_ENTER("sony_tuner_horus3a_CalcRFLevelFromAGC");
if ((!pTuner) || (!pRFLevel)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (!SONY_DTV_SYSTEM_IS_SAT (pTuner->system)) {
/* Satellite Only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/*------------------------------------------------
Gain_db = (AGCLevel - 8192) * (- 33/1024) - 142
Gain_db_x100 = (AGCLevel - 8192) * (-3300/1024) - 14200
= (AGCLevel - 8192) * (- 825/ 256) - 14200
------------------------------------------------*/
tempA = (int32_t)agcValue - 8192;
tempA *= -825;
tempDiv = 256;
if (tempA > 0) {
isNegative = 0;
tempQ = (uint32_t)tempA / tempDiv;
tempR = (uint32_t)tempA % tempDiv;
} else {
isNegative = 1;
tempQ = (uint32_t)(tempA * (-1)) / tempDiv;
tempR = (uint32_t)(tempA * (-1)) % tempDiv;
}
if (isNegative) {
if (tempR >= (tempDiv/2)) {
*pRFLevel = (int32_t)(tempQ + 1) * (int32_t)(-1);
} else {
*pRFLevel = (int32_t)tempQ * (int32_t)(-1);
}
} else {
if (tempR >= (tempDiv/2)) {
*pRFLevel = (int32_t)(tempQ + 1);
} else {
*pRFLevel = (int32_t)tempQ;
}
}
*pRFLevel -= 14200;
/*
* RF_Level = Input_Ref_Level - RF_Gain
* -> Input_Ref_Level = 0dB for this demodulator
*/
*pRFLevel *= -1;
SONY_TRACE_RETURN(SONY_RESULT_OK);
}
+67
View File
@@ -0,0 +1,67 @@
/*------------------------------------------------------------------------------
Copyright 2016-2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/07/05
Modification ID : c7c68d70868a4a9fb9e0f480d8b940e8a1e8f651
------------------------------------------------------------------------------*/
/**
@file sony_tuner_horus3a.h
This file provides the tuner control function for HORUS3A(CXD2832).
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_TUNER_HORUS3A_H
#define SONY_TUNER_HORUS3A_H
/*------------------------------------------------------------------------------
Includes
------------------------------------------------------------------------------*/
#include "sony_tuner.h"
#include "sony_horus3a.h"
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
/**
@brief Create a instance for HORUS3A driver.
@param pTuner The tuner driver instance to create.
Memory must have been allocated for this instance before creation.
@param xtalFreqMHz The crystal frequency of the tuner (MHz).
Supports 16MHz or 24MHz or 27MHz.
@param i2cAddress The I2C address of the HORUS3A device.
Typically 0xC0.
@param pI2c The I2C driver that the tuner driver will use for
communication.
@param configFlags See ::SONY_HORUS3A_CONFIG_REFOUT_OFF,
::SONY_HORUS3A_CONFIG_POWERSAVE_ENABLEXTAL,
::SONY_HORUS3A_CONFIG_EXT_REF,
::SONY_HORUS3A_CONFIG_LNA_ENABLE,
::SONY_HORUS3A_CONFIG_POWERSAVE_STOPLNA,
::SONY_HORUS3A_CONFIG_IQOUT_DIFFERENTIAL,
::SONY_HORUS3A_CONFIG_IQOUT_SINGLEEND,
::SONY_HORUS3A_CONFIG_IQOUT_SINGLEEND_LOWGAIN defined in
\link sony_horus3a.h \endlink
@param pHorus3a The HORUS3A tuner driver pointer to use.
Memory must have been allocated for the HORUS3A driver structure.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_horus3a_Create (sony_tuner_t * pTuner,
uint32_t xtalFreqMHz,
uint8_t i2cAddress,
sony_i2c_t * pI2c,
uint32_t configFlags,
sony_horus3a_t * pHorus3a);
/**
@brief Write to GPO.
@param pTuner Instance of the tuner driver.
@param value Output logic level, 0 = Low, 1 = High
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_horus3a_SetGPO (sony_tuner_t * pTuner, uint8_t value);
#endif /* SONY_TUNER_HORUS3A_H */
+3
View File
@@ -0,0 +1,3 @@
VPATH += $(ROOT_DIR)/app/sonytuner/source/tuner
C_SOURCE += sony_tuner.c
+302
View File
@@ -0,0 +1,302 @@
/*------------------------------------------------------------------------------
Copyright 2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/07/27
Modification ID : ff73ffebff57618d6a5aa6e2aa9eb009b86060d1
------------------------------------------------------------------------------*/
#include "sony_tuner.h"
#include <string.h>
#include <stdlib.h>
/*------------------------------------------------------------------------------
Static Functions
------------------------------------------------------------------------------*/
static sony_result_t sony_tuner_sw_combined_Initialize (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_sw_combined_Initialize");
if (!pTuner) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if ((pTuner->pTunerTerrCable) && (pTuner->pTunerTerrCable->Initialize)) {
result = pTuner->pTunerTerrCable->Initialize (pTuner->pTunerTerrCable);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
if ((pTuner->pTunerSat) && (pTuner->pTunerSat->Initialize)) {
result = pTuner->pTunerSat->Initialize (pTuner->pTunerSat);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
pTuner->frequencyKHz = 0;
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
static sony_result_t sony_tuner_sw_combined_Sleep (sony_tuner_t * pTuner);
static sony_result_t sony_tuner_sw_combined_TerrCableTune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
sony_dtv_bandwidth_t bandwidth)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_sw_combined_TerrCableTune");
if (!pTuner) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (!SONY_DTV_SYSTEM_IS_TERR_CABLE (system)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (SONY_DTV_SYSTEM_IS_SAT (pTuner->system)) {
result = sony_tuner_sw_combined_Sleep (pTuner);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
if ((pTuner->pTunerTerrCable) && (pTuner->pTunerTerrCable->TerrCableTune)) {
result = pTuner->pTunerTerrCable->TerrCableTune (pTuner->pTunerTerrCable,
centerFreqKHz, system, bandwidth);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
pTuner->frequencyKHz = pTuner->pTunerTerrCable->frequencyKHz;
} else {
pTuner->frequencyKHz = centerFreqKHz;
}
pTuner->system = system;
pTuner->bandwidth = bandwidth;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
static sony_result_t sony_tuner_sw_combined_SatTune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
uint32_t symbolRateKSps)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_sw_combined_SatTune");
if (!pTuner) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (!SONY_DTV_SYSTEM_IS_SAT (system)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (SONY_DTV_SYSTEM_IS_TERR_CABLE (pTuner->system)) {
result = sony_tuner_sw_combined_Sleep (pTuner);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
if ((pTuner->pTunerSat) && (pTuner->pTunerSat->SatTune)) {
result = pTuner->pTunerSat->SatTune (pTuner->pTunerSat,
centerFreqKHz, system, symbolRateKSps);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
pTuner->frequencyKHz = pTuner->pTunerSat->frequencyKHz;
} else {
pTuner->frequencyKHz = centerFreqKHz;
}
pTuner->system = system;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = symbolRateKSps;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
static sony_result_t sony_tuner_sw_combined_Sleep (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_sw_combined_Sleep");
if (!pTuner) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if ((pTuner->pTunerTerrCable) && (pTuner->pTunerTerrCable->Sleep)
&& SONY_DTV_SYSTEM_IS_TERR_CABLE (pTuner->system)) {
result = pTuner->pTunerTerrCable->Sleep (pTuner->pTunerTerrCable);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
if ((pTuner->pTunerSat) && (pTuner->pTunerSat->Sleep)
&& SONY_DTV_SYSTEM_IS_SAT (pTuner->system)) {
result = pTuner->pTunerSat->Sleep (pTuner->pTunerSat);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
pTuner->frequencyKHz = 0;
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
static sony_result_t sony_tuner_sw_combined_Shutdown (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_sw_combined_Shutdown");
if (!pTuner) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if ((pTuner->pTunerTerrCable) && (pTuner->pTunerTerrCable->Shutdown)) {
result = pTuner->pTunerTerrCable->Shutdown (pTuner->pTunerTerrCable);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
if ((pTuner->pTunerSat) && (pTuner->pTunerSat->Shutdown)) {
result = pTuner->pTunerSat->Shutdown (pTuner->pTunerSat);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
}
pTuner->frequencyKHz = 0;
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
static sony_result_t sony_tuner_sw_combined_ReadRFLevel (sony_tuner_t * pTuner,
int32_t *pRFLevel)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_sw_combined_ReadRFLevel");
if ((!pTuner) || (!pRFLevel)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (SONY_DTV_SYSTEM_IS_TERR_CABLE (pTuner->system)) {
if ((pTuner->pTunerTerrCable) && (pTuner->pTunerTerrCable->ReadRFLevel)) {
result = pTuner->pTunerTerrCable->ReadRFLevel (pTuner->pTunerTerrCable, pRFLevel);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
} else {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT);
}
} else if (SONY_DTV_SYSTEM_IS_SAT (pTuner->system)) {
if ((pTuner->pTunerSat) && (pTuner->pTunerSat->ReadRFLevel)) {
result = pTuner->pTunerSat->ReadRFLevel (pTuner->pTunerSat, pRFLevel);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
} else {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT);
}
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
static sony_result_t sony_tuner_sw_combined_CalcRFLevelFromAGC (sony_tuner_t * pTuner,
uint32_t agcValue,
int32_t *pRFLevel)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_sw_combined_CalcRFLevelFromAGC");
if ((!pTuner) || (!pRFLevel)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (SONY_DTV_SYSTEM_IS_TERR_CABLE (pTuner->system)) {
if ((pTuner->pTunerTerrCable) && (pTuner->pTunerTerrCable->CalcRFLevelFromAGC)) {
result = pTuner->pTunerTerrCable->CalcRFLevelFromAGC (pTuner->pTunerTerrCable, agcValue, pRFLevel);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
} else {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT);
}
} else if (SONY_DTV_SYSTEM_IS_SAT (pTuner->system)) {
if ((pTuner->pTunerSat) && (pTuner->pTunerSat->CalcRFLevelFromAGC)) {
result = pTuner->pTunerSat->CalcRFLevelFromAGC (pTuner->pTunerSat, agcValue, pRFLevel);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
} else {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT);
}
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
sony_result_t sony_tuner_sw_combined_Create (sony_tuner_t * pTuner,
sony_tuner_t * pTunerTerrCable,
sony_tuner_t * pTunerSat)
{
SONY_TRACE_ENTER ("sony_tuner_sw_combined_Create");
if (!pTuner) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
memset (pTuner, 0, sizeof (sony_tuner_t)); /* Zero filled */
if (pTunerTerrCable) {
pTuner->pTunerTerrCable = pTunerTerrCable;
pTuner->rfLevelFuncTerr = pTunerTerrCable->rfLevelFuncTerr;
}
if (pTunerSat) {
pTuner->pTunerSat = pTunerSat;
pTuner->rfLevelFuncSat = pTunerSat->rfLevelFuncSat;
/*
* symbolRateKSpsForSpectrum member is accessed from satellite blind scan function.
* So, should be copied to software combined tuner object.
*/
pTuner->symbolRateKSpsForSpectrum = pTunerSat->symbolRateKSpsForSpectrum;
}
pTuner->Initialize = sony_tuner_sw_combined_Initialize;
pTuner->TerrCableTune = sony_tuner_sw_combined_TerrCableTune;
pTuner->SatTune = sony_tuner_sw_combined_SatTune;
pTuner->Sleep = sony_tuner_sw_combined_Sleep;
pTuner->Shutdown = sony_tuner_sw_combined_Shutdown;
pTuner->ReadRFLevel = sony_tuner_sw_combined_ReadRFLevel;
pTuner->CalcRFLevelFromAGC = sony_tuner_sw_combined_CalcRFLevelFromAGC;
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
+182
View File
@@ -0,0 +1,182 @@
/*------------------------------------------------------------------------------
Copyright 2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/07/27
Modification ID : ff73ffebff57618d6a5aa6e2aa9eb009b86060d1
------------------------------------------------------------------------------*/
/**
@file sony_tuner.h
This file provides the tuner control interface.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_TUNER_H
#define SONY_TUNER_H
/*------------------------------------------------------------------------------
Includes
------------------------------------------------------------------------------*/
#include "../sony_common.h"
#include "../sony_i2c.h"
#include "../sony_dtv.h"
/*------------------------------------------------------------------------------
Enumerations
------------------------------------------------------------------------------*/
/**
@brief Recommended RF level function type.
*/
typedef enum {
SONY_TUNER_RFLEVEL_FUNC_NOSUPPORT, /** RF level function is not supported */
SONY_TUNER_RFLEVEL_FUNC_READ, /** ReadRFLevel function is recommended */
SONY_TUNER_RFLEVEL_FUNC_CALCFROMAGC /** CalcRFLevelFromAGC function is recommended */
} sony_tuner_rflevel_func_t;
/*------------------------------------------------------------------------------
Structs
------------------------------------------------------------------------------*/
/**
@brief Definition of the tuner driver API.
*/
typedef struct sony_tuner_t {
/* ======== Following members are for configuration ======== */
uint8_t i2cAddress; /**< I2C address. */
sony_i2c_t * pI2c; /**< I2C driver instance. */
uint32_t flags; /**< Flags that can be used by tuner drivers. */
uint32_t symbolRateKSpsForSpectrum; /**< Symbol rate setting to get power spectrum. (for satellite blindscan) */
/*
* Following members are used in sony_integ_xxxx_monitor_RFLevel functions.
* If ::SONY_TUNER_RFLEVEL_FUNC_READ is set, ReadRFLevel function pointer is called to get RF level.
* If ::SONY_TUNER_RFLEVEL_FUNC_CALCFROMAGC is set, CalcRFLevelFromAGC function pointer is called to get RF level.
*/
sony_tuner_rflevel_func_t rfLevelFuncTerr; /**< Recommended RF level function type for terrestrial/cable */
sony_tuner_rflevel_func_t rfLevelFuncSat; /**< Recommended RF level function type for satellite */
/*
* Following members are only used for software combined tuner case.
* If the system supports both terrestrial/cable and satellite system,
* terrestrial/satellite combined tuner is normally used. (Like Sony HELENE/HELENE2 tuner)
* But if the user would like to use 2 tuners, (terrestrial/cable only tuner + satellite only tuner)
* special sony_tuner_t object, "software combined" tuner object should be prepared.
* Please check ::sony_tuner_sw_combined_Create API to configure software combined tuner.
*/
struct sony_tuner_t * pTunerTerrCable; /**< Terrestrial/cable only tuner object. */
struct sony_tuner_t * pTunerSat; /**< Satellite only tuner object. */
void * user; /**< User defined data. */
/* ======== Following members are for storing current status ======== */
uint32_t frequencyKHz; /**< Current RF frequency(kHz) tuned. */
sony_dtv_system_t system; /**< Current system tuned. */
sony_dtv_bandwidth_t bandwidth; /**< Current bandwidth tuned. (for terrestrial/cable) */
uint32_t symbolRateKSps; /**< Current symbol rate (KSps) tuned. (for satellite) */
/* ======== Function pointers ======== */
/**
@brief Initialize the tuner.
@param pTuner Instance of the tuner driver.
@return SONY_RESULT_OK if successful.
*/
sony_result_t (*Initialize) (struct sony_tuner_t * pTuner);
/**
@brief Tune to a given frequency with a given bandwidth. (Terrestrial/Cable)
Tuner driver can block while waiting for PLL locked indication (if required).
@param pTuner Instance of the tuner driver.
@param centerFreqKHz RF frequency to tune to (kHz)
@param system The broadcasting system of the channel to tune to.
@param bandwidth The bandwidth of the channel.
@return SONY_RESULT_OK if tuner successfully tuned.
*/
sony_result_t (*TerrCableTune) (struct sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
sony_dtv_bandwidth_t bandwidth);
/**
@brief Tune to a given frequency with a given system and symbol rate. (Satellite)
Tuner driver can block while waiting for PLL locked indication (if required).
@param pTuner Instance of the tuner driver.
@param centerFreqKHz RF frequency to tune to (kHz)
@param system The broadcasting system of the channel to tune to.
@param symbolRateKSps The symbol rate of the channel in KHz.
@return SONY_RESULT_OK if tuner successfully tuned.
*/
sony_result_t (*SatTune) (struct sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
uint32_t symbolRateKSps);
/**
@brief Sleep the tuner device (if supported).
@param pTuner Instance of the tuner driver.
@return SONY_RESULT_OK if successful.
*/
sony_result_t (*Sleep) (struct sony_tuner_t * pTuner);
/**
@brief Shutdown the tuner device (if supported).
@param pTuner Instance of the tuner driver.
@return SONY_RESULT_OK if successful.
*/
sony_result_t (*Shutdown) (struct sony_tuner_t * pTuner);
/**
@brief Read RF level from the tuner device (if supported).
@param pTuner Instance of the tuner driver.
@param pRFLevel The RF Level estimation in dBm * 100.
@return SONY_RESULT_OK if tuner successfully tuned.
*/
sony_result_t (*ReadRFLevel) (struct sony_tuner_t * pTuner,
int32_t *pRFLevel);
/**
@brief Calculate RF level from demod AGC monitor value (if supported).
Note: This function should not access to tuner.
@param pTuner Instance of the tuner driver.
@param agcValue Sony demodulator AGC value.
@param pRFLevel The RF Level estimation in dBm * 100.
@return SONY_RESULT_OK if tuner successfully tuned.
*/
sony_result_t (*CalcRFLevelFromAGC) (struct sony_tuner_t * pTuner,
uint32_t agcValue,
int32_t *pRFLevel);
} sony_tuner_t;
/**
@brief Create both terrestrial/cable and satellite supported virtual tuner object.
This API should be used if terrestrial/cable only tuner and satellite only tuner are both used in the system.
NOTE: terrestrial/cable tuner instance (*pTunerTerrCable) and satellite tuner instance (*pTunerSat)
should be correctly initialized (by sony_tuner_xxx_Create function) before this function call.
@param pTuner Instance of the for software combined virtual tuner object.
@param pTunerTerrCable Instance of the terrestrial/cable only tuner driver.
@param pTunerSat Instance of the satellite only tuner driver.
@return SONY_RESULT_OK if tuner successfully tuned.
*/
sony_result_t sony_tuner_sw_combined_Create (sony_tuner_t * pTuner,
sony_tuner_t * pTunerTerrCable,
sony_tuner_t * pTunerSat);
#endif /* SONY_TUNER_H */
Binary file not shown.
@@ -0,0 +1,3 @@
VPATH += $(ROOT_DIR)/app/sonytuner/source/tuner/terr_cable_ascot3/refcode
C_SOURCE += sony_ascot3.c
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,445 @@
/*------------------------------------------------------------------------------
Copyright 2013-2019 Sony Semiconductor Solutions Corporation
Last Updated : 2019/06/28
File Revision : 2.1.3.0
------------------------------------------------------------------------------*/
/**
@file sony_ascot3.h
This file provides the ASCOT3 tuner control interface.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_ASCOT3_H
#define SONY_ASCOT3_H
#include "../../../sony_common.h"
#include "../../../sony_i2c.h"
/*------------------------------------------------------------------------------
Defines
------------------------------------------------------------------------------*/
/**
@brief Version of this driver.
*/
#define SONY_ASCOT3_VERSION "2.1.2.0"
/**
@brief Default I2C slave address of the ASCOT3 tuner.
*/
#define SONY_ASCOT3_ADDRESS 0xC0
/*------------------------------------------------------------------------------
Enums
------------------------------------------------------------------------------*/
/**
@brief ASCOT3 tuner state.
*/
typedef enum {
SONY_ASCOT3_STATE_UNKNOWN, /**< ASCOT3 state is Unknown */
SONY_ASCOT3_STATE_SLEEP, /**< ASCOT3 state is Sleep */
SONY_ASCOT3_STATE_ACTIVE /**< ASCOT3 state is Active */
} sony_ascot3_state_t;
/**
@brief ASCOT3 chip type.
*/
typedef enum {
SONY_ASCOT3_CHIP_ID_UNKNOWN, /**< Unknown */
SONY_ASCOT3_CHIP_ID_2871, /**< CXD2871 (for TV) */
SONY_ASCOT3_CHIP_ID_2872, /**< CXD2872 (for STB) */
SONY_ASCOT3_CHIP_ID_2871A, /**< CXD2871A (ASCOT3I) (for TV) */
SONY_ASCOT3_CHIP_ID_2875 /**< CXD2875 */
} sony_ascot3_chip_id_t;
/**
@brief Xtal frequencies supported by ASCOT3.
*/
typedef enum {
SONY_ASCOT3_XTAL_16000KHz, /**< 16 MHz */
SONY_ASCOT3_XTAL_20500KHz, /**< 20.5 MHz */
SONY_ASCOT3_XTAL_24000KHz, /**< 24 MHz */
SONY_ASCOT3_XTAL_41000KHz /**< 41 MHz */
} sony_ascot3_xtal_t;
/**
@brief Analog/Digital terrestrial broadcasting system definitions supported by ASCOT3.
Fc : Center Frequency, Fp : Picture Frequency
*/
typedef enum {
SONY_ASCOT3_TV_SYSTEM_UNKNOWN,
/* Analog */
SONY_ASCOT3_ATV_MN_EIAJ, /**< System-M (Japan) (IF: Fp=5.75MHz in default) */
SONY_ASCOT3_ATV_MN_SAP, /**< System-M (US) (IF: Fp=5.75MHz in default) */
SONY_ASCOT3_ATV_MN_A2, /**< System-M (Korea) (IF: Fp=5.9MHz in default) */
SONY_ASCOT3_ATV_BG, /**< System-B/G (IF: Fp=7.3MHz in default) */
SONY_ASCOT3_ATV_I, /**< System-I (IF: Fp=7.85MHz in default) */
SONY_ASCOT3_ATV_DK, /**< System-D/K (IF: Fp=7.85MHz in default) */
SONY_ASCOT3_ATV_L, /**< System-L (IF: Fp=7.85MHz in default) */
SONY_ASCOT3_ATV_L_DASH, /**< System-L DASH (IF: Fp=2.2MHz in default) */
/* Digital */
SONY_ASCOT3_DTV_8VSB, /**< ATSC 8VSB (IF: Fc=3.7MHz in default) */
SONY_ASCOT3_DTV_QAM, /**< US QAM (IF: Fc=3.7MHz in default) */
SONY_ASCOT3_DTV_ISDBT_6, /**< ISDB-T 6MHzBW (IF: Fc=3.55MHz in default) */
SONY_ASCOT3_DTV_ISDBT_7, /**< ISDB-T 7MHzBW (IF: Fc=4.15MHz in default) */
SONY_ASCOT3_DTV_ISDBT_8, /**< ISDB-T 8MHzBW (IF: Fc=4.75MHz in default) */
SONY_ASCOT3_DTV_DVBT_5, /**< DVB-T 5MHzBW (IF: Fc=3.6MHz in default) */
SONY_ASCOT3_DTV_DVBT_6, /**< DVB-T 6MHzBW (IF: Fc=3.6MHz in default) */
SONY_ASCOT3_DTV_DVBT_7, /**< DVB-T 7MHzBW (IF: Fc=4.2MHz in default) */
SONY_ASCOT3_DTV_DVBT_8, /**< DVB-T 8MHzBW (IF: Fc=4.8MHz in default) */
SONY_ASCOT3_DTV_DVBT2_1_7,/**< DVB-T2 1.7MHzBW (IF: Fc=3.5MHz in default) */
SONY_ASCOT3_DTV_DVBT2_5, /**< DVB-T2 5MHzBW (IF: Fc=3.6MHz in default) */
SONY_ASCOT3_DTV_DVBT2_6, /**< DVB-T2 6MHzBW (IF: Fc=3.6MHz in default) */
SONY_ASCOT3_DTV_DVBT2_7, /**< DVB-T2 7MHzBW (IF: Fc=4.2MHz in default) */
SONY_ASCOT3_DTV_DVBT2_8, /**< DVB-T2 8MHzBW (IF: Fc=4.8MHz in default) */
SONY_ASCOT3_DTV_DVBC_6, /**< DVB-C 6MHzBW (IF: Fc=3.7MHz in default) */
SONY_ASCOT3_DTV_DVBC_8, /**< DVB-C 8MHzBW (IF: Fc=4.9MHz in default) */
SONY_ASCOT3_DTV_DVBC2_6, /**< DVB-C2 6MHzBW (IF: Fc=3.7MHz in default) */
SONY_ASCOT3_DTV_DVBC2_8, /**< DVB-C2 8MHzBW (IF: Fc=4.9MHz in default) */
SONY_ASCOT3_DTV_ATSC3_6, /**< ATSC 3.0 6MHzBW (IF: Fc=3.6MHz in default) */
SONY_ASCOT3_DTV_ATSC3_7, /**< ATSC 3.0 7MHzBW (IF: Fc=4.2MHz in default) */
SONY_ASCOT3_DTV_ATSC3_8, /**< ATSC 3.0 8MHzBW (IF: Fc=4.8MHz in default) */
SONY_ASCOT3_DTV_J83B_5_6, /**< J.83B 5.6Msps (IF: Fc=3.75MHz in default) */
SONY_ASCOT3_DTV_DTMB, /**< DTMB (IF: Fc=5.1MHz in default) */
SONY_ASCOT3_ATV_MIN = SONY_ASCOT3_ATV_MN_EIAJ, /**< Minimum analog terrestrial system */
SONY_ASCOT3_ATV_MAX = SONY_ASCOT3_ATV_L_DASH, /**< Maximum analog terrestrial system */
SONY_ASCOT3_DTV_MIN = SONY_ASCOT3_DTV_8VSB, /**< Minimum digital terrestrial system */
SONY_ASCOT3_DTV_MAX = SONY_ASCOT3_DTV_DTMB, /**< Maximum digital terrestrial system */
SONY_ASCOT3_TV_SYSTEM_NUM /**< Number of supported broadcasting system */
} sony_ascot3_tv_system_t;
/**
@brief Macro to check that the system is analog terrestrial or not.
*/
#define SONY_ASCOT3_IS_ATV(tvSystem) (((tvSystem) >= SONY_ASCOT3_ATV_MIN) && ((tvSystem) <= SONY_ASCOT3_ATV_MAX))
/**
@brief Macro to check that the system is digital terrestrial or not.
*/
#define SONY_ASCOT3_IS_DTV(tvSystem) (((tvSystem) >= SONY_ASCOT3_DTV_MIN) && ((tvSystem) <= SONY_ASCOT3_DTV_MAX))
/*------------------------------------------------------------------------------
Structs
------------------------------------------------------------------------------*/
/**
@brief ASCOT3 settings that may need to change depend on customer's system.
*/
typedef struct sony_ascot3_adjust_param_t {
uint8_t OUTLMT; /**< Addr:0x68 Bit[1:0] : Maximum IF output. (0: 1.5Vp-p, 1: 1.2Vp-p) */
uint8_t RF_GAIN; /**< Addr:0x69 Bit[6:4] : RFVGA gain. 0xFF means Auto. (RF_GAIN_SEL = 1) */
uint8_t IF_BPF_GC; /**< Addr:0x69 Bit[3:0] : IF_BPF gain. */
uint8_t RFOVLD_DET_LV1_VL; /**< Addr:0x6B Bit[3:0] : RF overload RF input detect level. (FRF <= 172MHz) */
uint8_t RFOVLD_DET_LV1_VH; /**< Addr:0x6B Bit[3:0] : RF overload RF input detect level. (172MHz < FRF <= 464MHz) */
uint8_t RFOVLD_DET_LV1_U; /**< Addr:0x6B Bit[3:0] : RF overload RF input detect level. (FRF > 464MHz) */
uint8_t IFOVLD_DET_LV_VL; /**< Addr:0x6C Bit[2:0] : Internal RFAGC detect level. (FRF <= 172MHz) */
uint8_t IFOVLD_DET_LV_VH; /**< Addr:0x6C Bit[2:0] : Internal RFAGC detect level. (172MHz < FRF <= 464MHz) */
uint8_t IFOVLD_DET_LV_U; /**< Addr:0x6C Bit[2:0] : Internal RFAGC detect level. (FRF > 464MHz) */
uint8_t IF_BPF_F0; /**< Addr:0x6D Bit[5:4] : IF filter center offset. */
uint8_t BW; /**< Addr:0x6D Bit[1:0] : 6MHzBW(0x00) or 7MHzBW(0x01) or 8MHzBW(0x02) or 1.7MHzBW(0x03) */
uint8_t FIF_OFFSET; /**< Addr:0x6E Bit[4:0] : 5bit signed. IF offset (kHz) = FIF_OFFSET x 50 */
uint8_t BW_OFFSET; /**< Addr:0x6F Bit[4:0] : 5bit signed. BW offset (kHz) = BW_OFFSET x 50 (BW_OFFSET x 10 in 1.7MHzBW) */
uint8_t AGC_SEL; /**< Addr:0x74 Bit[5:4] : AGC pin select. (0: AGC1, 1: AGC2) 0xFF means Auto (by config flags) */
uint8_t IF_OUT_SEL; /**< Addr:0x74 Bit[1:0] : IFOUT pin select. (0: IFOUT1, 1: IFOUT2) 0xFF means Auto. (by config flags) */
uint8_t IS_LOWERLOCAL; /**< Addr:0x9C Bit[0] : Local polarity. (0: Upper Local, 1: Lower Local) */
} sony_ascot3_adjust_param_t;
/**
@brief The ASCOT3 tuner definition which allows control of the ASCOT3 tuner device
through the defined set of functions.
*/
typedef struct sony_ascot3_t {
sony_ascot3_xtal_t xtalFreq; /**< Xtal frequency for ASCOT3. */
uint8_t i2cAddress; /**< I2C slave address of the ASCOT3 tuner (8-bit form - 8'bxxxxxxx0) */
sony_i2c_t* pI2c; /**< I2C API instance. */
uint32_t flags; /**< ORed value of SONY_ASCOT3_CONFIG_XXXX */
/* For saving current setting */
sony_ascot3_state_t state; /**< The driver operating state. */
uint32_t frequencykHz; /**< Currently RF frequency(kHz) tuned. */
sony_ascot3_tv_system_t tvSystem; /**< Current broadcasting system tuned. */
sony_ascot3_chip_id_t chipId; /**< Auto detected chip ID at initialization */
/**
@brief Adjustment parameter table (SONY_ASCOT3_TV_SYSTEM_NUM size)
*/
const sony_ascot3_adjust_param_t *pParamTable;
/* Following Xtal related parameters can be changed if optimization is necessary. */
uint8_t xosc_sel; /**< Driver current setting for crystal oscillator. (Addr:0x82 Bit[4:0]) */
uint8_t xosc_cap_set; /**< Driver current setting for crystal oscillator. (Addr:0x83 Bit[6:0]) */
uint8_t isSiP; /**< SiP internal or not. Automatically detected in the reference code. */
void* user; /**< User defined data. */
} sony_ascot3_t;
/*
Config flag definitions. (ORed value should be set to flags argument of Create API.)
*/
/**
@brief Use external Xtal. (for CXD2871/2872/2871A)
Should be used for slave ASCOT3 in Xtal shared system.
*/
#define SONY_ASCOT3_CONFIG_EXT_REF 0x80000000
/**
@brief Disable Xtal in Sleep state. (for CXD2871/2872/2871A/2875)
Should NOT be used for Xtal shared system.
Not only for the master ASCOT3 which has Xtal, but also slave ASCOT3 which receive the clock signal.
Cannot be used with SONY_ASCOT3_CONFIG_EXT_REF.
*/
#define SONY_ASCOT3_CONFIG_SLEEP_DISABLEXTAL 0x40000000
/**
@brief Internal loop filter setting. (for CXD2871/2872/2871A)
If this is used, internal loop filter is used for
digital broadcasting system except for DVB-C/C2.
For analog and DVB-C/C2, external loop filter will be used.
*/
#define SONY_ASCOT3_CONFIG_LOOPFILTER_INTERNAL 0x10000000
/**
@brief Loop through enable. (for CXD2872)
*/
#define SONY_ASCOT3_CONFIG_LOOPTHRU_ENABLE 0x08000000
/**
@brief RFIN matching for Power Save state enable (for CXD2871/2872/2871A)
For CXD2872, this is automatically enabled if SONY_ASCOT3_CONFIG_LOOPTHRU_ENABLE is used.
*/
#define SONY_ASCOT3_CONFIG_RFIN_MATCHING_ENABLE 0x04000000
/**
@name IF/AGC pin individually setting. (for CXD2871/2871A)
Used if sony_ascot3_adjust_param_t::IFAGCSEL == 0xFF
Available CXD2871 only.
CXD2872/2875 only have IF2/AGC2.
*/
/**@{*/
#define SONY_ASCOT3_CONFIG_IF2_ATV 0x00100000 /**< IF2 is used for Analog. (Otherwise IF1 is used.) */
#define SONY_ASCOT3_CONFIG_AGC2_ATV 0x00200000 /**< AGC2 is used for Analog. (Otherwise AGC1 is used.) */
#define SONY_ASCOT3_CONFIG_IF2_DTV 0x00400000 /**< IF2 is used for Digital. (Otherwise IF1 is used.) */
#define SONY_ASCOT3_CONFIG_AGC2_DTV 0x00800000 /**< AGC2 is used for Digital. (Otherwise AGC1 is used.) */
/**@}*/
/**
@name IF/AGC pin setting for normal cases. (for CXD2871/2871A)
Used if sony_ascot3_adjust_param_t::IFAGCSEL == 0xFF
Available CXD2871 only.
CXD2872/2875 only have IF2/AGC2.
*/
/**@{*/
/**
@brief IF/AGC 1 is used for both Analog and Digital
*/
#define SONY_ASCOT3_CONFIG_IFAGCSEL_ALL1 0x00000000
/**
@brief IF/AGC 2 is used for both Analog and Digital
*/
#define SONY_ASCOT3_CONFIG_IFAGCSEL_ALL2 (SONY_ASCOT3_CONFIG_IF2_ATV | SONY_ASCOT3_CONFIG_AGC2_ATV | \
SONY_ASCOT3_CONFIG_IF2_DTV | SONY_ASCOT3_CONFIG_AGC2_DTV)
/**
@brief IF/AGC 1 is used for Analog, 2 is used for Digital
*/
#define SONY_ASCOT3_CONFIG_IFAGCSEL_A1D2 (SONY_ASCOT3_CONFIG_IF2_DTV | SONY_ASCOT3_CONFIG_AGC2_DTV)
/**
@brief IF/AGC 1 is used for Digital, 2 is used for Analog
*/
#define SONY_ASCOT3_CONFIG_IFAGCSEL_D1A2 (SONY_ASCOT3_CONFIG_IF2_ATV | SONY_ASCOT3_CONFIG_AGC2_ATV)
/**@}*/
/**
@name REFOUT setting related macros. (for CXD2871/2872/2871A/2875)
If following values are not used, REFOUT output is disabled.
*/
/**@{*/
/**
@brief REFOUT enable, output level is 500mVp-p.
*/
#define SONY_ASCOT3_CONFIG_REFOUT_500mVpp 0x00001000
/**
@brief REFOUT enable, output level is 400mVp-p.
*/
#define SONY_ASCOT3_CONFIG_REFOUT_400mVpp 0x00002000
/**
@brief REFOUT enable, output level is 600mVp-p.
*/
#define SONY_ASCOT3_CONFIG_REFOUT_600mVpp 0x00003000
/**
@brief REFOUT enable, output level is 800mVp-p.
*/
#define SONY_ASCOT3_CONFIG_REFOUT_800mVpp 0x00004000
/**
@brief Internal use only. Do not use this value.
*/
#define SONY_ASCOT3_CONFIG_REFOUT_MASK 0x00007000
/**@}*/
/*------------------------------------------------------------------------------
APIs
------------------------------------------------------------------------------*/
/**
@brief Set up the ASCOT3 tuner driver.
This MUST be called before calling sony_ascot3_Initialize.
@param pTuner Reference to memory allocated for the ASCOT3 instance.
The create function will setup this ASCOT3 instance.
@param xtalFreq The frequency of the ASCOT3 crystal.
@param i2cAddress The ASCOT3 tuner I2C slave address in 8-bit form.
@param pI2c The I2C APIs that the ASCOT3 driver will use as the I2C interface.
@param flags Configuration flags. It should be ORed value of SONY_ASCOT3_CONFIG_XXXX.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_ascot3_Create(sony_ascot3_t *pTuner, sony_ascot3_xtal_t xtalFreq,
uint8_t i2cAddress, sony_i2c_t *pI2c, uint32_t flags);
/**
@brief Set up the ASCOT3 tuner driver for CXD2875 (ASCOT3R).
This is the special create function for CXD2875.
@param pTuner Reference to memory allocated for the ASCOT3 instance.
The create function will setup this ASCOT3 instance.
@param i2cAddress The ASCOT3 tuner I2C slave address in 8-bit form.
@param pI2c The I2C APIs that the ASCOT3 driver will use as the I2C interface.
@param flags Configuration flags. It should be ORed value of SONY_ASCOT3_CONFIG_XXXX.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_ascot3_2875_Create(sony_ascot3_t *pTuner,
uint8_t i2cAddress, sony_i2c_t *pI2c, uint32_t flags);
/**
@brief Initialize the ASCOT3 tuner.
This MUST be called before calling sony_ascot3_Tune.
@param pTuner The ASCOT3 tuner instance.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_ascot3_Initialize(sony_ascot3_t *pTuner);
/**
@brief Tune to a given RF frequency with broadcasting system.
To complete tuning, sony_ascot3_TuneEnd should be called after waiting 50ms.
@param pTuner The ASCOT3 tuner instance.
@param frequencykHz RF frequency to tune. (kHz)
@param tvSystem The type of broadcasting system to tune.
@return SONY_RESULT_OK if tuner successfully tuned.
*/
sony_result_t sony_ascot3_Tune(sony_ascot3_t *pTuner, uint32_t frequencykHz, sony_ascot3_tv_system_t tvSystem);
/**
@brief Completes the ASCOT3 tuning sequence.
This MUST be called after calling sony_ascot3_Tune and 50ms wait.
@param pTuner The ASCOT3 tuner instance.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_ascot3_TuneEnd(sony_ascot3_t *pTuner);
/**
@brief Shift RF frequency.
This API shift RF frequency without VCO calibration.
This API is normally useful for analog TV "fine tuning" that
shift RF frequency without picture distortion.
@note Please check the frequency range that VCO calibration is unnecessary.
(See hardware specification sheet.)
@param pTuner The ASCOT3 tuner instance.
@param frequencykHz RF frequency to tune. (kHz)
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_ascot3_ShiftFRF(sony_ascot3_t *pTuner, uint32_t frequencykHz);
/**
@brief Put the ASCOT3 tuner into Sleep state.
From this state the tuner can be directly tuned by calling sony_ascot3_Tune.
@param pTuner The ASCOT3 tuner instance.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_ascot3_Sleep(sony_ascot3_t *pTuner);
/**
@brief Write to GPO0 or GPO1. (for CXD2871/2872/2871A)
@param pTuner The ASCOT3 tuner instance.
@param id Pin ID 0 = GPO0, 1 = GPO1
@param val Output logic level, 0 = Low, 1 = High
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_ascot3_SetGPO(sony_ascot3_t *pTuner, uint8_t id, uint8_t val);
/**
@brief Set the RF external circuit control pin. (for CXD2871/2871A)
(Set RF_EXT_EN register.)
@param pTuner The ASCOT3 tuner instance.
@param enable The value to set. (Enable(1) or Disable(0))
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_ascot3_SetRfExtCtrl(sony_ascot3_t *pTuner, uint8_t enable);
/**
@brief Read the RSSI in dBm from the tuner.
@note Target level of IF signal output (depend on demodulator)
is not added in default.
(RSSI_IFOUT_TGT(0x79) is not set in sony_ascot3.c.)
sony_ascot3_ReadRssi_CPU is legacy function only for CXD2871/2872/2875.
The difference is that sony_ascot3_ReadRssi_CPU uses chip internal CPU.
@param pTuner The ASCOT3 tuner instance.
@param pRssi RSSI in dBm * 100
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_ascot3_ReadRssi(sony_ascot3_t *pTuner, int32_t *pRssi);
sony_result_t sony_ascot3_ReadRssi_CPU(sony_ascot3_t *pTuner, int32_t *pRssi);
/**
@brief RF filter compensation setting for VHF-L band. (for CXD2871/2872)
(Please see RFVGA Description of datasheet.)
New setting will become effective after next tuning.
mult = coeff / 128
(compensated value) = (original value) * mult + offset
@param pTuner The ASCOT3 tuner instance.
@param coeff Multiplier value. (8bit unsigned)
@param offset Additional term. (8bit 2s complement)
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_ascot3_RFFilterConfig(sony_ascot3_t *pTuner, uint8_t coeff, uint8_t offset);
#endif /* SONY_ASCOT3_H */
@@ -0,0 +1,459 @@
/*------------------------------------------------------------------------------
Copyright 2016-2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/07/27
Modification ID : ff73ffebff57618d6a5aa6e2aa9eb009b86060d1
------------------------------------------------------------------------------*/
#include "sony_tuner_ascot3.h"
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
/*------------------------------------------------------------------------------
Driver Version
------------------------------------------------------------------------------*/
const char* sony_tuner_ascot3_version = SONY_ASCOT3_VERSION;
/*------------------------------------------------------------------------------
Static Function Prototypes
------------------------------------------------------------------------------*/
static sony_result_t sony_tuner_ascot3_Initialize (sony_tuner_t * pTuner);
static sony_result_t sony_tuner_ascot3_Tune (sony_tuner_t * pTuner,
uint32_t frequencyKHz,
sony_dtv_system_t system,
sony_dtv_bandwidth_t bandwidth);
static sony_result_t sony_tuner_ascot3_Sleep (sony_tuner_t * pTuner);
static sony_result_t sony_tuner_ascot3_Shutdown (sony_tuner_t * pTuner);
static sony_result_t sony_tuner_ascot3_ReadRFLevel (sony_tuner_t * pTuner, int32_t * pRFLevel);
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
sony_result_t sony_tuner_ascot3_Create (sony_tuner_t * pTuner,
sony_ascot3_xtal_t xtalFreq,
uint8_t i2cAddress,
sony_i2c_t * pI2c,
uint32_t configFlags,
sony_ascot3_t * pAscot3Tuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_ascot3_Create");
if ((!pI2c) || (!pAscot3Tuner) || (!pTuner)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
memset (pTuner, 0, sizeof (sony_tuner_t)); /* Zero filled */
/* Create the underlying Ascot3 reference driver. */
result = sony_ascot3_Create (pAscot3Tuner, xtalFreq, i2cAddress, pI2c, configFlags);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Populate / Initialize the sony_tuner_t structure */
pTuner->i2cAddress = i2cAddress;
pTuner->pI2c = pI2c;
pTuner->flags = configFlags;
pTuner->symbolRateKSpsForSpectrum = 0;
pTuner->rfLevelFuncTerr = SONY_TUNER_RFLEVEL_FUNC_READ; /* Use ReadRFLevel function for terrestrial */
pTuner->rfLevelFuncSat = SONY_TUNER_RFLEVEL_FUNC_NOSUPPORT; /* Not supported for satellite */
pTuner->user = pAscot3Tuner;
pTuner->Initialize = sony_tuner_ascot3_Initialize;
pTuner->TerrCableTune = sony_tuner_ascot3_Tune;
pTuner->SatTune = NULL;
pTuner->Sleep = sony_tuner_ascot3_Sleep;
pTuner->Shutdown = sony_tuner_ascot3_Shutdown;
pTuner->ReadRFLevel = sony_tuner_ascot3_ReadRFLevel;
pTuner->CalcRFLevelFromAGC = NULL;
SONY_TRACE_RETURN (result);
}
sony_result_t sony_tuner_ascot3_2875_Create (sony_tuner_t * pTuner,
uint8_t i2cAddress,
sony_i2c_t * pI2c,
uint32_t configFlags,
sony_ascot3_t * pAscot3Tuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_ascot3_2875_Create");
if ((!pI2c) || (!pAscot3Tuner) || (!pTuner)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
memset (pTuner, 0, sizeof (sony_tuner_t)); /* Zero filled */
/* Create the underlying Ascot3R reference driver. */
result = sony_ascot3_2875_Create(pAscot3Tuner, i2cAddress, pI2c, configFlags);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Populate / Initialize the sony_tuner_t structure */
pTuner->i2cAddress = i2cAddress;
pTuner->pI2c = pI2c;
pTuner->flags = configFlags;
pTuner->symbolRateKSpsForSpectrum = 0;
pTuner->rfLevelFuncTerr = SONY_TUNER_RFLEVEL_FUNC_READ; /* Use ReadRFLevel function for terrestrial */
pTuner->rfLevelFuncSat = SONY_TUNER_RFLEVEL_FUNC_NOSUPPORT; /* Not supported for satellite */
pTuner->user = pAscot3Tuner;
pTuner->Initialize = sony_tuner_ascot3_Initialize;
pTuner->TerrCableTune = sony_tuner_ascot3_Tune;
pTuner->SatTune = NULL;
pTuner->Sleep = sony_tuner_ascot3_Sleep;
pTuner->Shutdown = sony_tuner_ascot3_Shutdown;
pTuner->ReadRFLevel = sony_tuner_ascot3_ReadRFLevel;
pTuner->CalcRFLevelFromAGC = NULL;
SONY_TRACE_RETURN (result);
}
sony_result_t sony_tuner_ascot3_RFFilterConfig (sony_tuner_t * pTuner, uint8_t coeff, uint8_t offset)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_ascot3_RFFilterConfig");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_ascot3_RFFilterConfig (((sony_ascot3_t *) pTuner->user), coeff, offset);
SONY_TRACE_RETURN (result);
}
sony_result_t sony_tuner_ascot3_SetGPO (sony_tuner_t * pTuner, uint8_t id, uint8_t value)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_ascot3_Write_GPIO");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_ascot3_SetGPO (((sony_ascot3_t *) pTuner->user), id, value);
SONY_TRACE_RETURN (result);
}
sony_result_t sony_tuner_ascot3_ReadRssi (sony_tuner_t * pTuner, int32_t * pRssi)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_ascot3_ReadRssi");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_ascot3_ReadRssi (((sony_ascot3_t *) pTuner->user), pRssi);
SONY_TRACE_RETURN (result);
}
/*------------------------------------------------------------------------------
Static Functions
------------------------------------------------------------------------------*/
static sony_result_t sony_tuner_ascot3_Initialize (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_ascot3_Initialize");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. */
result = sony_ascot3_Initialize (((sony_ascot3_t *) pTuner->user));
/* Device is in "Power Save" state. */
pTuner->frequencyKHz = 0;
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
//printf("dbg_pr sony_tuner_ascot3_Initialize ret = %d\n", result);
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_ascot3_Tune (sony_tuner_t * pTuner,
uint32_t frequencyKHz,
sony_dtv_system_t system,
sony_dtv_bandwidth_t bandwidth)
{
sony_result_t result = SONY_RESULT_OK;
sony_ascot3_tv_system_t aSystem;
//SONY_TRACE_ENTER ("sony_tuner_ascot3_Tune");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
//printf("[%s,%d] system=%d\n",__FUNCTION__,__LINE__, system);
/* Convert system, bandwidth into dtv system. */
switch (system) {
case SONY_DTV_SYSTEM_DVBC:
switch (bandwidth) {
case SONY_DTV_BW_6_MHZ:
aSystem = SONY_ASCOT3_DTV_DVBC_6;
break;
case SONY_DTV_BW_7_MHZ:
/* 7MHZ BW setting is the same as 8MHz BW */
case SONY_DTV_BW_8_MHZ:
aSystem = SONY_ASCOT3_DTV_DVBC_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_DVBT:
switch (bandwidth) {
case SONY_DTV_BW_5_MHZ:
aSystem = SONY_ASCOT3_DTV_DVBT_5;
break;
case SONY_DTV_BW_6_MHZ:
aSystem = SONY_ASCOT3_DTV_DVBT_6;
break;
case SONY_DTV_BW_7_MHZ:
aSystem = SONY_ASCOT3_DTV_DVBT_7;
break;
case SONY_DTV_BW_8_MHZ:
aSystem = SONY_ASCOT3_DTV_DVBT_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_DVBT2:
switch (bandwidth) {
case SONY_DTV_BW_1_7_MHZ:
aSystem = SONY_ASCOT3_DTV_DVBT2_1_7;
break;
case SONY_DTV_BW_5_MHZ:
aSystem = SONY_ASCOT3_DTV_DVBT2_5;
break;
case SONY_DTV_BW_6_MHZ:
aSystem = SONY_ASCOT3_DTV_DVBT2_6;
break;
case SONY_DTV_BW_7_MHZ:
aSystem = SONY_ASCOT3_DTV_DVBT2_7;
break;
case SONY_DTV_BW_8_MHZ:
aSystem = SONY_ASCOT3_DTV_DVBT2_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_DVBC2:
switch (bandwidth) {
case SONY_DTV_BW_6_MHZ:
aSystem = SONY_ASCOT3_DTV_DVBC2_6;
break;
case SONY_DTV_BW_8_MHZ:
aSystem = SONY_ASCOT3_DTV_DVBC2_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_ISDBT:
switch (bandwidth) {
case SONY_DTV_BW_6_MHZ:
aSystem = SONY_ASCOT3_DTV_ISDBT_6;
break;
case SONY_DTV_BW_7_MHZ:
aSystem = SONY_ASCOT3_DTV_ISDBT_7;
break;
case SONY_DTV_BW_8_MHZ:
aSystem = SONY_ASCOT3_DTV_ISDBT_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_ISDBC:
aSystem = SONY_ASCOT3_DTV_DVBC_6; /* ISDB-C uses DVB-C 6MHz BW setting */
break;
case SONY_DTV_SYSTEM_ATSC: // [oneshu note] do this case
aSystem = SONY_ASCOT3_DTV_8VSB;
break;
case SONY_DTV_SYSTEM_ATSC3:
switch (bandwidth) {
case SONY_DTV_BW_6_MHZ:
aSystem = SONY_ASCOT3_DTV_ATSC3_6;
break;
case SONY_DTV_BW_7_MHZ:
aSystem = SONY_ASCOT3_DTV_ATSC3_7;
break;
case SONY_DTV_BW_8_MHZ:
aSystem = SONY_ASCOT3_DTV_ATSC3_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_J83B:
switch (bandwidth) {
case SONY_DTV_BW_J83B_5_06_5_36_MSPS:
aSystem = SONY_ASCOT3_DTV_DVBC_6; /* J.83B (5.057, 5.361Msps commonly used in US) uses DVB-C 6MHz BW setting */
break;
case SONY_DTV_BW_J83B_5_60_MSPS:
aSystem = SONY_ASCOT3_DTV_J83B_5_6; /* J.83B (5.6Msps used in Japan) uses special setting */
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
/* Intentional fall-through */
case SONY_DTV_SYSTEM_UNKNOWN:
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. */
result = sony_ascot3_Tune(((sony_ascot3_t *) pTuner->user), frequencyKHz, aSystem);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Allow the tuner time to settle */
printf("Allow the tuner time to settle, wait about 50 ms\n");
SONY_SLEEP(50);
result = sony_ascot3_TuneEnd((sony_ascot3_t *) pTuner->user);
printf("sony ascot3 tune, tunnd ret = %d\n", result);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Assign current values. */
pTuner->frequencyKHz = ((sony_ascot3_t *) pTuner->user)->frequencykHz;
pTuner->system = system;
pTuner->bandwidth = bandwidth;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_ascot3_Sleep (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_ascot3_Sleep");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. */
result = sony_ascot3_Sleep (((sony_ascot3_t *) pTuner->user));
/* Device is in "Power Save" state. */
pTuner->frequencyKHz = 0;
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_ascot3_Shutdown (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_ascot3_Shutdown");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. */
result = sony_ascot3_Sleep (((sony_ascot3_t *) pTuner->user));
/* Device is in "Power Save" state. */
pTuner->frequencyKHz = 0;
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
printf("sony ascot3 Shutdown, ret = %d\n", result);
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_ascot3_ReadRFLevel (sony_tuner_t * pTuner, int32_t * pRFLevel)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_ascot3_ReadRFLevel");
if (!pTuner || !pTuner->user || !pRFLevel) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (!SONY_DTV_SYSTEM_IS_TERR_CABLE (pTuner->system)) {
/* Terrestrial/Cable Only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
result = sony_ascot3_ReadRssi (((sony_ascot3_t *) pTuner->user), pRFLevel);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Add IFOUT value */
switch (pTuner->system) {
case SONY_DTV_SYSTEM_DVBT:
case SONY_DTV_SYSTEM_DVBT2:
case SONY_DTV_SYSTEM_DVBC2:
case SONY_DTV_SYSTEM_ATSC3:
*pRFLevel -= 400; /* -4.0dBm */
break;
case SONY_DTV_SYSTEM_DVBC:
case SONY_DTV_SYSTEM_ISDBC:
case SONY_DTV_SYSTEM_J83B:
*pRFLevel -= 150; /* -1.5dBm */
break;
case SONY_DTV_SYSTEM_ISDBT:
*pRFLevel -= 450; /* -4.5dBm */
break;
case SONY_DTV_SYSTEM_ATSC:
*pRFLevel -= 500; /* -5.0dBm */
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT);
}
//PR_TUN("dbg_pr sony_tuner_ascot3_ReadRFLevel sys=%d RRLvl=%d ret=%d\n", pTuner->system, *pRFLevel,result);
SONY_TRACE_RETURN (result);
}
@@ -0,0 +1,136 @@
/*------------------------------------------------------------------------------
Copyright 2016-2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/07/05
Modification ID : c7c68d70868a4a9fb9e0f480d8b940e8a1e8f651
------------------------------------------------------------------------------*/
/**
@file sony_tuner_ascot3.h
This file provides the DVB port of the Sony ASCOT3 tuner driver.
This driver wraps around the Ascot3 driver provided by
sony_ascot3.h by using an instance of the Ascot3 (sony_ascot3_t)
driver in the ::sony_tuner_t::user pointer.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_TUNER_ASCOT3_H
#define SONY_TUNER_ASCOT3_H
/*------------------------------------------------------------------------------
Includes
------------------------------------------------------------------------------*/
#include "../sony_tuner.h"
#include "refcode/sony_ascot3.h"
/*------------------------------------------------------------------------------
Driver Version
------------------------------------------------------------------------------*/
extern const char* sony_tuner_ascot3_version; /**< ASCOT3 driver version */
/*------------------------------------------------------------------------------
Defines
------------------------------------------------------------------------------*/
#define SONY_TUNER_ASCOT3_OFFSET_CUTOFF_HZ 50000 /**< Maximum carrier offset frequency before requiring a retune */
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
/**
@brief Creates an instance of the ASCOT3 tuner driver
@param pTuner The tuner driver instance to create. Memory
must have been allocated for this instance before
creation.
@param xtalFreq The crystal frequency of the tuner.
@param i2cAddress The I2C address of the ASCOT3 device.
Typically 0xC0.
@param pI2c The I2C driver that the tuner driver will use for
communication.
@param configFlags See "#define" ::SONY_ASCOT3_CONFIG_SLEEP_DISABLEXTAL,
::SONY_ASCOT3_CONFIG_LOOPFILTER_INTERNAL,
::SONY_ASCOT3_CONFIG_LOOPTHRU_ENABLE,
::SONY_ASCOT3_CONFIG_RFIN_MATCHING_ENABLE,
::SONY_ASCOT3_CONFIG_IF2_ATV,
::SONY_ASCOT3_CONFIG_AGC2_ATV,
::SONY_ASCOT3_CONFIG_IF2_DTV,
::SONY_ASCOT3_CONFIG_AGC2_DTV,
::SONY_ASCOT3_CONFIG_IFAGCSEL_ALL1,
::SONY_ASCOT3_CONFIG_IFAGCSEL_ALL2,
::SONY_ASCOT3_CONFIG_IFAGCSEL_A1D2,
::SONY_ASCOT3_CONFIG_IFAGCSEL_D1A2,
::SONY_ASCOT3_CONFIG_REFOUT_500mVpp
::SONY_ASCOT3_CONFIG_REFOUT_400mVpp
::SONY_ASCOT3_CONFIG_REFOUT_600mVpp
::SONY_ASCOT3_CONFIG_REFOUT_800mVpp defined in
\link sony_ascot3.h \endlink
@param pAscot3Tuner The Ascot3 tuner driver pointer to use.
Memory must have been allocated for the Ascot3 driver structure.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_ascot3_Create (sony_tuner_t * pTuner,
sony_ascot3_xtal_t xtalFreq,
uint8_t i2cAddress,
sony_i2c_t * pI2c,
uint32_t configFlags,
sony_ascot3_t * pAscot3Tuner);
/**
@brief Creates an instance of the ASCOT3R (CXD2875) tuner driver
@param pTuner The tuner driver instance to create. Memory
must have been allocated for this instance before
creation.
@param i2cAddress The I2C address of the ASCOT3R (CXD2875) device.
Typically 0xC0.
@param pI2c The I2C driver that the tuner driver will use for
communication.
@param configFlags See "#define" ::SONY_ASCOT3_CONFIG_SLEEP_DISABLEXTAL,
::SONY_ASCOT3_CONFIG_REFOUT_500mVpp
::SONY_ASCOT3_CONFIG_REFOUT_400mVpp
::SONY_ASCOT3_CONFIG_REFOUT_600mVpp
::SONY_ASCOT3_CONFIG_REFOUT_800mVpp defined in
\link sony_ascot3.h \endlink
@param pAscot3Tuner The Ascot3 tuner driver pointer to use.
Memory must have been allocated for the Ascot3 driver structure.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_ascot3_2875_Create (sony_tuner_t * pTuner,
uint8_t i2cAddress,
sony_i2c_t * pI2c,
uint32_t configFlags,
sony_ascot3_t * pAscot3Tuner);
/**
@brief RF filter compensation setting for VHF-L band.
(Please see RFVGA Description of datasheet.)
New setting will become effective after next tuning.
mult = VL_TRCKOUT_COEFF(8bit unsigned) / 128
ofs = VL_TRCKOUT_OFS(8bit 2s complement)
(compensated value) = (original value) * mult + ofs
@param pTuner Instance of the tuner driver.
@param coeff VL_TRCKOUT_COEFF (multiplier)
@param offset VL_TRCKOUT_OFS (additional term)
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_ascot3_RFFilterConfig (sony_tuner_t * pTuner, uint8_t coeff, uint8_t offset);
/**
@brief Write to GPIO0 or GPIO1.
@param pTuner Instance of the tuner driver.
@param id Pin ID 0 = GPIO0, 1 = GPIO1
@param value Output logic level, 0 = Low, 1 = High
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_ascot3_SetGPO (sony_tuner_t * pTuner, uint8_t id, uint8_t value);
#endif /* SONY_TUNER_ASCOT3_H */
@@ -0,0 +1,4 @@
VPATH += $(ROOT_DIR)/app/sonytuner/source/tuner/terr_cable_ascot3
C_SOURCE += sony_tuner_ascot3.c
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,611 @@
/*------------------------------------------------------------------------------
Copyright 2020-2022 Sony Semiconductor Solutions Corporation
Last Updated : 2022/08/10
File Revision : 1.0.2.0
------------------------------------------------------------------------------*/
/**
@file sony_freia.h
This file provides the FREIA tuner control interface.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_FREIA_H
#define SONY_FREIA_H
#include "../../../sony_common.h"
#include "../../../sony_i2c.h"
/*------------------------------------------------------------------------------
Defines
------------------------------------------------------------------------------*/
/**
@brief Version of this driver.
*/
#define SONY_FREIA_VERSION "1.2.0.0"
/**
@brief Default I2C slave address of the FREIA tuner.
*/
#define SONY_FREIA_ADDRESS 0xC0
/*------------------------------------------------------------------------------
Enums
------------------------------------------------------------------------------*/
/**
@brief FREIA tuner state.
*/
typedef enum {
SONY_FREIA_STATE_UNKNOWN, /**< FREIA state is Unknown */
SONY_FREIA_STATE_SLEEP, /**< FREIA state is Sleep */
SONY_FREIA_STATE_ACTIVE_T, /**< FREIA state is Active (terrestrial) */
SONY_FREIA_STATE_ACTIVE_S, /**< FREIA state is Active (satellite) */
SONY_FREIA_STATE_ACTIVE_IQ /**< FREIA state is Active (terrestrial with IQ output) */
} sony_freia_state_t;
/**
@brief FREIA chip type.
*/
typedef enum {
SONY_FREIA_CHIP_ID_UNKNOWN, /**< Unknown */
SONY_FREIA_CHIP_ID_6868ER, /**< CXD6868ER (FREIA Plus) */
SONY_FREIA_CHIP_ID_6866AER, /**< CXD6866AER (FREIA) */
SONY_FREIA_CHIP_ID_6866ER, /**< CXD6866ER (ASCOT4) */
} sony_freia_chip_id_t;
/**
@brief Analog/Digital terrestrial, satellite broadcasting system definitions supported by FREIA.
Fc : Center Frequency, Fp : Picture Frequency
*/
typedef enum {
SONY_FREIA_TV_SYSTEM_UNKNOWN,
/* Terrestrial Analog */
SONY_FREIA_ATV_MN_EIAJ, /**< System-M (Japan) (IF: Fp=5.75MHz in default) */
SONY_FREIA_ATV_MN_SAP, /**< System-M (US) (IF: Fp=5.75MHz in default) */
SONY_FREIA_ATV_MN_A2, /**< System-M (Korea) (IF: Fp=5.9MHz in default) */
SONY_FREIA_ATV_BG, /**< System-B/G (IF: Fp=7.3MHz in default) */
SONY_FREIA_ATV_I, /**< System-I (IF: Fp=7.85MHz in default) */
SONY_FREIA_ATV_DK, /**< System-D/K (IF: Fp=7.85MHz in default) */
SONY_FREIA_ATV_L, /**< System-L (IF: Fp=7.85MHz in default) */
SONY_FREIA_ATV_L_DASH, /**< System-L DASH (IF: Fp=2.2MHz in default) */
/* Terrestrial/Cable Digital */
SONY_FREIA_DTV_8VSB, /**< ATSC 8VSB (IF: Fc=3.7MHz in default) */
SONY_FREIA_DTV_ISDBT_6, /**< ISDB-T 6MHzBW (IF: Fc=3.55MHz in default) */
SONY_FREIA_DTV_ISDBT_7, /**< ISDB-T 7MHzBW (IF: Fc=4.15MHz in default) */
SONY_FREIA_DTV_ISDBT_8, /**< ISDB-T 8MHzBW (IF: Fc=4.75MHz in default) */
SONY_FREIA_DTV_DVBT_5, /**< DVB-T 5MHzBW (IF: Fc=3.6MHz in default) */
SONY_FREIA_DTV_DVBT_6, /**< DVB-T 6MHzBW (IF: Fc=3.6MHz in default) */
SONY_FREIA_DTV_DVBT_7, /**< DVB-T 7MHzBW (IF: Fc=4.2MHz in default) */
SONY_FREIA_DTV_DVBT_8, /**< DVB-T 8MHzBW (IF: Fc=4.8MHz in default) */
SONY_FREIA_DTV_DVBT2_1_7,/**< DVB-T2 1.7MHzBW (IF: Fc=3.5MHz in default) */
SONY_FREIA_DTV_DVBT2_5, /**< DVB-T2 5MHzBW (IF: Fc=3.6MHz in default) */
SONY_FREIA_DTV_DVBT2_6, /**< DVB-T2 6MHzBW (IF: Fc=3.6MHz in default) */
SONY_FREIA_DTV_DVBT2_7, /**< DVB-T2 7MHzBW (IF: Fc=4.2MHz in default) */
SONY_FREIA_DTV_DVBT2_8, /**< DVB-T2 8MHzBW (IF: Fc=4.8MHz in default) */
SONY_FREIA_DTV_CABLE_6, /**< DVB-C 6MHzBW/ISDB-C/J.83B (IF: Fc=3.7MHz in default) */
SONY_FREIA_DTV_CABLE_8, /**< DVB-C 8MHzBW/7MHzBW (IF: Fc=4.9MHz in default) */
SONY_FREIA_DTV_DVBC2_6, /**< DVB-C2 6MHzBW (IF: Fc=3.7MHz in default) */
SONY_FREIA_DTV_DVBC2_8, /**< DVB-C2 8MHzBW (IF: Fc=4.9MHz in default) */
SONY_FREIA_DTV_ATSC3_6, /**< ATSC 3.0 6MHzBW (IF: Fc=3.6MHz in default) */
SONY_FREIA_DTV_ATSC3_7, /**< ATSC 3.0 7MHzBW (IF: Fc=4.2MHz in default) */
SONY_FREIA_DTV_ATSC3_8, /**< ATSC 3.0 8MHzBW (IF: Fc=4.8MHz in default) */
SONY_FREIA_DTV_SKP_OPT, /**< J.83B 5.6Msps (IF: Fc=3.75MHz in default) */
SONY_FREIA_DTV_DTMB, /**< DTMB (IF: Fc=5.1MHz in default) */
/* Satellite */
SONY_FREIA_STV_ISDBS, /**< ISDB-S */
SONY_FREIA_STV_ISDBS3, /**< ISDB-S3 */
SONY_FREIA_STV_DVBS, /**< DVB-S */
SONY_FREIA_STV_DVBS2, /**< DVB-S2 */
SONY_FREIA_ATV_MIN = SONY_FREIA_ATV_MN_EIAJ, /**< Minimum analog terrestrial system */
SONY_FREIA_ATV_MAX = SONY_FREIA_ATV_L_DASH, /**< Maximum analog terrestrial system */
SONY_FREIA_DTV_MIN = SONY_FREIA_DTV_8VSB, /**< Minimum digital terrestrial system */
SONY_FREIA_DTV_MAX = SONY_FREIA_DTV_DTMB, /**< Maximum digital terrestrial system */
SONY_FREIA_TERR_TV_SYSTEM_NUM, /**< Number of supported terrestrial broadcasting system */
SONY_FREIA_STV_MIN = SONY_FREIA_STV_ISDBS, /**< Minimum satellite system */
SONY_FREIA_STV_MAX = SONY_FREIA_STV_DVBS2 /**< Maximum satellite system */
} sony_freia_tv_system_t;
/**
@brief Macro to check that the system is analog terrestrial or not.
*/
#define SONY_FREIA_IS_ATV(tvSystem) (((tvSystem) >= SONY_FREIA_ATV_MIN) && ((tvSystem) <= SONY_FREIA_ATV_MAX))
/**
@brief Macro to check that the system is digital terrestrial or not.
*/
#define SONY_FREIA_IS_DTV(tvSystem) (((tvSystem) >= SONY_FREIA_DTV_MIN) && ((tvSystem) <= SONY_FREIA_DTV_MAX))
/**
@brief Macro to check that the system is satellite or not.
*/
#define SONY_FREIA_IS_STV(tvSystem) (((tvSystem) >= SONY_FREIA_STV_MIN) && ((tvSystem) <= SONY_FREIA_STV_MAX))
/*------------------------------------------------------------------------------
Structs
------------------------------------------------------------------------------*/
/**
@brief FREIA settings that may need to change depend on customer's system.
*/
typedef struct sony_freia_terr_adjust_param_t {
uint8_t RF_GAIN; /**< Addr:0x69 Bit[6:4] : RFVGA gain. 0xFF means Auto. (RF_GAIN_SEL = 1) */
uint8_t IF_BPF_GC; /**< Addr:0x69 Bit[3:0] : IF_BPF gain. */
uint8_t RFOVLD_DET_LV1_VL; /**< Addr:0x6B Bit[3:0] : RF overload RF input detect level. (FRF <= 172MHz) */
uint8_t RFOVLD_DET_LV1_VH; /**< Addr:0x6B Bit[3:0] : RF overload RF input detect level. (172MHz < FRF <= 464MHz) */
uint8_t RFOVLD_DET_LV1_U; /**< Addr:0x6B Bit[3:0] : RF overload RF input detect level. (FRF > 464MHz) */
uint8_t IFOVLD_DET_LV_VL; /**< Addr:0x6C Bit[2:0] : Internal RFAGC detect level. (FRF <= 172MHz) */
uint8_t IFOVLD_DET_LV_VH; /**< Addr:0x6C Bit[2:0] : Internal RFAGC detect level. (172MHz < FRF <= 464MHz) */
uint8_t IFOVLD_DET_LV_U; /**< Addr:0x6C Bit[2:0] : Internal RFAGC detect level. (FRF > 464MHz) */
uint8_t IF_BPF_F0; /**< Addr:0x6D Bit[5:4] : IF filter center offset. */
uint8_t BW; /**< Addr:0x6D Bit[1:0] : 6MHzBW(0x00) or 7MHzBW(0x01) or 8MHzBW(0x02) or 1.7MHzBW(0x03) */
uint8_t FIF_OFFSET; /**< Addr:0x6E Bit[4:0] : 5bit signed. IF offset (kHz) = FIF_OFFSET x 50 */
uint8_t BW_OFFSET; /**< Addr:0x6F Bit[4:0] : 5bit signed. BW offset (kHz) = BW_OFFSET x 50 (BW_OFFSET x 10 in 1.7MHzBW) */
uint8_t AGC_SEL; /**< Addr:0x74 Bit[5:4] : AGC pin select. (0: AGC1, 1: AGC2) 0xFF means Auto (by config flags) */
uint8_t IF_OUT_SEL; /**< Addr:0x74 Bit[0:1] : IFOUT pin select. (0: IFOUT1, 1: IFOUT2) 0xFF means Auto. (by config flags) */
} sony_freia_terr_adjust_param_t;
/**
@brief The FREIA tuner definition which allows control of the FREIA tuner device
through the defined set of functions.
*/
typedef struct sony_freia_t {
uint8_t i2cAddress; /**< I2C slave address of the FREIA tuner (8-bit form - 8'bxxxxxxx0) */
sony_i2c_t* pI2c; /**< I2C API instance. */
uint32_t flags; /**< ORed value of SONY_FREIA_CONFIG_XXXX */
/* For saving current setting */
sony_freia_state_t state; /**< The driver operating state. */
uint32_t frequencykHz; /**< Currently RF frequency(kHz) tuned. */
sony_freia_tv_system_t tvSystem; /**< Current broadcasting system tuned. */
uint32_t symbolRateksps; /**< Current symbol rate(ksym/s) tuned. */
uint8_t isFreesatMode; /**< UK Freesat mode or not. */
uint8_t isExternalOvldTc; /**< External OVLD TC mode or not. */
/**
@brief AGC Limiter setting for terrestrial. Set to 0 for normal operation. Set to 1 when the monotonicity of terrestrial AGC
is not obtained.
*/
uint8_t agcLimiterSetting;
uint8_t isQDumpOn; /**< Q_Dump is On or not. (for IQ mode)*/
sony_freia_chip_id_t chipId; /**< Auto detected chip ID at initialization */
/**
@brief Adjustment parameter table (SONY_FREIA_TV_SYSTEM_NUM size)
*/
const sony_freia_terr_adjust_param_t *pTerrParamTable;
/* Following Xtal related parameters can be changed if optimization is necessary. */
uint8_t xosc_sel; /**< Driver current setting for crystal oscillator. (Addr:0x82 Bit[4:0]) */
uint8_t xosc_cap_set; /**< Driver current setting for crystal oscillator. (Addr:0x83 Bit[5:0]) */
void* user; /**< User defined data. */
} sony_freia_t;
/*
Config flag definitions. (ORed value should be set to flags argument of Create API.)
*/
/**
@brief Use external Xtal
Should be used for slave FREIA in Xtal shared system.
*/
#define SONY_FREIA_CONFIG_EXT_REF 0x80000000
/**
@brief Disable Xtal in Sleep state.
Should NOT be used for Xtal shared system.
Not only for the master FREIA which has Xtal, but also slave FREIA which receive the clock signal.
Cannot be used with SONY_FREIA_CONFIG_EXT_REF.
*/
#define SONY_FREIA_CONFIG_SLEEP_DISABLEXTAL 0x40000000
/**
@brief Internal loop filter setting.
If this is used, internal loop filter is used for
digital broadcasting system except for DVB-C.
For analog and DVB-C, external loop filter will be used.
*/
#define SONY_FREIA_CONFIG_LOOPFILTER_INTERNAL 0x10000000
/**
@brief Satellite Gain Mode setting.
*/
#define SONY_FREIA_CONFIG_SAT_LOW_GAIN_MODE 0x08000000
/**
@name Power Save setting for terrestrial.
These settings are for avoiding steep input impedance change in power save state.
*/
/**@{*/
#define SONY_FREIA_CONFIG_POWERSAVE_TERR_NORMAL_MATCHING_DISABLE 0x00000000 /**< Normal matching disable (default) */
#define SONY_FREIA_CONFIG_POWERSAVE_TERR_NORMAL_MATCHING_ENABLE 0x00400000 /**< Normal matching enable */
#define SONY_FREIA_CONFIG_POWERSAVE_TERR_RF_ACTIVE_MATCHING_DISABLE 0x00800000 /**< Keep RF part active, matching disable */
#define SONY_FREIA_CONFIG_POWERSAVE_TERR_RF_ACTIVE_MATCHING_ENABLE 0x00C00000 /**< Keep RF part active, matching enalbe */
#define SONY_FREIA_CONFIG_POWERSAVE_TERR_MASK 0x00C00000 /**< Do not use this value */
/**@}*/
/**
@name Power Save setting for satellite.
These settings are for avoiding steep input impedance change in power save state.
*/
/**@{*/
#define SONY_FREIA_CONFIG_POWERSAVE_SAT_NORMAL 0x00000000 /**< Normal Setting (SAT LNA block disable) */
#define SONY_FREIA_CONFIG_POWERSAVE_SAT_RF_ACTIVE 0x00100000 /**< Keep RF part active */
#define SONY_FREIA_CONFIG_POWERSAVE_SAT_RF_ACTIVE_AGC_FULL 0x00200000 /**< Keep RF part active(AGC Full attenuation) */
#define SONY_FREIA_CONFIG_POWERSAVE_SAT_MASK 0x00300000 /**< Do not use this value */
/**@}*/
/**
@name Maximum IF and IQ output setting. (for terrestrial analog)
*/
/**@{*/
#define SONY_FREIA_CONFIG_OUTLMT_ATV_1_5Vpp 0x00000000 /**< 1.5Vpp (default) */
#define SONY_FREIA_CONFIG_OUTLMT_ATV_1_2Vpp 0x00080000 /**< 1.2Vpp */
/**@}*/
/**
@name Maximum IF and IQ output setting. (for terrestrial digital)
*/
/**@{*/
#define SONY_FREIA_CONFIG_OUTLMT_DTV_1_5Vpp 0x00000000 /**< 1.5Vpp (default) */
#define SONY_FREIA_CONFIG_OUTLMT_DTV_1_2Vpp 0x00040000 /**< 1.2Vpp */
/**@}*/
/**
@name Maximum IF and IQ output setting. (for satellite)
*/
/**@{*/
#define SONY_FREIA_CONFIG_OUTLMT_STV_0_75Vpp 0x00000000 /**< 0.75Vpp (default) */
#define SONY_FREIA_CONFIG_OUTLMT_STV_0_6Vpp 0x00020000 /**< 0.6Vpp */
/**@}*/
/**
@name REFOUT setting related macros.
If following values are not used, REFOUT output is disabled.
*/
/**@{*/
/**
@brief REFOUT enable, output level is 500mVp-p.
*/
#define SONY_FREIA_CONFIG_REFOUT_500mVpp 0x00001000
/**
@brief REFOUT enable, output level is 400mVp-p.
*/
#define SONY_FREIA_CONFIG_REFOUT_400mVpp 0x00002000
/**
@brief REFOUT enable, output level is 600mVp-p.
*/
#define SONY_FREIA_CONFIG_REFOUT_600mVpp 0x00003000
/**
@brief REFOUT enable, output level is 800mVp-p.
*/
#define SONY_FREIA_CONFIG_REFOUT_800mVpp 0x00004000
/**
@brief Internal use only. Do not use this value.
*/
#define SONY_FREIA_CONFIG_REFOUT_MASK 0x00007000
/**@}*/
/**
@name IF/AGC pin individually setting. (for CXD6866ER)
Used if sony_freia_terr_adjust_param_t::IFAGCSEL == 0xFF
Available CXD6866ER only.
CXD6868ER/CXD6866AER only use IF1/AGC1.
*/
/**@{*/
#define SONY_FREIA_CONFIG_IF2_ATV 0x00000100 /**< IF2 is used for Analog. (Otherwise IF1 is used.) */
#define SONY_FREIA_CONFIG_AGC2_ATV 0x00000200 /**< AGC2 is used for Analog. (Otherwise AGC1 is used.) */
#define SONY_FREIA_CONFIG_IF2_DTV 0x00000400 /**< IF2 is used for Digital. (Otherwise IF1 is used.) */
#define SONY_FREIA_CONFIG_AGC2_DTV 0x00000800 /**< AGC2 is used for Digital. (Otherwise AGC1 is used.) */
/**@}*/
/**
@name IF/AGC pin setting for normal cases. (for CXD6866ER)
Used if sony_freia_terr_adjust_param_t::IFAGCSEL == 0xFF
Available CXD6866ER only.
CXD6868ER/CXD6866AER only use IF1/AGC1.
*/
/**@{*/
/**
@brief IF/AGC 1 is used for both Analog and Digital
*/
#define SONY_FREIA_CONFIG_IFAGC_SEL_ALL1 0x00000000
/**
@brief IF/AGC 2 is used for both Analog and Digital
*/
#define SONY_FREIA_CONFIG_IFAGC_SEL_ALL2 (SONY_FREIA_CONFIG_IF2_ATV | SONY_FREIA_CONFIG_AGC2_ATV | \
SONY_FREIA_CONFIG_IF2_DTV | SONY_FREIA_CONFIG_AGC2_DTV)
/**
@brief IF/AGC 1 is used for Analog, 2 is used for Digital
*/
#define SONY_FREIA_CONFIG_IFAGC_SEL_A1D2 (SONY_FREIA_CONFIG_IF2_DTV | SONY_FREIA_CONFIG_AGC2_DTV)
/**
@brief IF/AGC 1 is used for Digital, 2 is used for Analog
*/
#define SONY_FREIA_CONFIG_IFAGC_SEL_D1A2 (SONY_FREIA_CONFIG_IF2_ATV | SONY_FREIA_CONFIG_AGC2_ATV)
/**
@name IFOUT DC bias setting.
Used for SiP2 (CXD6820 family) configuration.
*/
/**@{*/
#define SONY_FREIA_CONFIG_IFOUT_DC_BIAS_750mV 0x00000000 /**< 750mV (default) */
#define SONY_FREIA_CONFIG_IFOUT_DC_BIAS_500mV 0x00000080 /**< 500mV */
/**@}*/
/*------------------------------------------------------------------------------
APIs
------------------------------------------------------------------------------*/
/**
@brief Set up the FREIA tuner driver.
This MUST be called before calling sony_freia_Initialize.
@param pTuner Reference to memory allocated for the FREIA instance.
The create function will setup this FREIA instance.
@param i2cAddress The FREIA tuner I2C slave address in 8-bit form.
@param pI2c The I2C APIs that the FREIA driver will use as the I2C interface.
@param flags Configuration flags. It should be ORed value of SONY_FREIA_CONFIG_XXXX.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_Create(sony_freia_t *pTuner, uint8_t i2cAddress, sony_i2c_t *pI2c, uint32_t flags);
/**
@brief Initialize the FREIA tuner.
This MUST be called before calling sony_freia_terr_Tune and sony_freia_sat_Tune.
@param pTuner The FREIA tuner instance.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_Initialize(sony_freia_t *pTuner);
/**
@brief Tune to a given RF frequency with terrestrial broadcasting system.
To complete tuning, sony_freia_terr_TuneEnd should be called after waiting 50ms.
@param pTuner The FREIA tuner instance.
@param frequencykHz RF frequency to tune. (kHz)
@param tvSystem The type of broadcasting system to tune.
@return SONY_RESULT_OK if tuner successfully tuned.
*/
sony_result_t sony_freia_terr_Tune(sony_freia_t *pTuner, uint32_t frequencykHz,
sony_freia_tv_system_t tvSystem);
/**
@brief Completes the terrestrial tuning sequence.
This MUST be called after calling sony_freia_terr_Tune and 50ms wait.
@param pTuner The FREIA tuner instance.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_terr_TuneEnd(sony_freia_t *pTuner);
/**
@brief Tune to a given RF frequency with satellite broadcasting system.
@param pTuner The FREIA tuner instance.
@param frequencykHz RF frequency to tune. (kHz)
@param tvSystem The type of broadcasting system to tune.
@param symbolRateksps Symbol rate to tune. (ksps)
@return SONY_RESULT_OK if tuner successfully tuned.
*/
sony_result_t sony_freia_sat_Tune(sony_freia_t *pTuner, uint32_t frequencykHz,
sony_freia_tv_system_t tvSystem, uint32_t symbolRateksps);
/**
@brief Tune to a given RF frequency with satellite broadcasting system delivered by cable broadcast.
To complete tuning, sony_freia_terr_IQ_TuneEnd should be called after waiting 50ms.
@param pTuner The FREIA tuner instance.
@param frequencykHz RF frequency to tune. (kHz)
@param tvSystem The type of broadcasting system to tune.
@param symbolRateksps Symbol rate to tune. (ksps)
@return SONY_RESULT_OK if tuner successfully tuned.
*/
sony_result_t sony_freia_terr_IQ_Tune(sony_freia_t *pTuner, uint32_t frequencykHz,
sony_freia_tv_system_t tvSystem, uint32_t symbolRateksps);
/**
@brief Completes the terrestrial tuning sequence with IQ output.
This MUST be called after calling sony_freia_terr_Tune and 50ms wait.
@param pTuner The FREIA tuner instance.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_terr_IQ_TuneEnd(sony_freia_t *pTuner);
/**
@brief Shift RF frequency.
This API shift RF frequency without VCO calibration.
This API is normally useful for analog TV "fine tuning" that
shift RF frequency without picture distortion.
@note Please check the frequency range that VCO calibration is unnecessary.
(See hardware specification sheet.)
@param pTuner The FREIA tuner instance.
@param frequencykHz RF frequency to tune. (kHz)
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_ShiftFRF(sony_freia_t *pTuner, uint32_t frequencykHz);
/**
@brief Put the FREIA tuner into Sleep state.
From this state the tuner can be directly tuned by calling sony_freia_Tune.
@param pTuner The FREIA tuner instance.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_Sleep(sony_freia_t *pTuner);
/**
@brief Write to GPO0 or GPO1.
@param pTuner The FREIA tuner instance.
@param id Pin ID 0 = GPO0, 1 = GPO1
@param val Output logic level, 0 = Low, 1 = High
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_SetGPO(sony_freia_t *pTuner, uint8_t id, uint8_t val);
/**
@brief Read GPI0 or GPI1 value.
@param pTuner The FREIA tuner instance.
@param id Pin ID 0 = GPI0, 1 = GPI1
@param pVal GPI logic level, 0 = Low, 1 = High
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_GetGPI(sony_freia_t *pTuner, uint8_t id, uint8_t *pVal);
/**
@brief Set the RF external circuit control pin. (for terrestrial)
(Set RF_EXT_CTRL register.)
@param pTuner The FREIA tuner instance.
@param enable The value to set. (Enable(1) or Disable(0))
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_SetRfExtCtrl(sony_freia_t *pTuner, uint8_t enable);
/**
@brief Set UK Freesat mode.
If this mode is enabled, Freesat optimized setting will be used in sony_freia_sat_Tune.
If internal loop filter is used, (SONY_FREIA_CONFIG_LOOPFILTER_INTERNAL is ORed)
UK Freesat mode has no effect.
@param pTuner The FREIA tuner instance.
@param enable The value to set. (Enable(1) or Disable(0))
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_SetFreesatMode(sony_freia_t *pTuner, uint8_t enable);
/**
@brief Set External OVLD TC mode.
If this mode is enabled, OVLD TC optimized setting will be used in sony_freia_sat_Tune.
@param pTuner The FREIA tuner instance.
@param enable The value to set. (Enable(1) or Disable(0))
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_SetExternalOvldTcMode(sony_freia_t *pTuner, uint8_t enable);
/**
@brief Set AGC Limiter.
Set the AGC limiter setting to Normal or not.
@param pTuner The FREIA tuner instance.
@param setting The value to set. (Normal(0) or Not Normal(1))
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_SetAgcLimiter(sony_freia_t *pTuner, uint8_t setting);
/**
@brief Set Q Dump.
Set the Q_Dump Off/On.
@param pTuner The FREIA tuner instance.
@param setting The value to set. (Off(0) or On(1))
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_SetQDump(sony_freia_t *pTuner, uint8_t setting);
/**
@brief Read the RSSI in dBm from the tuner. (for terrestrial)
@note Target level of IF signal output (depend on demodulator)
is not added in default.
@param pTuner The FREIA tuner instance.
@param pRssi RSSI in dBm * 100
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_terr_ReadRssi(sony_freia_t *pTuner, int32_t *pRssi);
/**
@brief Read the RSSI in dBm from the tuner. (for satellite)
@note Target level of IF signal output (depend on demodulator)
is not added in default.
@param pTuner The FREIA tuner instance.
@param pRssi RSSI in dBm * 100
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_sat_ReadRssi(sony_freia_t *pTuner, int32_t *pRssi);
/**
@brief Read the RSSI in dBm from the tuner. (for terrestrial IQ)
@note Target level of IF signal output (depend on demodulator)
is not added in default.
@param pTuner The FREIA tuner instance.
@param pRssi RSSI in dBm * 100
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_terr_IQ_ReadRssi(sony_freia_t *pTuner, int32_t *pRssi);
/**
@brief RF filter compensation setting.
(Please see RFVGA Description of datasheet.)
New setting will become effective after next tuning.
mult = coeff / 128
(compensated value) = (original value) * mult + offset
@param pTuner The FREIA tuner instance.
@param vlCoeff Multiplier value. (8bit unsigned)
@param vlOffset Additional term. (8bit 2s complement)
@param uvhCoeff Multiplier value. (8bit unsigned)
@param uvhOffset Additional term. (8bit 2s complement)
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_freia_RFFilterConfig(sony_freia_t *pTuner, uint8_t vlCoeff, uint8_t vlOffset,
uint8_t uvhCoeff, uint8_t uvhOffset);
#endif /* SONY_FREIA_H */
@@ -0,0 +1,592 @@
/*------------------------------------------------------------------------------
Copyright 2021 Sony Semiconductor Solutions Corporation
Last Updated : 2021/10/15
Modification ID : 9b08f7abcf5fbb728cf490012b1ae0ddacbd0374
------------------------------------------------------------------------------*/
#include "sony_tuner_freia.h"
#include "../../sony_stdlib.h"
/*------------------------------------------------------------------------------
Driver Version
------------------------------------------------------------------------------*/
const char* sony_tuner_freia_version = SONY_FREIA_VERSION;
/*------------------------------------------------------------------------------
Static Prototypes
------------------------------------------------------------------------------*/
static sony_result_t sony_tuner_freia_Initialize (sony_tuner_t * pTuner);
static sony_result_t sony_tuner_freia_terr_Tune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
sony_dtv_bandwidth_t bandwidth);
static sony_result_t sony_tuner_freia_sat_Tune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
uint32_t symbolRateKSps);
static sony_result_t sony_tuner_freia_Sleep (sony_tuner_t * pTuner);
static sony_result_t sony_tuner_freia_Shutdown (sony_tuner_t * pTuner);
static sony_result_t sony_tuner_freia_ReadRFLevel (sony_tuner_t * pTuner, int32_t * pRFLevel);
static sony_result_t sony_tuner_freia_CalcRFLevelFromAGC (sony_tuner_t * pTuner, uint32_t agcValue, int32_t * pRFLevel);
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
sony_result_t sony_tuner_freia_Create (sony_tuner_t * pTuner,
uint8_t i2cAddress,
sony_i2c_t * pI2c,
uint32_t configFlags,
sony_freia_t * pFreiaTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_freia_Create");
if ((!pI2c) || (!pFreiaTuner) || (!pTuner)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
sony_memset (pTuner, 0, sizeof (sony_tuner_t)); /* Zero filled */
/* Create the underlying FREIA reference driver. */
result = sony_freia_Create (pFreiaTuner, i2cAddress, pI2c, configFlags);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Populate / Initialize the sony_tuner_t structure */
pTuner->i2cAddress = i2cAddress;
pTuner->pI2c = pI2c;
pTuner->flags = configFlags;
pTuner->symbolRateKSpsForSpectrum = 45000;
pTuner->rfLevelFuncTerr = SONY_TUNER_RFLEVEL_FUNC_READ; /* Use ReadRFLevel function for terrestrial */
pTuner->rfLevelFuncSat = SONY_TUNER_RFLEVEL_FUNC_READ; /* Use ReadRFLevel function for satellite */
pTuner->user = pFreiaTuner;
pTuner->Initialize = sony_tuner_freia_Initialize;
pTuner->TerrCableTune = sony_tuner_freia_terr_Tune;
pTuner->SatTune = sony_tuner_freia_sat_Tune;
pTuner->Sleep = sony_tuner_freia_Sleep;
pTuner->Shutdown = sony_tuner_freia_Shutdown;
pTuner->ReadRFLevel = sony_tuner_freia_ReadRFLevel;
pTuner->CalcRFLevelFromAGC = sony_tuner_freia_CalcRFLevelFromAGC;
SONY_TRACE_RETURN (result);
}
sony_result_t sony_tuner_freia_SetGPO (sony_tuner_t * pTuner, uint8_t id, uint8_t value)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_freia_Write_GPIO");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_freia_SetGPO (((sony_freia_t *) pTuner->user), id, value);
SONY_TRACE_RETURN (result);
}
sony_result_t sony_tuner_freia_GetGPI (sony_tuner_t * pTuner, uint8_t id, uint8_t * pValue)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_freia_GetGPI");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_freia_GetGPI (((sony_freia_t *) pTuner->user), id, pValue);
SONY_TRACE_RETURN (result);
}
sony_result_t sony_tuner_freia_RFFilterConfig (sony_tuner_t * pTuner, uint8_t vlCoeff, uint8_t vlOffset,
uint8_t uvhCoeff, uint8_t uvhOffset)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_freia_RFFilterConfig");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_freia_RFFilterConfig (((sony_freia_t *) pTuner->user), vlCoeff, vlOffset, uvhCoeff, uvhOffset);
SONY_TRACE_RETURN (result);
}
sony_result_t sony_tuner_freia_terr_IQ_Tune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
uint32_t symbolRateKSps)
{
sony_result_t result = SONY_RESULT_OK;
sony_freia_tv_system_t hSystem = SONY_FREIA_TV_SYSTEM_UNKNOWN;
SONY_TRACE_ENTER ("sony_tuner_freia_terr_Tune");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. Convert system, bandwidth into dtv system. */
switch(system)
{
case SONY_DTV_SYSTEM_DVBS:
hSystem = SONY_FREIA_STV_DVBS;
break;
case SONY_DTV_SYSTEM_DVBS2:
hSystem = SONY_FREIA_STV_DVBS2;
break;
case SONY_DTV_SYSTEM_ISDBS:
hSystem = SONY_FREIA_STV_ISDBS;
break;
case SONY_DTV_SYSTEM_ISDBS3:
hSystem = SONY_FREIA_STV_ISDBS3;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_freia_terr_IQ_Tune (((sony_freia_t *) pTuner->user), centerFreqKHz, hSystem, symbolRateKSps);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Allow the tuner time to settle */
SONY_SLEEP(50);
result = sony_freia_terr_IQ_TuneEnd ((sony_freia_t *) pTuner->user);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Assign current values. */
pTuner->frequencyKHz = ((sony_freia_t *) pTuner->user)->frequencykHz;
pTuner->system = system;
pTuner->symbolRateKSps = symbolRateKSps;
SONY_TRACE_RETURN (result);
}
/*------------------------------------------------------------------------------
Static Functions
------------------------------------------------------------------------------*/
static sony_result_t sony_tuner_freia_Initialize (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_freia_Initialize");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. */
result = sony_freia_Initialize (((sony_freia_t *) pTuner->user));
/* Device is in "Power Save" state. */
pTuner->frequencyKHz = 0;
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_freia_terr_Tune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
sony_dtv_bandwidth_t bandwidth)
{
sony_result_t result = SONY_RESULT_OK;
sony_freia_tv_system_t hSystem = SONY_FREIA_TV_SYSTEM_UNKNOWN;
SONY_TRACE_ENTER ("sony_tuner_freia_terr_Tune");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. Convert system, bandwidth into dtv system. */
switch (system) {
case SONY_DTV_SYSTEM_DVBC:
switch (bandwidth) {
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_FREIA_DTV_CABLE_6;
break;
case SONY_DTV_BW_7_MHZ:
/* 7MHZ BW setting is the same as 8MHz BW */
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_FREIA_DTV_CABLE_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_DVBT:
switch (bandwidth) {
case SONY_DTV_BW_5_MHZ:
hSystem = SONY_FREIA_DTV_DVBT_5;
break;
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_FREIA_DTV_DVBT_6;
break;
case SONY_DTV_BW_7_MHZ:
hSystem = SONY_FREIA_DTV_DVBT_7;
break;
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_FREIA_DTV_DVBT_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_DVBT2:
switch (bandwidth) {
case SONY_DTV_BW_1_7_MHZ:
hSystem = SONY_FREIA_DTV_DVBT2_1_7;
break;
case SONY_DTV_BW_5_MHZ:
hSystem = SONY_FREIA_DTV_DVBT2_5;
break;
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_FREIA_DTV_DVBT2_6;
break;
case SONY_DTV_BW_7_MHZ:
hSystem = SONY_FREIA_DTV_DVBT2_7;
break;
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_FREIA_DTV_DVBT2_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_DVBC2:
switch (bandwidth) {
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_FREIA_DTV_DVBC2_6;
break;
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_FREIA_DTV_DVBC2_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_ISDBT:
switch (bandwidth) {
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_FREIA_DTV_ISDBT_6;
break;
case SONY_DTV_BW_7_MHZ:
hSystem = SONY_FREIA_DTV_ISDBT_7;
break;
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_FREIA_DTV_ISDBT_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_ISDBC:
hSystem = SONY_FREIA_DTV_CABLE_6; /* ISDB-C uses DVB-C 6MHz BW setting */
break;
case SONY_DTV_SYSTEM_ATSC:
hSystem = SONY_FREIA_DTV_8VSB;
break;
case SONY_DTV_SYSTEM_ATSC3:
switch (bandwidth) {
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_FREIA_DTV_ATSC3_6;
break;
case SONY_DTV_BW_7_MHZ:
hSystem = SONY_FREIA_DTV_ATSC3_7;
break;
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_FREIA_DTV_ATSC3_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_J83B:
switch (bandwidth) {
case SONY_DTV_BW_J83B_5_06_5_36_MSPS:
hSystem = SONY_FREIA_DTV_CABLE_6; /* J.83B (5.057, 5.361Msps commonly used in US) uses DVB-C 6MHz BW setting */
break;
case SONY_DTV_BW_J83B_5_60_MSPS:
hSystem = SONY_FREIA_DTV_SKP_OPT; /* J.83B (5.6Msps used in Japan) uses special setting */
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
/* Intentional fall-through */
case SONY_DTV_SYSTEM_UNKNOWN:
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_freia_terr_Tune (((sony_freia_t *) pTuner->user), centerFreqKHz, hSystem);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Allow the tuner time to settle */
SONY_SLEEP(50);
result = sony_freia_terr_TuneEnd ((sony_freia_t *) pTuner->user);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Assign current values. */
pTuner->frequencyKHz = ((sony_freia_t *) pTuner->user)->frequencykHz;
pTuner->system = system;
pTuner->bandwidth = bandwidth;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_freia_sat_Tune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
uint32_t symbolRateKSps)
{
sony_result_t result = SONY_RESULT_OK;
sony_freia_tv_system_t hSystem = SONY_FREIA_STV_DVBS2;
SONY_TRACE_ENTER ("sony_tuner_freia_sat_Tune");
if ((!pTuner) || (!pTuner->user)){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
switch(system)
{
case SONY_DTV_SYSTEM_DVBS:
hSystem = SONY_FREIA_STV_DVBS;
break;
case SONY_DTV_SYSTEM_DVBS2:
hSystem = SONY_FREIA_STV_DVBS2;
break;
case SONY_DTV_SYSTEM_ISDBS:
hSystem = SONY_FREIA_STV_ISDBS;
break;
case SONY_DTV_SYSTEM_ISDBS3:
hSystem = SONY_FREIA_STV_ISDBS3;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_freia_sat_Tune (((sony_freia_t *) pTuner->user), centerFreqKHz, hSystem, symbolRateKSps);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
pTuner->frequencyKHz = ((sony_freia_t *) pTuner->user)->frequencykHz;
pTuner->system = system;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = symbolRateKSps;
/* Tuner stabillization time */
SONY_SLEEP (50);
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_freia_Sleep (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_freia_Sleep");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. */
result = sony_freia_Sleep (((sony_freia_t *) pTuner->user));
/* Device is in "Power Save" state. */
pTuner->frequencyKHz = 0;
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_freia_Shutdown (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_freia_Shutdown");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. */
result = sony_freia_Sleep (((sony_freia_t *) pTuner->user));
/* Device is in "Power Save" state. */
pTuner->frequencyKHz = 0;
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_freia_ReadRFLevel (sony_tuner_t * pTuner, int32_t * pRFLevel)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_freia_ReadRFLevel");
if (!pTuner || !pTuner->user || !pRFLevel) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (SONY_DTV_SYSTEM_IS_TERR_CABLE (pTuner->system)) {
result = sony_freia_terr_ReadRssi (((sony_freia_t *) pTuner->user), pRFLevel);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Add IFOUT value */
switch (pTuner->system) {
case SONY_DTV_SYSTEM_DVBT:
case SONY_DTV_SYSTEM_DVBT2:
case SONY_DTV_SYSTEM_DVBC2:
case SONY_DTV_SYSTEM_ATSC3:
*pRFLevel -= 400; /* -4.0dBm */
break;
case SONY_DTV_SYSTEM_DVBC:
case SONY_DTV_SYSTEM_ISDBC:
case SONY_DTV_SYSTEM_J83B:
*pRFLevel -= 150; /* -1.5dBm */
break;
case SONY_DTV_SYSTEM_ISDBT:
*pRFLevel -= 450; /* -4.5dBm */
break;
case SONY_DTV_SYSTEM_ATSC:
*pRFLevel -= 500; /* -5.0dBm */
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT);
}
} else if (SONY_DTV_SYSTEM_IS_SAT (pTuner->system)) {
result = sony_freia_sat_ReadRssi (((sony_freia_t *) pTuner->user), pRFLevel);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Add IFOUT value */
*pRFLevel -= 300; /* -3.0dBm */
} else {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
static sony_result_t sony_tuner_freia_CalcRFLevelFromAGC (sony_tuner_t * pTuner,
uint32_t agcValue,
int32_t * pRFLevel)
{
/* This API is only for satellite. (blind scan) */
int32_t tempA = 0;
uint8_t isNegative = 0;
uint32_t tempDiv = 0;
uint32_t tempQ = 0;
uint32_t tempR = 0;
SONY_TRACE_ENTER("sony_tuner_freia_CalcRFLevelFromAGC");
if ((!pTuner) || (!pRFLevel)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (!SONY_DTV_SYSTEM_IS_SAT (pTuner->system)) {
/* Satellite Only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/*------------------------------------------------
Gain_db = AGCLevel * (-14 / 403) + 97
Gain_db_x100 = AGCLevel * (-1400 / 403) + 9700
-------------------------------------------------*/
tempA = (int32_t)agcValue * (-1400);
tempDiv = 403;
if (tempA > 0) {
isNegative = 0;
tempQ = (uint32_t)tempA / tempDiv;
tempR = (uint32_t)tempA % tempDiv;
} else {
isNegative = 1;
tempQ = (uint32_t)(tempA * (-1)) / tempDiv;
tempR = (uint32_t)(tempA * (-1)) % tempDiv;
}
if (isNegative) {
if (tempR >= (tempDiv/2)) {
*pRFLevel = (int32_t)(tempQ + 1) * (int32_t)(-1);
} else {
*pRFLevel = (int32_t)tempQ * (int32_t)(-1);
}
} else {
if (tempR >= (tempDiv/2)) {
*pRFLevel = (int32_t)(tempQ + 1);
} else {
*pRFLevel = (int32_t)tempQ;
}
}
*pRFLevel += 9700;
/*
* RF_Level = Input_Ref_Level - RF_Gain
* -> Input_Ref_Level = 0dB for this demodulator
*/
*pRFLevel *= -1;
SONY_TRACE_RETURN(SONY_RESULT_OK);
}
@@ -0,0 +1,152 @@
/*------------------------------------------------------------------------------
Copyright 2021 Sony Semiconductor Solutions Corporation
Last Updated : 2021/12/13
Modification ID : 3cc1b1863ae94a345715678192a80bd188f58cc0
------------------------------------------------------------------------------*/
/**
@file sony_tuner_freia.h
This file provides the DVB port of the Sony FREIA tuner driver.
This driver wraps around the Freia driver provided by
sony_freia.h by using an instance of the Freia (sony_freia_t)
driver in the ::sony_tuner_t::user pointer.
Please note, if the Freia tuner is used in a system without the
terrestrial or satellite demodulator components then the unused
structure, pTunerSat or pTunerTerrCable must be declared prior to
calling tuner create function.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_TUNER_FREIA_H
#define SONY_TUNER_FREIA_H
/*------------------------------------------------------------------------------
Includes
------------------------------------------------------------------------------*/
#include "../sony_tuner.h"
#include "./refcode/sony_freia.h"
/*------------------------------------------------------------------------------
Driver Version
------------------------------------------------------------------------------*/
extern const char* sony_tuner_freia_version; /**< FREIA driver version */
/*------------------------------------------------------------------------------
Defines
------------------------------------------------------------------------------*/
#define SONY_TUNER_FREIA_OFFSET_CUTOFF_HZ 50000 /**< Maximum carrier offset frequency before requiring a retune */
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
/**
@brief Creates an instance of the FREIA tuner driver
@param pTuner The tuner driver instance to create.
Memory must have been allocated for this instance before creation.
@param i2cAddress The I2C address of the FREIA device.
Typically 0xC0.
@param pI2c The I2C driver that the tuner driver will use for
communication.
@param configFlags See ::SONY_FREIA_CONFIG_EXT_REF,
::SONY_FREIA_CONFIG_SLEEP_DISABLEXTAL,
::SONY_FREIA_CONFIG_LOOPFILTER_INTERNAL,
::SONY_FREIA_CONFIG_SAT_LOW_GAIN_MODE,
::SONY_FREIA_CONFIG_POWERSAVE_TERR_NORMAL_MATCHING_DISABLE
::SONY_FREIA_CONFIG_POWERSAVE_TERR_NORMAL_MATCHING_ENABLE
::SONY_FREIA_CONFIG_POWERSAVE_TERR_RF_ACTIVE_MATCHING_DISABLE
::SONY_FREIA_CONFIG_POWERSAVE_TERR_RF_ACTIVE_MATCHING_ENABLE
::SONY_FREIA_CONFIG_POWERSAVE_SAT_NORMAL
::SONY_FREIA_CONFIG_POWERSAVE_SAT_RF_ACTIVE
::SONY_FREIA_CONFIG_POWERSAVE_SAT_RF_ACTIVE_AGC_FULL
::SONY_FREIA_CONFIG_OUTLMT_ATV_1_5Vpp
::SONY_FREIA_CONFIG_OUTLMT_ATV_1_2Vpp
::SONY_FREIA_CONFIG_OUTLMT_DTV_1_5Vpp
::SONY_FREIA_CONFIG_OUTLMT_DTV_1_2Vpp
::SONY_FREIA_CONFIG_OUTLMT_STV_0_75Vpp
::SONY_FREIA_CONFIG_OUTLMT_STV_0_6Vpp
::SONY_FREIA_CONFIG_REFOUT_500mVpp
::SONY_FREIA_CONFIG_REFOUT_400mVpp
::SONY_FREIA_CONFIG_REFOUT_600mVpp
::SONY_FREIA_CONFIG_REFOUT_800mVpp
::SONY_FREIA_CONFIG_IFAGC_SEL_ALL1
::SONY_FREIA_CONFIG_IFAGC_SEL_ALL2
::SONY_FREIA_CONFIG_IFAGC_SEL_A1D2
::SONY_FREIA_CONFIG_IFAGC_SEL_D1A2
::SONY_FREIA_CONFIG_IFOUT_DC_BIAS_750mV
::SONY_FREIA_CONFIG_IFOUT_DC_BIAS_500mV
defined in
\link sony_freia.h \endlink
@param pFreiaTuner The Freia tuner driver pointer to use.
Memory must have been allocated for the Freia driver structure.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_freia_Create (sony_tuner_t * pTuner,
uint8_t i2cAddress,
sony_i2c_t * pI2c,
uint32_t configFlags,
sony_freia_t * pFreiaTuner);
/**
@brief Write to GPIO0 or GPIO1.
@param pTuner Instance of the tuner driver.
@param id Pin ID 0 = GPIO0, 1 = GPIO1
@param value Output logic level, 0 = Low, 1 = High
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_freia_SetGPO (sony_tuner_t * pTuner, uint8_t id, uint8_t value);
/**
@brief Read from GPIO0 or GPIO1.
@param pTuner Instance of the tuner driver.
@param id Pin ID 0 = GPIO0, 1 = GPIO1
@param pValue Read logic level, 0 = Low, 1 = High
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_freia_GetGPI (sony_tuner_t * pTuner, uint8_t id, uint8_t * pValue);
/**
@brief RF filter compensation setting.
(Please see RFVGA Description of datasheet.)
New setting will become effective after next tuning.
mult = coeff / 128
(compensated value) = (original value) * mult + offset
@param pTuner Instance of the tuner driver.
@param vlCoeff Multiplier value. (8bit unsigned)
@param vlOffset Additional term. (8bit 2s complement)
@param uvhCoeff Multiplier value. (8bit unsigned)
@param uvhOffset Additional term. (8bit 2s complement)
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_freia_RFFilterConfig (sony_tuner_t * pTuner, uint8_t vlCoeff, uint8_t vlOffset,
uint8_t uvhCoeff, uint8_t uvhOffset);
/**
@brief Tune to a given RF frequency with satellite broadcasting system delivered by cable broadcast.
@param pTuner Instance of the tuner driver.
@param centerFreqKHz RF frequency to tune. (kHz)
@param system The type of broadcasting system to tune.
@param symbolRateKSps Symbol rate to tune. (ksps)
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_freia_terr_IQ_Tune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
uint32_t symbolRateKSps);
#endif /* SONY_TUNER_FREIA_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,460 @@
/*------------------------------------------------------------------------------
Copyright 2014-2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/07/05
File Revision : 1.1.2.0
------------------------------------------------------------------------------*/
/**
@file sony_helene.h
This file provides the HELENE tuner control interface.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_HELENE_H
#define SONY_HELENE_H
#include "sony_common.h"
#include "sony_i2c.h"
/*------------------------------------------------------------------------------
Defines
------------------------------------------------------------------------------*/
/**
@brief Version of this driver.
*/
#define SONY_HELENE_VERSION "1.1.2.0"
/**
@brief Default I2C slave address of the HELENE tuner.
*/
#define SONY_HELENE_ADDRESS 0xC0
/*------------------------------------------------------------------------------
Enums
------------------------------------------------------------------------------*/
/**
@brief HELENE tuner state.
*/
typedef enum {
SONY_HELENE_STATE_UNKNOWN, /**< HELENE state is Unknown */
SONY_HELENE_STATE_SLEEP, /**< HELENE state is Sleep */
SONY_HELENE_STATE_ACTIVE_T, /**< HELENE state is Active (terrestrial) */
SONY_HELENE_STATE_ACTIVE_S /**< HELENE state is Active (satellite) */
} sony_helene_state_t;
/**
@brief Xtal frequencies supported by HELENE.
*/
typedef enum {
SONY_HELENE_XTAL_16000KHz, /**< 16 MHz */
SONY_HELENE_XTAL_20500KHz, /**< 20.5 MHz */
SONY_HELENE_XTAL_24000KHz, /**< 24 MHz */
SONY_HELENE_XTAL_41000KHz /**< 41 MHz */
} sony_helene_xtal_t;
/**
@brief Analog/Digital terrestrial, satellite broadcasting system definitions supported by HELENE.
Fc : Center Frequency, Fp : Picture Frequency
*/
typedef enum {
SONY_HELENE_TV_SYSTEM_UNKNOWN,
/* Terrestrial Analog */
SONY_HELENE_ATV_MN_EIAJ, /**< System-M (Japan) (IF: Fp=5.75MHz in default) */
SONY_HELENE_ATV_MN_SAP, /**< System-M (US) (IF: Fp=5.75MHz in default) */
SONY_HELENE_ATV_MN_A2, /**< System-M (Korea) (IF: Fp=5.9MHz in default) */
SONY_HELENE_ATV_BG, /**< System-B/G (IF: Fp=7.3MHz in default) */
SONY_HELENE_ATV_I, /**< System-I (IF: Fp=7.85MHz in default) */
SONY_HELENE_ATV_DK, /**< System-D/K (IF: Fp=7.85MHz in default) */
SONY_HELENE_ATV_L, /**< System-L (IF: Fp=7.85MHz in default) */
SONY_HELENE_ATV_L_DASH, /**< System-L DASH (IF: Fp=2.2MHz in default) */
/* Terrestrial/Cable Digital */
SONY_HELENE_DTV_8VSB, /**< ATSC 8VSB (IF: Fc=3.7MHz in default) */
SONY_HELENE_DTV_QAM, /**< US QAM (IF: Fc=3.7MHz in default) */
SONY_HELENE_DTV_ISDBT_6, /**< ISDB-T 6MHzBW (IF: Fc=3.55MHz in default) */
SONY_HELENE_DTV_ISDBT_7, /**< ISDB-T 7MHzBW (IF: Fc=4.15MHz in default) */
SONY_HELENE_DTV_ISDBT_8, /**< ISDB-T 8MHzBW (IF: Fc=4.75MHz in default) */
SONY_HELENE_DTV_DVBT_5, /**< DVB-T 5MHzBW (IF: Fc=3.6MHz in default) */
SONY_HELENE_DTV_DVBT_6, /**< DVB-T 6MHzBW (IF: Fc=3.6MHz in default) */
SONY_HELENE_DTV_DVBT_7, /**< DVB-T 7MHzBW (IF: Fc=4.2MHz in default) */
SONY_HELENE_DTV_DVBT_8, /**< DVB-T 8MHzBW (IF: Fc=4.8MHz in default) */
SONY_HELENE_DTV_DVBT2_1_7,/**< DVB-T2 1.7MHzBW (IF: Fc=3.5MHz in default) */
SONY_HELENE_DTV_DVBT2_5, /**< DVB-T2 5MHzBW (IF: Fc=3.6MHz in default) */
SONY_HELENE_DTV_DVBT2_6, /**< DVB-T2 6MHzBW (IF: Fc=3.6MHz in default) */
SONY_HELENE_DTV_DVBT2_7, /**< DVB-T2 7MHzBW (IF: Fc=4.2MHz in default) */
SONY_HELENE_DTV_DVBT2_8, /**< DVB-T2 8MHzBW (IF: Fc=4.8MHz in default) */
SONY_HELENE_DTV_DVBC_6, /**< DVB-C 6MHzBW (IF: Fc=3.7MHz in default) */
SONY_HELENE_DTV_DVBC_8, /**< DVB-C 8MHzBW (IF: Fc=4.9MHz in default) */
SONY_HELENE_DTV_DVBC2_6, /**< DVB-C2 6MHzBW (IF: Fc=3.7MHz in default) */
SONY_HELENE_DTV_DVBC2_8, /**< DVB-C2 8MHzBW (IF: Fc=4.9MHz in default) */
SONY_HELENE_DTV_ATSC3_6, /**< ATSC 3.0 6MHzBW (IF: Fc=3.6MHz in default) */
SONY_HELENE_DTV_ATSC3_7, /**< ATSC 3.0 7MHzBW (IF: Fc=4.2MHz in default) */
SONY_HELENE_DTV_ATSC3_8, /**< ATSC 3.0 8MHzBW (IF: Fc=4.8MHz in default) */
SONY_HELENE_DTV_J83B_5_6, /**< J.83B 5.6Msps (IF: Fc=3.75MHz in default) */
SONY_HELENE_DTV_DTMB, /**< DTMB (IF: Fc=5.1MHz in default) */
/* Satellite */
SONY_HELENE_STV_ISDBS, /**< ISDB-S */
SONY_HELENE_STV_DVBS, /**< DVB-S */
SONY_HELENE_STV_DVBS2, /**< DVB-S2 */
SONY_HELENE_ATV_MIN = SONY_HELENE_ATV_MN_EIAJ, /**< Minimum analog terrestrial system */
SONY_HELENE_ATV_MAX = SONY_HELENE_ATV_L_DASH, /**< Maximum analog terrestrial system */
SONY_HELENE_DTV_MIN = SONY_HELENE_DTV_8VSB, /**< Minimum digital terrestrial system */
SONY_HELENE_DTV_MAX = SONY_HELENE_DTV_DTMB, /**< Maximum digital terrestrial system */
SONY_HELENE_TERR_TV_SYSTEM_NUM, /**< Number of supported terrestrial broadcasting system */
SONY_HELENE_STV_MIN = SONY_HELENE_STV_ISDBS, /**< Minimum satellite system */
SONY_HELENE_STV_MAX = SONY_HELENE_STV_DVBS2 /**< Maximum satellite system */
} sony_helene_tv_system_t;
/**
@brief Macro to check that the system is analog terrestrial or not.
*/
#define SONY_HELENE_IS_ATV(tvSystem) (((tvSystem) >= SONY_HELENE_ATV_MIN) && ((tvSystem) <= SONY_HELENE_ATV_MAX))
/**
@brief Macro to check that the system is digital terrestrial or not.
*/
#define SONY_HELENE_IS_DTV(tvSystem) (((tvSystem) >= SONY_HELENE_DTV_MIN) && ((tvSystem) <= SONY_HELENE_DTV_MAX))
/**
@brief Macro to check that the system is satellite or not.
*/
#define SONY_HELENE_IS_STV(tvSystem) (((tvSystem) >= SONY_HELENE_STV_MIN) && ((tvSystem) <= SONY_HELENE_STV_MAX))
/*------------------------------------------------------------------------------
Structs
------------------------------------------------------------------------------*/
/**
@brief HELENE settings that may need to change depend on customer's system.
*/
typedef struct sony_helene_terr_adjust_param_t {
uint8_t RF_GAIN; /**< Addr:0x69 Bit[6:4] : RFVGA gain. 0xFF means Auto. (RF_GAIN_SEL = 1) */
uint8_t IF_BPF_GC; /**< Addr:0x69 Bit[3:0] : IF_BPF gain. */
uint8_t RFOVLD_DET_LV1_VL; /**< Addr:0x6B Bit[3:0] : RF overload RF input detect level. (FRF <= 172MHz) */
uint8_t RFOVLD_DET_LV1_VH; /**< Addr:0x6B Bit[3:0] : RF overload RF input detect level. (172MHz < FRF <= 464MHz) */
uint8_t RFOVLD_DET_LV1_U; /**< Addr:0x6B Bit[3:0] : RF overload RF input detect level. (FRF > 464MHz) */
uint8_t IFOVLD_DET_LV_VL; /**< Addr:0x6C Bit[2:0] : Internal RFAGC detect level. (FRF <= 172MHz) */
uint8_t IFOVLD_DET_LV_VH; /**< Addr:0x6C Bit[2:0] : Internal RFAGC detect level. (172MHz < FRF <= 464MHz) */
uint8_t IFOVLD_DET_LV_U; /**< Addr:0x6C Bit[2:0] : Internal RFAGC detect level. (FRF > 464MHz) */
uint8_t IF_BPF_F0; /**< Addr:0x6D Bit[5:4] : IF filter center offset. */
uint8_t BW; /**< Addr:0x6D Bit[1:0] : 6MHzBW(0x00) or 7MHzBW(0x01) or 8MHzBW(0x02) or 1.7MHzBW(0x03) */
uint8_t FIF_OFFSET; /**< Addr:0x6E Bit[4:0] : 5bit signed. IF offset (kHz) = FIF_OFFSET x 50 */
uint8_t BW_OFFSET; /**< Addr:0x6F Bit[4:0] : 5bit signed. BW offset (kHz) = BW_OFFSET x 50 (BW_OFFSET x 10 in 1.7MHzBW) */
uint8_t IS_LOWERLOCAL; /**< Addr:0x9C Bit[0] : Local polarity. (0: Upper Local, 1: Lower Local) */
} sony_helene_terr_adjust_param_t;
/**
@brief The HELENE tuner definition which allows control of the HELENE tuner device
through the defined set of functions.
*/
typedef struct sony_helene_t {
sony_helene_xtal_t xtalFreq; /**< Xtal frequency for HELENE. */
uint8_t i2cAddress; /**< I2C slave address of the HELENE tuner (8-bit form - 8'bxxxxxxx0) */
sony_i2c_t* pI2c; /**< I2C API instance. */
uint32_t flags; /**< ORed value of SONY_HELENE_CONFIG_XXXX */
/* For saving current setting */
sony_helene_state_t state; /**< The driver operating state. */
uint32_t frequencykHz; /**< Currently RF frequency(kHz) tuned. */
sony_helene_tv_system_t tvSystem; /**< Current broadcasting system tuned. */
uint32_t symbolRateksps; /**< Current symbol rate(ksym/s) tuned. */
uint8_t isFreesatMode; /**< UK Freesat mode or not. */
/**
@brief Adjustment parameter table (SONY_HELENE_TV_SYSTEM_NUM size)
*/
const sony_helene_terr_adjust_param_t *pTerrParamTable;
/* Following Xtal related parameters can be changed if optimization is necessary. */
uint8_t xosc_sel; /**< Driver current setting for crystal oscillator. (Addr:0x82 Bit[4:0]) */
uint8_t xosc_cap_set; /**< Driver current setting for crystal oscillator. (Addr:0x83 Bit[6:0]) */
void* user; /**< User defined data. */
} sony_helene_t;
/*
Config flag definitions. (ORed value should be set to flags argument of Create API.)
*/
/**
@brief Use external Xtal
Should be used for slave HELENE in Xtal shared system.
*/
#define SONY_HELENE_CONFIG_EXT_REF 0x80000000
/**
@brief Disable Xtal in Sleep state.
Should NOT be used for Xtal shared system.
Not only for the master HELENE which has Xtal, but also slave HELENE which receive the clock signal.
Cannot be used with SONY_HELENE_CONFIG_EXT_REF.
*/
#define SONY_HELENE_CONFIG_SLEEP_DISABLEXTAL 0x40000000
/**
@brief Internal loop filter setting.
If this is used, internal loop filter is used for
digital broadcasting system except for DVB-C/C2.
For analog and DVB-C/C2, external loop filter will be used.
*/
#define SONY_HELENE_CONFIG_LOOPFILTER_INTERNAL 0x10000000
/**
@brief Satellite LNA OFF (path through) setting.
*/
#define SONY_HELENE_CONFIG_SAT_LNA_OFF 0x08000000
/**
@name Power Save setting for terrestrial.
These settings are for avoiding steep input impedance change in power save state.
*/
/**@{*/
#define SONY_HELENE_CONFIG_POWERSAVE_TERR_NORMAL 0x00000000 /**< Normal (default) */
#define SONY_HELENE_CONFIG_POWERSAVE_TERR_RFIN_MATCHING 0x00400000 /**< RFIN matching enable */
#define SONY_HELENE_CONFIG_POWERSAVE_TERR_RF_ACTIVE 0x00800000 /**< Keep RF part active */
#define SONY_HELENE_CONFIG_POWERSAVE_TERR_MASK 0x00C00000 /**< Do not use this value */
/**@}*/
/**
@name Power Save setting for satellite.
These settings are for avoiding steep input impedance change in power save state.
*/
/**@{*/
#define SONY_HELENE_CONFIG_POWERSAVE_SAT_NORMAL 0x00000000 /**< Normal (default) */
#define SONY_HELENE_CONFIG_POWERSAVE_SAT_RFIN_MATCHING 0x00100000 /**< RFIN matching enable */
#define SONY_HELENE_CONFIG_POWERSAVE_SAT_RF_ACTIVE 0x00200000 /**< Keep RF part active */
#define SONY_HELENE_CONFIG_POWERSAVE_SAT_MASK 0x00300000 /**< Do not use this value */
/**@}*/
/**
@name Maximum IF and IQ output setting. (for terrestrial analog)
*/
/**@{*/
#define SONY_HELENE_CONFIG_OUTLMT_ATV_1_5Vpp 0x00000000 /**< 1.5Vpp (default) */
#define SONY_HELENE_CONFIG_OUTLMT_ATV_1_2Vpp 0x00080000 /**< 1.2Vpp */
/**@}*/
/**
@name Maximum IF and IQ output setting. (for terrestrial digital)
*/
/**@{*/
#define SONY_HELENE_CONFIG_OUTLMT_DTV_1_5Vpp 0x00000000 /**< 1.5Vpp (default) */
#define SONY_HELENE_CONFIG_OUTLMT_DTV_1_2Vpp 0x00040000 /**< 1.2Vpp */
/**@}*/
/**
@name Maximum IF and IQ output setting. (for satellite)
*/
/**@{*/
#define SONY_HELENE_CONFIG_OUTLMT_STV_0_75Vpp 0x00000000 /**< 0.75Vpp (default) */
#define SONY_HELENE_CONFIG_OUTLMT_STV_0_6Vpp 0x00020000 /**< 0.6Vpp */
/**@}*/
/**
@name REFOUT setting related macros.
If following values are not used, REFOUT output is disabled.
*/
/**@{*/
/**
@brief REFOUT enable, output level is 500mVp-p.
*/
#define SONY_HELENE_CONFIG_REFOUT_500mVpp 0x00001000
/**
@brief REFOUT enable, output level is 400mVp-p.
*/
#define SONY_HELENE_CONFIG_REFOUT_400mVpp 0x00002000
/**
@brief REFOUT enable, output level is 600mVp-p.
*/
#define SONY_HELENE_CONFIG_REFOUT_600mVpp 0x00003000
/**
@brief REFOUT enable, output level is 800mVp-p.
*/
#define SONY_HELENE_CONFIG_REFOUT_800mVpp 0x00004000
/**
@brief Internal use only. Do not use this value.
*/
#define SONY_HELENE_CONFIG_REFOUT_MASK 0x00007000
/**@}*/
/*------------------------------------------------------------------------------
APIs
------------------------------------------------------------------------------*/
/**
@brief Set up the HELENE tuner driver.
This MUST be called before calling sony_helene_Initialize.
@param pTuner Reference to memory allocated for the HELENE instance.
The create function will setup this HELENE instance.
@param xtalFreq The frequency of the HELENE crystal.
@param i2cAddress The HELENE tuner I2C slave address in 8-bit form.
@param pI2c The I2C APIs that the HELENE driver will use as the I2C interface.
@param flags Configuration flags. It should be ORed value of SONY_HELENE_CONFIG_XXXX.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene_Create(sony_helene_t *pTuner, sony_helene_xtal_t xtalFreq,
uint8_t i2cAddress, sony_i2c_t *pI2c, uint32_t flags);
/**
@brief Initialize the HELENE tuner.
This MUST be called before calling sony_helene_terr_Tune and sony_helene_sat_Tune.
@param pTuner The HELENE tuner instance.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene_Initialize(sony_helene_t *pTuner);
/**
@brief Tune to a given RF frequency with terrestrial broadcasting system.
To complete tuning, sony_helene_terr_TuneEnd should be called after waiting 50ms.
@param pTuner The HELENE tuner instance.
@param frequencykHz RF frequency to tune. (kHz)
@param tvSystem The type of broadcasting system to tune.
@return SONY_RESULT_OK if tuner successfully tuned.
*/
sony_result_t sony_helene_terr_Tune(sony_helene_t *pTuner, uint32_t frequencykHz,
sony_helene_tv_system_t tvSystem);
/**
@brief Completes the terrestrial tuning sequence.
This MUST be called after calling sony_helene_terr_Tune and 50ms wait.
@param pTuner The HELENE tuner instance.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene_terr_TuneEnd(sony_helene_t *pTuner);
/**
@brief Tune to a given RF frequency with satellite broadcasting system.
@param pTuner The HELENE tuner instance.
@param frequencykHz RF frequency to tune. (kHz)
@param tvSystem The type of broadcasting system to tune.
@param symbolRateksps Symbol rate to tune. (ksps)
@return SONY_RESULT_OK if tuner successfully tuned.
*/
sony_result_t sony_helene_sat_Tune(sony_helene_t *pTuner, uint32_t frequencykHz,
sony_helene_tv_system_t tvSystem, uint32_t symbolRateksps);
/**
@brief Shift RF frequency.
This API shift RF frequency without VCO calibration.
This API is normally useful for analog TV "fine tuning" that
shift RF frequency without picture distortion.
@note Please check the frequency range that VCO calibration is unnecessary.
(See hardware specification sheet.)
@param pTuner The HELENE tuner instance.
@param frequencykHz RF frequency to tune. (kHz)
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene_ShiftFRF(sony_helene_t *pTuner, uint32_t frequencykHz);
/**
@brief Put the HELENE tuner into Sleep state.
From this state the tuner can be directly tuned by calling sony_helene_Tune.
@param pTuner The HELENE tuner instance.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene_Sleep(sony_helene_t *pTuner);
/**
@brief Write to GPO0 or GPO1.
@param pTuner The HELENE tuner instance.
@param id Pin ID 0 = GPO0, 1 = GPO1
@param val Output logic level, 0 = Low, 1 = High
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene_SetGPO(sony_helene_t *pTuner, uint8_t id, uint8_t val);
/**
@brief Read GPI1 value.
@param pTuner The HELENE tuner instance.
@param pVal GPI logic level, 0 = Low, 1 = High
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene_GetGPI1(sony_helene_t *pTuner, uint8_t *pVal);
/**
@brief Set the RF external circuit control pin. (for terrestrial)
(Set RF_EXT_CTRL register.)
@param pTuner The HELENE tuner instance.
@param enable The value to set. (Enable(1) or Disable(0))
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene_SetRfExtCtrl(sony_helene_t *pTuner, uint8_t enable);
/**
@brief Set UK Freesat mode.
If this mode is enabled, Freesat optimized setting will be used in sony_helene_sat_Tune.
If internal loop filter is used, (SONY_HELENE_CONFIG_LOOPFILTER_INTERNAL is ORed)
UK Freesat mode has no effect.
@param pTuner The HELENE tuner instance.
@param enable The value to set. (Enable(1) or Disable(0))
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene_SetFreesatMode(sony_helene_t *pTuner, uint8_t enable);
/**
@brief Read the RSSI in dBm from the tuner. (for terrestrial)
@note Target level of IF signal output (depend on demodulator)
is not added in default.
@param pTuner The HELENE tuner instance.
@param pRssi RSSI in dBm * 100
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene_ReadRssi(sony_helene_t *pTuner, int32_t *pRssi);
/**
@brief RF filter compensation setting for VHF-L band.
(Please see RFVGA Description of datasheet.)
New setting will become effective after next tuning.
mult = coeff / 128
(compensated value) = (original value) * mult + offset
@param pTuner The HELENE tuner instance.
@param coeff Multiplier value. (8bit unsigned)
@param offset Additional term. (8bit 2s complement)
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene_RFFilterConfig(sony_helene_t *pTuner, uint8_t coeff, uint8_t offset);
#endif /* SONY_HELENE_H */
@@ -0,0 +1,519 @@
/*------------------------------------------------------------------------------
Copyright 2016-2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/07/05
Modification ID : c7c68d70868a4a9fb9e0f480d8b940e8a1e8f651
------------------------------------------------------------------------------*/
#include "sony_tuner_helene.h"
#include <string.h>
#include <stdlib.h>
/*------------------------------------------------------------------------------
Driver Version
------------------------------------------------------------------------------*/
const char* sony_tuner_helene_version = SONY_HELENE_VERSION;
/*------------------------------------------------------------------------------
Static Prototypes
------------------------------------------------------------------------------*/
static sony_result_t sony_tuner_helene_Initialize (sony_tuner_t * pTuner);
static sony_result_t sony_tuner_helene_terr_Tune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
sony_dtv_bandwidth_t bandwidth);
static sony_result_t sony_tuner_helene_sat_Tune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
uint32_t symbolRateKSps);
static sony_result_t sony_tuner_helene_Sleep (sony_tuner_t * pTuner);
static sony_result_t sony_tuner_helene_Shutdown (sony_tuner_t * pTuner);
static sony_result_t sony_tuner_helene_ReadRFLevel (sony_tuner_t * pTuner, int32_t * pRFLevel);
static sony_result_t sony_tuner_helene_CalcRFLevelFromAGC (sony_tuner_t * pTuner, uint32_t agcValue, int32_t * pRFLevel);
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
sony_result_t sony_tuner_helene_Create (sony_tuner_t * pTuner,
sony_helene_xtal_t xtalFreq,
uint8_t i2cAddress,
sony_i2c_t * pI2c,
uint32_t configFlags,
sony_helene_t * pHeleneTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_helene_Create");
if ((!pI2c) || (!pHeleneTuner) || (!pTuner)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
memset (pTuner, 0, sizeof (sony_tuner_t)); /* Zero filled */
/* Create the underlying HELENE reference driver. */
result = sony_helene_Create (pHeleneTuner, xtalFreq, i2cAddress, pI2c, configFlags);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Populate / Initialize the sony_tuner_t structure */
pTuner->i2cAddress = i2cAddress;
pTuner->pI2c = pI2c;
pTuner->flags = configFlags;
pTuner->symbolRateKSpsForSpectrum = 45000;
pTuner->rfLevelFuncTerr = SONY_TUNER_RFLEVEL_FUNC_READ; /* Use ReadRFLevel function for terrestrial */
pTuner->rfLevelFuncSat = SONY_TUNER_RFLEVEL_FUNC_CALCFROMAGC; /* Use CalcRFLevelFromAGC function for satellite */
pTuner->user = pHeleneTuner;
pTuner->Initialize = sony_tuner_helene_Initialize;
pTuner->TerrCableTune = sony_tuner_helene_terr_Tune;
pTuner->SatTune = sony_tuner_helene_sat_Tune;
pTuner->Sleep = sony_tuner_helene_Sleep;
pTuner->Shutdown = sony_tuner_helene_Shutdown;
pTuner->ReadRFLevel = sony_tuner_helene_ReadRFLevel;
pTuner->CalcRFLevelFromAGC = sony_tuner_helene_CalcRFLevelFromAGC;
SONY_TRACE_RETURN (result);
}
sony_result_t sony_tuner_helene_SetGPO (sony_tuner_t * pTuner, uint8_t id, uint8_t value)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_helene_Write_GPIO");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_helene_SetGPO (((sony_helene_t *) pTuner->user), id, value);
SONY_TRACE_RETURN (result);
}
sony_result_t sony_tuner_helene_GetGPI1 (sony_tuner_t * pTuner, uint8_t * pValue)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_helene_GetGPI1");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_helene_GetGPI1 (((sony_helene_t *) pTuner->user), pValue);
SONY_TRACE_RETURN (result);
}
sony_result_t sony_tuner_helene_RFFilterConfig (sony_tuner_t * pTuner, uint8_t coeff, uint8_t offset)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_helene_RFFilterConfig");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_helene_RFFilterConfig (((sony_helene_t *) pTuner->user), coeff, offset);
SONY_TRACE_RETURN (result);
}
/*------------------------------------------------------------------------------
Static Functions
------------------------------------------------------------------------------*/
static sony_result_t sony_tuner_helene_Initialize (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_helene_Initialize");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. */
result = sony_helene_Initialize (((sony_helene_t *) pTuner->user));
/* Device is in "Power Save" state. */
pTuner->frequencyKHz = 0;
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_helene_terr_Tune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
sony_dtv_bandwidth_t bandwidth)
{
sony_result_t result = SONY_RESULT_OK;
sony_helene_tv_system_t hSystem = SONY_HELENE_TV_SYSTEM_UNKNOWN;
SONY_TRACE_ENTER ("sony_tuner_helene_terr_Tune");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. Convert system, bandwidth into dtv system. */
switch (system) {
case SONY_DTV_SYSTEM_DVBC:
switch (bandwidth) {
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_HELENE_DTV_DVBC_6;
break;
case SONY_DTV_BW_7_MHZ:
/* 7MHZ BW setting is the same as 8MHz BW */
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_HELENE_DTV_DVBC_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_DVBT:
switch (bandwidth) {
case SONY_DTV_BW_5_MHZ:
hSystem = SONY_HELENE_DTV_DVBT_5;
break;
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_HELENE_DTV_DVBT_6;
break;
case SONY_DTV_BW_7_MHZ:
hSystem = SONY_HELENE_DTV_DVBT_7;
break;
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_HELENE_DTV_DVBT_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_DVBT2:
switch (bandwidth) {
case SONY_DTV_BW_1_7_MHZ:
hSystem = SONY_HELENE_DTV_DVBT2_1_7;
break;
case SONY_DTV_BW_5_MHZ:
hSystem = SONY_HELENE_DTV_DVBT2_5;
break;
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_HELENE_DTV_DVBT2_6;
break;
case SONY_DTV_BW_7_MHZ:
hSystem = SONY_HELENE_DTV_DVBT2_7;
break;
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_HELENE_DTV_DVBT2_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_DVBC2:
switch (bandwidth) {
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_HELENE_DTV_DVBC2_6;
break;
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_HELENE_DTV_DVBC2_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_ISDBT:
switch (bandwidth) {
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_HELENE_DTV_ISDBT_6;
break;
case SONY_DTV_BW_7_MHZ:
hSystem = SONY_HELENE_DTV_ISDBT_7;
break;
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_HELENE_DTV_ISDBT_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_ISDBC:
hSystem = SONY_HELENE_DTV_DVBC_6; /* ISDB-C uses DVB-C 6MHz BW setting */
break;
case SONY_DTV_SYSTEM_ATSC:
hSystem = SONY_HELENE_DTV_8VSB;
break;
case SONY_DTV_SYSTEM_ATSC3:
switch (bandwidth) {
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_HELENE_DTV_ATSC3_6;
break;
case SONY_DTV_BW_7_MHZ:
hSystem = SONY_HELENE_DTV_ATSC3_7;
break;
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_HELENE_DTV_ATSC3_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_J83B:
switch (bandwidth) {
case SONY_DTV_BW_J83B_5_06_5_36_MSPS:
hSystem = SONY_HELENE_DTV_DVBC_6; /* J.83B (5.057, 5.361Msps commonly used in US) uses DVB-C 6MHz BW setting */
break;
case SONY_DTV_BW_J83B_5_60_MSPS:
hSystem = SONY_HELENE_DTV_J83B_5_6; /* J.83B (5.6Msps used in Japan) uses special setting */
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
/* Intentional fall-through */
case SONY_DTV_SYSTEM_UNKNOWN:
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_helene_terr_Tune (((sony_helene_t *) pTuner->user), centerFreqKHz, hSystem);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Allow the tuner time to settle */
SONY_SLEEP(50);
result = sony_helene_terr_TuneEnd ((sony_helene_t *) pTuner->user);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Assign current values. */
pTuner->frequencyKHz = ((sony_helene_t *) pTuner->user)->frequencykHz;
pTuner->system = system;
pTuner->bandwidth = bandwidth;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_helene_sat_Tune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
uint32_t symbolRateKSps)
{
sony_result_t result = SONY_RESULT_OK;
sony_helene_tv_system_t hSystem = SONY_HELENE_STV_DVBS2;
SONY_TRACE_ENTER ("sony_tuner_helene_sat_Tune");
if ((!pTuner) || (!pTuner->user)){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
switch(system)
{
case SONY_DTV_SYSTEM_DVBS:
hSystem = SONY_HELENE_STV_DVBS;
break;
case SONY_DTV_SYSTEM_DVBS2:
hSystem = SONY_HELENE_STV_DVBS2;
break;
case SONY_DTV_SYSTEM_ISDBS:
case SONY_DTV_SYSTEM_ISDBS3:
hSystem = SONY_HELENE_STV_ISDBS;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_helene_sat_Tune (((sony_helene_t *) pTuner->user), centerFreqKHz, hSystem, symbolRateKSps);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
pTuner->frequencyKHz = ((sony_helene_t *) pTuner->user)->frequencykHz;
pTuner->system = system;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = symbolRateKSps;
/* Tuner stabillization time */
SONY_SLEEP (50);
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_helene_Sleep (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_helene_Sleep");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. */
result = sony_helene_Sleep (((sony_helene_t *) pTuner->user));
/* Device is in "Power Save" state. */
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->frequencyKHz = 0;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_helene_Shutdown (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_helene_Shutdown");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. */
result = sony_helene_Sleep (((sony_helene_t *) pTuner->user));
/* Device is in "Power Save" state. */
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->frequencyKHz = 0;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_helene_ReadRFLevel (sony_tuner_t * pTuner, int32_t * pRFLevel)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_helene_ReadRFLevel");
if (!pTuner || !pTuner->user || !pRFLevel) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (!SONY_DTV_SYSTEM_IS_TERR_CABLE (pTuner->system)) {
/* Terrestrial/Cable Only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
result = sony_helene_ReadRssi (((sony_helene_t *) pTuner->user), pRFLevel);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Add IFOUT value */
switch (pTuner->system) {
case SONY_DTV_SYSTEM_DVBT:
case SONY_DTV_SYSTEM_DVBT2:
case SONY_DTV_SYSTEM_DVBC2:
case SONY_DTV_SYSTEM_ATSC3:
*pRFLevel -= 400; /* -4.0dBm */
break;
case SONY_DTV_SYSTEM_DVBC:
case SONY_DTV_SYSTEM_ISDBC:
case SONY_DTV_SYSTEM_J83B:
*pRFLevel -= 150; /* -1.5dBm */
break;
case SONY_DTV_SYSTEM_ISDBT:
*pRFLevel -= 450; /* -4.5dBm */
break;
case SONY_DTV_SYSTEM_ATSC:
*pRFLevel -= 500; /* -5.0dBm */
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT);
}
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_helene_CalcRFLevelFromAGC (sony_tuner_t * pTuner,
uint32_t agcValue,
int32_t * pRFLevel)
{
int32_t tempA = 0;
uint8_t isNegative = 0;
uint32_t tempDiv = 0;
uint32_t tempQ = 0;
uint32_t tempR = 0;
SONY_TRACE_ENTER("sony_tuner_helene_CalcRFLevelFromAGC");
if ((!pTuner) || (!pRFLevel)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (!SONY_DTV_SYSTEM_IS_SAT (pTuner->system)) {
/* Satellite Only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/*------------------------------------------------
Gain_db = AGCLevel * (-14 / 403) + 97
Gain_db_x100 = AGCLevel * (-1400 / 403) + 9700
-------------------------------------------------*/
tempA = (int32_t)agcValue * (-1400);
tempDiv = 403;
if (tempA > 0) {
isNegative = 0;
tempQ = (uint32_t)tempA / tempDiv;
tempR = (uint32_t)tempA % tempDiv;
} else {
isNegative = 1;
tempQ = (uint32_t)(tempA * (-1)) / tempDiv;
tempR = (uint32_t)(tempA * (-1)) % tempDiv;
}
if (isNegative){
if (tempR >= (tempDiv/2)) {
*pRFLevel = (int32_t)(tempQ + 1) * (int32_t)(-1);
} else {
*pRFLevel = (int32_t)tempQ * (int32_t)(-1);
}
} else {
if (tempR >= (tempDiv/2)) {
*pRFLevel = (int32_t)(tempQ + 1);
} else {
*pRFLevel = (int32_t)tempQ;
}
}
*pRFLevel += 9700;
/*
* RF_Level = Input_Ref_Level - RF_Gain
* -> Input_Ref_Level = 0dB for this demodulator
*/
*pRFLevel *= -1;
SONY_TRACE_RETURN(SONY_RESULT_OK);
}
@@ -0,0 +1,129 @@
/*------------------------------------------------------------------------------
Copyright 2016-2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/07/05
Modification ID : c7c68d70868a4a9fb9e0f480d8b940e8a1e8f651
------------------------------------------------------------------------------*/
/**
@file sony_tuner_helene.h
This file provides the DVB port of the Sony HELENE tuner driver.
This driver wraps around the Ascot3 driver provided by
sony_helene.h by using an instance of the Ascot3 (sony_helene_t)
driver in the ::sony_tuner_t::user pointer.
Please note, if the Helene tuner is used in a system without the
terrestrial or satellite demodulator components then the unused
structure, pTunerSat or pTunerTerrCable must be declared prior to
calling tuner create function.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_TUNER_HELENE_H
#define SONY_TUNER_HELENE_H
/*------------------------------------------------------------------------------
Includes
------------------------------------------------------------------------------*/
#include "sony_tuner.h"
#include "sony_helene.h"
/*------------------------------------------------------------------------------
Driver Version
------------------------------------------------------------------------------*/
extern const char* sony_tuner_helene_version; /**< HELENE driver version */
/*------------------------------------------------------------------------------
Defines
------------------------------------------------------------------------------*/
#define SONY_TUNER_HELENE_OFFSET_CUTOFF_HZ 50000 /**< Maximum carrier offset frequency before requiring a retune */
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
/**
@brief Creates an instance of the HELENE tuner driver
@param pTuner The tuner driver instance to create.
Memory must have been allocated for this instance before creation.
@param xtalFreq The crystal frequency of the tuner.
@param i2cAddress The I2C address of the HELENE device.
Typically 0xC0.
@param pI2c The I2C driver that the tuner driver will use for
communication.
@param configFlags See ::SONY_HELENE_CONFIG_EXT_REF,
::SONY_HELENE_CONFIG_SLEEP_DISABLEXTAL,
::SONY_HELENE_CONFIG_LOOPFILTER_INTERNAL,
::SONY_HELENE_CONFIG_SAT_LNA_OFF,
::SONY_HELENE_CONFIG_POWERSAVE_TERR_NORMAL,
::SONY_HELENE_CONFIG_POWERSAVE_TERR_RFIN_MATCHING
::SONY_HELENE_CONFIG_POWERSAVE_TERR_RF_ACTIVE
::SONY_HELENE_CONFIG_POWERSAVE_SAT_NORMAL
::SONY_HELENE_CONFIG_POWERSAVE_SAT_RFIN_MATCHING
::SONY_HELENE_CONFIG_POWERSAVE_SAT_RF_ACTIVE
::SONY_HELENE_CONFIG_POWERSAVE_SAT_RFIN_MATCHING
::SONY_HELENE_CONFIG_OUTLMT_ATV_1_5Vpp
::SONY_HELENE_CONFIG_OUTLMT_ATV_1_2Vpp
::SONY_HELENE_CONFIG_OUTLMT_DTV_1_5Vpp
::SONY_HELENE_CONFIG_OUTLMT_DTV_1_2Vpp
::SONY_HELENE_CONFIG_OUTLMT_STV_0_75Vpp
::SONY_HELENE_CONFIG_OUTLMT_STV_0_6Vpp
::SONY_HELENE_CONFIG_REFOUT_500mVpp
::SONY_HELENE_CONFIG_REFOUT_400mVpp
::SONY_HELENE_CONFIG_REFOUT_600mVpp
::SONY_HELENE_CONFIG_REFOUT_800mVpp
defined in
\link sony_helene.h \endlink
@param pHeleneTuner The Helene tuner driver pointer to use.
Memory must have been allocated for the Helene driver structure.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_helene_Create (sony_tuner_t * pTuner,
sony_helene_xtal_t xtalFreq,
uint8_t i2cAddress,
sony_i2c_t * pI2c,
uint32_t configFlags,
sony_helene_t * pHeleneTuner);
/**
@brief Write to GPIO0 or GPIO1.
@param pTuner Instance of the tuner driver.
@param id Pin ID 0 = GPIO0, 1 = GPIO1
@param value Output logic level, 0 = Low, 1 = High
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_helene_SetGPO (sony_tuner_t * pTuner, uint8_t id, uint8_t value);
/**
@brief Read from GPIO1.
@param pTuner Instance of the tuner driver.
@param pValue Read logic level, 0 = Low, 1 = High
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_helene_GetGPI1 (sony_tuner_t * pTuner, uint8_t * pValue);
/**
@brief RF filter compensation setting for VHF-L band.
(Please see RFVGA Description of datasheet.)
New setting will become effective after next tuning.
mult = VL_TRCKOUT_COEFF(8bit unsigned) / 128
ofs = VL_TRCKOUT_OFS(8bit 2s complement)
(compensated value) = (original value) * mult + ofs
@param pTuner Instance of the tuner driver.
@param coeff VL_TRCKOUT_COEFF (multiplier)
@param offset VL_TRCKOUT_OFS (additional term)
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_helene_RFFilterConfig (sony_tuner_t * pTuner, uint8_t coeff, uint8_t offset);
#endif /* SONY_TUNER_HELENE_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,524 @@
/*------------------------------------------------------------------------------
Copyright 2017-2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/10/31
File Revision : 1.0.2.0
------------------------------------------------------------------------------*/
/**
@file sony_helene2.h
This file provides the HELENE2 tuner control interface.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_HELENE2_H
#define SONY_HELENE2_H
#include "sony_common.h"
#include "sony_i2c.h"
/*------------------------------------------------------------------------------
Defines
------------------------------------------------------------------------------*/
/**
@brief Version of this driver.
*/
#define SONY_HELENE2_VERSION "1.0.2.0"
/**
@brief Default I2C slave address of the HELENE2 tuner.
*/
#define SONY_HELENE2_ADDRESS 0xC0
/*------------------------------------------------------------------------------
Enums
------------------------------------------------------------------------------*/
/**
@brief HELENE2 tuner state.
*/
typedef enum {
SONY_HELENE2_STATE_UNKNOWN, /**< HELENE2 state is Unknown */
SONY_HELENE2_STATE_SLEEP, /**< HELENE2 state is Sleep */
SONY_HELENE2_STATE_ACTIVE_T, /**< HELENE2 state is Active (terrestrial) */
SONY_HELENE2_STATE_ACTIVE_S /**< HELENE2 state is Active (satellite) */
} sony_helene2_state_t;
/**
@brief HELENE2 chip type.
*/
typedef enum {
SONY_HELENE2_CHIP_ID_UNKNOWN, /**< Unknown */
SONY_HELENE2_CHIP_ID_2868, /**< CXD2868 (HELENE2 Plus) */
SONY_HELENE2_CHIP_ID_2866, /**< CXD2866 (HELENE2) */
} sony_helene2_chip_id_t;
/**
@brief Xtal frequencies supported by HELENE2.
*/
typedef enum {
SONY_HELENE2_XTAL_16000KHz, /**< 16 MHz */
SONY_HELENE2_XTAL_24000KHz, /**< 24 MHz */
} sony_helene2_xtal_t;
/**
@brief Analog/Digital terrestrial, satellite broadcasting system definitions supported by HELENE2.
Fc : Center Frequency, Fp : Picture Frequency
*/
typedef enum {
SONY_HELENE2_TV_SYSTEM_UNKNOWN,
/* Terrestrial Analog */
SONY_HELENE2_ATV_MN_EIAJ, /**< System-M (Japan) (IF: Fp=5.75MHz in default) */
SONY_HELENE2_ATV_MN_SAP, /**< System-M (US) (IF: Fp=5.75MHz in default) */
SONY_HELENE2_ATV_MN_A2, /**< System-M (Korea) (IF: Fp=5.9MHz in default) */
SONY_HELENE2_ATV_BG, /**< System-B/G (IF: Fp=7.3MHz in default) */
SONY_HELENE2_ATV_I, /**< System-I (IF: Fp=7.85MHz in default) */
SONY_HELENE2_ATV_DK, /**< System-D/K (IF: Fp=7.85MHz in default) */
SONY_HELENE2_ATV_L, /**< System-L (IF: Fp=7.85MHz in default) */
SONY_HELENE2_ATV_L_DASH, /**< System-L DASH (IF: Fp=2.2MHz in default) */
/* Terrestrial/Cable Digital */
SONY_HELENE2_DTV_8VSB, /**< ATSC 8VSB (IF: Fc=3.7MHz in default) */
SONY_HELENE2_DTV_ISDBT_6, /**< ISDB-T 6MHzBW (IF: Fc=3.55MHz in default) */
SONY_HELENE2_DTV_ISDBT_7, /**< ISDB-T 7MHzBW (IF: Fc=4.15MHz in default) */
SONY_HELENE2_DTV_ISDBT_8, /**< ISDB-T 8MHzBW (IF: Fc=4.75MHz in default) */
SONY_HELENE2_DTV_DVBT_5, /**< DVB-T 5MHzBW (IF: Fc=3.6MHz in default) */
SONY_HELENE2_DTV_DVBT_6, /**< DVB-T 6MHzBW (IF: Fc=3.6MHz in default) */
SONY_HELENE2_DTV_DVBT_7, /**< DVB-T 7MHzBW (IF: Fc=4.2MHz in default) */
SONY_HELENE2_DTV_DVBT_8, /**< DVB-T 8MHzBW (IF: Fc=4.8MHz in default) */
SONY_HELENE2_DTV_DVBT2_1_7,/**< DVB-T2 1.7MHzBW (IF: Fc=3.5MHz in default) */
SONY_HELENE2_DTV_DVBT2_5, /**< DVB-T2 5MHzBW (IF: Fc=3.6MHz in default) */
SONY_HELENE2_DTV_DVBT2_6, /**< DVB-T2 6MHzBW (IF: Fc=3.6MHz in default) */
SONY_HELENE2_DTV_DVBT2_7, /**< DVB-T2 7MHzBW (IF: Fc=4.2MHz in default) */
SONY_HELENE2_DTV_DVBT2_8, /**< DVB-T2 8MHzBW (IF: Fc=4.8MHz in default) */
SONY_HELENE2_DTV_DVBC_6, /**< DVB-C 6MHzBW/ISDB-C/J.83B (IF: Fc=3.7MHz in default) */
SONY_HELENE2_DTV_DVBC_8, /**< DVB-C 8MHzBW/7MHzBW (IF: Fc=4.9MHz in default) */
SONY_HELENE2_DTV_DVBC2_6, /**< DVB-C2 6MHzBW (IF: Fc=3.7MHz in default) */
SONY_HELENE2_DTV_DVBC2_8, /**< DVB-C2 8MHzBW (IF: Fc=4.9MHz in default) */
SONY_HELENE2_DTV_ATSC3_6, /**< ATSC 3.0 6MHzBW (IF: Fc=3.6MHz in default) */
SONY_HELENE2_DTV_ATSC3_7, /**< ATSC 3.0 7MHzBW (IF: Fc=4.2MHz in default) */
SONY_HELENE2_DTV_ATSC3_8, /**< ATSC 3.0 8MHzBW (IF: Fc=4.8MHz in default) */
SONY_HELENE2_DTV_J83B_5_6, /**< J.83B 5.6Msps (IF: Fc=3.75MHz in default) */
SONY_HELENE2_DTV_DTMB, /**< DTMB (IF: Fc=5.1MHz in default) */
/* Satellite */
SONY_HELENE2_STV_ISDBS, /**< ISDB-S */
SONY_HELENE2_STV_ISDBS3, /**< ISDB-S3 */
SONY_HELENE2_STV_DVBS, /**< DVB-S */
SONY_HELENE2_STV_DVBS2, /**< DVB-S2 */
SONY_HELENE2_ATV_MIN = SONY_HELENE2_ATV_MN_EIAJ, /**< Minimum analog terrestrial system */
SONY_HELENE2_ATV_MAX = SONY_HELENE2_ATV_L_DASH, /**< Maximum analog terrestrial system */
SONY_HELENE2_DTV_MIN = SONY_HELENE2_DTV_8VSB, /**< Minimum digital terrestrial system */
SONY_HELENE2_DTV_MAX = SONY_HELENE2_DTV_DTMB, /**< Maximum digital terrestrial system */
SONY_HELENE2_TERR_TV_SYSTEM_NUM, /**< Number of supported terrestrial broadcasting system */
SONY_HELENE2_STV_MIN = SONY_HELENE2_STV_ISDBS, /**< Minimum satellite system */
SONY_HELENE2_STV_MAX = SONY_HELENE2_STV_DVBS2 /**< Maximum satellite system */
} sony_helene2_tv_system_t;
/**
@brief Macro to check that the system is analog terrestrial or not.
*/
#define SONY_HELENE2_IS_ATV(tvSystem) (((tvSystem) >= SONY_HELENE2_ATV_MIN) && ((tvSystem) <= SONY_HELENE2_ATV_MAX))
/**
@brief Macro to check that the system is digital terrestrial or not.
*/
#define SONY_HELENE2_IS_DTV(tvSystem) (((tvSystem) >= SONY_HELENE2_DTV_MIN) && ((tvSystem) <= SONY_HELENE2_DTV_MAX))
/**
@brief Macro to check that the system is satellite or not.
*/
#define SONY_HELENE2_IS_STV(tvSystem) (((tvSystem) >= SONY_HELENE2_STV_MIN) && ((tvSystem) <= SONY_HELENE2_STV_MAX))
/*------------------------------------------------------------------------------
Structs
------------------------------------------------------------------------------*/
/**
@brief HELENE2 settings that may need to change depend on customer's system.
*/
typedef struct sony_helene2_terr_adjust_param_t {
uint8_t RF_GAIN; /**< Addr:0x69 Bit[6:4] : RFVGA gain. 0xFF means Auto. (RF_GAIN_SEL = 1) */
uint8_t IF_BPF_GC; /**< Addr:0x69 Bit[3:0] : IF_BPF gain. */
uint8_t RFOVLD_DET_LV1_VL; /**< Addr:0x6B Bit[3:0] : RF overload RF input detect level. (FRF <= 172MHz) */
uint8_t RFOVLD_DET_LV1_VH; /**< Addr:0x6B Bit[3:0] : RF overload RF input detect level. (172MHz < FRF <= 464MHz) */
uint8_t RFOVLD_DET_LV1_U; /**< Addr:0x6B Bit[3:0] : RF overload RF input detect level. (FRF > 464MHz) */
uint8_t IFOVLD_DET_LV_VL; /**< Addr:0x6C Bit[2:0] : Internal RFAGC detect level. (FRF <= 172MHz) */
uint8_t IFOVLD_DET_LV_VH; /**< Addr:0x6C Bit[2:0] : Internal RFAGC detect level. (172MHz < FRF <= 464MHz) */
uint8_t IFOVLD_DET_LV_U; /**< Addr:0x6C Bit[2:0] : Internal RFAGC detect level. (FRF > 464MHz) */
uint8_t IF_BPF_F0; /**< Addr:0x6D Bit[5:4] : IF filter center offset. */
uint8_t BW; /**< Addr:0x6D Bit[1:0] : 6MHzBW(0x00) or 7MHzBW(0x01) or 8MHzBW(0x02) or 1.7MHzBW(0x03) */
uint8_t FIF_OFFSET; /**< Addr:0x6E Bit[4:0] : 5bit signed. IF offset (kHz) = FIF_OFFSET x 50 */
uint8_t BW_OFFSET; /**< Addr:0x6F Bit[4:0] : 5bit signed. BW offset (kHz) = BW_OFFSET x 50 (BW_OFFSET x 10 in 1.7MHzBW) */
uint8_t AGC_SEL; /**< Addr:0x74 Bit[5:4] : AGC pin select. (0: AGC1, 1: AGC2) 0xFF means Auto (by config flags) */
uint8_t IS_LOWERLOCAL; /**< Addr:0x9C Bit[0] : Local polarity. (0: Upper Local, 1: Lower Local) */
} sony_helene2_terr_adjust_param_t;
/**
@brief The HELENE2 tuner definition which allows control of the HELENE2 tuner device
through the defined set of functions.
*/
typedef struct sony_helene2_t {
sony_helene2_xtal_t xtalFreq; /**< Xtal frequency for HELENE2. */
uint8_t i2cAddress; /**< I2C slave address of the HELENE2 tuner (8-bit form - 8'bxxxxxxx0) */
sony_i2c_t* pI2c; /**< I2C API instance. */
uint32_t flags; /**< ORed value of SONY_HELENE2_CONFIG_XXXX */
/* For saving current setting */
sony_helene2_state_t state; /**< The driver operating state. */
uint32_t frequencykHz; /**< Currently RF frequency(kHz) tuned. */
sony_helene2_tv_system_t tvSystem; /**< Current broadcasting system tuned. */
uint32_t symbolRateksps; /**< Current symbol rate(ksym/s) tuned. */
uint8_t isFreesatMode; /**< UK Freesat mode or not. */
sony_helene2_chip_id_t chipId; /**< Auto detected chip ID at initialization */
/**
@brief Adjustment parameter table (SONY_HELENE2_TV_SYSTEM_NUM size)
*/
const sony_helene2_terr_adjust_param_t *pTerrParamTable;
/* Following Xtal related parameters can be changed if optimization is necessary. */
uint8_t xosc_sel; /**< Driver current setting for crystal oscillator. (Addr:0x82 Bit[4:0]) */
uint8_t xosc_cap_set; /**< Driver current setting for crystal oscillator. (Addr:0x83 Bit[6:0]) */
void* user; /**< User defined data. */
} sony_helene2_t;
/*
Config flag definitions. (ORed value should be set to flags argument of Create API.)
*/
/**
@brief Use external Xtal
Should be used for slave HELENE2 in Xtal shared system.
*/
#define SONY_HELENE2_CONFIG_EXT_REF 0x80000000
/**
@brief Disable Xtal in Sleep state.
Should NOT be used for Xtal shared system.
Not only for the master HELENE2 which has Xtal, but also slave HELENE2 which receive the clock signal.
Cannot be used with SONY_HELENE2_CONFIG_EXT_REF.
*/
#define SONY_HELENE2_CONFIG_SLEEP_DISABLEXTAL 0x40000000
/**
@brief Internal loop filter setting.
If this is used, internal loop filter is used for
digital broadcasting system except for DVB-C.
For analog and DVB-C, external loop filter will be used.
*/
#define SONY_HELENE2_CONFIG_LOOPFILTER_INTERNAL 0x10000000
/**
@brief Satellite LNA OFF (path through) setting.
*/
#define SONY_HELENE2_CONFIG_SAT_LNA_OFF 0x08000000
/**
@name Power Save setting for terrestrial.
These settings are for avoiding steep input impedance change in power save state.
*/
/**@{*/
#define SONY_HELENE2_CONFIG_POWERSAVE_TERR_RFIN_MATCHING_DISABLE 0x00000000 /**< RFIN matching disable (default) */
#define SONY_HELENE2_CONFIG_POWERSAVE_TERR_RFIN_MATCHING_ENABLE 0x00400000 /**< RFIN matching enable */
#define SONY_HELENE2_CONFIG_POWERSAVE_TERR_RF_ACTIVE 0x00800000 /**< Keep RF part active */
#define SONY_HELENE2_CONFIG_POWERSAVE_TERR_MASK 0x00C00000 /**< Do not use this value */
/**@}*/
/**
@name Power Save setting for satellite.
These settings are for avoiding steep input impedance change in power save state.
*/
/**@{*/
#define SONY_HELENE2_CONFIG_POWERSAVE_SAT_RFIN_MATCHING_ENABLE 0x00000000 /**< RFIN matching enable (default) */
#define SONY_HELENE2_CONFIG_POWERSAVE_SAT_RFIN_MATCHING_DISABLE 0x00100000 /**< RFIN matching disable */
#define SONY_HELENE2_CONFIG_POWERSAVE_SAT_RF_ACTIVE 0x00200000 /**< Keep RF part active */
#define SONY_HELENE2_CONFIG_POWERSAVE_SAT_MASK 0x00300000 /**< Do not use this value */
/**@}*/
/**
@name Maximum IF and IQ output setting. (for terrestrial analog)
*/
/**@{*/
#define SONY_HELENE2_CONFIG_OUTLMT_ATV_1_5Vpp 0x00000000 /**< 1.5Vpp (default) */
#define SONY_HELENE2_CONFIG_OUTLMT_ATV_1_2Vpp 0x00080000 /**< 1.2Vpp */
/**@}*/
/**
@name Maximum IF and IQ output setting. (for terrestrial digital)
*/
/**@{*/
#define SONY_HELENE2_CONFIG_OUTLMT_DTV_1_5Vpp 0x00000000 /**< 1.5Vpp (default) */
#define SONY_HELENE2_CONFIG_OUTLMT_DTV_1_2Vpp 0x00040000 /**< 1.2Vpp */
/**@}*/
/**
@name Maximum IF and IQ output setting. (for satellite)
*/
/**@{*/
#define SONY_HELENE2_CONFIG_OUTLMT_STV_0_75Vpp 0x00000000 /**< 0.75Vpp (default) */
#define SONY_HELENE2_CONFIG_OUTLMT_STV_0_6Vpp 0x00020000 /**< 0.6Vpp */
/**@}*/
/**
@name REFOUT setting related macros.
If following values are not used, REFOUT output is disabled.
*/
/**@{*/
/**
@brief REFOUT enable, output level is 500mVp-p.
*/
#define SONY_HELENE2_CONFIG_REFOUT_500mVpp 0x00001000
/**
@brief REFOUT enable, output level is 400mVp-p.
*/
#define SONY_HELENE2_CONFIG_REFOUT_400mVpp 0x00002000
/**
@brief REFOUT enable, output level is 600mVp-p.
*/
#define SONY_HELENE2_CONFIG_REFOUT_600mVpp 0x00003000
/**
@brief REFOUT enable, output level is 800mVp-p.
*/
#define SONY_HELENE2_CONFIG_REFOUT_800mVpp 0x00004000
/**
@brief Internal use only. Do not use this value.
*/
#define SONY_HELENE2_CONFIG_REFOUT_MASK 0x00007000
/**@}*/
/**
@name Satellite IQ output type setting
*/
/**@{*/
#define SONY_HELENE2_CONFIG_IQ_OUTPUT_SINGLE 0x00000000 /**< Single Output (default) */
#define SONY_HELENE2_CONFIG_IQ_OUTPUT_BALANCED 0x00000800 /**< Balanced Output */
/**@}*/
/**
@name AGC pin individually setting.
Used if sony_helene2_terr_adjust_param_t::AGC_SEL == 0xFF
*/
/**@{*/
#define SONY_HELENE2_CONFIG_TAGC2_ATV 0x00000400 /**< AGC_T2 is used for Terrestrial Analog. (Otherwise AGC_T1 is used.) */
#define SONY_HELENE2_CONFIG_TAGC2_DTV 0x00000200 /**< AGC_T2 is used for Terrestrial Digital. (Otherwise AGC_T1 is used.) */
/**@}*/
/**
@name AGC pin setting for normal cases.
Used if sony_helene2_terr_adjust_param_t::AGC_SEL == 0xFF
*/
/**@{*/
/**
@brief AGC 1 is used for both Analog and Digital
*/
#define SONY_HELENE2_CONFIG_TAGC_SEL_ALL1 0x00000000
/**
@brief AGC 2 is used for both Analog and Digital
*/
#define SONY_HELENE2_CONFIG_TAGC_SEL_ALL2 (SONY_HELENE2_CONFIG_TAGC2_ATV | SONY_HELENE2_CONFIG_TAGC2_DTV)
/**
@brief AGC 1 is used for Analog, 2 is used for Digital
*/
#define SONY_HELENE2_CONFIG_TAGC_SEL_A1D2 (SONY_HELENE2_CONFIG_TAGC2_DTV)
/**
@brief AGC 1 is used for Digital, 2 is used for Analog
*/
#define SONY_HELENE2_CONFIG_TAGC_SEL_D1A2 (SONY_HELENE2_CONFIG_TAGC2_ATV)
/**@}*/
/*------------------------------------------------------------------------------
APIs
------------------------------------------------------------------------------*/
/**
@brief Set up the HELENE2 tuner driver.
This MUST be called before calling sony_helene2_Initialize.
@param pTuner Reference to memory allocated for the HELENE2 instance.
The create function will setup this HELENE2 instance.
@param xtalFreq The frequency of the HELENE2 crystal.
@param i2cAddress The HELENE2 tuner I2C slave address in 8-bit form.
@param pI2c The I2C APIs that the HELENE2 driver will use as the I2C interface.
@param flags Configuration flags. It should be ORed value of SONY_HELENE2_CONFIG_XXXX.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene2_Create(sony_helene2_t *pTuner, sony_helene2_xtal_t xtalFreq,
uint8_t i2cAddress, sony_i2c_t *pI2c, uint32_t flags);
/**
@brief Initialize the HELENE2 tuner.
This MUST be called before calling sony_helene2_terr_Tune and sony_helene2_sat_Tune.
@param pTuner The HELENE2 tuner instance.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene2_Initialize(sony_helene2_t *pTuner);
/**
@brief Tune to a given RF frequency with terrestrial broadcasting system.
To complete tuning, sony_helene2_terr_TuneEnd should be called after waiting 50ms.
@param pTuner The HELENE2 tuner instance.
@param frequencykHz RF frequency to tune. (kHz)
@param tvSystem The type of broadcasting system to tune.
@return SONY_RESULT_OK if tuner successfully tuned.
*/
sony_result_t sony_helene2_terr_Tune(sony_helene2_t *pTuner, uint32_t frequencykHz,
sony_helene2_tv_system_t tvSystem);
/**
@brief Completes the terrestrial tuning sequence.
This MUST be called after calling sony_helene2_terr_Tune and 50ms wait.
@param pTuner The HELENE2 tuner instance.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene2_terr_TuneEnd(sony_helene2_t *pTuner);
/**
@brief Tune to a given RF frequency with satellite broadcasting system.
@param pTuner The HELENE2 tuner instance.
@param frequencykHz RF frequency to tune. (kHz)
@param tvSystem The type of broadcasting system to tune.
@param symbolRateksps Symbol rate to tune. (ksps)
@return SONY_RESULT_OK if tuner successfully tuned.
*/
sony_result_t sony_helene2_sat_Tune(sony_helene2_t *pTuner, uint32_t frequencykHz,
sony_helene2_tv_system_t tvSystem, uint32_t symbolRateksps);
/**
@brief Shift RF frequency.
This API shift RF frequency without VCO calibration.
This API is normally useful for analog TV "fine tuning" that
shift RF frequency without picture distortion.
@note Please check the frequency range that VCO calibration is unnecessary.
(See hardware specification sheet.)
@param pTuner The HELENE2 tuner instance.
@param frequencykHz RF frequency to tune. (kHz)
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene2_ShiftFRF(sony_helene2_t *pTuner, uint32_t frequencykHz);
/**
@brief Put the HELENE2 tuner into Sleep state.
From this state the tuner can be directly tuned by calling sony_helene2_Tune.
@param pTuner The HELENE2 tuner instance.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene2_Sleep(sony_helene2_t *pTuner);
/**
@brief Write to GPO0 or GPO1.
@param pTuner The HELENE2 tuner instance.
@param id Pin ID 0 = GPO0, 1 = GPO1
@param val Output logic level, 0 = Low, 1 = High
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene2_SetGPO(sony_helene2_t *pTuner, uint8_t id, uint8_t val);
/**
@brief Read GPI1 value.
@param pTuner The HELENE2 tuner instance.
@param pVal GPI logic level, 0 = Low, 1 = High
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene2_GetGPI1(sony_helene2_t *pTuner, uint8_t *pVal);
/**
@brief Set the RF external circuit control pin. (for terrestrial)
(Set RF_EXT_CTRL register.)
@param pTuner The HELENE2 tuner instance.
@param enable The value to set. (Enable(1) or Disable(0))
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene2_SetRfExtCtrl(sony_helene2_t *pTuner, uint8_t enable);
/**
@brief Set UK Freesat mode.
If this mode is enabled, Freesat optimized setting will be used in sony_helene2_sat_Tune.
If internal loop filter is used, (SONY_HELENE2_CONFIG_LOOPFILTER_INTERNAL is ORed)
UK Freesat mode has no effect.
@param pTuner The HELENE2 tuner instance.
@param enable The value to set. (Enable(1) or Disable(0))
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene2_SetFreesatMode(sony_helene2_t *pTuner, uint8_t enable);
/**
@brief Read the RSSI in dBm from the tuner. (for terrestrial)
@note Target level of IF signal output (depend on demodulator)
is not added in default.
@param pTuner The HELENE2 tuner instance.
@param pRssi RSSI in dBm * 100
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene2_terr_ReadRssi(sony_helene2_t *pTuner, int32_t *pRssi);
/**
@brief Read the RSSI in dBm from the tuner. (for satellite)
@note Target level of IF signal output (depend on demodulator)
is not added in default.
@param pTuner The HELENE2 tuner instance.
@param pRssi RSSI in dBm * 100
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene2_sat_ReadRssi(sony_helene2_t *pTuner, int32_t *pRssi);
/**
@brief RF filter compensation setting for VHF-L band.
(Please see RFVGA Description of datasheet.)
New setting will become effective after next tuning.
mult = coeff / 128
(compensated value) = (original value) * mult + offset
@param pTuner The HELENE2 tuner instance.
@param coeff Multiplier value. (8bit unsigned)
@param offset Additional term. (8bit 2s complement)
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_helene2_RFFilterConfig(sony_helene2_t *pTuner, uint8_t coeff, uint8_t offset);
#endif /* SONY_HELENE2_H */
@@ -0,0 +1,532 @@
/*------------------------------------------------------------------------------
Copyright 2017-2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/07/05
Modification ID : c7c68d70868a4a9fb9e0f480d8b940e8a1e8f651
------------------------------------------------------------------------------*/
#include "sony_tuner_helene2.h"
#include <string.h>
#include <stdlib.h>
/*------------------------------------------------------------------------------
Driver Version
------------------------------------------------------------------------------*/
const char* sony_tuner_helene2_version = SONY_HELENE2_VERSION;
/*------------------------------------------------------------------------------
Static Prototypes
------------------------------------------------------------------------------*/
static sony_result_t sony_tuner_helene2_Initialize (sony_tuner_t * pTuner);
static sony_result_t sony_tuner_helene2_terr_Tune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
sony_dtv_bandwidth_t bandwidth);
static sony_result_t sony_tuner_helene2_sat_Tune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
uint32_t symbolRateKSps);
static sony_result_t sony_tuner_helene2_Sleep (sony_tuner_t * pTuner);
static sony_result_t sony_tuner_helene2_Shutdown (sony_tuner_t * pTuner);
static sony_result_t sony_tuner_helene2_ReadRFLevel (sony_tuner_t * pTuner, int32_t * pRFLevel);
static sony_result_t sony_tuner_helene2_CalcRFLevelFromAGC (sony_tuner_t * pTuner, uint32_t agcValue, int32_t * pRFLevel);
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
sony_result_t sony_tuner_helene2_Create (sony_tuner_t * pTuner,
sony_helene2_xtal_t xtalFreq,
uint8_t i2cAddress,
sony_i2c_t * pI2c,
uint32_t configFlags,
sony_helene2_t * pHelene2Tuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_helene2_Create");
if ((!pI2c) || (!pHelene2Tuner) || (!pTuner)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
memset (pTuner, 0, sizeof (sony_tuner_t)); /* Zero filled */
/* Create the underlying HELENE2 reference driver. */
result = sony_helene2_Create (pHelene2Tuner, xtalFreq, i2cAddress, pI2c, configFlags);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Populate / Initialize the sony_tuner_t structure */
pTuner->i2cAddress = i2cAddress;
pTuner->pI2c = pI2c;
pTuner->flags = configFlags;
pTuner->symbolRateKSpsForSpectrum = 45000;
pTuner->rfLevelFuncTerr = SONY_TUNER_RFLEVEL_FUNC_READ; /* Use ReadRFLevel function for terrestrial */
pTuner->rfLevelFuncSat = SONY_TUNER_RFLEVEL_FUNC_READ; /* Use ReadRFLevel function for satellite */
pTuner->user = pHelene2Tuner;
pTuner->Initialize = sony_tuner_helene2_Initialize;
pTuner->TerrCableTune = sony_tuner_helene2_terr_Tune;
pTuner->SatTune = sony_tuner_helene2_sat_Tune;
pTuner->Sleep = sony_tuner_helene2_Sleep;
pTuner->Shutdown = sony_tuner_helene2_Shutdown;
pTuner->ReadRFLevel = sony_tuner_helene2_ReadRFLevel;
pTuner->CalcRFLevelFromAGC = sony_tuner_helene2_CalcRFLevelFromAGC;
SONY_TRACE_RETURN (result);
}
sony_result_t sony_tuner_helene2_SetGPO (sony_tuner_t * pTuner, uint8_t id, uint8_t value)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_helene2_Write_GPIO");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_helene2_SetGPO (((sony_helene2_t *) pTuner->user), id, value);
SONY_TRACE_RETURN (result);
}
sony_result_t sony_tuner_helene2_GetGPI1 (sony_tuner_t * pTuner, uint8_t * pValue)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_helene2_GetGPI1");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_helene2_GetGPI1 (((sony_helene2_t *) pTuner->user), pValue);
SONY_TRACE_RETURN (result);
}
sony_result_t sony_tuner_helene2_RFFilterConfig (sony_tuner_t * pTuner, uint8_t coeff, uint8_t offset)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_helene2_RFFilterConfig");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_helene2_RFFilterConfig (((sony_helene2_t *) pTuner->user), coeff, offset);
SONY_TRACE_RETURN (result);
}
/*------------------------------------------------------------------------------
Static Functions
------------------------------------------------------------------------------*/
static sony_result_t sony_tuner_helene2_Initialize (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_helene2_Initialize");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. */
result = sony_helene2_Initialize (((sony_helene2_t *) pTuner->user));
/* Device is in "Power Save" state. */
pTuner->frequencyKHz = 0;
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_helene2_terr_Tune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
sony_dtv_bandwidth_t bandwidth)
{
sony_result_t result = SONY_RESULT_OK;
sony_helene2_tv_system_t hSystem = SONY_HELENE2_TV_SYSTEM_UNKNOWN;
SONY_TRACE_ENTER ("sony_tuner_helene2_terr_Tune");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. Convert system, bandwidth into dtv system. */
switch (system) {
case SONY_DTV_SYSTEM_DVBC:
switch (bandwidth) {
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_HELENE2_DTV_DVBC_6;
break;
case SONY_DTV_BW_7_MHZ:
/* 7MHZ BW setting is the same as 8MHz BW */
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_HELENE2_DTV_DVBC_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_DVBT:
switch (bandwidth) {
case SONY_DTV_BW_5_MHZ:
hSystem = SONY_HELENE2_DTV_DVBT_5;
break;
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_HELENE2_DTV_DVBT_6;
break;
case SONY_DTV_BW_7_MHZ:
hSystem = SONY_HELENE2_DTV_DVBT_7;
break;
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_HELENE2_DTV_DVBT_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_DVBT2:
switch (bandwidth) {
case SONY_DTV_BW_1_7_MHZ:
hSystem = SONY_HELENE2_DTV_DVBT2_1_7;
break;
case SONY_DTV_BW_5_MHZ:
hSystem = SONY_HELENE2_DTV_DVBT2_5;
break;
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_HELENE2_DTV_DVBT2_6;
break;
case SONY_DTV_BW_7_MHZ:
hSystem = SONY_HELENE2_DTV_DVBT2_7;
break;
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_HELENE2_DTV_DVBT2_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_DVBC2:
switch (bandwidth) {
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_HELENE2_DTV_DVBC2_6;
break;
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_HELENE2_DTV_DVBC2_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_ISDBT:
switch (bandwidth) {
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_HELENE2_DTV_ISDBT_6;
break;
case SONY_DTV_BW_7_MHZ:
hSystem = SONY_HELENE2_DTV_ISDBT_7;
break;
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_HELENE2_DTV_ISDBT_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_ISDBC:
hSystem = SONY_HELENE2_DTV_DVBC_6; /* ISDB-C uses DVB-C 6MHz BW setting */
break;
case SONY_DTV_SYSTEM_ATSC:
hSystem = SONY_HELENE2_DTV_8VSB;
break;
case SONY_DTV_SYSTEM_ATSC3:
switch (bandwidth) {
case SONY_DTV_BW_6_MHZ:
hSystem = SONY_HELENE2_DTV_ATSC3_6;
break;
case SONY_DTV_BW_7_MHZ:
hSystem = SONY_HELENE2_DTV_ATSC3_7;
break;
case SONY_DTV_BW_8_MHZ:
hSystem = SONY_HELENE2_DTV_ATSC3_8;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
case SONY_DTV_SYSTEM_J83B:
switch (bandwidth) {
case SONY_DTV_BW_J83B_5_06_5_36_MSPS:
hSystem = SONY_HELENE2_DTV_DVBC_6; /* J.83B (5.057, 5.361Msps commonly used in US) uses DVB-C 6MHz BW setting */
break;
case SONY_DTV_BW_J83B_5_60_MSPS:
hSystem = SONY_HELENE2_DTV_J83B_5_6; /* J.83B (5.6Msps used in Japan) uses special setting */
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
break;
/* Intentional fall-through */
case SONY_DTV_SYSTEM_UNKNOWN:
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_helene2_terr_Tune (((sony_helene2_t *) pTuner->user), centerFreqKHz, hSystem);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Allow the tuner time to settle */
SONY_SLEEP(50);
result = sony_helene2_terr_TuneEnd ((sony_helene2_t *) pTuner->user);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Assign current values. */
pTuner->frequencyKHz = ((sony_helene2_t *) pTuner->user)->frequencykHz;
pTuner->system = system;
pTuner->bandwidth = bandwidth;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_helene2_sat_Tune (sony_tuner_t * pTuner,
uint32_t centerFreqKHz,
sony_dtv_system_t system,
uint32_t symbolRateKSps)
{
sony_result_t result = SONY_RESULT_OK;
sony_helene2_tv_system_t hSystem = SONY_HELENE2_STV_DVBS2;
SONY_TRACE_ENTER ("sony_tuner_helene2_sat_Tune");
if ((!pTuner) || (!pTuner->user)){
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
switch(system)
{
case SONY_DTV_SYSTEM_DVBS:
hSystem = SONY_HELENE2_STV_DVBS;
break;
case SONY_DTV_SYSTEM_DVBS2:
hSystem = SONY_HELENE2_STV_DVBS2;
break;
case SONY_DTV_SYSTEM_ISDBS:
hSystem = SONY_HELENE2_STV_ISDBS;
break;
case SONY_DTV_SYSTEM_ISDBS3:
hSystem = SONY_HELENE2_STV_ISDBS3;
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
result = sony_helene2_sat_Tune (((sony_helene2_t *) pTuner->user), centerFreqKHz, hSystem, symbolRateKSps);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
pTuner->frequencyKHz = ((sony_helene2_t *) pTuner->user)->frequencykHz;
pTuner->system = system;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = symbolRateKSps;
/* Tuner stabillization time */
SONY_SLEEP (50);
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_helene2_Sleep (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_helene2_Sleep");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. */
result = sony_helene2_Sleep (((sony_helene2_t *) pTuner->user));
/* Device is in "Power Save" state. */
pTuner->frequencyKHz = 0;
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_helene2_Shutdown (sony_tuner_t * pTuner)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_helene2_Shutdown");
if (!pTuner || !pTuner->user) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
/* Call into underlying driver. */
result = sony_helene2_Sleep (((sony_helene2_t *) pTuner->user));
/* Device is in "Power Save" state. */
pTuner->frequencyKHz = 0;
pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
pTuner->bandwidth = SONY_DTV_BW_UNKNOWN;
pTuner->symbolRateKSps = 0;
SONY_TRACE_RETURN (result);
}
static sony_result_t sony_tuner_helene2_ReadRFLevel (sony_tuner_t * pTuner, int32_t * pRFLevel)
{
sony_result_t result = SONY_RESULT_OK;
SONY_TRACE_ENTER ("sony_tuner_helene2_ReadRFLevel");
if (!pTuner || !pTuner->user || !pRFLevel) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (SONY_DTV_SYSTEM_IS_TERR_CABLE (pTuner->system)) {
result = sony_helene2_terr_ReadRssi (((sony_helene2_t *) pTuner->user), pRFLevel);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Add IFOUT value */
switch (pTuner->system) {
case SONY_DTV_SYSTEM_DVBT:
case SONY_DTV_SYSTEM_DVBT2:
case SONY_DTV_SYSTEM_DVBC2:
case SONY_DTV_SYSTEM_ATSC3:
*pRFLevel -= 400; /* -4.0dBm */
break;
case SONY_DTV_SYSTEM_DVBC:
case SONY_DTV_SYSTEM_ISDBC:
case SONY_DTV_SYSTEM_J83B:
*pRFLevel -= 150; /* -1.5dBm */
break;
case SONY_DTV_SYSTEM_ISDBT:
*pRFLevel -= 450; /* -4.5dBm */
break;
case SONY_DTV_SYSTEM_ATSC:
*pRFLevel -= 500; /* -5.0dBm */
break;
default:
SONY_TRACE_RETURN (SONY_RESULT_ERROR_NOSUPPORT);
}
} else if (SONY_DTV_SYSTEM_IS_SAT (pTuner->system)) {
result = sony_helene2_sat_ReadRssi (((sony_helene2_t *) pTuner->user), pRFLevel);
if (result != SONY_RESULT_OK) {
SONY_TRACE_RETURN (result);
}
/* Add IFOUT value */
*pRFLevel -= 300; /* -3.0dBm */
} else {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
SONY_TRACE_RETURN (SONY_RESULT_OK);
}
static sony_result_t sony_tuner_helene2_CalcRFLevelFromAGC (sony_tuner_t * pTuner,
uint32_t agcValue,
int32_t * pRFLevel)
{
/* This API is only for satellite. (blind scan) */
int32_t tempA = 0;
uint8_t isNegative = 0;
uint32_t tempDiv = 0;
uint32_t tempQ = 0;
uint32_t tempR = 0;
SONY_TRACE_ENTER("sony_tuner_helene2_CalcRFLevelFromAGC");
if ((!pTuner) || (!pRFLevel)) {
SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
}
if (!SONY_DTV_SYSTEM_IS_SAT (pTuner->system)) {
/* Satellite Only */
SONY_TRACE_RETURN (SONY_RESULT_ERROR_SW_STATE);
}
/*------------------------------------------------
Gain_db = AGCLevel * (-14 / 403) + 97
Gain_db_x100 = AGCLevel * (-1400 / 403) + 9700
-------------------------------------------------*/
tempA = (int32_t)agcValue * (-1400);
tempDiv = 403;
if (tempA > 0) {
isNegative = 0;
tempQ = (uint32_t)tempA / tempDiv;
tempR = (uint32_t)tempA % tempDiv;
} else {
isNegative = 1;
tempQ = (uint32_t)(tempA * (-1)) / tempDiv;
tempR = (uint32_t)(tempA * (-1)) % tempDiv;
}
if (isNegative) {
if (tempR >= (tempDiv/2)) {
*pRFLevel = (int32_t)(tempQ + 1) * (int32_t)(-1);
} else {
*pRFLevel = (int32_t)tempQ * (int32_t)(-1);
}
} else {
if (tempR >= (tempDiv/2)) {
*pRFLevel = (int32_t)(tempQ + 1);
} else {
*pRFLevel = (int32_t)tempQ;
}
}
*pRFLevel += 9700;
/*
* RF_Level = Input_Ref_Level - RF_Gain
* -> Input_Ref_Level = 0dB for this demodulator
*/
*pRFLevel *= -1;
SONY_TRACE_RETURN(SONY_RESULT_OK);
}
@@ -0,0 +1,134 @@
/*------------------------------------------------------------------------------
Copyright 2017-2018 Sony Semiconductor Solutions Corporation
Last Updated : 2018/08/30
Modification ID : 902dae58eb5249e028ccc5d7f60bb66cca9b43a9
------------------------------------------------------------------------------*/
/**
@file sony_tuner_helene2.h
This file provides the DVB port of the Sony HELENE2 tuner driver.
This driver wraps around the Ascot3 driver provided by
sony_helene2.h by using an instance of the Ascot3 (sony_helene2_t)
driver in the ::sony_tuner_t::user pointer.
Please note, if the Helene2 tuner is used in a system without the
terrestrial or satellite demodulator components then the unused
structure, pTunerSat or pTunerTerrCable must be declared prior to
calling tuner create function.
*/
/*----------------------------------------------------------------------------*/
#ifndef SONY_TUNER_HELENE2_H
#define SONY_TUNER_HELENE2_H
/*------------------------------------------------------------------------------
Includes
------------------------------------------------------------------------------*/
#include "sony_tuner.h"
#include "sony_helene2.h"
/*------------------------------------------------------------------------------
Driver Version
------------------------------------------------------------------------------*/
extern const char* sony_tuner_helene2_version; /**< HELENE2 driver version */
/*------------------------------------------------------------------------------
Defines
------------------------------------------------------------------------------*/
#define SONY_TUNER_HELENE2_OFFSET_CUTOFF_HZ 50000 /**< Maximum carrier offset frequency before requiring a retune */
/*------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------*/
/**
@brief Creates an instance of the HELENE2 tuner driver
@param pTuner The tuner driver instance to create.
Memory must have been allocated for this instance before creation.
@param xtalFreq The crystal frequency of the tuner.
@param i2cAddress The I2C address of the HELENE2 device.
Typically 0xC0.
@param pI2c The I2C driver that the tuner driver will use for
communication.
@param configFlags See ::SONY_HELENE2_CONFIG_EXT_REF,
::SONY_HELENE2_CONFIG_SLEEP_DISABLEXTAL,
::SONY_HELENE2_CONFIG_LOOPFILTER_INTERNAL,
::SONY_HELENE2_CONFIG_SAT_LNA_OFF,
::SONY_HELENE2_CONFIG_POWERSAVE_TERR_RFIN_MATCHING_DISABLE
::SONY_HELENE2_CONFIG_POWERSAVE_TERR_RFIN_MATCHING_ENABLE
::SONY_HELENE2_CONFIG_POWERSAVE_TERR_RF_ACTIVE
::SONY_HELENE2_CONFIG_POWERSAVE_SAT_RFIN_MATCHING_ENABLE
::SONY_HELENE2_CONFIG_POWERSAVE_SAT_RFIN_MATCHING_DISABLE
::SONY_HELENE2_CONFIG_POWERSAVE_SAT_RF_ACTIVE
::SONY_HELENE2_CONFIG_OUTLMT_ATV_1_5Vpp
::SONY_HELENE2_CONFIG_OUTLMT_ATV_1_2Vpp
::SONY_HELENE2_CONFIG_OUTLMT_DTV_1_5Vpp
::SONY_HELENE2_CONFIG_OUTLMT_DTV_1_2Vpp
::SONY_HELENE2_CONFIG_OUTLMT_STV_0_75Vpp
::SONY_HELENE2_CONFIG_OUTLMT_STV_0_6Vpp
::SONY_HELENE2_CONFIG_REFOUT_500mVpp
::SONY_HELENE2_CONFIG_REFOUT_400mVpp
::SONY_HELENE2_CONFIG_REFOUT_600mVpp
::SONY_HELENE2_CONFIG_REFOUT_800mVpp
::SONY_HELENE2_CONFIG_IQ_OUTPUT_SINGLE
::SONY_HELENE2_CONFIG_IQ_OUTPUT_BALANCED
::SONY_HELENE2_CONFIG_TAGC_SEL_ALL1
::SONY_HELENE2_CONFIG_TAGC_SEL_ALL2
::SONY_HELENE2_CONFIG_TAGC_SEL_A1D2
::SONY_HELENE2_CONFIG_TAGC_SEL_D1A2
defined in
\link sony_helene2.h \endlink
@param pHelene2Tuner The Helene2 tuner driver pointer to use.
Memory must have been allocated for the Helene2 driver structure.
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_helene2_Create (sony_tuner_t * pTuner,
sony_helene2_xtal_t xtalFreq,
uint8_t i2cAddress,
sony_i2c_t * pI2c,
uint32_t configFlags,
sony_helene2_t * pHelene2Tuner);
/**
@brief Write to GPIO0 or GPIO1.
@param pTuner Instance of the tuner driver.
@param id Pin ID 0 = GPIO0, 1 = GPIO1
@param value Output logic level, 0 = Low, 1 = High
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_helene2_SetGPO (sony_tuner_t * pTuner, uint8_t id, uint8_t value);
/**
@brief Read from GPIO1.
@param pTuner Instance of the tuner driver.
@param pValue Read logic level, 0 = Low, 1 = High
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_helene2_GetGPI1 (sony_tuner_t * pTuner, uint8_t * pValue);
/**
@brief RF filter compensation setting for VHF-L band.
(Please see RFVGA Description of datasheet.)
New setting will become effective after next tuning.
mult = VL_TRCKOUT_COEFF(8bit unsigned) / 128
ofs = VL_TRCKOUT_OFS(8bit 2s complement)
(compensated value) = (original value) * mult + ofs
@param pTuner Instance of the tuner driver.
@param coeff VL_TRCKOUT_COEFF (multiplier)
@param offset VL_TRCKOUT_OFS (additional term)
@return SONY_RESULT_OK if successful.
*/
sony_result_t sony_tuner_helene2_RFFilterConfig (sony_tuner_t * pTuner, uint8_t coeff, uint8_t offset);
#endif /* SONY_TUNER_HELENE2_H */