From: "Hans Werner" <HWerner4@gmx.de>
To: linux-dvb@linuxtv.org, alex.betis@gmail.com
Subject: [linux-dvb] [PATCH] scan-s2: fixes and diseqc rotor support
Date: Wed, 12 Nov 2008 03:31:12 +0100 [thread overview]
Message-ID: <20081112023112.94740@gmx.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 831 bytes --]
I have attached two patches for scan-s2 at http://mercurial.intuxication.org/hg/scan-s2.
Patch1: Some fixes for problems I found. QAM_AUTO is not supported by all drivers,
in particular the HVR-4000, so one needs to use QPSK as the default and ensure that
settings are parsed properly from the network information -- the new S2 FECs and
modulations were not handled.
Patch2: Add DiSEqC 1.2 rotor support. Use it like this to move the dish to the correct
position for the scan:
scan-s2 -r 19.2E -n dvb-s/Astra-19.2E
or
scan-s2 -R 2 -n dvb-s/Astra-19.2E
A file (rotor.conf) listing the rotor positions is used (NB: rotors vary -- do check your
rotor manual).
Regards,
Hans
--
Release early, release often.
Ist Ihr Browser Vista-kompatibel? Jetzt die neuesten
Browser-Versionen downloaden: http://www.gmx.net/de/go/browser
[-- Attachment #2: patch1_qpsk_default.diff --]
[-- Type: text/x-patch, Size: 2781 bytes --]
diff -r 40368fdba59a scan.c
--- a/scan.c
+++ b/scan.c
@@ -393,25 +397,32 @@ static void parse_s2_satellite_delivery_
static void parse_satellite_delivery_system_descriptor (const unsigned char *buf, struct transponder *t)
{
- static const fe_code_rate_t fec_tab [8] = {
- FEC_AUTO, FEC_1_2, FEC_2_3, FEC_3_4,
- FEC_5_6, FEC_7_8, FEC_NONE, FEC_NONE
- };
-
if (!t) {
warning("satellite_delivery_system_descriptor outside transport stream definition (ignored)\n");
return;
}
- if(((buf[8] >> 1) & 0x01) == 0) {
- t->delivery_system = SYS_DVBS;
- }
- else {
- t->delivery_system = SYS_DVBS2;
+ switch ( getBits(buf,69,1) ) {
+ case 0: t->delivery_system = SYS_DVBS; break;
+ case 1: t->delivery_system = SYS_DVBS2; break;
}
t->frequency = 10 * bcd32_to_cpu (buf[2], buf[3], buf[4], buf[5]);
- t->fec = fec_tab[buf[12] & 0x07];
+
+ switch ( getBits(buf,100,4) ) {
+ case 0 : t->fec = FEC_AUTO; break;
+ case 1 : t->fec = FEC_1_2; break;
+ case 2 : t->fec = FEC_2_3; break;
+ case 3 : t->fec = FEC_3_4; break;
+ case 4 : t->fec = FEC_5_6; break;
+ case 5 : t->fec = FEC_7_8; break;
+ case 6 : t->fec = FEC_8_9; break;
+ case 7 : t->fec = FEC_3_5; break;
+ case 8 : t->fec = FEC_4_5; break;
+ case 9 : t->fec = FEC_9_10; break;
+ case 15 : t->fec = FEC_NONE; break;
+ }
+
t->symbol_rate = 10 * bcd32_to_cpu (buf[9], buf[10], buf[11], buf[12] & 0xf0);
t->inversion = spectral_inversion;
@@ -419,6 +430,13 @@ static void parse_satellite_delivery_sys
t->polarisation = (buf[8] >> 5) & 0x03;
t->orbital_pos = bcd32_to_cpu (0x00, 0x00, buf[6], buf[7]);
t->we_flag = buf[8] >> 7;
+
+ switch ( getBits(buf,70,2) ) {
+ case 0 : t->modulation = QAM_AUTO; break;
+ case 1 : t->modulation = QPSK; break;
+ case 2 : t->modulation = PSK_8; break;
+ case 3 : t->modulation = QAM_16; break;
+ }
if (verbosity >= 5) {
debug("%#04x/%#04x ", t->network_id, t->transport_stream_id);
@@ -1858,7 +1892,7 @@ struct strtab qamtab[] = {
static enum fe_modulation str2qam(const char *qam)
{
- return str2enum(qam, qamtab, QAM_AUTO);
+ return str2enum(qam, qamtab, QPSK);
}
static const char* qam2str(enum fe_modulation qam)
@@ -1968,8 +2074,8 @@ static int tune_initial (int frontend_fd
else if (sscanf(buf, "S %u %1[HVLR] %u %4s %4s %6s\n", &f, pol, &sr, fec, rolloff, qam) >= 3) {
t = alloc_transponder(f);
t->delivery_system = SYS_DVBS;
- t->modulation = QAM_AUTO;
- t->rolloff = ROLLOFF_AUTO;
+ t->modulation = QPSK;
+ t->rolloff = ROLLOFF_35;
t->fec = FEC_AUTO;
switch(pol[0])
{
[-- Attachment #3: patch2_add_diseqc_rotor.diff --]
[-- Type: text/x-patch, Size: 8899 bytes --]
diff -r 40368fdba59a diseqc.c
--- a/diseqc.c
+++ b/diseqc.c
@@ -45,6 +45,77 @@ struct diseqc_cmd uncommitted_switch_cmd
};
/*--------------------------------------------------------------------------*/
+
+#define DISEQC_X 2
+int rotor_command( int frontend_fd, int cmd, int n1, int n2, int n3 )
+{
+ int err;
+ struct dvb_diseqc_master_cmd cmds[] = {
+ { { 0xe0, 0x31, 0x60, 0x00, 0x00, 0x00 }, 3 }, //0 Stop Positioner movement
+ { { 0xe0, 0x31, 0x63, 0x00, 0x00, 0x00 }, 3 }, //1 Disable Limits
+ { { 0xe0, 0x31, 0x66, 0x00, 0x00, 0x00 }, 3 }, //2 Set East Limit
+ { { 0xe0, 0x31, 0x67, 0x00, 0x00, 0x00 }, 3 }, //3 Set West Limit
+ { { 0xe0, 0x31, 0x68, 0x00, 0x00, 0x00 }, 4 }, //4 Drive Motor East continously
+ { { 0xe0, 0x31, 0x68,256-n1,0x00, 0x00 }, 4 }, //5 Drive Motor East nn steps
+ { { 0xe0, 0x31, 0x69,256-n1,0x00, 0x00 }, 4 }, //6 Drive Motor West nn steps
+ { { 0xe0, 0x31, 0x69, 0x00, 0x00, 0x00 }, 4 }, //7 Drive Motor West continously
+ { { 0xe0, 0x31, 0x6a, n1, 0x00, 0x00 }, 4 }, //8 Store nn
+ { { 0xe0, 0x31, 0x6b, n1, 0x00, 0x00 }, 4 }, //9 Goto nn
+ { { 0xe0, 0x31, 0x6f, n1, n2, n3 }, 4}, //10 Recalculate Position
+ { { 0xe0, 0x31, 0x6a, 0x00, 0x00, 0x00 }, 4 }, //11 Enable Limits
+ { { 0xe0, 0x31, 0x6e, n1, n2, 0x00 }, 5 }, //12 Gotoxx
+ { { 0xe0, 0x10, 0x38, 0xF4, 0x00, 0x00 }, 4 } //13 User
+ };
+
+ int i;
+ for ( i=0; i<DISEQC_X; ++i ) {
+ usleep(15*1000);
+ if ( err = ioctl( frontend_fd, FE_DISEQC_SEND_MASTER_CMD, &cmds[cmd] ) )
+ error("rotor_command: FE_DISEQC_SEND_MASTER_CMD failed, err=%i\n",err);
+ }
+ return err;
+}
+
+int rotate_rotor (int frontend_fd, int from_rotor_pos, int to_rotor_pos, int voltage_18){
+ /* Rotate a DiSEqC 1.2 rotor from position from_rotor_pos to position to_rotor_pos */
+ /* Uses Goto nn (command 9) */
+ float rotor_wait_time; //seconds
+ int err=0;
+
+ float speed_13V = 1.5; //degrees per second
+ float speed_18V = 2.4; //degrees per second
+ float degreesmoved,a1,a2;
+
+ if (to_rotor_pos != 0) {
+ if (from_rotor_pos != to_rotor_pos) {
+ info("Moving rotor from position %i to position %i\n",from_rotor_pos,to_rotor_pos);
+ if (from_rotor_pos == 0) {
+ rotor_wait_time = 15; // starting from unknown position
+ } else {
+ a1 = rotor_angle(to_rotor_pos);
+ a2 = rotor_angle(from_rotor_pos);
+ degreesmoved = abs(a1-a2);
+ if (degreesmoved>180) degreesmoved=360-degreesmoved;
+ rotor_wait_time = degreesmoved / (voltage_18 ? speed_18V : speed_13V);
+ }
+ err = rotor_command(frontend_fd, 9, to_rotor_pos, 0, 0);
+ if (err) {
+ info("Rotor move error!\n");
+ } else {
+ int i;
+ info("Rotating");
+ for (i=0; i<10; i++){
+ usleep(rotor_wait_time*100000);
+ info(".");
+ }
+ info("completed.\n");
+ }
+ } else {
+ info("Rotor already at position %i\n", from_rotor_pos);
+ }
+ }
+ return err;
+}
static inline void msleep(uint32_t msec)
{
diff -r 40368fdba59a diseqc.h
--- a/diseqc.h
+++ b/diseqc.h
@@ -17,6 +17,7 @@ extern int diseqc_send_msg (int fd, fe_s
* set up the switch to position/voltage/tone
*/
extern int setup_switch (int frontend_fd, int switch_pos, int voltage_18, int freq, int uncommitted_switch_pos);
+extern int rotate_rotor (int frontend_fd, int from_rotor_pos, int to_rotor_pos, int voltage_18);
#endif
diff -r 40368fdba59a scan.c
--- a/scan.c
+++ b/scan.c
@@ -84,10 +84,14 @@ static fe_spectral_inversion_t spectral_
static fe_spectral_inversion_t spectral_inversion = INVERSION_AUTO;
static int switch_pos = 0;
static int uncommitted_switch_pos = 0;
+static int rotor_pos = 0;
+static int curr_rotor_pos = 0;
+static char rotor_pos_name[16] = "";
static char override_orbital_pos[16] = "";
static enum format output_format = OUTPUT_VDR;
static int output_format_set = 0;
+static rotorslot_t rotor[49];
struct section_buf {
struct list_head list;
@@ -1569,6 +1587,22 @@ static int __tune_to_transponder (int fr
if (verbosity >= 2) {
dprintf(1,"DVB-S IF freq is %d\n", if_freq);
}
+
+
+ if (rotor_pos != 0 ) {
+ /* Rotate DiSEqC 1.2 rotor to correct orbital position */
+ if (t->orbital_pos!=0) rotor_pos = rotor_nn(t->orbital_pos, t->we_flag);
+ int err;
+ err = rotate_rotor( frontend_fd,
+ curr_rotor_pos,
+ rotor_pos,
+ t->polarisation == POLARISATION_VERTICAL ? 0 : 1);
+ if (err)
+ error("Error in rotate_rotor err=%i\n",err);
+ else
+ curr_rotor_pos = rotor_pos;
+ }
+
break;
case SYS_DVBT:
@@ -1939,6 +1973,78 @@ static const char* hier2str(enum fe_hier
return enum2str(hier, hiertab, "???");
}
+static int read_rotor_conf(const char *rotor_conf)
+{
+ FILE *rotor_conf_fd;
+ unsigned int nn;
+ char buf[200], angle_we[20], angle[20], we[2];
+ int i = -1;
+ rotor_conf_fd = fopen (rotor_conf, "r");
+ if (!rotor_conf_fd){
+ error("Cannot open rotor configuration file '%s'.");
+ return errno;
+ }
+ while (fgets(buf, sizeof(buf), rotor_conf_fd)) {
+ if (buf[0] != '#' && buf[0] != '\n') {
+ if (sscanf(buf, "%u %s\n", &nn, angle_we)==2) {
+ i++;
+ rotor[i].nn = nn;
+ strcpy(rotor[i].angle_we,angle_we);
+ strncpy(angle,angle_we,strlen(angle_we)-1);
+ rotor[i].orbital_pos = atof(angle) * 10;
+ strncpy(we,angle_we+strlen(angle_we)-1,1);
+ we[1]='\0';
+ rotor[i].we_flag = (strcmp(we,"W")==0 || strcmp(we,"w")==0) ? 0 : 1;
+ //info("rotor: i=%i, nn=%i, orbital_pos=%i we_flag=%i\n",
+ // i, rotor[i].nn, rotor[i].orbital_pos, rotor[i].we_flag);
+ }
+ }
+ }
+ fclose(rotor_conf_fd);
+ return 0;
+}
+
+int rotor_nn(int orbital_pos, int we_flag){
+ /*given say 192,1 return the position number*/
+ int i;
+ for (i=0; i<49; i++){
+ if (rotor[i].orbital_pos == orbital_pos && rotor[i].we_flag == we_flag) {
+ return rotor[i].nn;
+ }
+ }
+ error("rotor_nn: orbital_pos=%i, we_flag=%i not found.\n", orbital_pos, we_flag);
+ return 0;
+}
+
+int rotor_name2nn(char *angle_we){
+ /*given say '19.2E' return the position number*/
+ int i;
+ for (i=0; i<49; i++){
+ if (strcmp(rotor[i].angle_we, angle_we) == 0) {
+ return rotor[i].nn;
+ }
+ }
+ error("rotor_name2nn: '%s' not found.\n", angle_we);
+ return 0;
+}
+
+float rotor_angle(int nn) {
+ /*given nn, return the angle in 0.0-359.9 range (1=1.0E, 359=1.0W) */
+ int i;
+ float angle;
+ for (i=0; i<49; i++){
+ if (rotor[i].nn == nn) {
+ if(rotor[i].we_flag == 0) //west
+ angle = 360.00 - rotor[i].orbital_pos / 10;
+ else //east
+ angle = rotor[i].orbital_pos / 10;
+ return angle;
+ }
+ }
+ error("rotor_angle: nn=%i not found",nn);
+ return -999;
+}
+
static int tune_initial (int frontend_fd, const char *initial)
{
FILE *inif;
@@ -2353,6 +2459,8 @@ static const char *usage = "\n"
" -d N use DVB /dev/dvb/adapter?/demuxN\n"
" -s N use DiSEqC switch position N (DVB-S only)\n"
" -S N use DiSEqC uncommitted switch position N (DVB-S only)\n"
+" -r sat move DiSEqC rotor to satellite location, e.g. '13.0E' or '1.0W'\n"
+" -R N move DiSEqC rotor to position number N\n"
" -i N spectral inversion setting (0: off, 1: on, 2: auto [default])\n"
" -n evaluate NIT messages for full network scan (slow!)\n"
" -5 multiply all filter timeouts by factor 5\n"
@@ -2431,7 +2539,7 @@ int main (int argc, char **argv)
/* start with default lnb type */
lnb_type = *lnb_enum(0);
- while ((opt = getopt(argc, argv, "5cnpa:f:d:O:k:I:S:s:o:x:t:i:l:vquPA:U")) != -1) {
+ while ((opt = getopt(argc, argv, "5cnpa:f:d:O:k:I:S:s:r:R:o:x:t:i:l:vquPA:U")) != -1) {
switch (opt)
{
case 'a':
@@ -2474,6 +2582,14 @@ int main (int argc, char **argv)
case 'S':
uncommitted_switch_pos = strtoul(optarg, NULL, 0);
+ break;
+
+ case 'r':
+ strncpy(rotor_pos_name,optarg,sizeof(rotor_pos_name)-1);
+ break;
+
+ case 'R':
+ rotor_pos = strtoul(optarg, NULL, 0);
break;
case 'O':
@@ -2567,6 +2683,16 @@ int main (int argc, char **argv)
fprintf (stderr, "uncommitted_switch position needs to be < 16!\n");
return -1;
}
+
+ read_rotor_conf("rotor.conf");
+ if (strlen(rotor_pos_name)>0){
+ rotor_pos=rotor_name2nn(rotor_pos_name);
+ if (rotor_pos == 0){
+ fprintf(stderr,"Rotor position '%s' not found. Check config.",rotor_pos_name);
+ return -1;
+ }
+ }
+
if (initial)
info("scanning %s\n", initial);
diff -r 40368fdba59a scan.h
--- a/scan.h
+++ b/scan.h
@@ -103,6 +103,12 @@ typedef struct transponder {
uint32_t *other_f; /* DVB-T freqeuency-list descriptor */
} transponder_t;
+typedef struct rotorslot {
+ unsigned int nn;
+ int orbital_pos; // 192 degrees*10
+ unsigned int we_flag; // 0=W, 1=E
+ char angle_we[8]; // '19.2E'
+} rotorslot_t;
#endif
[-- Attachment #4: rotor.conf --]
[-- Type: text/plain, Size: 200 bytes --]
# rotor.conf
# diseqc_position_number orbital_position
1 13.0E
2 19.2E
3 16.0E
4 10.0E
5 7.0E
6 5.0E
7 3.0E
10 8.0W
11 18.0W
13 27.5W
16 23.5E
17 26.0E
19 28.2E
26 1.0W
27 7.0W
28 12.5W
[-- Attachment #5: Type: text/plain, Size: 150 bytes --]
_______________________________________________
linux-dvb mailing list
linux-dvb@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb
next reply other threads:[~2008-11-12 2:31 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-12 2:31 Hans Werner [this message]
2008-11-12 6:46 ` [linux-dvb] [PATCH] scan-s2: fixes and diseqc rotor support Goga777
2008-11-12 10:21 ` Per Heldal
2008-11-12 10:44 ` Alex Betis
2008-11-12 11:51 ` Hans Werner
2008-11-12 10:43 ` Alex Betis
2008-11-12 11:24 ` BOUWSMA Barry
2008-11-12 11:44 ` Ales Jurik
2008-11-12 12:08 ` Alex Betis
2008-11-12 12:47 ` BOUWSMA Barry
2008-11-12 12:59 ` Alex Betis
2008-11-12 13:20 ` BOUWSMA Barry
2008-11-12 12:59 ` Christophe Thommeret
[not found] ` <200811121353.47705.hftom@free.fr>
2008-11-12 13:01 ` Alex Betis
2008-11-12 13:04 ` Christophe Thommeret
2008-11-12 14:03 ` Hans Werner
2008-11-12 12:39 ` Hans Werner
2008-11-12 20:56 ` Alex Betis
2008-11-13 23:04 ` Hans Werner
2008-11-14 8:30 ` Alex Betis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20081112023112.94740@gmx.net \
--to=hwerner4@gmx.de \
--cc=alex.betis@gmail.com \
--cc=linux-dvb@linuxtv.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox