📄 radiodrv.c
字号:
#ifdef SUPPORT_RADIO_RDS
//*********************************************************************************************************
// @summary This function be used to initiate RDS functions
// @param None
// @return None
// @retval None
// @description
// This function be used to initiate RDS functions
// @bug None
// @history
//*********************************************************************************************************
void RADIODRV_RDSInit(void)
{
BYTE bIndex;
//initial RDS variable
wRADIODRV_PI=0x00;
bRADIODRV_CountPI=0x00;
bRADIODRV_CountPTY=0x00;
bRADIODRV_CountPS=0x00;
bRADIODRV_CountECC=0x00;
bRADIODRV_CountPTYN=0x00;
bRADIODRV_RDS_RTLen=0x00;
bRADIODRV_TP=0x00; //traffic programme id
bRADIODRV_TA=0x00;//traffic announcement
//initial array
for(bIndex=0x00;bIndex<sizeof(bRADIODRV_RDS_PTY);bIndex++ )
bRADIODRV_RDS_PTY[bIndex]=0x20;
for(bIndex=0x00;bIndex<sizeof(bRADIODRV_RDS_PS);bIndex++ )
bRADIODRV_RDS_PS[bIndex]=0x20;
for(bIndex=0x00;bIndex<sizeof(bRADIODRV_RDS_PTYN);bIndex++ )
bRADIODRV_RDS_PTYN[bIndex]=0x20;
for(bIndex=0x00;bIndex<sizeof(bRADIODRV_RDS_RT);bIndex++ )
{
bRADIODRV_RDS_RT[bIndex]=0x20;
// bRADIODRV_RDS_RTmp[bIndex]=0x20;
}
//Read RDS register setting
_RADIODRV_ReadReg(0x0f, wRADIODRVTunerReg);
bRADIODRV_RDS_flag=(BYTE)((wRADIODRVTunerReg[0xD] & 0x0010) >> 4);
bRADIODRV_RDS_RTFirst=0x00; //the flag use the first segment address about radio text (RT)
bRADIODRV_RDS_RTEnd=0x00;
wRADIODRV_RDS_RTmp=0x00;
wRADIODRV_RDS_RT=0x00;
// printf("\n @0x0A:%x",wRADIODRVTunerReg[0x0A]);
}
//*********************************************************************************************************
// @summary This function be used to check RDS type from on-air
// @param bRDS_TYPE User needs to get RDS type form on-air
// @return Get the status of the RDS type
// @retval TRUE Support RDS tpye of the on-air
// @retval FALSE Don't support RDS type of the on-air
// @description
// This function be used to check RDS type from on-air
// @bug None
// @history
//*********************************************************************************************************
BYTE RADIODRV_RDSTYPE(BYTE bRDS_TYPE)
{
BYTE bRDS_Group=0; //record RDS group type
//step[1]:read the RDS group type
_RADIODRV_ReadReg(0x0D, wRADIODRVTunerReg);
//printf("\n @0x0A=%x",wRADIODRVTunerReg[0x0A]);
//step[2]: wait RDS data ready, then read group
if((wRADIODRVTunerReg[0x0A]&0x8000)==0x8000)
{
bRDS_Group=(BYTE)(wRADIODRVTunerReg[0x0D]>>11);
//step[3]: compare desired bRDS_TYPE to from bRDS_Group
switch(bRDS_TYPE)
{
case RDS_PI: //program identification which support all group from RDS spec.
case RDS_PTY: //program type which suppport all group from RDS spec.
case RDS_TP: //Traffic programme identification code which support all group frim RDS spec.
if((bRDS_Group>=RDS_TYPE_0A)||(bRDS_Group<=RDS_TYPE_15B))
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
case RDS_ECC: //support the Externd country code
if(bRDS_Group==RDS_TYPE_1A)
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
case RDS_PS: //program service name only in 0x0A and 0x0B group
if((bRDS_Group==RDS_TYPE_0A)||(bRDS_Group==RDS_TYPE_0B))
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
case RDS_AF: //alternative frequency only in 0x0A and 0x0B group
if(bRDS_Group==RDS_TYPE_0A)
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
case RDS_TA://Traffic announcement only in 0x0A, 0x0B, 0x14B, 0x15B
if((bRDS_Group==RDS_TYPE_0A)||(bRDS_Group==RDS_TYPE_0B)||(bRDS_Group==RDS_TYPE_14B)||(bRDS_Group==RDS_TYPE_15B))
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
case RDS_DI://decoder identification code only in 0x0A, 0x0B, 0x15B
case RDS_MS://music speed only in 0x0A, 0x0B, 0x15B
if((bRDS_Group==RDS_TYPE_0A)||(bRDS_Group==RDS_TYPE_0B)||(bRDS_Group==RDS_TYPE_15B))
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
case RDS_RT: //radio text only in 0x2A, 0x2B
if((bRDS_Group==RDS_TYPE_2A)||(bRDS_Group==RDS_TYPE_2B))
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
case RDS_PTYN:
if((bRDS_Group==RDS_TYPE_10A))
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
case RDS_EON://Enhanced other networks inforamtion only in 0x14A
if(bRDS_Group==RDS_TYPE_14A)
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
case RDS_CT: //support the clock-time and date
if(bRDS_Group==RDS_TYPE_4A)
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
default:
return RADIODRV_ERR;
break;
}
}
return FALSE; //non support this type
}
//*********************************************************************************************************
// @summary This function be used to update RDS information
// @param bRDS_TYPE User needs to update RDS type information
// @param pbRDString User desires to display message
// @return Get the status of updated RDS information
// @retval TRUE Updated the RDS information is ready
// @retval FALSE Updated the RDS information is un-ready
// @description
// This function be used to update RDS information
// @bug None
// @history
//*********************************************************************************************************
BYTE RADIODRV_UpdateRDS(BYTE bRDS_Type, BYTE* pbRDString)
{
//step[0]: read the RDS block data
_RADIODRV_ReadReg(0x0f, wRADIODRVTunerReg);
//step[1]: wait RDS data ready, then read group
if((wRADIODRVTunerReg[0x0A]&0x8000)==0x8000)
{
if((wRADIODRVTunerReg[0x0B]&0xC000) || (wRADIODRVTunerReg[0x0B]&0x3000) || (wRADIODRVTunerReg[0x0B]&0x0C00))
{
return FALSE;
}
// printf("\n @@ U_RDS!!");
switch(bRDS_Type)
{
//
case RDS_PI: //program identification
if(RADIODRV_RDS_PI(pbRDString))
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
//
case RDS_PTY://program type
if(RADIODRV_RDS_PTY(pbRDString))
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
//
case RDS_TP: //traffic programme
if(RADIODRV_RDS_TP())
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
//
case RDS_ECC: //traffic programme
if(RADIODRV_RDS_ECC(pbRDString))
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
//
case RDS_TA:
if(RADIODRV_RDS_TA())
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
//
case RDS_DI:
if(RADIODRV_RDS_DI())
return RADIODRV_RDS_DI();
else
return RADIODRV_ERR;
break;
//
case RDS_PS://program service name
if(RADIODRV_RDS_PS(pbRDString))
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
//
case RDS_RT://radio text
if(RADIODRV_RDS_RT(pbRDString))
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
//
case RDS_CT://clock time
if(RADIODRV_RDS_CT(pbRDString))
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
//
case RDS_PTYN:
if(RADIODRV_RDS_PTYN(pbRDString))
return RADIODRV_NOERR;
else
return RADIODRV_ERR;
break;
//
default:
return RADIODRV_ERR;
break;
}
return FALSE;
}
return FALSE;
}
//*********************************************************************************************************
// @summary This function be used to access PI code form the broadcasting
// @param pbRDS_PI User needs to get PI code information
// @return Get the status of the PI code
// @retval TRUE Get the PI code successfully
// @retval FALSE Get the PI code fail
// @description
// This function be used to access PI code from the broadcasting
// @bug None
// @history
//*********************************************************************************************************
BYTE RADIODRV_RDS_PI(BYTE* pbRDS_PI )
{
BYTE bRDS_GRP;
//step[1]: check group 0x0A only block 1 support PI code,but group 0x0B block1/3 support PI code
bRDS_GRP=(BYTE)(wRADIODRVTunerReg[0x0D]>>11);
//step[2]: needs more time to check actual PI code
if(bRDS_GRP&0x01)//group 0x0B : PI code exist two block
{
if((wRADIODRV_PI==wRADIODRVTunerReg[0x0C])&&(wRADIODRVTunerReg[0x0C]==wRADIODRVTunerReg[0x0E]))
{
wRADIODRV_PI=wRADIODRVTunerReg[0x0C];
bRADIODRV_CountPI+=1;
}
else
{
wRADIODRV_PI=wRADIODRVTunerReg[0x0C];
}
}
else//group 0x0A
{
if(wRADIODRV_PI==wRADIODRVTunerReg[0x0C])
{
wRADIODRV_PI=wRADIODRVTunerReg[0x0C];
bRADIODRV_CountPI+=1;
// printf("\n @@PI--%x",wRADIODRVTunerReg[0x0C]);
}
else
{
wRADIODRV_PI=wRADIODRVTunerReg[0x0C];
}
}
//step[3]: return PI code
if(bRADIODRV_CountPI>=RDS_VALIDATE_LIMIT)
{
pbRDS_PI[0]=0x02; // PI code length
pbRDS_PI[1]=(BYTE)(wRADIODRVTunerReg[0x0C]&0x00FF); //low BYTE for programme reference number
pbRDS_PI[2]=(BYTE)(wRADIODRVTunerReg[0x0C]>>8); //high BYTE for high-nibble for programme type
wRADIODRV_PI=0x00; //low-nibble for country identification
bRADIODRV_CountPI=0x00;
// printf("@@_PI_1 %hx, %hx, %hx",bRADIODRV_CountPI,pbRDS_PI[2],pbRDS_PI[1]);
return RADIODRV_NOERR; //true
}
return RADIODRV_ERR;//false
}
//*********************************************************************************************************
// @summary This function be used to access ECC info. from the broadcasting
// @param pbRDS_ECC User needs to access ECC info. from the broadcasting
// @return Get the status of the ECC code
// @retval TRUE Get the ECC code successfully
// @retval FALSE Get the ECC code fail
// @description
// This function be used to access ECC code from the broadcasting
// @bug None
// @history
//*********************************************************************************************************
BYTE RADIODRV_RDS_ECC(BYTE* pbRDS_ECC )
{
BYTE bRDS_GRP;
//step[1]: check group 0x0A only block 1 support PI code,but group 0x0B block1/3 support PI code
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -