On Tuesday 02 of September 2008, Goga777 wrote:
> Hi
>
> could you download please this gotoxx-patches for vdr 160 & vdr 170
> somewhere As far as I understand no need to insatll rotor-plugin with these
> patches foe gotoxx/usals thanks
>
> Goga

HI,

ok, I hope that Seppo will not be very disappointed ;) .

Attached diffs are against plain versions of vdr.

So, the goal of this patch is possible to read at 
http://www.linuxtv.org/pipermail/vdr/2008-March/016164.html.

The diseqc.conf should be like Seppo wrote in his file 
http://www.linuxtv.org/pipermail/vdr/attachments/20080315/ae33847e/attachment-0001.txt.


I'm using it with diseqc switch (EMP S164) and diseqc motor (Stab HH 120). 
Motor is at 4th position of the switch. Two weeks ago when I've had the TT 
S2-3200 this combination was very unreliable (so sometime I had no feel to 
which position my motor is pointing). Now, with HVR-4000 I have no problems. 
Maybe new version of Igor Liplianin's multiproto will work also with TT 
S2-3200 but I didn't test it.

I'm using for 4th input of the switch and my diseqc.conf entries are like 
this:

S0.8W     11700 V  9750  t v W15 [E0 10 38 FC] W150 G v t
S0.8W     99999 V 10600  t v W15 [E0 10 38 FD] W150 G v T
S0.8W     11700 H  9750  t V W15 [E0 10 38 FE] W150 G V t
S0.8W     99999 H 10600  t V W15 [E0 10 38 FF] W150 G V T

S4.0W     11700 V  9750  t v W15 [E0 10 38 FC] W150 G v t
S4.0W     99999 V 10600  t v W15 [E0 10 38 FD] W150 G v T
S4.0W     11700 H  9750  t V W15 [E0 10 38 FE] W150 G V t
S4.0W     99999 H 10600  t V W15 [E0 10 38 FF] W150 G V T

for all positions to which I want to move the dish.

BR,

Ales


diff -ruNp vdr-1.6.0.orig/config.c vdr-1.6.0/config.c
--- vdr-1.6.0.orig/config.c	2008-02-17 14:39:00.000000000 +0100
+++ vdr-1.6.0/config.c	2008-03-24 18:39:14.032327377 +0100
@@ -229,6 +229,11 @@ cSetup::cSetup(void)
   LnbFrequLo =  9750;
   LnbFrequHi = 10600;
   DiSEqC = 0;
+  UseGotox = 0;
+  GotoxSpeed = 100;
+  GotoxRepeat = 0;
+  GotoxSN = 0; GotoxLat = 613; GotoxEW = 1; GotoxLong = 236; // Somewhere at Tampere, Finland :^)
+  GotoxPrevSource = 0;
   SetSystemTime = 0;
   TimeSource = 0;
   TimeTransponder = 0;
@@ -402,6 +407,14 @@ bool cSetup::Parse(const char *Name, con
   else if (!strcasecmp(Name, "LnbFrequLo"))          LnbFrequLo         = atoi(Value);
   else if (!strcasecmp(Name, "LnbFrequHi"))          LnbFrequHi         = atoi(Value);
   else if (!strcasecmp(Name, "DiSEqC"))              DiSEqC             = atoi(Value);
+  else if (!strcasecmp(Name, "UseGotox"))            UseGotox           = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxSpeed"))          GotoxSpeed         = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxRepeat"))         GotoxRepeat        = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxSN"))             GotoxSN            = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxLat"))            GotoxLat           = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxEW"))             GotoxEW            = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxLong"))           GotoxLong          = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxPrevSource"))     GotoxPrevSource    = atoi(Value);
   else if (!strcasecmp(Name, "SetSystemTime"))       SetSystemTime      = atoi(Value);
   else if (!strcasecmp(Name, "TimeSource"))          TimeSource         = cSource::FromString(Value);
   else if (!strcasecmp(Name, "TimeTransponder"))     TimeTransponder    = atoi(Value);
@@ -485,6 +498,14 @@ bool cSetup::Save(void)
   Store("LnbFrequLo",         LnbFrequLo);
   Store("LnbFrequHi",         LnbFrequHi);
   Store("DiSEqC",             DiSEqC);
+  Store("UseGotox",           UseGotox);
+  Store("GotoxSpeed",         GotoxSpeed);
+  Store("GotoxRepeat",        GotoxRepeat);
+  Store("GotoxSN",            GotoxSN);
+  Store("GotoxLat",           GotoxLat);
+  Store("GotoxEW",            GotoxEW);
+  Store("GotoxLong",          GotoxLong);
+  Store("GotoxPrevSource",    GotoxPrevSource);
   Store("SetSystemTime",      SetSystemTime);
   Store("TimeSource",         cSource::ToString(TimeSource));
   Store("TimeTransponder",    TimeTransponder);
diff -ruNp vdr-1.6.0.orig/config.h vdr-1.6.0/config.h
--- vdr-1.6.0.orig/config.h	2008-03-23 11:26:10.000000000 +0100
+++ vdr-1.6.0/config.h	2008-03-24 18:39:14.020326693 +0100
@@ -215,6 +215,14 @@ public:
   int LnbFrequLo;
   int LnbFrequHi;
   int DiSEqC;
+  int GotoxRepeat;
+  int GotoxSN;
+  int GotoxEW;
+  int GotoxSpeed;
+  int GotoxLat;
+  int GotoxLong;
+  int UseGotox;
+  int GotoxPrevSource;
   int SetSystemTime;
   int TimeSource;
   int TimeTransponder;
diff -ruNp vdr-1.6.0.orig/diseqc.c vdr-1.6.0/diseqc.c
--- vdr-1.6.0.orig/diseqc.c	2008-02-10 15:09:27.000000000 +0100
+++ vdr-1.6.0/diseqc.c	2008-03-24 18:39:14.068329428 +0100
@@ -114,6 +114,7 @@ cDiseqc::eDiseqcActions cDiseqc::Execute
           case 'V': return daVoltage18;
           case 'A': return daMiniA;
           case 'B': return daMiniB;
+	  case 'G': return daGotoX;
           case 'W': *CurrentAction = Wait(*CurrentAction); break;
           case '[': *CurrentAction = Codes(*CurrentAction); return *CurrentAction ? daCodes : daNone;
           default: return daNone;
diff -ruNp vdr-1.6.0.orig/diseqc.h vdr-1.6.0/diseqc.h
--- vdr-1.6.0.orig/diseqc.h	2002-12-07 14:54:02.000000000 +0100
+++ vdr-1.6.0/diseqc.h	2008-03-24 18:39:14.076329884 +0100
@@ -22,6 +22,7 @@ public:
     daVoltage18,
     daMiniA,
     daMiniB,
+    daGotoX,
     daCodes,
     };
   enum { MaxDiseqcCodes = 6 };
diff -ruNp vdr-1.6.0.orig/dvbdevice.c vdr-1.6.0/dvbdevice.c
--- vdr-1.6.0.orig/dvbdevice.c	2008-02-09 17:11:44.000000000 +0100
+++ vdr-1.6.0/dvbdevice.c	2008-03-24 18:44:46.007245549 +0100
@@ -17,6 +17,7 @@
 #include <linux/dvb/video.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
+#include <math.h>
 #include "channels.h"
 #include "diseqc.h"
 #include "dvbci.h"
@@ -171,6 +172,87 @@ static unsigned int FrequencyToHz(unsign
   return f;
 }
 
+void HandleGotox(int fd_frontend, int new_source)
+{
+  
+  int gotoXTable[10] = { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E };
+  int satlong;
+  int satprev;
+  float waitseconds = 0;
+
+  if (Setup.UseGotox == 0)
+    return;
+
+  // Check if zapped into new source position?
+  if (new_source != Setup.GotoxPrevSource) {
+    satlong = (new_source & ~0xC800);
+    satprev = (Setup.GotoxPrevSource & ~0xC800);
+    if ((new_source & 0xC000) != 0x8000) 
+      return; // Fail
+    if (new_source & 0x0800)
+      satlong = satlong * (-1);
+    if (Setup.GotoxPrevSource & 0x0800)
+      satprev = satprev * (-1);
+    if (Setup.GotoxSpeed > 0) {
+      waitseconds = fabs(satlong-satprev)/(float)(Setup.GotoxSpeed);
+      if (waitseconds < 0.0) waitseconds = 0.0; // Should not happen but ...
+      if (waitseconds > 60.0) waitseconds = 60.0; // Limit wait time to 60s
+    }
+    int Long=Setup.GotoxEW ? -Setup.GotoxLong : Setup.GotoxLong;
+    int Lat=Setup.GotoxSN ? -Setup.GotoxLat : Setup.GotoxLat;
+    double azimuth=M_PI+atan(tan((satlong-Long)*M_PI/1800)/sin(Lat*M_PI/1800));
+    double x=acos(cos((satlong-Long)*M_PI/1800)*cos(Lat*M_PI/1800));
+    double elevation=atan((cos(x)-0.1513)/sin(x));
+    double SatHourangle=180+atan((-cos(elevation)*sin(azimuth))/(sin(elevation)*cos(Lat*M_PI/1800)
+			   -cos(elevation)*sin(Lat*M_PI/1800)*cos(azimuth)))*180/M_PI;
+    int tmp=(int)(fabs(180-SatHourangle)*10);
+    tmp=(tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
+    int p2=(tmp%0x0100);
+    int p1=(tmp/0x0100);
+    if (SatHourangle < 180)
+      p1 |= 0xe0;
+    else
+      p1 |= 0xd0;
+
+    dsyslog("DiSEqC GotoX %d (%d) -> %d (%d), wait time %4.1fs",
+	    satprev, Setup.GotoxPrevSource, satlong, new_source, waitseconds);
+
+#if 1
+    // Set high LNB voltage and tone off, then wait > 15ms
+    CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18));
+    CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF));
+    usleep(20000);
+    
+    // Send 1st GotoX command, then wait > 15ms
+    uchar gotox_bytes[5] = { 0xe0, 0x31, 0x6e, p1, p2};
+    struct dvb_diseqc_master_cmd gotox_cmd;
+    memcpy(gotox_cmd.msg, gotox_bytes, 5);
+    gotox_cmd.msg_len = 5;
+    CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &gotox_cmd));
+    usleep(20000);
+
+    // Send repeated GotoX command, then wait > 15ms
+    if (Setup.GotoxRepeat) {
+      gotox_bytes[0] = 0xe1;
+      memcpy(gotox_cmd.msg, gotox_bytes, 5);
+      CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &gotox_cmd));
+      usleep(20000);
+    }
+    
+    // Wait for dish movement
+    while (waitseconds > 0.0) {
+      usleep(100000); // 100ms
+      waitseconds = waitseconds - 100e-3;
+    }
+
+#endif
+
+    Setup.GotoxPrevSource = new_source;
+    dsyslog("DiSEqC GotoX done.");
+  }
+}
+
+
 bool cDvbTuner::SetFrontend(void)
 {
   dvb_frontend_parameters Frontend;
@@ -196,6 +278,7 @@ bool cDvbTuner::SetFrontend(void)
                         case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
                         case cDiseqc::daMiniA:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
                         case cDiseqc::daMiniB:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
+                        case cDiseqc::daGotoX:     HandleGotox(fd_frontend, channel.Source()); break;
                         case cDiseqc::daCodes: {
                              int n = 0;
                              uchar *codes = diseqc->Codes(n);
@@ -219,8 +302,11 @@ bool cDvbTuner::SetFrontend(void)
                }
             }
          else {
-            int tone = SEC_TONE_OFF;
+            // Send GotoX DiSEqC command if activated in vdr setup. Then wait with high LNB voltage
+            // estimated time for dish movement
+            HandleGotox(fd_frontend, channel.Source()); 
 
+            int tone = SEC_TONE_OFF;
             if (frequency < (unsigned int)Setup.LnbSLOF) {
                frequency -= Setup.LnbFrequLo;
                tone = SEC_TONE_OFF;
@@ -855,7 +941,7 @@ bool cDvbDevice::SetChannelDevice(const 
         }
      if (IsPrimaryDevice())
         AddPid(Channel->Tpid(), ptTeletext);
-     CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, true)); // actually one would expect 'false' here, but according to Marco Schl��ler <[EMAIL PROTECTED]> this works
+     CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, true)); // actually one would expect 'false' here, but according to Marco Schl��ler <[EMAIL PROTECTED]> this works
                                                    // to avoid missing audio after replaying a DVD; with 'false' there is an audio disturbance when switching
                                                    // between two channels on the same transponder on DVB-S
      CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
diff -ruNp vdr-1.6.0.orig/menu.c vdr-1.6.0/menu.c
--- vdr-1.6.0.orig/menu.c	2008-03-16 12:15:28.000000000 +0100
+++ vdr-1.6.0/menu.c	2008-03-24 18:39:14.040327833 +0100
@@ -2602,8 +2602,14 @@ void cMenuSetupLNB::Setup(void)
      Add(new cMenuEditIntItem( tr("Setup.LNB$SLOF (MHz)"),               &data.LnbSLOF));
      Add(new cMenuEditIntItem( tr("Setup.LNB$Low LNB frequency (MHz)"),  &data.LnbFrequLo));
      Add(new cMenuEditIntItem( tr("Setup.LNB$High LNB frequency (MHz)"), &data.LnbFrequHi));
-     }
-
+  }
+  Add(new cMenuEditBoolItem(tr("Setup.LNB$Use GotoX dish positioning"), &data.UseGotox));
+  if (data.UseGotox) {
+     Add(new cMenuEditBoolItem(tr("Setup.LNB$Repeat GotoX commands"), &data.GotoxRepeat));
+     Add(new cMenuEditIntpItem(tr("Setup.LNB$Latitude"), &data.GotoxLat,0,900,&data.GotoxSN,tr("North"),tr("South")));
+     Add(new cMenuEditIntpItem(tr("Setup.LNB$Longitude"), &data.GotoxLong,0,1800,&data.GotoxEW,tr("West"),tr("East")));
+     Add(new cMenuEditIntdItem(tr("Setup.LNB$Rotor speed (deg/s)"), &data.GotoxSpeed, 1, 100));
+  }
   SetCurrent(Get(current));
   Display();
 }
@@ -2611,10 +2617,15 @@ void cMenuSetupLNB::Setup(void)
 eOSState cMenuSetupLNB::ProcessKey(eKeys Key)
 {
   int oldDiSEqC = data.DiSEqC;
+  int oldUseGotox = data.UseGotox;
   eOSState state = cMenuSetupBase::ProcessKey(Key);
 
   if (Key != kNone && data.DiSEqC != oldDiSEqC)
      Setup();
+
+  if (Key != kNone && data.UseGotox != oldUseGotox)
+     Setup();
+
   return state;
 }
 
diff -ruNp vdr-1.6.0.orig/menuitems.c vdr-1.6.0/menuitems.c
--- vdr-1.6.0.orig/menuitems.c	2008-02-10 17:03:30.000000000 +0100
+++ vdr-1.6.0/menuitems.c	2008-03-24 18:39:14.040327833 +0100
@@ -981,3 +981,121 @@ void cMenuSetupPage::SetupStore(const ch
   if (plugin)
      plugin->SetupStore(Name, Value);
 }
+
+// cMenuEditIntpItem & cMenuEditIntdItem for GotoX function
+
+void cMenuEditIntpItem::Set(void)
+{
+  char buf[16];
+  snprintf(buf, sizeof(buf), "%d.%d %s", *value/10, *value % 10, *value2 ? trueString : falseString);
+  SetValue(buf);
+}
+
+void cMenuEditIntdItem::Set(void)
+{
+  char buf[16];
+  snprintf(buf, sizeof(buf), "%d.%d", *value/10, *value % 10);
+  SetValue(buf);
+}
+
+
+cMenuEditIntpItem::cMenuEditIntpItem(const char *Name, int *Value, int Min, int Max,int *Value2, const char *FalseString,const char *TrueString):cMenuEditIntItem(Name, Value, Min, Max)
+{
+  value = Value;
+  value2= Value2;
+  trueString = TrueString;
+  falseString = FalseString;
+  min = Min;
+  max = Max;
+  Set();
+}
+
+cMenuEditIntdItem::cMenuEditIntdItem(const char *Name, int *Value, int Min, int Max):cMenuEditIntItem(Name, Value, Min, Max)
+{
+  value = Value;
+  min = Min;
+  max = Max;
+  Set();
+}
+
+eOSState cMenuEditIntpItem::ProcessKey(eKeys Key)
+{
+  eOSState state = cMenuEditItem::ProcessKey(Key);
+  if (state == osUnknown)
+  {
+    int newValue = *value;
+    int newValue2= *value2;
+    Key = NORMALKEY(Key);
+    switch (Key) {
+      case kNone  : break;
+      case k0...k9:
+                    if (fresh)
+                    {
+                      *value = 0;
+                      fresh = false;
+                    }
+                    newValue = *value * 10 + (Key - k0);
+                    break;
+      case kLeft  :
+                    newValue2 = 0;
+                    fresh = true;
+                    break;
+      case kRight :
+                    newValue2 = 1;
+                    fresh = true;
+                    break;
+      default     :
+                    if (*value < min) { *value = min; Set(); }
+                    if (*value > max) { *value = max; Set(); }
+                    return state;
+                 }
+    if ((!fresh || min <= newValue) && newValue <= max)
+    {
+      *value = newValue;
+      *value2 = newValue2;
+      Set();
+    }
+ state = osContinue;
+  }
+  return state;
+}
+
+eOSState cMenuEditIntdItem::ProcessKey(eKeys Key)
+{
+  eOSState state = cMenuEditItem::ProcessKey(Key);
+  if (state == osUnknown)
+  {
+    int newValue = *value;
+    Key = NORMALKEY(Key);
+    switch (Key) {
+      case kNone  : break;
+      case k0...k9:
+                    if (fresh)
+                    {
+                      *value = 0;
+                      fresh = false;
+                    }
+                    newValue = *value * 10 + (Key - k0);
+                    break;
+      case kLeft  :
+	            newValue = *value - 1;
+                    fresh = true;
+                    break;
+      case kRight :
+                    newValue = *value + 1;
+                    fresh = true;
+                    break;
+      default     :
+                    if (*value < min) { *value = min; Set(); }
+                    if (*value > max) { *value = max; Set(); }
+                    return state;
+                 }
+    if ((!fresh || min <= newValue) && newValue <= max)
+    {
+      *value = newValue;
+      Set();
+    }
+    state = osContinue;
+  }
+  return state;
+}
diff -ruNp vdr-1.6.0.orig/menuitems.h vdr-1.6.0/menuitems.h
--- vdr-1.6.0.orig/menuitems.h	2008-02-16 17:09:58.000000000 +0100
+++ vdr-1.6.0/menuitems.h	2008-03-24 18:39:14.040327833 +0100
@@ -176,4 +176,22 @@ public:
   void SetPlugin(cPlugin *Plugin);
   };
 
+class cMenuEditIntpItem : public cMenuEditIntItem {
+protected:
+  virtual void Set(void);
+  const char *falseString, *trueString;
+  int *value2;
+public:
+  cMenuEditIntpItem(const char *Name, int *Value, int Min = 0, int Max = INT_MAX, int *Value2=0, const char *FalseString = "", const char *TrueSting = NULL);
+  virtual eOSState ProcessKey(eKeys Key);
+};
+
+class cMenuEditIntdItem : public cMenuEditIntItem {
+protected:
+  virtual void Set(void);
+public:
+  cMenuEditIntdItem(const char *Name, int *Value, int Min = 0, int Max = INT_MAX);
+  virtual eOSState ProcessKey(eKeys Key);
+};
+
 #endif //__MENUITEMS_H
diff -ruNp vdr-1.7.0.orig/config.c vdr-1.7.0/config.c
--- vdr-1.7.0.orig/config.c	2008-02-17 14:39:00.000000000 +0100
+++ vdr-1.7.0/config.c	2008-09-02 11:08:39.633819400 +0200
@@ -229,6 +229,11 @@ cSetup::cSetup(void)
   LnbFrequLo =  9750;
   LnbFrequHi = 10600;
   DiSEqC = 0;
+  UseGotox = 0;
+  GotoxSpeed = 100;
+  GotoxRepeat = 0;
+  GotoxSN = 0; GotoxLat = 613; GotoxEW = 1; GotoxLong = 236; // Somewhere at Tampere, Finland :^)
+  GotoxPrevSource = 0;
   SetSystemTime = 0;
   TimeSource = 0;
   TimeTransponder = 0;
@@ -402,6 +407,14 @@ bool cSetup::Parse(const char *Name, con
   else if (!strcasecmp(Name, "LnbFrequLo"))          LnbFrequLo         = atoi(Value);
   else if (!strcasecmp(Name, "LnbFrequHi"))          LnbFrequHi         = atoi(Value);
   else if (!strcasecmp(Name, "DiSEqC"))              DiSEqC             = atoi(Value);
+  else if (!strcasecmp(Name, "UseGotox"))            UseGotox           = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxSpeed"))          GotoxSpeed         = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxRepeat"))         GotoxRepeat        = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxSN"))             GotoxSN            = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxLat"))            GotoxLat           = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxEW"))             GotoxEW            = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxLong"))           GotoxLong          = atoi(Value);
+  else if (!strcasecmp(Name, "GotoxPrevSource"))     GotoxPrevSource    = atoi(Value);
   else if (!strcasecmp(Name, "SetSystemTime"))       SetSystemTime      = atoi(Value);
   else if (!strcasecmp(Name, "TimeSource"))          TimeSource         = cSource::FromString(Value);
   else if (!strcasecmp(Name, "TimeTransponder"))     TimeTransponder    = atoi(Value);
@@ -485,6 +498,14 @@ bool cSetup::Save(void)
   Store("LnbFrequLo",         LnbFrequLo);
   Store("LnbFrequHi",         LnbFrequHi);
   Store("DiSEqC",             DiSEqC);
+  Store("UseGotox",           UseGotox);
+  Store("GotoxSpeed",         GotoxSpeed);
+  Store("GotoxRepeat",        GotoxRepeat);
+  Store("GotoxSN",            GotoxSN);
+  Store("GotoxLat",           GotoxLat);
+  Store("GotoxEW",            GotoxEW);
+  Store("GotoxLong",          GotoxLong);
+  Store("GotoxPrevSource",    GotoxPrevSource);
   Store("SetSystemTime",      SetSystemTime);
   Store("TimeSource",         cSource::ToString(TimeSource));
   Store("TimeTransponder",    TimeTransponder);
diff -ruNp vdr-1.7.0.orig/config.h vdr-1.7.0/config.h
--- vdr-1.7.0.orig/config.h	2008-04-12 15:02:10.000000000 +0200
+++ vdr-1.7.0/config.h	2008-09-02 11:08:39.633819400 +0200
@@ -215,6 +215,14 @@ public:
   int LnbFrequLo;
   int LnbFrequHi;
   int DiSEqC;
+  int GotoxRepeat;
+  int GotoxSN;
+  int GotoxEW;
+  int GotoxSpeed;
+  int GotoxLat;
+  int GotoxLong;
+  int UseGotox;
+  int GotoxPrevSource;
   int SetSystemTime;
   int TimeSource;
   int TimeTransponder;
diff -ruNp vdr-1.7.0.orig/diseqc.c vdr-1.7.0/diseqc.c
--- vdr-1.7.0.orig/diseqc.c	2008-02-10 15:09:27.000000000 +0100
+++ vdr-1.7.0/diseqc.c	2008-09-02 11:08:39.633819400 +0200
@@ -114,6 +114,7 @@ cDiseqc::eDiseqcActions cDiseqc::Execute
           case 'V': return daVoltage18;
           case 'A': return daMiniA;
           case 'B': return daMiniB;
+	  case 'G': return daGotoX;
           case 'W': *CurrentAction = Wait(*CurrentAction); break;
           case '[': *CurrentAction = Codes(*CurrentAction); return *CurrentAction ? daCodes : daNone;
           default: return daNone;
diff -ruNp vdr-1.7.0.orig/diseqc.h vdr-1.7.0/diseqc.h
--- vdr-1.7.0.orig/diseqc.h	2002-12-07 14:54:02.000000000 +0100
+++ vdr-1.7.0/diseqc.h	2008-09-02 11:08:39.637817080 +0200
@@ -22,6 +22,7 @@ public:
     daVoltage18,
     daMiniA,
     daMiniB,
+    daGotoX,
     daCodes,
     };
   enum { MaxDiseqcCodes = 6 };
diff -ruNp vdr-1.7.0.orig/dvbdevice.c vdr-1.7.0/dvbdevice.c
--- vdr-1.7.0.orig/dvbdevice.c	2008-04-13 16:15:35.000000000 +0200
+++ vdr-1.7.0/dvbdevice.c	2008-09-02 11:14:19.000000000 +0200
@@ -17,6 +17,7 @@
 #include <linux/dvb/video.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
+#include <math.h>
 #include "channels.h"
 #include "diseqc.h"
 #include "dvbci.h"
@@ -190,6 +191,87 @@ static unsigned int FrequencyToHz(unsign
   return f;
 }
 
+void HandleGotox(int fd_frontend, int new_source)
+{
+  
+  int gotoXTable[10] = { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E };
+  int satlong;
+  int satprev;
+  float waitseconds = 0;
+
+  if (Setup.UseGotox == 0)
+    return;
+
+  // Check if zapped into new source position?
+  if (new_source != Setup.GotoxPrevSource) {
+    satlong = (new_source & ~0xC800);
+    satprev = (Setup.GotoxPrevSource & ~0xC800);
+    if ((new_source & 0xC000) != 0x8000) 
+      return; // Fail
+    if (new_source & 0x0800)
+      satlong = satlong * (-1);
+    if (Setup.GotoxPrevSource & 0x0800)
+      satprev = satprev * (-1);
+    if (Setup.GotoxSpeed > 0) {
+      waitseconds = fabs(satlong-satprev)/(float)(Setup.GotoxSpeed);
+      if (waitseconds < 0.0) waitseconds = 0.0; // Should not happen but ...
+      if (waitseconds > 60.0) waitseconds = 60.0; // Limit wait time to 60s
+    }
+    int Long=Setup.GotoxEW ? -Setup.GotoxLong : Setup.GotoxLong;
+    int Lat=Setup.GotoxSN ? -Setup.GotoxLat : Setup.GotoxLat;
+    double azimuth=M_PI+atan(tan((satlong-Long)*M_PI/1800)/sin(Lat*M_PI/1800));
+    double x=acos(cos((satlong-Long)*M_PI/1800)*cos(Lat*M_PI/1800));
+    double elevation=atan((cos(x)-0.1513)/sin(x));
+    double SatHourangle=180+atan((-cos(elevation)*sin(azimuth))/(sin(elevation)*cos(Lat*M_PI/1800)
+			   -cos(elevation)*sin(Lat*M_PI/1800)*cos(azimuth)))*180/M_PI;
+    int tmp=(int)(fabs(180-SatHourangle)*10);
+    tmp=(tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
+    int p2=(tmp%0x0100);
+    int p1=(tmp/0x0100);
+    if (SatHourangle < 180)
+      p1 |= 0xe0;
+    else
+      p1 |= 0xd0;
+
+    dsyslog("DiSEqC GotoX %d (%d) -> %d (%d), wait time %4.1fs",
+	    satprev, Setup.GotoxPrevSource, satlong, new_source, waitseconds);
+
+#if 1
+    // Set high LNB voltage and tone off, then wait > 15ms
+    CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18));
+    CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF));
+    usleep(20000);
+    
+    // Send 1st GotoX command, then wait > 15ms
+    uchar gotox_bytes[5] = { 0xe0, 0x31, 0x6e, p1, p2};
+    struct dvb_diseqc_master_cmd gotox_cmd;
+    memcpy(gotox_cmd.msg, gotox_bytes, 5);
+    gotox_cmd.msg_len = 5;
+    CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &gotox_cmd));
+    usleep(20000);
+
+    // Send repeated GotoX command, then wait > 15ms
+    if (Setup.GotoxRepeat) {
+      gotox_bytes[0] = 0xe1;
+      memcpy(gotox_cmd.msg, gotox_bytes, 5);
+      CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &gotox_cmd));
+      usleep(20000);
+    }
+    
+    // Wait for dish movement
+    while (waitseconds > 0.0) {
+      usleep(100000); // 100ms
+      waitseconds = waitseconds - 100e-3;
+    }
+
+#endif
+
+    Setup.GotoxPrevSource = new_source;
+    dsyslog("DiSEqC GotoX done.");
+  }
+}
+
+
 bool cDvbTuner::SetFrontend(void)
 {
   dvbfe_params Frontend;
@@ -211,6 +293,7 @@ bool cDvbTuner::SetFrontend(void)
                     case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
                     case cDiseqc::daMiniA:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
                     case cDiseqc::daMiniB:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
+                    case cDiseqc::daGotoX:     HandleGotox(fd_frontend, channel.Source()); break;
                     case cDiseqc::daCodes: {
                          int n = 0;
                          uchar *codes = diseqc->Codes(n);
@@ -234,6 +317,10 @@ bool cDvbTuner::SetFrontend(void)
            }
         }
      else {
+         // Send GotoX DiSEqC command if activated in vdr setup. Then wait with high LNB voltage
+         // estimated time for dish movement
+        HandleGotox(fd_frontend, channel.Source()); 
+
         int tone = SEC_TONE_OFF;
         if (frequency < (unsigned int)Setup.LnbSLOF) {
            frequency -= Setup.LnbFrequLo;
@@ -922,7 +1009,7 @@ bool cDvbDevice::SetChannelDevice(const 
         }
      if (IsPrimaryDevice())
         AddPid(Channel->Tpid(), ptTeletext);
-     CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, true)); // actually one would expect 'false' here, but according to Marco Schller <[EMAIL PROTECTED]> this works
+     CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, true)); // actually one would expect 'false' here, but according to Marco Schl��ler <[EMAIL PROTECTED]> this works
                                                    // to avoid missing audio after replaying a DVD; with 'false' there is an audio disturbance when switching
                                                    // between two channels on the same transponder on DVB-S
      CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
diff -ruNp vdr-1.7.0.orig/menu.c vdr-1.7.0/menu.c
--- vdr-1.7.0.orig/menu.c	2008-04-12 13:37:17.000000000 +0200
+++ vdr-1.7.0/menu.c	2008-09-02 11:08:39.641804400 +0200
@@ -2542,8 +2542,14 @@ void cMenuSetupLNB::Setup(void)
      Add(new cMenuEditIntItem( tr("Setup.LNB$SLOF (MHz)"),               &data.LnbSLOF));
      Add(new cMenuEditIntItem( tr("Setup.LNB$Low LNB frequency (MHz)"),  &data.LnbFrequLo));
      Add(new cMenuEditIntItem( tr("Setup.LNB$High LNB frequency (MHz)"), &data.LnbFrequHi));
-     }
-
+  }
+  Add(new cMenuEditBoolItem(tr("Setup.LNB$Use GotoX dish positioning"), &data.UseGotox));
+  if (data.UseGotox) {
+     Add(new cMenuEditBoolItem(tr("Setup.LNB$Repeat GotoX commands"), &data.GotoxRepeat));
+     Add(new cMenuEditIntpItem(tr("Setup.LNB$Latitude"), &data.GotoxLat,0,900,&data.GotoxSN,tr("North"),tr("South")));
+     Add(new cMenuEditIntpItem(tr("Setup.LNB$Longitude"), &data.GotoxLong,0,1800,&data.GotoxEW,tr("West"),tr("East")));
+     Add(new cMenuEditIntdItem(tr("Setup.LNB$Rotor speed (deg/s)"), &data.GotoxSpeed, 1, 100));
+  }
   SetCurrent(Get(current));
   Display();
 }
@@ -2551,10 +2557,15 @@ void cMenuSetupLNB::Setup(void)
 eOSState cMenuSetupLNB::ProcessKey(eKeys Key)
 {
   int oldDiSEqC = data.DiSEqC;
+  int oldUseGotox = data.UseGotox;
   eOSState state = cMenuSetupBase::ProcessKey(Key);
 
   if (Key != kNone && data.DiSEqC != oldDiSEqC)
      Setup();
+
+  if (Key != kNone && data.UseGotox != oldUseGotox)
+     Setup();
+
   return state;
 }
 
diff -ruNp vdr-1.7.0.orig/menuitems.c vdr-1.7.0/menuitems.c
--- vdr-1.7.0.orig/menuitems.c	2008-04-12 14:05:25.000000000 +0200
+++ vdr-1.7.0/menuitems.c	2008-09-02 11:08:39.679752760 +0200
@@ -1039,3 +1039,121 @@ void cMenuSetupPage::SetupStore(const ch
   if (plugin)
      plugin->SetupStore(Name, Value);
 }
+
+// cMenuEditIntpItem & cMenuEditIntdItem for GotoX function
+
+void cMenuEditIntpItem::Set(void)
+{
+  char buf[16];
+  snprintf(buf, sizeof(buf), "%d.%d %s", *value/10, *value % 10, *value2 ? trueString : falseString);
+  SetValue(buf);
+}
+
+void cMenuEditIntdItem::Set(void)
+{
+  char buf[16];
+  snprintf(buf, sizeof(buf), "%d.%d", *value/10, *value % 10);
+  SetValue(buf);
+}
+
+
+cMenuEditIntpItem::cMenuEditIntpItem(const char *Name, int *Value, int Min, int Max,int *Value2, const char *FalseString,const char *TrueString):cMenuEditIntItem(Name, Value, Min, Max)
+{
+  value = Value;
+  value2= Value2;
+  trueString = TrueString;
+  falseString = FalseString;
+  min = Min;
+  max = Max;
+  Set();
+}
+
+cMenuEditIntdItem::cMenuEditIntdItem(const char *Name, int *Value, int Min, int Max):cMenuEditIntItem(Name, Value, Min, Max)
+{
+  value = Value;
+  min = Min;
+  max = Max;
+  Set();
+}
+
+eOSState cMenuEditIntpItem::ProcessKey(eKeys Key)
+{
+  eOSState state = cMenuEditItem::ProcessKey(Key);
+  if (state == osUnknown)
+  {
+    int newValue = *value;
+    int newValue2= *value2;
+    Key = NORMALKEY(Key);
+    switch (Key) {
+      case kNone  : break;
+      case k0...k9:
+                    if (fresh)
+                    {
+                      *value = 0;
+                      fresh = false;
+                    }
+                    newValue = *value * 10 + (Key - k0);
+                    break;
+      case kLeft  :
+                    newValue2 = 0;
+                    fresh = true;
+                    break;
+      case kRight :
+                    newValue2 = 1;
+                    fresh = true;
+                    break;
+      default     :
+                    if (*value < min) { *value = min; Set(); }
+                    if (*value > max) { *value = max; Set(); }
+                    return state;
+                 }
+    if ((!fresh || min <= newValue) && newValue <= max)
+    {
+      *value = newValue;
+      *value2 = newValue2;
+      Set();
+    }
+ state = osContinue;
+  }
+  return state;
+}
+
+eOSState cMenuEditIntdItem::ProcessKey(eKeys Key)
+{
+  eOSState state = cMenuEditItem::ProcessKey(Key);
+  if (state == osUnknown)
+  {
+    int newValue = *value;
+    Key = NORMALKEY(Key);
+    switch (Key) {
+      case kNone  : break;
+      case k0...k9:
+                    if (fresh)
+                    {
+                      *value = 0;
+                      fresh = false;
+                    }
+                    newValue = *value * 10 + (Key - k0);
+                    break;
+      case kLeft  :
+	            newValue = *value - 1;
+                    fresh = true;
+                    break;
+      case kRight :
+                    newValue = *value + 1;
+                    fresh = true;
+                    break;
+      default     :
+                    if (*value < min) { *value = min; Set(); }
+                    if (*value > max) { *value = max; Set(); }
+                    return state;
+                 }
+    if ((!fresh || min <= newValue) && newValue <= max)
+    {
+      *value = newValue;
+      Set();
+    }
+    state = osContinue;
+  }
+  return state;
+}
diff -ruNp vdr-1.7.0.orig/menuitems.h vdr-1.7.0/menuitems.h
--- vdr-1.7.0.orig/menuitems.h	2008-04-12 14:03:59.000000000 +0200
+++ vdr-1.7.0/menuitems.h	2008-09-02 11:08:39.679752760 +0200
@@ -187,4 +187,22 @@ public:
   void SetPlugin(cPlugin *Plugin);
   };
 
+class cMenuEditIntpItem : public cMenuEditIntItem {
+protected:
+  virtual void Set(void);
+  const char *falseString, *trueString;
+  int *value2;
+public:
+  cMenuEditIntpItem(const char *Name, int *Value, int Min = 0, int Max = INT_MAX, int *Value2=0, const char *FalseString = "", const char *TrueSting = NULL);
+  virtual eOSState ProcessKey(eKeys Key);
+};
+
+class cMenuEditIntdItem : public cMenuEditIntItem {
+protected:
+  virtual void Set(void);
+public:
+  cMenuEditIntdItem(const char *Name, int *Value, int Min = 0, int Max = INT_MAX);
+  virtual eOSState ProcessKey(eKeys Key);
+};
+
 #endif //__MENUITEMS_H
_______________________________________________
vdr mailing list
vdr@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr

Reply via email to