From 5454d76cda10f4d4b0919614e4cada7c2dcc4fe0 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 21 Nov 2010 16:37:29 +0000 Subject: [PATCH] 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: https://github.com/neutrino-images/ni-neutrino/commit/8c2b8e2522833eebb5109c9847a210338ad76158 Author: Stefan Seyfried Date: 2010-11-21 (Sun, 21 Nov 2010) --- src/zapit/include/zapit/frontend_c.h | 1 + src/zapit/src/frontend.cpp | 64 +++++++++++++++++++++++++++- src/zapit/src/zapit.cpp | 10 +++++ 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/zapit/include/zapit/frontend_c.h b/src/zapit/include/zapit/frontend_c.h index e26491a3c..964904962 100644 --- a/src/zapit/include/zapit/frontend_c.h +++ b/src/zapit/include/zapit/frontend_c.h @@ -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); diff --git a/src/zapit/src/frontend.cpp b/src/zapit/src/frontend.cpp index 84794b872..1e33ccbed 100644 --- a/src/zapit/src/frontend.cpp +++ b/src/zapit/src/frontend.cpp @@ -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); diff --git a/src/zapit/src/zapit.cpp b/src/zapit/src/zapit.cpp index 218b3e981..9ce16e1b1 100644 --- a/src/zapit/src/zapit.cpp +++ b/src/zapit/src/zapit.cpp @@ -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