Advertisement
Guest User

TEF6686.cpp

a guest
Dec 27th, 2019
303
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.21 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement