zapit: add first experimental EN50494 (aka unicable) support

This adds first experimental and rudimentary support for unicable.
This will not work with complex setups (DiSEqC-Switches combined with
SCR Matrices etc). Only simple setups are supported.
Also, there is no GUI configuration yet. To enale, kill running
neutrino, then add "uni_scr={0...7}" (only one value, from 0 to 7) to
/var/tuxbox/config/zapit/zapit.conf. Note that the "receiver number" you
probably got for your installation is probably from 1 to 8, so you need
to decrease it by one to get the SCR value.
If your setup has nonstandard frequencies, you might want to add your
assigned frequency as "uni_qrg=1234" (in MHz).

Check the log for those lines if it does not work:
[fe0] tune to frequency 11303000 pol Horizontal/Left srate 22000000
[fe0] tuner to frequency 1553000 (offset 9750000)
VOLT18=1 TONE_ON=0, freq=1553000 bpf=1284 ret=1283000
[fe0] Diseqc cmd: 0xE0 0x10 0x5A 0x9 0x67
[fe0] DEMOD: FEC 2/3 system DVB-S2 modulation 8PSK pilot on, freq 1283000

git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-experimental@889 e54a6e83-5905-42d5-8d5c-058d10e6a962


Origin commit data
------------------
Commit: 8c2b8e2522
Author: Stefan Seyfried <seife@tuxbox-git.slipkontur.de>
Date: 2010-11-21 (Sun, 21 Nov 2010)
This commit is contained in:
Stefan Seyfried
2010-11-21 16:37:29 +00:00
parent 7f3bad0218
commit 5454d76cda
3 changed files with 74 additions and 1 deletions

View File

@@ -116,6 +116,7 @@ class CFrontend
void sendDiseqcPowerOn(void);
void sendDiseqcReset(void);
void sendDiseqcSmatvRemoteTuningCommand(const uint32_t frequency);
uint32_t sendEN50494TuningCommand(const uint32_t frequency, const int high_band, const int horizontal, const int bank);
void sendDiseqcStandby(void);
void sendDiseqcZeroByteCommand(const uint8_t frm, const uint8_t addr, const uint8_t cmd);
void sendToneBurst(const fe_sec_mini_cmd_t burst, const uint32_t ms);

View File

@@ -47,6 +47,9 @@ extern bool playing;
extern int motorRotationSpeed;
extern CEventServer *eventServer;
extern int uni_scr;
extern int uni_qrg;
#define SOUTH 0
#define NORTH 1
#define EAST 0
@@ -708,7 +711,13 @@ int CFrontend::setFrontend(const struct dvb_frontend_parameters *feparams, bool
}
//TIMER_STOP("[fe0] clear events took");
}
printf("[fe0] DEMOD: FEC %s system %s modulation %s pilot %s\n", f, s, m, pilot == PILOT_ON ? "on" : "off");
if (uni_scr >= 0)
p->props[FREQUENCY].u.data = sendEN50494TuningCommand(feparams->frequency,
currentToneMode == SEC_TONE_ON,
currentVoltage == SEC_VOLTAGE_18,
0); /* bank 0/1, like mini-diseqc a/b, not impl.*/
printf("[fe0] DEMOD: FEC %s system %s modulation %s pilot %s, freq %d\n", f, s, m, pilot == PILOT_ON ? "on" : "off", p->props[FREQUENCY].u.data);
{
TIMER_INIT();
@@ -740,6 +749,16 @@ void CFrontend::secSetTone(const fe_sec_tone_mode_t toneMode, const uint32_t ms)
if (currentToneMode == toneMode)
return;
if (uni_scr >= 0) {
/* this is too ugly for words. the "currentToneMode" is the only place
where the global "highband" state is saved. So we need to fake it for
unicable and still set the tone on... */
currentToneMode = toneMode; /* need to know polarization for unicable */
fop(ioctl, FE_SET_TONE, SEC_TONE_OFF); /* tone must be off except for the time
of sending commands */
return;
}
printf("[fe%d] tone %s\n", fenumber, toneMode == SEC_TONE_ON ? "on" : "off");
TIMER_INIT();
TIMER_START();
@@ -762,6 +781,13 @@ void CFrontend::secSetVoltage(const fe_sec_voltage_t voltage, const uint32_t ms)
//TIMER_INIT();
//TIMER_START();
if (uni_scr >= 0) {
/* see my comment in secSetTone... */
currentVoltage = voltage; /* need to know polarization for unicable */
fop(ioctl, FE_SET_VOLTAGE, SEC_VOLTAGE_13); /* voltage must not be 18V */
return;
}
if (fop(ioctl, FE_SET_VOLTAGE, voltage) == 0) {
currentVoltage = voltage;
//TIMER_STOP("[fe0] FE_SET_VOLTAGE took");
@@ -958,6 +984,42 @@ void CFrontend::setInput(t_satellite_position satellitePosition, uint32_t freque
}
}
/* frequency is the IF-frequency (950-2100), what a stupid spec...
high_band, horizontal, bank are actually bool (0/1)
bank specifies the "switch bank" (as in Mini-DiSEqC A/B) */
uint32_t CFrontend::sendEN50494TuningCommand(const uint32_t frequency, const int high_band,
const int horizontal, const int bank)
{
uint32_t uni_qrgs[] = { 1284, 1400, 1516, 1632, 1748, 1864, 1980, 2096 };
uint32_t bpf;
if (uni_qrg == 0)
bpf = uni_qrgs[uni_scr];
else
bpf = uni_qrg;
struct dvb_diseqc_master_cmd cmd = {
{0xe0, 0x10, 0x5a, 0x00, 0x00, 0x00}, 5
};
unsigned int t = (frequency / 1000 + bpf + 2) / 4 - 350;
if (t < 1024 && uni_scr >= 0 && uni_scr < 8)
{
fprintf(stderr, "VOLT18=%d TONE_ON=%d, freq=%d bpf=%d ret=%d\n", currentVoltage == SEC_VOLTAGE_18, currentToneMode == SEC_TONE_ON, frequency, bpf, (t + 350) * 4000 - frequency);
cmd.msg[3] = (t >> 8) | /* highest 3 bits of t */
(uni_scr << 5) | /* adress */
(bank << 4) | /* not implemented yet */
(horizontal << 3) | /* horizontal == 0x08 */
(high_band) << 2; /* high_band == 0x04 */
cmd.msg[4] = t & 0xFF;
fop(ioctl, FE_SET_VOLTAGE, SEC_VOLTAGE_18);
usleep(15 * 1000); /* en50494 says: >4ms and < 22 ms */
sendDiseqcCommand(&cmd, 50); /* en50494 says: >2ms and < 60 ms */
fop(ioctl, FE_SET_VOLTAGE, SEC_VOLTAGE_13);
return (t + 350) * 4000 - frequency;
}
WARN("ooops. t > 1024? (%d) or uni_scr out of range? (%d)", t, uni_scr);
return 0;
}
bool CFrontend::tuneChannel(CZapitChannel * /*channel*/, bool /*nvod*/)
{
//printf("tuneChannel: tpid %llx\n", currentTransponder.TP_id);

View File

@@ -103,6 +103,10 @@ char pipzap = 0;
bool g_list_changed = false; // flag to indicate, allchans was changed
int sig_delay = 2; // seconds between signal check
/* variables for EN 50494 (a.k.a Unicable) */
int uni_scr = -1; /* the unicable SCR address, -1 == no unicable */
int uni_qrg = 0; /* the unicable frequency in MHz, 0 == from spec */
double gotoXXLatitude, gotoXXLongitude;
int gotoXXLaDirection, gotoXXLoDirection, useGotoXX;
int scanSDT;
@@ -232,6 +236,9 @@ void saveZapitSettings(bool write, bool write_a)
//config.setInt32("useGotoXX", useGotoXX);
config.setInt32("repeatUsals", repeatUsals);
config.setInt32("uni_scr", uni_scr);
config.setInt32("uni_qrg", uni_qrg);
config.setInt32("scanSDT", scanSDT);
if (config.getModifiedFlag())
config.saveConfig(CONFIGFILE);
@@ -302,6 +309,9 @@ void loadZapitSettings()
scanSDT = config.getInt32("scanSDT", 0);
uni_scr = config.getInt32("uni_scr", -1);
uni_qrg = config.getInt32("uni_qrg", 0);
diseqcType = (diseqc_t)config.getInt32("diseqcType", NO_DISEQC);
motorRotationSpeed = config.getInt32("motorRotationSpeed", 18); // default: 1.8 degrees per second