📄 mt352.c
字号:
/* enable Viterbi error measurements */
ucBuffer=MT352_VIT_CTL_DEFAULT+MT352_VIT_CTL_ERRPER_EN;//0x78, 0x02
if (! MT352_WRITE(MT352_VIT_CTL))
return FALSE;//MT352_VIT_CTL=0xB5
/* set up the ITB frequency & spectral inversion */
if (!Tnim_SetITB(psTnim))
return FALSE;
MT352_READ(MT352_CHIP_ID);
printf("MT352 Chip ID: %x\n", (int)ucBuffer);
if ( ucBuffer != 0x13 )
{
return FALSE;
}
Show_Status();//jacky
return TRUE;
}
/************************Zarlink Semiconductor*********************************
* Name:Tnim_GetClockMode()
* Purpose:Determines the clock mode from the settings
* Remarks: 2 ADC rates are availble. If tuner IF is 44.75MHz
* and the output is at IF1, we select the lower frequency (~19.5 MHz)
* otherwise we use the higher 20.5MHz.
* NOTE: this means that the 19.5 Xtal option is only suitable for
* 4.57 and 44.75 MHz inputs.
* Inputs:STnimControl Structure
* Outputs: Byte containing 20_8 bit and three clock mode bits
********************************************************************************/
u8 Tnim_GetClockMode(PSTNIMCTL psTnim)
{
return g_tnim2_ucModes[psTnim->Xtal]
[((psTnim->psTunerInfo->IF1kHz>40000) && ((psTnim->psTunerInfo->Settings) & TUNER_IF1_OUTPUT))?1:0]
[psTnim->AdcPll];
}
/************************Zarlink Semiconductor*********************************
* Name:Tnim_SetITB()
* Purpose:programs the ITB frequency and spectral inversion
* Remarks:
* ITB = -Fin*16384/Fadc where
* Fin = 4.57 for "baseband input"
* Fin = 2*Fadc-Fin for IF input
* Inputs:STnimControl Structure
* Outputs: success TRUE or FALSE
********************************************************************************/
bool8 Tnim_SetITB(STnimControl* psTnim)
{
s32 freqITB;
u16 clockADC=Tnim_ADCClock_x3(psTnim);
u8 ucBuffer;
if ((psTnim->psTunerInfo->Settings) & TUNER_IF1_OUTPUT)
{
freqITB = clockADC;
freqITB *=2;
freqITB /=3;
freqITB-=psTnim->psTunerInfo->IF1kHz;
}
else
{
freqITB = 4571;
}
freqITB *= 49152;
freqITB += (clockADC/2);
freqITB /= clockADC;
clockADC=0; /* use to keep track of net spectral inversion*/
if (freqITB>0)
freqITB=-freqITB;/* make result -ve */
else
clockADC++; /* already negative, need inversion*/
/*Each of the following adds an inversion*/
if ((psTnim->psTunerInfo->Settings) & TUNER_LO_INJECTION)
clockADC++;
if ((psTnim->psTunerInfo->Settings) & TUNER_SPECTRAL_INV)
clockADC++;
/* set up spectral inversion*/
if (!MT352_READ(MT352_ACQ_CTL))
return FALSE;
if (clockADC & 0x01)
ucBuffer |=MT352_ACQ_CTL_SPECINV;
else
ucBuffer &=~MT352_ACQ_CTL_SPECINV;
if (!MT352_WRITE(MT352_ACQ_CTL))
return FALSE;
return Tnim_WriteRegisterValue(psTnim,MT352_INPUT_FREQ,2,(u32)freqITB);
}
/************************Zarlink Semiconductor*********************************
* Name:TnimReadPreViterbiBER()
* Purpose:Calculates Pre Viterbi BER
* Remarks:Pre Viterbi BER = VIT_ERCNT/(VIT_ERRPER*4)
* Output is BER * 1000
* Inputs:
* Outputs:
********************************************************************************/
bool8 TnimReadPreViterbiBER(PSTNIMCTL psTnim, u32 *pdwBER)
{
bool8 ret= TRUE;
u32 dwPeriod;
u32 dwCount=0;
u8 ucBuffer=0;
TNIM_ENTRYB;
if (pdwBER!=NULL)
{/* get the period*/
ret=Tnim_ReadRegisterValue(psTnim,MT352_CIT_ERRPER,3,&dwPeriod);
if (ret && dwPeriod!=0)
{/*get the count*/
ret=Tnim_ReadRegisterValue(psTnim,MT352_VIT_ERRCNT,3,&dwCount);
}
if (ret) ret = MT352_READ(MT352_VIT_CTL);
if (ret && (ucBuffer & MT352_VIT_CTL_ERRPER_EN))
{/* calculate the BER*/
*pdwBER = dwCount *250;
*pdwBER /=dwPeriod;
}
else
{
*pdwBER=Uint32T_MAX;
ret=FALSE;
}
}
TNIM_EXIT;
return ret;
}
/************************Zarlink Semiconductor*********************************
* Name:TnimReadPostViterbiBER()
* Purpose:Calculates PostViterbi BER
* Remarks:formula is RS_BERCNT/(RS_ERRPER*1024*204*8)
* the result is multiplied by 100E6 to get an integer value, the
* formula becomes
* BER = 100e6/(1024*204*8) *RS_BERCNT/RS_ERRPER = 60*RS_BERCNT/RS_ERRPER
* Inputs:
* Outputs:
********************************************************************************/
bool8 TnimReadPostViterbiBER(PSTNIMCTL psTnim, u32 *pdwBER,u32 *pdwCount)
{
bool8 ret= TRUE;
u32 dwCount,dwPeriod;
TNIM_ENTRYB;
ret = Tnim_ReadRegisterValue(psTnim,MT352_RS_ERRCNT,3,&dwCount);//MT352_RS_ERRCNT=0x0D
// printf("\nResult of Read MT352_RS_ERRCNT=%d, dwCount=%ld\n", ret, dwCount);
if (ret && (pdwCount!=NULL))*pdwCount = dwCount;/* wants the count*/
if (ret && (pdwBER !=NULL))
{/* wants the calculated error*/
ret=Tnim_ReadRegisterValue(psTnim,MT352_RS_ERRPER,2,&dwPeriod);//MT352_RS_ERRPER=0x7C
// printf("\nResult of Read MT352_RS_ERRPER=%d, dwPeriod=%X\n", ret, dwPeriod);
if (ret && dwPeriod>0
&& ((psTnim->RSUBC<50) || psTnim->NoAutoRSUBC)
/*&& TNIM_STATEINTERNAL_LOCK==psTnim->State*/)
{/* calculate the result*/
*pdwBER = dwCount * 240;/* maximise before arithmetic*/
*pdwBER /=dwPeriod;
*pdwBER +=2;/* rounding*/
*pdwBER /=4; /* finish off */
}
else
{/* error reading error period, or the RS count is too high*/
*pdwBER=Uint32T_MAX;
ret = FALSE;
}
}
TNIM_EXIT;
return ret;
}
/************************Zarlink Semiconductor*********************************
* Name: TnimSelectLPdata()
* Purpose:selects LP data stream (if bWantLP is true) or HP data stream
* Remarks:Initial channel acquisition defaults to HP
* Inputs:
* Outputs:
********************************************************************************/
bool8 TnimSelectLPdata(PSTNIMCTL psTnim, bool8 bWantLP)
{
bool8 ret;
u8 ucBuffer;
TNIM_ENTRYB;
ret = Tnim_IsLocked(psTnim);
if (ret)
{
ret=MT352_READ(MT352_TPS_RECEIVED);//MT352_TPS_RECEIVED=0x1E
if (ret && ((0x80<(ucBuffer & 0x9C)) || !bWantLP) )
{/*TPS is valid and hierarchical*/
ret = MT352_READ(MT352_TPS_GIVEN);//MT352_TPS_GIVEN=0x51
ucBuffer &= ~MT352_TPS_GIVENH_LP;//MT352_TPS_GIVENH_LP=0x80
if (bWantLP) ucBuffer |=MT352_TPS_GIVENH_LP;
if (ret) ret = MT352_WRITE(MT352_TPS_GIVEN);
}
}
TNIM_EXIT;
return ret;
}
void TestPrintTPSdata(STnimAuxChannelInfo aux, bool8 bShowActive)
{
switch (TPS_CONSTELLATION(aux.wTPS))
{
case 0: printf(" QPSK ");break;
case 1: printf(" 16QAM ");break;
case 2: printf(" 64QAM ");break;
default:printf(" ????? ");
}
switch(TPS_HIERARCHY(aux.wTPS))
{
case 0: printf(" none ");break;
case 1: printf(" 1 ");break;
case 2: printf(" 2 ");break;
case 3: printf(" 4 ");break;
default:printf(" ??? ");
}
printf(" %d/%d %s%d/%d", FORMAT_CODERATE(TPS_HPCODERATE(aux.wTPS)),
FORMAT_CODERATE(TPS_HPCODERATE(aux.wTPS))+1,
bShowActive?(TPS_LPACTIVE(aux.wTPS)?" >":"< "):" ",
FORMAT_CODERATE(TPS_LPCODERATE(aux.wTPS)),
FORMAT_CODERATE(TPS_LPCODERATE(aux.wTPS))+1 );
switch (TPS_GUARDINTERVAL(aux.wTPS))
{
case 0:printf(" 1/32");break;
case 1:printf(" 1/16");break;
case 2:printf(" 1/8 ");break;
case 3:printf(" 1/4 ");break;
default:printf(" ????");break;
}
printf(" %sk", TPS_FFTMODE8K(aux.wTPS)?"8":"2" );
printf(" 0x%04x%s\n",aux.wCellID,(aux.ucValid & UCVALID_CELLIDVALID)?" ":"?");
}
/************************Zarlink Semiconductor*********************************
* Name: TnimReadChannel()
* Purpose:Reads channel information when locked, and restarts scan if any
* Remarks: fills in STnimChannel and/or STnimAuxChannelInfo, if relevant
* pointer is non NULL
* Inputs:
* Outputs:
********************************************************************************/
bool8 TnimReadChannel(PSTNIMCTL psTnim, PSCHANNEL psChannel,PSAUXINFO psAuxInfo)
{
bool8 isTps=FALSE, isID=FALSE;
u8 ucBuffer;
u32 dwTemp;
TNIM_ENTRYB;
if (psChannel!=NULL)
{
if (psTnim->Channel.Number & 0x80)
{/* channel number is invalid*/
psChannel->Number=0xFF;
psChannel->Offset=0;
}
else
{
*psChannel=psTnim->Channel;
if (psTnim->State==TNIM_STATEINTERNAL_SCANSTOP)
{
if (Tnim_ReadOffsetkHz(psTnim,(s32*)&dwTemp))
{
if ((s32)dwTemp >84)
psChannel->Offset = 1;
else if ((s32)dwTemp <-84)
psChannel->Offset = -1;
}
}
}
}
if (psAuxInfo!=NULL)
{
psAuxInfo->ucValid=0;
psAuxInfo->wCellID=0;
psAuxInfo->wTPS=0;
if (Tnim_IsLocked(psTnim))
{
isTps = Tnim_ReadRegisterValue(psTnim,MT352_TPS_RECEIVED,2,&dwTemp);//MT352_TPS_RECEIVED=0x1E
if (isTps && dwTemp & 0x8000)
{
psAuxInfo->ucValid |= UCVALID_TPSVALID;//UCVALID_TPSVALID=0x01
psAuxInfo->wTPS = (u16)(dwTemp & 0x7FFF);/* remove valid flag*/
isTps=MT352_READ(MT352_TPS_GIVEN);/* get LP flag*/ //MT352_TPS_GIVEN=0x51
if (ucBuffer & MT352_TPS_GIVENH_LP)//MT352_TPS_GIVENH_LP 0x80
psAuxInfo->wTPS |= 0x8000;
}
isID = Tnim_ReadRegisterValue(psTnim,MT352_TPS_CELL_ID,2,&dwTemp);//0x22
if (isID)
psAuxInfo->wCellID = (u16) dwTemp;
isID = MT352_READ(MT352_FSMSTAT);//0x02
if (isID)
{/* check if reported as valid */
if (isID && (ucBuffer &0x01)==0x01)
psAuxInfo->ucValid |= UCVALID_CELLIDVALID;//0x02
}
}
}
TNIM_COMMAND(TNIM_COMMAND_PROCEED);//TNIM_COMMAND_PROCEED 6
TNIM_EXIT;
return isID && isTps;
}
/************************Zarlink Semiconductor*********************************
* Name: Tnim_ReadOffsetkH()
* Purpose:calculates frequency offset (transmitter relative to tuner)
* Remarks:
* Foff kHz= CRL * BW(MHz) /29360/x where x is 1(2k) or 4 (8k)
* Inputs:
* Outputs:TRUE if read was sucessful.
********************************************************************************/
bool8 Tnim_ReadOffsetkHz(PSTNIMCTL psTnim, s32 *lOffsetkHz)
{
u8 ucBuffer;
if (!Tnim_ReadRegisterValue(psTnim,MT352_FREQ_OFFSET,3,(u32*)lOffsetkHz))//MT352_FREQ_OFFSET=0x17
return FALSE;
/* get low byte of TPS with fft mode in it*/
if (!MT352_READ(MT352_TPS_RECEIVED+1))
return FALSE;//MT352_TPS_RECEIVED=0x1E
*lOffsetkHz = -(*lOffsetkHz<<8)>>8;
printf("lOffsetkHz =%x , %x\n",*lOffsetkHz, (int)ucBuffer );
*lOffsetkHz *= psTnim->ucBW;
if (ucBuffer &0x01)
*lOffsetkHz/=4;
*lOffsetkHz/=29360;
return TRUE; /* finished*/
}
/************************Zarlink Semiconductor*********************************
* Name:Tnim_readInterrupts()
* Purpose:Read in any interrupts
* Remarks: Adds any new flags to the IRQ cache
* Inputs:
* Outputs:TRUE if successful read occured
********************************************************************************/
bool8 Tnim_ReadInterrupts(PSTNIMCTL psTnim)
{
u32 dwIRQ;
if (!Tnim_ReadRegisterValue(psTnim,MT352_IRQ,4,&dwIRQ))return FALSE;
psTnim->IRQcache |=dwIRQ;
return TRUE;
}
/************************Zarlink Semiconductor*********************************
* Name:Tnim_AcqInit()
* Purpose:Sets Acquisition of channel stored in TNIM structure
* Remarks:If the channel number is not valid, skips programming
* of tuner and bandwidth
* Inputs:
* Outputs:TRUE if successful programmed
********************************************************************************/
bool8 Tnim_AcqInit(PSTNIMCTL psTnim)
{
u32 dwBWFreq;
u8 ucBuffer;
/* capture range*/
if (!MT352_READ(MT352_CAPT_RANGE))
return FALSE;//MT352_CAPT_RANGE=0x75
ucBuffer &= 0xFC;
ucBuffer |= 1; /* default capture range */
if (!MT352_WRITE(MT352_CAPT_RANGE))
return FALSE;
/* default to HP data stream */
if (!MT352_READ(MT352_TPS_GIVEN))
return FALSE;//MT352_TPS_GIVEN=0x51
ucBuffer &= ~MT352_TPS_GIVENH_LP;//MT352_TPS_GIVENH_LP=0x80
if (!MT352_WRITE(MT352_TPS_GIVEN))
return FALSE;
/* turn on automatic acquisition features */
if (! MT352_READ(MT352_ACQ_CTL))
return FALSE;//MT352_ACQ_CTL=0x53
ucBuffer &=MT352_ACQ_CTL_AUTO;//MT352_ACQ_CTL_AUTO=0xF4
ucBuffer |=0x20; /* Auto reaquire when Reedsolomon loss lock */
if (! MT352_WRITE(MT352_ACQ_CTL))
return FALSE;
/* turn on automatic re-acquisition features */
if (! MT352_READ(MT352_FSM_CTL))
return FALSE;//MT352_FSM_CTL=0x7B
ucBuffer |= MT352_FSM_CTL_AUTO;//MT352_FSM_CTL_AUTO=0x03
if (! MT352_WRITE(MT352_FSM_CTL))
return FALSE;
ucBuffer=MT352_TUNER_GOAQUIRE;//MT352_TUNER_GOAQUIRE=0x01
return MT352_WRITE(MT352_TUNER_GO);
}
/************************Zarlink Semiconductor*********************************
* Name:TnimReadRSUBC()
* Purpose:Read the uncorrected block count
* Remarks: if psTnim->NoAutoRSUBC is set, returns value from chip
* Inputs:
* Outputs:
********************************************************************************/
bool8 TnimReadRSUBC(PSTNIMCTL psTnim, u16 *wRSUBC)
{
bool8 ret;
u32 dwRSUBC;
TNIM_ENTRYB;
ret= Tnim_IsLocked(psTnim);
if (ret)
{
if (psTnim->NoAutoRSUBC)
{
ret = Tnim_ReadRegisterValue(psTnim,MT352_RS_UBC,2,&dwRSUBC);
*wRSUBC = (u16) dwRSUBC;
}
else
*wRSUBC = psTnim->RSUBC;
}
TNIM_EXIT;
return ret;
}
/************************Zarlink Semiconductor*********************************
* Name: TnimAcquireChannel()
* Purpose:Acquires the channel in psChannel
* Remarks:if psChannel=NULL, Acquires previous channel if any
* Inputs:
* Outputs:
********************************************************************************/
bool8 TnimAcquireChannel(PSTNIMCTL psTnim,STnimChannel *psChannel)
{
TNIM_ENTRYB;
if (psChannel!=NULL)
psTnim->Channel = *psChannel;
psTnim->Channel.Number &= 0x7F; /* mark number as valid*/
TNIM_COMMAND(TNIM_COMMAND_ACQUIRE);
TNIM_EXIT;
return TRUE;
}
/************************Zarlink Semiconductor*********************************
* Name: TnimAcquireSynth()
* Purpose:allows direct programming of synth , followed by acquisition
* Remarks:Reads 5 bytes into MT352, and kicks off Acquisition
* if ucBW is non zero, programs the MT352 bandwidth as well
* Inputs:
* Outputs:
********************************************************************************/
bool8 TnimAcquireSynth(PSTNIMCTL psTnim,u8* ucBuffer,u8 ucBW)
{
bool8 ret;
TNIM_ENTRYB;
ret = RegisterWrite2wb(psTnim->DeviceID,MT352_TUNER_ADDR,ucBuffer,5);
if (ret && ucBW)
ret = Tnim_ProgramBW(psTnim,ucBW);
psTnim->Channel.Number |= 0x80; /*invalidate the channel number*/
TNIM_COMMAND(TNIM_COMMAND_ACQUIRE);
TNIM_EXIT;
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -