linuxdvb: added rotor GOTOX/USALS implementation
This is taken from PR #238. I still don't have the movement duration stuff done. And now I really need to think more about the config.
This commit is contained in:
parent
2327b87304
commit
2825bdf9a4
2 changed files with 191 additions and 7 deletions
|
@ -29,7 +29,7 @@
|
|||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <linux/dvb/dmx.h>
|
||||
#include <math.h>
|
||||
|
||||
/* **************************************************************************
|
||||
* Class definition
|
||||
|
@ -39,18 +39,98 @@ typedef struct linuxdvb_rotor
|
|||
{
|
||||
linuxdvb_diseqc_t;
|
||||
|
||||
/* Port settings */
|
||||
int ls_toneburst;
|
||||
int ls_committed;
|
||||
int ls_uncomitted;
|
||||
enum {
|
||||
ROTOR_GOTOX,
|
||||
ROTOR_USALS
|
||||
} lr_type;
|
||||
|
||||
double lr_site_lat;
|
||||
double lr_site_lon;
|
||||
double lr_sat_lon;
|
||||
|
||||
uint32_t lr_position;
|
||||
|
||||
uint32_t lr_rate;
|
||||
|
||||
} linuxdvb_rotor_t;
|
||||
|
||||
static const void *
|
||||
linuxdvb_rotor_class_type_get ( void *o )
|
||||
{
|
||||
static const char *str;
|
||||
linuxdvb_rotor_t *lr = o;
|
||||
str = lr->lr_type == ROTOR_GOTOX ? "GOTOX" : "USALS";
|
||||
return &str;
|
||||
}
|
||||
|
||||
static int
|
||||
linuxdvb_rotor_class_type_set ( void *o, const void *p )
|
||||
{
|
||||
const char *str = p;
|
||||
linuxdvb_rotor_t *lr = o;
|
||||
if (!strcmp("GOTOX", str))
|
||||
lr->lr_type = ROTOR_GOTOX;
|
||||
else
|
||||
lr->lr_type = ROTOR_USALS;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static htsmsg_t *
|
||||
linuxdvb_rotor_class_type_list ( void *o )
|
||||
{
|
||||
htsmsg_t *m = htsmsg_create_list();
|
||||
htsmsg_add_str(m, NULL, "GOTOX");
|
||||
htsmsg_add_str(m, NULL, "USALS");
|
||||
return m;
|
||||
}
|
||||
|
||||
const idclass_t linuxdvb_rotor_class =
|
||||
{
|
||||
.ic_class = "linuxdvb_switch",
|
||||
.ic_caption = "DiseqC switch",
|
||||
.ic_properties = (const property_t[]) {
|
||||
{
|
||||
.type = PT_STR,
|
||||
.id = "type",
|
||||
.name = "Rotor Type",
|
||||
.get = linuxdvb_rotor_class_type_get,
|
||||
.set = linuxdvb_rotor_class_type_set,
|
||||
.list = linuxdvb_rotor_class_type_list,
|
||||
},
|
||||
#if 0
|
||||
{
|
||||
.type = PT_DBL,
|
||||
.id = "site_lat",
|
||||
.name = "Site Lat",
|
||||
.off = offsetof(linuxdvb_rotor_t, lr_site_lat),
|
||||
},
|
||||
{
|
||||
.type = PT_DBL,
|
||||
.id = "site_lon",
|
||||
.name = "Site Lon",
|
||||
.off = offsetof(linuxdvb_rotor_t, lr_site_lon),
|
||||
},
|
||||
{
|
||||
.type = PT_DBL,
|
||||
.id = "sat_lon",
|
||||
.name = "Sat Lon",
|
||||
.off = offsetof(linuxdvb_rotor_t, lr_sat_lon),
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.type = PT_U16,
|
||||
.id = "position",
|
||||
.name = "Position",
|
||||
.off = offsetof(linuxdvb_rotor_t, lr_site_lat),
|
||||
},
|
||||
{
|
||||
.type = PT_U16,
|
||||
.id = "rate",
|
||||
.name = "Rate (millis/deg)",
|
||||
.off = offsetof(linuxdvb_rotor_t, lr_rate),
|
||||
},
|
||||
{
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -58,11 +138,108 @@ const idclass_t linuxdvb_rotor_class =
|
|||
* Class methods
|
||||
* *************************************************************************/
|
||||
|
||||
/* GotoX */
|
||||
static int
|
||||
linuxdvb_rotor_gotox_tune
|
||||
( linuxdvb_rotor_t *lr, linuxdvb_mux_t *lm, int fd )
|
||||
{
|
||||
if (diseqc_send_msg(fd, 0xE0, 0x31, 0x6B, lr->lr_position, 0, 0, 4)) {
|
||||
tvherror("linuxdvb", "failed to set GOTOX pos %d", lr->lr_position);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tvhdebug("linuxdvb", "rotor GOTOX pos %d sent", lr->lr_position);
|
||||
return 120; // TODO: calculate period (2 min hardcoded)
|
||||
}
|
||||
|
||||
/* USALS */
|
||||
static int
|
||||
linuxdvb_rotor_usals_tune
|
||||
( linuxdvb_rotor_t *lr, linuxdvb_mux_t *lm, int fd )
|
||||
{
|
||||
/*
|
||||
* Code originally written in PR #238 by Jason Millard jsm174
|
||||
*
|
||||
* USALS rotor logic adapted from tune-s2
|
||||
* http://updatelee.blogspot.com/2010/09/tune-s2.html
|
||||
*
|
||||
* Antenna Alignment message data format:
|
||||
* http://www.dvb.org/technology/standards/A155-3_DVB-RCS2_Higher_layer_satellite_spec.pdf
|
||||
*/
|
||||
|
||||
#define TO_DEG(x) ((x * 180.0) / M_PI)
|
||||
#define TO_RAD(x) ((x * M_PI) / 180.0)
|
||||
|
||||
static const double r_eq = 6378.14;
|
||||
static const double r_sat = 42164.57;
|
||||
|
||||
double lat = TO_RAD(lr->lr_site_lat);
|
||||
double lon = TO_RAD(lr->lr_site_lon);
|
||||
double pos = TO_RAD(lr->lr_sat_lon);
|
||||
|
||||
double dishVector[3] = {
|
||||
(r_eq * cos(lat)),
|
||||
0,
|
||||
(r_eq * sin(lat)),
|
||||
};
|
||||
|
||||
double satVector[3] = {
|
||||
(r_sat * cos(lon - pos)),
|
||||
(r_sat * sin(lon - pos)),
|
||||
0
|
||||
};
|
||||
|
||||
double satPointing[3] = {
|
||||
(satVector[0] - dishVector[0]),
|
||||
(satVector[1] - dishVector[1]),
|
||||
(satVector[2] - dishVector[2])
|
||||
};
|
||||
|
||||
double motor_angle = TO_DEG(atan(satPointing[1] / satPointing[0]));
|
||||
|
||||
int sixteenths = ((fabs(motor_angle) * 16.0) + 0.5);
|
||||
|
||||
int angle_1 = (((motor_angle > 0.0) ? 0xd0 : 0xe0) | (sixteenths >> 8));
|
||||
int angle_2 = (sixteenths & 0xff);
|
||||
|
||||
tvhtrace("linuxdvb", "rotor USALS goto %0.1f%c (motor %0.2f %sclockwise)",
|
||||
fabs(pos), (pos > 0.0) ? 'E' : 'W',
|
||||
motor_angle, (motor_angle > 0.0) ? "counter-" : "");
|
||||
|
||||
if (diseqc_send_msg(fd, 0xE0, 0x31, 0x6E, angle_1, angle_2, 0, 5)) {
|
||||
tvherror("linuxdvb", "failed to send USALS command");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 120; // TODO: calculate period (2 min hardcoded)
|
||||
}
|
||||
|
||||
static int
|
||||
linuxdvb_rotor_tune
|
||||
( linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm, int fd )
|
||||
{
|
||||
return 0;
|
||||
linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld;
|
||||
|
||||
/* Force to 18v (quicker movement) */
|
||||
if (ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18)) {
|
||||
tvherror("linuxdvb", "failed to set 18v for rotor movement");
|
||||
return -1;
|
||||
}
|
||||
usleep(15000);
|
||||
|
||||
/* GotoX */
|
||||
if (lr->lr_type == ROTOR_GOTOX)
|
||||
return linuxdvb_rotor_gotox_tune(lr, lm, fd);
|
||||
|
||||
/* USALS */
|
||||
return linuxdvb_rotor_usals_tune(lr, lm, fd);
|
||||
}
|
||||
|
||||
static int
|
||||
linuxdvb_rotor_grace
|
||||
( linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm )
|
||||
{
|
||||
return 120; // TODO: calculate approx period
|
||||
}
|
||||
|
||||
/* **************************************************************************
|
||||
|
@ -76,7 +253,8 @@ linuxdvb_rotor_create0
|
|||
linuxdvb_diseqc_t *ld
|
||||
= linuxdvb_diseqc_create(linuxdvb_rotor, NULL, conf);
|
||||
if (ld) {
|
||||
ld->ld_tune = linuxdvb_rotor_tune;
|
||||
ld->ld_tune = linuxdvb_rotor_tune;
|
||||
ld->ld_grace = linuxdvb_rotor_grace;
|
||||
}
|
||||
|
||||
return ld;
|
||||
|
|
|
@ -252,6 +252,12 @@ linuxdvb_satconf_tune ( linuxdvb_satconf_t *ls )
|
|||
(linuxdvb_diseqc_t*)ls->ls_lnb
|
||||
};
|
||||
|
||||
/* Disable tone */
|
||||
if (ioctl(lfe->lfe_fe_fd, FE_SET_TONE, SEC_TONE_OFF)) {
|
||||
tvherror("linuxdvb", "failed to disable tone");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Diseqc */
|
||||
i = ls->ls_diseqc_idx;
|
||||
for (i = ls->ls_diseqc_idx; i < 3; i++) {
|
||||
|
|
Loading…
Add table
Reference in a new issue