Hi, I was working on some diseqc software experiment on mythtv, and got is half-way working, meaning that channels with specific pol etc parameters did tune while others did not... Anyhow, during this work I at some point just lost the Hauppauge Nexus-S card. I have not been able to view satellite channels with mplayer dvb://, and tuning with szap sets the BER quite soon to 00000. I checked that on the cable to diseqc the card is still giving 17.5 volts, and even tuning to V pol channels keeps it there.
I have the DVB build from yesterday - and I cannot confirm did this problem show up as a result of updating to the latest DVB or as a result of something happening while accessing the DVB API. In the nexus-no-feed is output of szap where BER turns to 0000 after lock, and corresponding dmesg with frontend debug on. In the diff you can see the diseqc stuff should be fairly std - I assume. Any ideas on this one? Petri
reading channels from file '/root/.szap/channels.conf' zapping to 'EuroNews': sat 3, frequency = 11953 MHz H, symbolrate 27500000, vpid = 0x08ad, apid = 0x08b9 using '/dev/dvb/adapter0/frontend0' and '/dev/dvb/adapter0/demux0' status 03 | signal b40c | snr a11f | ber 00003108 | unc 00000000 | status 1f | signal ac82 | snr c3bd | ber 00009400 | unc 00000000 | FE_HAS_LOCK status 1f | signal adb3 | snr c3f0 | ber 00000000 | unc 00000000 | FE_HAS_LOCK status 1f | signal ac80 | snr c3c0 | ber 00000000 | unc 00000000 | FE_HAS_LOCK status 1f | signal adbc | snr c3a5 | ber 00000000 | unc 00000000 | FE_HAS_LOCK status 1f | signal ac79 | snr c3bd | ber 00000000 | unc 00000000 | FE_HAS_LOCK status 1f | signal ac81 | snr c387 | ber 00000000 | unc 00000000 | FE_HAS_LOCK status 1f | signal adbd | snr c3d5 | ber 00000000 | unc 00000000 | FE_HAS_LOCK status 1f | signal ac86 | snr c3e1 | ber 00000000 | unc 00000000 | FE_HAS_LOCK ---------------------------------------- the dmesg looks like this: dvb_frontend_open dvb_frontend_start dvb_frontend_thread dvb_call_frontend_notifiers DVB: initialising frontend 0:0 (STV0299/TSA5059/SL1935 based)... dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_get_event dvb_frontend_ioctl dvb_bend_frequency dvb_frontend_set_parameters: f == 1353000, drift == 0 dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_internal_ioctl update_delay dvb_frontend_recover dvb_bend_frequency dvb_frontend_set_parameters: f == 1353000, drift == 1718 dvb_frontend_internal_ioctl dvb_frontend_internal_ioctl dvb_frontend_add_event dvb_call_frontend_notifiers dvb_frontend_internal_ioctl update_delay dvb_frontend_add_event dvb_frontend_internal_ioctl dvb_call_frontend_notifiers dvb_frontend_internal_ioctl update_delay dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_internal_ioctl update_delay dvb_frontend_internal_ioctl update_delay dvb_frontend_internal_ioctl update_delay dvb_frontend_internal_ioctl update_delay dvb_frontend_internal_ioctl update_delay dvb_frontend_internal_ioctl update_delay dvb_frontend_internal_ioctl update_delay dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_internal_ioctl update_delay dvb_frontend_internal_ioctl update_delay dvb_frontend_internal_ioctl update_delay dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_internal_ioctl update_delay dvb_frontend_internal_ioctl update_delay dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_internal_ioctl update_delay dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_ioctl dvb_frontend_internal_ioctl dvb_frontend_internal_ioctl update_delay dvb_frontend_release
--- libs/libmythtv/originals/dvbtypes.h 2003-09-17 00:49:50.000000000 +0300 +++ libs/libmythtv/dvbtypes.h 2003-09-17 01:00:25.000000000 +0300 @@ -28,6 +28,7 @@ struct dvb_frontend_parameters params; fe_sec_voltage_t voltage; fe_sec_tone_mode_t tone; + u_int16_t diseqc; } dvb_tuning_t; typedef struct dvbpids @@ -55,4 +56,10 @@ typedef map<u_int16_t, ipack*> pid_ipack_t; +typedef struct dvb_diseqc_cmd { + struct dvb_diseqc_master_cmd cmd; + uint32_t wait; +} dvb_diseqc_cmd_t; + + #endif --- libs/libmythtv/originals/dvbrecorder.cpp 2003-09-17 00:49:11.000000000 +0300 +++ libs/libmythtv/dvbrecorder.cpp 2003-09-17 00:57:11.000000000 +0300 @@ -191,9 +191,9 @@ { int this_pid = pids[i]; - if (this_pid < 0x100 || this_pid > 0x1fff) + if (this_pid < 0x1 || this_pid > 0x1fff) { - ERR(QString("PID Value (%1) out of range (0xff-0x1fff).").arg(this_pid)); + ERR(QString("PID Value (%1) out of range (0x01-0x1fff).").arg(this_pid)); continue; } --- libs/libmythtv/originals/dvbchannel.h 2003-09-17 00:49:42.000000000 +0300 +++ libs/libmythtv/dvbchannel.h 2003-09-17 00:57:11.000000000 +0300 @@ -48,6 +48,10 @@ bool CheckCodeRate(fe_code_rate_t& rate); bool Tune(); + + void DiseqcSendMsg(int fd, fe_sec_voltage_t v, dvb_diseqc_cmd_t *cmd, fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b); //pny + bool Diseqc(int secfd, int sat_no, int pol, int hi_lo); //pny + bool TuneQPSK(dvb_tuning_t& tuning, bool reset, bool& havetuned); bool TuneQAM(dvb_tuning_t& tuning, bool reset, bool& havetuned); bool TuneOFDM(dvb_tuning_t& tuning, bool reset, bool& havetuned); --- libs/libmythtv/originals/dvbchannel.cpp 2003-09-17 00:49:42.000000000 +0300 +++ libs/libmythtv/dvbchannel.cpp 2003-09-17 00:57:10.000000000 +0300 @@ -220,10 +220,19 @@ switch(info.type) { case FE_QPSK: - CHANNEL(QString("Frequency: %1 Symbol Rate: %2 Pol: %3.") - .arg(t.params.frequency) - .arg(t.params.u.qpsk.symbol_rate) - .arg(t.voltage==SEC_VOLTAGE_13?'V':'H')); + if(t.diseqc) + { + CHANNEL(QString("Frequency: %1 Symbol Rate: %2 Pol: %3 Diseqc: %4.") + .arg(t.params.frequency) + .arg(t.params.u.qpsk.symbol_rate) + .arg(t.voltage==SEC_VOLTAGE_13?'V':'H') + .arg(t.diseqc)); + } else { + CHANNEL(QString("Frequency: %1 Symbol Rate: %2 Pol: %3.") + .arg(t.params.frequency) + .arg(t.params.u.qpsk.symbol_rate) + .arg(t.voltage==SEC_VOLTAGE_13?'V':'H')); + } break; case FE_QAM: CHANNEL(QString("Frequency: %1 Symbol Rate: %2.") @@ -274,6 +283,8 @@ if (!CheckCodeRate(t.params.u.qpsk.fec_inner)) WARNING("Unsupported fec_inner parameter."); + if (t.diseqc > 4) + WARNING("Unsupported diseqc parameter."); break; case FE_QAM: symbol_rate = t.params.u.qam.symbol_rate; @@ -365,7 +376,7 @@ switch(info.type) { case FE_QPSK: - query += QString("freq, inversion, symbol_rate, fec_inner, pol"); + query += QString("freq, inversion, symbol_rate, fec_inner, pol, diseqc"); break; case FE_QAM: query += QString("freq, inversion, symbol_rate, fec_inner," @@ -408,25 +419,25 @@ for (unsigned int i=0; i<audio.size(); i++) { - if (audio[i].toInt() > 0xff) + if (audio[i].toInt() > 0x00) pids.audio.push_back(audio[i].toInt()); } for (unsigned int i=0; i<video.size(); i++) { - if (video[i].toInt() > 0xff) + if (video[i].toInt() > 0x00) pids.video.push_back(video[i].toInt()); } for (unsigned int i=0; i<teletext.size(); i++) { - if (teletext[i].toInt() > 0xff) + if (teletext[i].toInt() > 0x00) pids.teletext.push_back(teletext[i].toInt()); } for (unsigned int i=0; i<subtitle.size(); i++) { - if (subtitle[i].toInt() > 0xff) + if (subtitle[i].toInt() > 0x00) pids.subtitle.push_back(subtitle[i].toInt()); } @@ -488,6 +499,11 @@ ERROR("Invalid polarization, aborting."); return false; } + if((t.diseqc = query.value(13).toInt()) > 4) + { + ERROR("Invalid diseqc, aborting."); + return false; + } break; } case FE_QAM: // DVB-C @@ -769,6 +785,7 @@ { if (ioctl(fd_frontend, FE_GET_EVENT, &event) < 0) { + if(errno == EOVERFLOW) continue; @@ -841,6 +858,43 @@ return true; } +/* Original from http://linuxtv.org/cgi-bin/cvsweb.cgi/DVB/apps/szap/szap.c */ +void DVBChannel::DiseqcSendMsg(int fd, fe_sec_voltage_t v, dvb_diseqc_cmd_t *cmd, fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b) +{ + ioctl(fd, FE_SET_TONE, SEC_TONE_OFF); + ioctl(fd, FE_SET_VOLTAGE, v); + usleep(15 * 1000); + ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &cmd->cmd); + usleep(cmd->wait * 1000); + usleep(15 * 1000); + ioctl(fd, FE_DISEQC_SEND_BURST, b); + usleep(15 * 1000); + ioctl(fd, FE_SET_TONE, t); +} + + +/* digital satellite equipment control, + * specification is available from http://www.eutelsat.com/ + */ + +/* Original from http://linuxtv.org/cgi-bin/cvsweb.cgi/DVB/apps/szap/szap.c */ +bool DVBChannel::Diseqc(int secfd, int sat_no, int pol, int hi_lo) +{ + dvb_diseqc_cmd_t cmd = + { {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 }; + + /* param: high nibble: reset bits, low nibble set bits, + * bits are: option, position, polarizaion, band + */ + cmd.cmd.msg[3] = + 0xf0 | (((sat_no * 4) & 0x0f) | (hi_lo ? 1 : 0) | (pol ? 0 : 2)); + + DiseqcSendMsg(secfd, pol ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18, + &cmd, hi_lo ? SEC_TONE_ON : SEC_TONE_OFF, + (sat_no / 4) % 2 ? SEC_MINI_B : SEC_MINI_A); + return TRUE; +} + bool DVBChannel::TuneQPSK(dvb_tuning_t& tuning, bool reset, bool& havetuned) { int frequency = tuning.params.frequency; @@ -855,30 +909,52 @@ tuning.tone = SEC_TONE_OFF; } - if (prev_tuning.tone != tuning.tone || reset) - { - if (ioctl(fd_frontend, FE_SET_TONE, tuning.tone) < 0) + if (tuning.diseqc != 0 && + ((prev_tuning.diseqc != tuning.diseqc || + prev_tuning.tone != tuning.tone || + prev_tuning.voltage != tuning.voltage) || reset)) + { + CHANNEL("Diseqc Settings SAT: " << + tuning.diseqc-1 << + " POL: " << (tuning.voltage == SEC_VOLTAGE_18 ? "H" : "V") << + " HI_LO: " << (tuning.tone == SEC_TONE_ON ? "TONE ON" : "TONE OFF") << "\n"); + + if (!Diseqc(fd_frontend, tuning.diseqc-1, (tuning.voltage == SEC_VOLTAGE_18 ? 0 : 1), (tuning.tone == SEC_TONE_ON ? 1 : 0))) { - ERROR("Setting Tone mode failed.\n" << - " The Error Was (" << errno << "): "<< strerror(errno)); - return false; + ERROR("Setting Diseqc failed.\n"); + return false; } - + prev_tuning.diseqc = tuning.diseqc; prev_tuning.tone = tuning.tone; - havetuned = true; - } + prev_tuning.voltage = tuning.voltage; + havetuned = true; + } else { - if (prev_tuning.voltage != tuning.voltage || reset) - { - if (ioctl(fd_frontend, FE_SET_VOLTAGE, tuning.voltage) < 0) - { - ERROR("Setting Polarization failed.\n" << + if (prev_tuning.tone != tuning.tone || reset) + { + if (ioctl(fd_frontend, FE_SET_TONE, tuning.tone) < 0) + { + ERROR("Setting Tone mode failed.\n" << " The Error Was (" << errno << "): "<< strerror(errno)); - return false; + return false; + } + + prev_tuning.tone = tuning.tone; + havetuned = true; } - prev_tuning.voltage = tuning.voltage; - havetuned = true; + if (prev_tuning.voltage != tuning.voltage || reset) + { + if (ioctl(fd_frontend, FE_SET_VOLTAGE, tuning.voltage) < 0) + { + ERROR("Setting Polarization failed.\n" << + " The Error Was (" << errno << "): "<< strerror(errno)); + return false; + } + + prev_tuning.voltage = tuning.voltage; + havetuned = true; + } } if (reset ||