Guest User

TEF6686.cpp

a guest
Dec 27th, 2019
62
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "TEF6686.h"
  2. char* ptyLUT[51] = {
  3.       "      None      ",
  4.       "      News      ",
  5.       "  Information   ",
  6.       "     Sports     ",
  7.       "      Talk      ",
  8.       "      Rock      ",
  9.       "  Classic Rock  ",
  10.       "   Adult Hits   ",
  11.       "   Soft Rock    ",
  12.       "     Top 40     ",
  13.       "    Country     ",
  14.       "     Oldies     ",
  15.       "      Soft      ",
  16.       "   Nostalgia    ",
  17.       "      Jazz      ",
  18.       "   Classical    ",
  19.       "Rhythm and Blues",
  20.       "   Soft R & B   ",
  21.       "Foreign Language",
  22.       "Religious Music ",
  23.       " Religious Talk ",
  24.       "  Personality   ",
  25.       "     Public     ",
  26.       "    College     ",
  27.       " Reserved  -24- ",
  28.       " Reserved  -25- ",
  29.       " Reserved  -26- ",
  30.       " Reserved  -27- ",
  31.       " Reserved  -28- ",
  32.       "     Weather    ",
  33.       " Emergency Test ",
  34.       "  !!!ALERT!!!   ",
  35.       "Current Affairs ",
  36.       "   Education    ",
  37.       "     Drama      ",
  38.       "    Cultures    ",
  39.       "    Science     ",
  40.       " Varied Speech  ",
  41.       " Easy Listening ",
  42.       " Light Classics ",
  43.       "Serious Classics",
  44.       "  Other Music   ",
  45.       "    Finance     ",
  46.       "Children's Progs",
  47.       " Social Affairs ",
  48.       "    Phone In    ",
  49.       "Travel & Touring",
  50.       "Leisure & Hobby ",
  51.       " National Music ",
  52.       "   Folk Music   ",
  53.       "  Documentary   "};
  54.  
  55. TEF6686::TEF6686() {
  56. }
  57.  
  58. uint8_t TEF6686::init() {
  59.   uint8_t result;
  60.   uint8_t counter = 0;
  61.   uint8_t status;
  62.  
  63.   Tuner_I2C_Init();
  64.  
  65.   delay(5);
  66.   while (true) {
  67.     result = devTEF668x_APPL_Get_Operation_Status(&status);
  68.     if (result == 1) {
  69.       Tuner_Init();
  70.       powerOff();
  71.       return 1; //Ok
  72.     }
  73.     else if (++counter > 50) {
  74.       return 2; //Doesn't exist
  75.     }
  76.     else {
  77.       delay(5);
  78.       return 0;  //Busy
  79.     }
  80.   }
  81. }
  82.  
  83. void TEF6686::powerOn() {
  84.   devTEF668x_APPL_Set_OperationMode(0);
  85. }
  86.  
  87. void TEF6686::powerOff() {
  88.   devTEF668x_APPL_Set_OperationMode(1);
  89. }
  90.  
  91. void TEF6686::setFrequency(uint16_t frequency) {
  92.   Radio_SetFreq(Radio_PRESETMODE, FM1_BAND, frequency);
  93. }
  94.  
  95. uint16_t TEF6686::getFrequency() {
  96.   return Radio_GetCurrentFreq();
  97. }
  98.  
  99. uint16_t TEF6686::getLevel() {
  100.   return Radio_Get_Level(1);
  101. }
  102.  
  103. uint8_t TEF6686::getStereoStatus() {
  104.   return Radio_CheckStereo();
  105. }
  106.  
  107. uint16_t TEF6686::seekUp() {
  108.   clearRDS();
  109.     return seek(1);
  110. }
  111.  
  112. uint16_t TEF6686::seekDown() {
  113.   clearRDS();
  114.     return seek(0);
  115. }
  116.  
  117. uint16_t TEF6686::tuneUp() {
  118.   clearRDS();
  119.   return tune(1);
  120. }
  121.  
  122. uint16_t TEF6686::tuneDown() {
  123.   clearRDS();
  124.   return tune(0);
  125. }
  126.  
  127. void TEF6686::setVolume(uint16_t volume) {
  128.   devTEF668x_Audio_Set_Volume(volume);
  129. }
  130.  
  131. void TEF6686::setMute() {
  132.   devTEF668x_Audio_Set_Mute(1);
  133. }
  134.  
  135. void TEF6686::setUnMute() {
  136.   devTEF668x_Audio_Set_Mute(0);
  137. }
  138.  
  139. bool TEF6686::readRDS() {
  140.   char status;
  141.   uint8_t rdsBHigh, rdsBLow, rdsCHigh, rdsCLow, rdsDHigh, rdsDLow, isPsReady;
  142.  
  143.   uint16_t rdsStat, rdsA, rdsB, rdsC, rdsD, rdsErr;
  144.   uint16_t result = devTEF668x_Radio_Get_RDS_Data(1, &rdsStat, &rdsA, &rdsB, &rdsC, &rdsD, &rdsErr);
  145.  
  146.   // status
  147.   // dataAvailable: is there any usable data
  148.   // dataLoss: 0: prevoius data was read
  149.   // dataType: 1: first PI appeared after sync
  150.   // groupVersion: 0: A, 1: B
  151.   // sync: is RDS sync available
  152.   bool dataAvailable = bitRead(rdsStat, 15);
  153.   bool dataLoss = bitRead(rdsStat, 14);
  154.   bool dataType = bitRead(rdsStat, 13);
  155.   bool groupVersion = bitRead(rdsStat, 12);
  156.   bool sync = bitRead(rdsStat, 9);
  157.  
  158.   if (!dataAvailable) {
  159.     return sync;
  160.   }
  161.  
  162.   // error
  163.   uint8_t errA = (rdsErr & 0b1100000000000000) >> 14;
  164.   uint8_t errB = (rdsErr & 0b0011000000000000) >> 12;
  165.   uint8_t errC = (rdsErr & 0b0000110000000000) >> 10;
  166.   uint8_t errD = (rdsErr & 0b0000001100000000) >> 8;
  167. /*
  168.   Serial.print("result:");
  169.   Serial.print(result);
  170.   Serial.println();
  171.  
  172.   Serial.print("data available:");
  173.   Serial.print(dataAvailable);
  174.   Serial.println();
  175.  
  176.   Serial.print("data loss:");
  177.   Serial.print(dataLoss);
  178.   Serial.println();
  179.  
  180.   Serial.print("data available type:");
  181.   Serial.print(dataType);
  182.   Serial.println();
  183.  
  184.   Serial.print("group version:");
  185.   Serial.print(groupVersion);
  186.   Serial.println();
  187.  
  188.   Serial.print("sync status:");
  189.   Serial.print(sync);
  190.   Serial.println();
  191. */
  192.  
  193.  
  194.   rdsBHigh = (uint8_t)(rdsB >> 8);
  195.   rdsBLow = (uint8_t)rdsB;
  196.   rdsCHigh = (uint8_t)(rdsC >> 8);
  197.   rdsCLow = (uint8_t)rdsC;
  198.   rdsDHigh = (uint8_t)(rdsD >> 8);
  199.   rdsDLow = (uint8_t)rdsD;
  200.  
  201.   // group type (0: PS, 2: RT, 4: CT, 10: PTYN
  202.   uint8_t type = (rdsBHigh >> 4) & 15;
  203.  
  204.   // PTY
  205.   if (errB <= 1) {
  206.     uint8_t programType = ((rdsBHigh & 3) << 3) | ((rdsBLow >> 5) & 7);
  207.     strcpy(rdsProgramType, (programType >= 0 && programType < 32) ? ptyLUT[programType] : "    PTY ERROR   ");
  208.   }
  209.  
  210.   // PI
  211.   char Hex[16]={ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  212.   rdsProgramId[0]=Hex[(rdsA & 0xF000U) >> 12];
  213.   rdsProgramId[1]=Hex[(rdsA & 0x0F00U) >> 8];
  214.   rdsProgramId[2]=Hex[(rdsA & 0x00F0U) >> 4];
  215.   rdsProgramId[3]=Hex[(rdsA & 0x000FU)];
  216.   rdsProgramId[4]='\0';
  217.  
  218.  
  219.   /*
  220.   if (groupVersion == 1){
  221.     Serial.print("error A:");
  222.     Serial.print(errA);
  223.     Serial.println();
  224.  
  225.     Serial.print("error B:");
  226.     Serial.print(errB);
  227.     Serial.println();
  228.  
  229.     Serial.print("error C:");
  230.     Serial.print(errC);
  231.     Serial.println();
  232.  
  233.     Serial.print("error D:");
  234.     Serial.print(errD);
  235.     Serial.println();
  236.    
  237.     Serial.print(Hex[(rdsA & 0xF000U) >> 12]);
  238.     Serial.print(Hex[(rdsA & 0x0F00U) >> 8]);
  239.     Serial.print(Hex[(rdsA & 0x00F0U) >> 4]);
  240.     Serial.print(Hex[(rdsA & 0x000FU)]);    
  241.     Serial.print(" - ");
  242.     Serial.print(Hex[(rdsC & 0xF000U) >> 12]);
  243.     Serial.print(Hex[(rdsC & 0x0F00U) >> 8]);
  244.     Serial.print(Hex[(rdsC & 0x00F0U) >> 4]);
  245.     Serial.print(Hex[(rdsC & 0x000FU)]);
  246.     Serial.println();
  247.   }
  248.  
  249.   Serial.print("group type number: ");
  250.   Serial.print(type);
  251.   Serial.println();
  252.  
  253.   if (type == 0){
  254.     Serial.print(char(rdsDHigh));
  255.     Serial.print(char(rdsDLow));
  256.     Serial.println();
  257.   }
  258. */
  259.  
  260.   // Groups 0A & 0B
  261.   // Basic tuning and switching information only
  262.    if (type == 0) {
  263.     // Safe PS
  264.     uint8_t address = rdsBLow & 3;
  265.     uint8_t errPs = errB > errD ? errB : errD;
  266.     if (address >= 0 && address <= 3) {
  267.       if (address < prevAddress) {
  268.         psErrors = psErrors | 0x44444444;
  269.         psAB = !psAB;
  270.       }
  271.       prevAddress = address;
  272.       // store ps block if: no stored ps char yet || arriving data's error <= 1 || previously set data's error >= 2
  273.       if (!bitRead(psCharIsSet, 7 - (psAB * 4 + address))  || errPs <= 1 || (bitRead(psErrors, 31 - (psAB * 16 + address * 4 + 2)) && !bitRead(psErrors, 31 - (psAB * 16 + address * 4)))) {
  274.         //psCharIsSet set
  275.         bitWrite(psCharIsSet, 7 - (psAB * 4 + address), 1);
  276.        
  277.         // setting psErrors
  278.         bitWrite(psErrors, 31 - (psAB * 16 + address * 4), 0);
  279.         bitWrite(psErrors, 31 - (psAB * 16 + address * 4 + 1), 0);
  280.         if (errPs <= 1) {
  281.           bitWrite(psErrors, 31 - (psAB * 16 + address * 4 + 2), 0);
  282.           if (errPs == 1) {
  283.             bitWrite(psErrors, 31 - (psAB * 16 + address * 4 + 3), 1);
  284.           }
  285.         }
  286.         if (errPs == 0 || errPs == 2) {
  287.           bitWrite(psErrors, 31 - (psAB * 16 + address * 4 + 3), 0);
  288.         }
  289.  
  290.         // SAFE MODE
  291.         if (rdsDHigh != '\0') {
  292.           unsafePs[psAB][address * 2] = rdsDHigh;
  293.         }  
  294.         if (rdsDLow != '\0') {
  295.           unsafePs[psAB][address * 2 + 1] = rdsDLow;
  296.         }
  297.  
  298.         // UNSAFE MODE
  299.         if (errPs <= 1) {
  300.           if (rdsDHigh != '\0') {
  301.             rdsProgramServiceUnsafe[address * 2] = rdsDHigh;
  302.           }  
  303.           if (rdsDLow != '\0') {
  304.             rdsProgramServiceUnsafe[address * 2 + 1] = rdsDLow;
  305.           }
  306.           // TODO: escape only rdsDHigh + rdsDLow
  307.           rdsFormatString(rdsProgramServiceUnsafe, 8);
  308.         }
  309.       }    
  310.  
  311.       //check if current unsafePs can be written to safe PS
  312.       if ((psCharIsSet == 0xFF && strncmp(unsafePs[0], unsafePs[1], 8) == 0)  || (psAB ? (psErrors & 0xFFFF) == 0 : (psErrors & 0xFFFF0000) == 0)) {
  313.         strncpy(rdsProgramService, unsafePs[psAB], 8);
  314.         rdsProgramService[8] = '\0';
  315.         rdsFormatString(rdsProgramService, 8);
  316.         psCharIsSet = 0;
  317.         psErrors = 0xFFFFFFFF;
  318.       }
  319.     }
  320.   }
  321.    
  322.   // Groups 2A & 2B
  323.   // Radio Text
  324.   else if (type == 2 && errB <= 1) {
  325.     uint16_t addressRT = rdsBLow & 15;
  326.     uint8_t ab = bitRead(rdsBLow, 4);
  327.     uint8_t cr = 0;
  328.     uint8_t len = 64;
  329.     if (groupVersion == 0) {
  330.       if (addressRT >= 0 && addressRT <= 15) {
  331.         if (errC <=1) {
  332.           if (rdsCHigh != 0x0D) {
  333.             rdsRadioText[addressRT*4] = rdsCHigh;
  334.           }  
  335.           else {
  336.             len = addressRT * 4;
  337.             cr = 1;
  338.           }
  339.           if (rdsCLow != 0x0D) {
  340.             rdsRadioText[addressRT * 4 + 1] = rdsCLow;
  341.           }  
  342.           else {
  343.             len = addressRT * 4 + 1;
  344.             cr = 1;
  345.           }
  346.         }
  347.         else if (errD <= 1) {
  348.           if (rdsDHigh != 0x0D) {
  349.             rdsRadioText[addressRT * 4 + 2] = rdsDHigh;
  350.           }  
  351.           else {
  352.             len = addressRT * 4 + 2;
  353.             cr = 1;
  354.           }
  355.           if (rdsDLow != 0x0D) {
  356.             rdsRadioText[addressRT * 4 + 3] = rdsDLow;
  357.           }
  358.           else {
  359.             len = addressRT * 4 + 3;
  360.             cr = 1;
  361.           }
  362.         }
  363.       }
  364.     }
  365.     else if (errD <= 1) {
  366.       if (addressRT >= 0 && addressRT <= 7) {
  367.         if (rdsDHigh != '\0') {
  368.           rdsRadioText[addressRT * 2] = rdsDHigh;
  369.         }  
  370.         if (rdsDLow != '\0') {
  371.           rdsRadioText[addressRT * 2 + 1] = rdsDLow;
  372.         }
  373.       }
  374.     }
  375.     if (cr) {
  376.       for (uint8_t i = len; i < 64; i++) {
  377.         rdsRadioText[i] = ' ';
  378.       }
  379.     }
  380.     if (ab != rdsAb) {      
  381.       for (uint8_t i = 0; i < 64; i++) {
  382.         rdsRadioText[i] = ' ';
  383.       }
  384.       rdsRadioText[64] = '\0';    
  385.       isRdsNewRadioText = 1;
  386.     }
  387.     else {
  388.       isRdsNewRadioText = 0;
  389.     }
  390.     rdsAb = ab;
  391.     rdsFormatString(rdsRadioText, 64);
  392.   }
  393.   return true;
  394. }
  395.  
  396. void TEF6686::getRDS(RdsInfo* rdsInfo) {
  397.   strcpy(rdsInfo->programType, rdsProgramType);
  398.   strcpy(rdsInfo->programId, rdsProgramId);
  399.   strcpy(rdsInfo->programService, rdsProgramService);
  400.   strcpy(rdsInfo->programServiceUnsafe, rdsProgramServiceUnsafe);
  401.   strcpy(rdsInfo->radioText, rdsRadioText);
  402. }
  403.  
  404. void TEF6686::clearRDS() {
  405.   strcpy(rdsProgramType, "No PTY");
  406.   strcpy(rdsProgramId, "0000");
  407.   strcpy(rdsProgramService, "        ");
  408.   strcpy(rdsProgramServiceUnsafe, "        ");
  409.   strcpy(rdsRadioText, "No RT");
  410.   psErrors = 0xFFFFFFFF;
  411.   psCharIsSet = 0;
  412. }
  413.  
  414. void TEF6686::rdsFormatString(char* str, uint16_t length) {  
  415.   for (uint16_t i = 0; i < length; i++) {    
  416.     if ((str[i] != 0 && str[i] < 32) || str[i] > 126 ) {
  417.       str[i] = ' ';  
  418.     }
  419.   }
  420. }
  421.  
  422. uint16_t TEF6686::seek(uint8_t up) {
  423.   uint16_t mode = 20;
  424.   uint16_t startFrequency = Radio_GetCurrentFreq();
  425.  
  426.   while (true) {
  427.     switch(mode){
  428.       case 20:
  429.         Radio_ChangeFreqOneStep(up);
  430.         Radio_SetFreq(Radio_SEARCHMODE, Radio_GetCurrentBand(), Radio_GetCurrentFreq());
  431.      
  432.         mode = 30;
  433.         Radio_CheckStationInit();
  434.         Radio_ClearCurrentStation();
  435.        
  436.         break;
  437.      
  438.       case 30:
  439.         delay(20);
  440.         Radio_CheckStation();
  441.         if (Radio_CheckStationStatus() >= NO_STATION) {
  442.           mode = 40;
  443.         }  
  444.        
  445.         break;
  446.  
  447.       case 40:
  448.         if (Radio_CheckStationStatus() == NO_STATION) {        
  449.           mode = (startFrequency == Radio_GetCurrentFreq()) ? 50 : 20;
  450.         }
  451.         else if (Radio_CheckStationStatus() == PRESENT_STATION) {
  452.           mode = 50;
  453.         }
  454.        
  455.         break;
  456.      
  457.       case 50:
  458.         Radio_SetFreq(Radio_PRESETMODE, Radio_GetCurrentBand(), Radio_GetCurrentFreq());
  459.         return Radio_GetCurrentFreq();
  460.     }
  461.   }
  462.   return 0;
  463. }
  464.  
  465. uint16_t TEF6686::tune(uint8_t up) {
  466.   Radio_ChangeFreqOneStep(up);
  467.  
  468.   Radio_SetFreq(Radio_PRESETMODE, Radio_GetCurrentBand(), Radio_GetCurrentFreq());
  469.   Radio_ClearCurrentStation();
  470.   return Radio_GetCurrentFreq();
  471. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×