Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: RDA5807M-FM-Radio EFM32 RDA5807M RDS Radio
RDA5807M.cpp
00001 #include "RDA5807M.h" 00002 00003 00004 unsigned int RDA5807M_WriteRegDef[6] ={0xC004,0x0000,0x0100,0x84D4,0x4000,0x0000}; // initial data 00005 00006 RDA5807M::RDA5807M(PinName sda, PinName scl) : i2c(sda, scl) 00007 { 00008 i2c.frequency(400000); 00009 Init(); 00010 } 00011 00012 RDA5807M::~RDA5807M() 00013 { 00014 } 00015 00016 void RDA5807M::WriteAll() 00017 { 00018 char buf[30]; 00019 int i,x = 0; 00020 for(i=0; i<12; i=i+2){ 00021 buf[i] = RDA5807M_WriteReg[x] >> 8; 00022 x++;} 00023 x = 0; 00024 for(i=1; i<13; i=i+2){ 00025 buf[i] = RDA5807M_WriteReg[x] & 0xFF; 00026 x++;} 00027 i2c.write(0x20, buf, 14); 00028 } 00029 00030 void RDA5807M::Init(){ 00031 int i; 00032 for(i=0; i<6; i++){ 00033 RDA5807M_WriteReg[i] = RDA5807M_WriteRegDef[i]; 00034 WriteAll(); 00035 } 00036 } 00037 00038 void RDA5807M::PowerOn(){ 00039 RDA5807M_WriteReg[1] = RDA5807M_WriteReg[1] | RDA_TUNE_ON; 00040 RDA5807M_WriteReg[0] = RDA5807M_WriteReg[0] | RDA_POWER; 00041 WriteAll(); power=1; 00042 RDA5807M_WriteReg[1] = RDA5807M_WriteReg[1] & 0xFFEF; //Disable tune after PowerOn operation 00043 } 00044 00045 void RDA5807M::PowerOff(){ 00046 RDA5807M_WriteReg[0] = RDA5807M_WriteReg[0] ^ RDA_POWER; 00047 WriteAll();power=0; 00048 } 00049 00050 void RDA5807M::Reset(){ 00051 Init(); 00052 PowerOn(); 00053 RDSinit(); 00054 RDS(); 00055 Volume(InitialVolume); 00056 Frequency(DefaultFreq); // set default start frequency. 00057 } 00058 00059 void RDA5807M::Volume(int vol){ 00060 if(vol > 15){ 00061 vol = 15; 00062 } 00063 if(vol < 0){ 00064 vol = 0; 00065 } 00066 RDA5807M_WriteReg[3] = (RDA5807M_WriteReg[3] & 0xFFF0)| vol; // Set New Volume 00067 volume=vol; 00068 WriteAll(); 00069 } 00070 00071 void RDA5807M::BassBoost(){ 00072 if ((RDA5807M_WriteReg[0] & 0x1000)==0){ 00073 RDA5807M_WriteReg[0] = RDA5807M_WriteReg[0] | RDA_BASS_ON; 00074 bass=1; 00075 } 00076 else{ 00077 RDA5807M_WriteReg[0] = RDA5807M_WriteReg[0] & RDA_BASS_OFF; 00078 bass=0; 00079 } 00080 WriteAll(); 00081 } 00082 00083 void RDA5807M::Mono(){ 00084 if ((RDA5807M_WriteReg[0] & 0x2000)==0){ 00085 RDA5807M_WriteReg[0] = RDA5807M_WriteReg[0] | RDA_MONO_ON; 00086 mono=1; 00087 } 00088 else{ 00089 RDA5807M_WriteReg[0] = RDA5807M_WriteReg[0] & RDA_MONO_OFF; 00090 mono=0; 00091 } 00092 WriteAll(); 00093 } 00094 00095 void RDA5807M::Mute(){ 00096 if ((RDA5807M_WriteReg[0] & 0x8000)==0){ 00097 RDA5807M_WriteReg[0] = RDA5807M_WriteReg[0] | 0x8000; 00098 mute=0; 00099 } 00100 else{ 00101 RDA5807M_WriteReg[0] = RDA5807M_WriteReg[0] & 0x7FFF; 00102 mute=1; 00103 } 00104 WriteAll(); 00105 } 00106 00107 void RDA5807M::Softmute(){ 00108 if ((RDA5807M_WriteReg[2] & 0x0200)==0){ 00109 RDA5807M_WriteReg[2] = RDA5807M_WriteReg[2] | 0x0200; 00110 softmute=1; 00111 } 00112 else{ 00113 RDA5807M_WriteReg[2] = RDA5807M_WriteReg[2] & 0xFDFF; 00114 softmute=0; 00115 } 00116 WriteAll(); 00117 } 00118 00119 void RDA5807M::SoftBlend(){ 00120 if ((RDA5807M_WriteReg[6] & 0x0001)==0){ 00121 RDA5807M_WriteReg[6] = RDA5807M_WriteReg[6] | 0x0001; 00122 softblend=1; 00123 } 00124 else{ 00125 RDA5807M_WriteReg[6] = RDA5807M_WriteReg[6] & 0xFFFE; 00126 softblend=0; 00127 } 00128 WriteAll(); 00129 } 00130 00131 void RDA5807M::AFC(){ 00132 if ((RDA5807M_WriteReg[2] & 0x0100)==0){ 00133 RDA5807M_WriteReg[2] = RDA5807M_WriteReg[2] | 0x0100; 00134 afc=1; 00135 } 00136 else{ 00137 RDA5807M_WriteReg[2] = RDA5807M_WriteReg[2] & 0xFEFE; 00138 afc=0; 00139 } 00140 WriteAll(); 00141 } 00142 00143 void RDA5807M::SeekUp(){ 00144 RDA5807M_WriteReg[0] = RDA5807M_WriteReg[0] | RDA_SEEK_UP; // Set Seek Up 00145 WriteAll(); 00146 RDA5807M_WriteReg[0] = RDA5807M_WriteReg[0] & RDA_SEEK_STOP; // Disable Seek 00147 } 00148 00149 void RDA5807M::SeekDown(){ 00150 RDA5807M_WriteReg[0] = RDA5807M_WriteReg[0] | RDA_SEEK_DOWN; // Set Seek Down 00151 WriteAll(); 00152 RDA5807M_WriteReg[0] = RDA5807M_WriteReg[0] & RDA_SEEK_STOP; // Disable Seek 00153 } 00154 00155 void RDA5807M::Frequency(float Freq){ 00156 int Channel; 00157 Channel = ((Freq-StartingFreq)/0.1)+0.05; 00158 Channel = Channel & 0x03FF; 00159 RDA5807M_WriteReg[1] = Channel*64 + 0x10; // Channel + TUNE-Bit + Band=00(87-108) + Space=00(100kHz) 00160 WriteAll(); 00161 RDA5807M_WriteReg[1] = RDA5807M_WriteReg[1] & RDA_TUNE_OFF; 00162 } 00163 00164 void RDA5807M::RDS(){ 00165 if ((RDA5807M_WriteReg[0] & RDA_RDS_ON)==0){ 00166 RDA5807M_WriteReg[0] = RDA5807M_WriteReg[0] | RDA_RDS_ON; 00167 rds=1; 00168 } 00169 else{ 00170 RDA5807M_WriteReg[0] = RDA5807M_WriteReg[0] & RDA_RDS_OFF; 00171 rds=0; 00172 } 00173 WriteAll(); 00174 } 00175 00176 void RDA5807M::Readregisters(){ 00177 int i; 00178 char rcv[12]; 00179 i2c.read(0x20, rcv,12); // read 12 bytes for reg 0x0A .. reg 0x0F 00180 for(i=0; i<6; i++){ 00181 RDA5807M_ReadReg[i] = ((rcv[i *2] << 8) | rcv [(i*2) +1] ); 00182 } 00183 block1 = RDA5807M_ReadReg[2]; 00184 block2 = RDA5807M_ReadReg[3]; 00185 block3 = RDA5807M_ReadReg[4]; 00186 block4 = RDA5807M_ReadReg[5]; 00187 00188 rdsready = RDA5807M_ReadReg[0] & 0x8000; //if rdsready != 0 rds data are ready 00189 tuneok = RDA5807M_ReadReg[0] & 0x4000; //if tuneok != 0 seek/tune completed 00190 nochannel = RDA5807M_ReadReg[0] & 0x2000; //if nochannel != 0 no channel found 00191 rdssynchro = RDA5807M_ReadReg[0] & 0x1000; //if rdssynchro = 1000 rds decoder syncrhonized 00192 stereo = RDA5807M_ReadReg[0] & 0x0400; //if stereo = 0 station is mono else stereo 00193 freq = (((RDA5807M_ReadReg[0] & 0x03FF) * 100) + 87000); //return freq ex 102600KHz > 102.6MHz 00194 signal = RDA5807M_ReadReg[1] >> 10; //return signal strength rssi 00195 fmready = RDA5807M_ReadReg[1] & 0x0008; //if fmready = 8 > fm is ready 00196 fmstation = RDA5807M_ReadReg[1] & 0x0100; //if fmstation = 100 fm station is true 00197 rdsblockerror = RDA5807M_ReadReg[1] & 0x000C; //check for rds blocks errors 00198 //00= 0 errors,01= 1~2 errors requiring correction 00199 //10= 3~5 errors requiring correction 00200 //11= 6+ errors or error in checkword, correction not possible. 00201 } 00202 00203 void RDA5807M::RDSinit() { 00204 strcpy(StationName, " "); 00205 strcpy(PSName, " "); 00206 strcpy(PSName1, " "); 00207 strcpy(PSName2, " "); 00208 memset(RDSText, '\0', sizeof(RDSText)); 00209 memset(RDSTxt, '\0', sizeof(RDSTxt)); 00210 lastTextIDX = 0; 00211 mins=0; 00212 sprintf(CTtime, "CT --:--"); 00213 } 00214 00215 void RDA5807M::ProcessData() 00216 { 00217 Readregisters(); 00218 if (rdssynchro != 0x1000){ // reset all the RDS info. 00219 RDSinit(); 00220 return; 00221 } 00222 // analyzing Block 2 00223 rdsGroupType = 0x0A | ((block2 & 0xF000) >> 8) | ((block2 & 0x0800) >> 11); 00224 rdsTP = (block2 & 0x0400); 00225 rdsPTY = (block2 & 0x0400); 00226 00227 switch (rdsGroupType) { 00228 case 0x0A: 00229 case 0x0B: 00230 // The data received is part of the Service Station Name 00231 idx = 2 * (block2 & 0x0003); 00232 // new data is 2 chars from block 4 00233 c1 = block4 >> 8; 00234 c2 = block4 & 0x00FF; 00235 // check that the data was received successfully twice 00236 // before sending the station name 00237 if ((PSName1[idx] == c1) && (PSName1[idx + 1] == c2)) { 00238 // retrieve the text a second time: store to _PSName2 00239 PSName2[idx] = c1; 00240 PSName2[idx + 1] = c2; 00241 PSName2[8] = '\0'; 00242 if (strcmp(PSName1, PSName2) == 0) { 00243 // populate station name 00244 n=0; 00245 for(i=0;i<(8);i++){ // remove non-printable error ASCCi characters 00246 if(PSName2[i] > 31 && PSName2[i] < 127){ 00247 StationName[n] = PSName2[i]; 00248 n++; 00249 } 00250 } 00251 } 00252 } 00253 if ((PSName1[idx] != c1) || (PSName1[idx + 1] != c2)) { 00254 PSName1[idx] = c1; 00255 PSName1[idx + 1] = c2; 00256 PSName1[8] = '\0'; 00257 } 00258 break; 00259 00260 case 0x2A: 00261 // RDS text 00262 textAB = (block2 & 0x0010); 00263 idx = 4 * (block2 & 0x000F); 00264 if (idx < lastTextIDX) { 00265 // The existing text might be complete because the index is starting at the beginning again. 00266 // Populate RDS text array. 00267 n=0; 00268 for(i=0;i<strlen(RDSTxt);i++){ 00269 if(RDSTxt[i] > 31 && RDSTxt[i] < 127){ // remove any non printable error charcters 00270 RDSText[n] = RDSTxt[i]; 00271 n++; 00272 } 00273 } 00274 } 00275 lastTextIDX = idx; 00276 if (textAB != lasttextAB) { 00277 // when this bit is toggled the whole buffer should be cleared. 00278 lasttextAB = textAB; 00279 memset(RDSTxt, 0, sizeof(RDSTxt)); 00280 memset(RDSText, '\0', sizeof(RDSText)); 00281 } 00282 if(rdsblockerror < 4){ 00283 // new data is 2 chars from block 3 00284 RDSTxt[idx] = (block3 >> 8); idx++; 00285 RDSTxt[idx] = (block3 & 0x00FF); idx++; 00286 // new data is 2 chars from block 4 00287 RDSTxt[idx] = (block4 >> 8); idx++; 00288 RDSTxt[idx] = (block4 & 0x00FF); idx++; 00289 } 00290 break; 00291 00292 case 0x4A: 00293 // Clock time and date 00294 if(rdsblockerror <3){ // allow limited RDS data errors as we have no correctioin code 00295 offset = (block4) & 0x3F; // 6 bits 00296 mins = (block4 >> 6) & 0x3F; // 6 bits 00297 mins += 60 * (((block3 & 0x0001) << 4) | ((block4 >> 12) & 0x0F)); 00298 } 00299 // adjust offset 00300 if (offset & 0x20) { 00301 mins -= 30 * (offset & 0x1F); 00302 } 00303 else { 00304 mins += 30 * (offset & 0x1F); 00305 } 00306 if(mins == lastmins+1){ // get CT time twice before populating time 00307 minutes=mins;} 00308 lastmins=mins; 00309 if(rdssynchro == 0x1000){ 00310 if(minutes>0 && minutes<1500){sprintf(CTtime, "CT %2d:%02d",(minutes/60),(minutes%60));} 00311 } 00312 else{minutes=0;sprintf(CTtime, "CT --:--");} // CT time formatted string 00313 break; 00314 00315 case 0x6A: 00316 // IH 00317 break; 00318 00319 case 0x8A: 00320 // TMC 00321 break; 00322 00323 case 0xAA: 00324 // TMC 00325 break; 00326 00327 case 0xCA: 00328 // TMC 00329 break; 00330 00331 case 0xEA: 00332 // IH 00333 break; 00334 00335 default: 00336 00337 break; 00338 } 00339 } 00340
Generated on Wed Jul 20 2022 21:48:03 by
1.7.2