Single-instance fe; Fix using global structs

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


Origin commit data
------------------
Branch: ni/coolstream
Commit: 2569ec4d33
Author: [CST] Focus <focus.cst@gmail.com>
Date: 2011-07-21 (Thu, 21 Jul 2011)



------------------
This commit was generated by Migit
This commit is contained in:
[CST] Focus
2011-07-21 10:24:55 +00:00
parent 7b75459cf9
commit bf7f59c936
2 changed files with 143 additions and 127 deletions

View File

@@ -25,6 +25,7 @@
#include <inttypes.h> #include <inttypes.h>
#include "types.h" #include "types.h"
#include "channel.h" #include "channel.h"
#include <map>
#define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_AUTO+1) //10 #define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_AUTO+1) //10
#define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_S2_QPSK_1_2+1) //11 #define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_S2_QPSK_1_2+1) //11
@@ -75,11 +76,22 @@ typedef struct dvb_frontend_parameters FrontendParameters;
#define MAX_LNBS 64 /* due to Diseqc 1.1 (2003-01-10 rasc) */ #define MAX_LNBS 64 /* due to Diseqc 1.1 (2003-01-10 rasc) */
class CFrontend;
typedef std::map<unsigned short, CFrontend*> fe_map_t;
typedef fe_map_t::iterator fe_map_iterator_t;
class CFrontend class CFrontend
{ {
private: private:
/* frontend filedescriptor */
int fd; int fd;
/* use count for locking purposes */
int usecount;
/* current adapter where this frontend is on */
int adapter;
/* current frontend instance */
static CFrontend *currentFe;
fe_map_t femap;
/* tuning finished flag */ /* tuning finished flag */
bool tuned; bool tuned;
/* information about the used frontend type */ /* information about the used frontend type */
@@ -106,9 +118,10 @@ class CFrontend
bool slave; bool slave;
int fenumber; int fenumber;
bool standby; bool standby;
bool buildProperties(const dvb_frontend_parameters*, struct dtv_properties &);
uint32_t getDiseqcReply(const int timeout_ms) const; uint32_t getDiseqcReply(const int timeout_ms) const;
struct dvb_frontend_parameters getFrontend(void) const; struct dvb_frontend_parameters getFrontend(void) const;
void secResetOverload(void); void secResetOverload(void);
void secSetTone(const fe_sec_tone_mode_t mode, const uint32_t ms); void secSetTone(const fe_sec_tone_mode_t mode, const uint32_t ms);
void secSetVoltage(const fe_sec_voltage_t voltage, const uint32_t ms); void secSetVoltage(const fe_sec_voltage_t voltage, const uint32_t ms);
@@ -124,12 +137,11 @@ class CFrontend
void setSec(const uint8_t sat_no, const uint8_t pol, const bool high_band); void setSec(const uint8_t sat_no, const uint8_t pol, const bool high_band);
void set12V(bool enable); void set12V(bool enable);
void reset(void); void reset(void);
/* Private constructor */
public: public:
CFrontend(int fe = 0); CFrontend(int Number = 0, int Adapter = 0);
~CFrontend(void); ~CFrontend(void);
static CFrontend *getInstance(int Number = 0, int Adapter = 0);
static fe_code_rate_t getCodeRate(const uint8_t fec_inner, int system = 0); static fe_code_rate_t getCodeRate(const uint8_t fec_inner, int system = 0);
uint8_t getDiseqcPosition(void) const { return currentTransponder.diseqc; } uint8_t getDiseqcPosition(void) const { return currentTransponder.diseqc; }
uint8_t getDiseqcRepeats(void) const { return diseqcRepeats; } uint8_t getDiseqcRepeats(void) const { return diseqcRepeats; }
@@ -151,14 +163,14 @@ class CFrontend
void setDiseqcRepeats(const uint8_t repeats) { diseqcRepeats = repeats; } void setDiseqcRepeats(const uint8_t repeats) { diseqcRepeats = repeats; }
void setDiseqcType(const diseqc_t type); void setDiseqcType(const diseqc_t type);
int setParameters(TP_params *TP, bool nowait = 0); int setParameters(TP_params *TP, bool nowait = 0);
int tuneFrequency (struct dvb_frontend_parameters * feparams, uint8_t polarization, bool nowait = 0); int tuneFrequency (struct dvb_frontend_parameters * feparams, uint8_t polarization, bool nowait = false);
const TP_params* getParameters(void) const { return &currentTransponder; }; const TP_params* getParameters(void) const { return &currentTransponder; };
struct dvb_frontend_event* setParametersResponse(TP_params *TP); struct dvb_frontend_event* setParametersResponse(TP_params *TP);
void setCurrentSatellitePosition(int32_t satellitePosition) {currentSatellitePosition = satellitePosition; } void setCurrentSatellitePosition(int32_t satellitePosition) {currentSatellitePosition = satellitePosition; }
void positionMotor(uint8_t motorPosition); void positionMotor(uint8_t motorPosition);
void sendMotorCommand(uint8_t cmdtype, uint8_t address, uint8_t command, uint8_t num_parameters, uint8_t parameter1, uint8_t parameter2, int repeat = 0); void sendMotorCommand(uint8_t cmdtype, uint8_t address, uint8_t command, uint8_t num_parameters, uint8_t parameter1, uint8_t parameter2, int repeat = 0);
void gotoXX(t_satellite_position pos); void gotoXX(t_satellite_position pos);
bool tuneChannel(CZapitChannel *channel, bool nvod); bool tuneChannel(CZapitChannel *channel, bool nvod);
bool retuneChannel(void); bool retuneChannel(void);
bool retuneTP(bool nowait = true); bool retuneTP(bool nowait = true);
@@ -167,8 +179,12 @@ class CFrontend
transponder_id_t getTsidOnid() { return currentTransponder.TP_id; } transponder_id_t getTsidOnid() { return currentTransponder.TP_id; }
void setTsidOnid(transponder_id_t newid) { currentTransponder.TP_id = newid; } void setTsidOnid(transponder_id_t newid) { currentTransponder.TP_id = newid; }
uint32_t getRate (); uint32_t getRate ();
void Close();
void Open(); void Open();
void Close();
bool Lock();
void Unlock();
bool sendUncommittedSwitchesCommand(int input); bool sendUncommittedSwitchesCommand(int input);
bool setInput(CZapitChannel *channel, bool nvod); bool setInput(CZapitChannel *channel, bool nvod);
void setInput(t_satellite_position satellitePosition, uint32_t frequency, uint8_t polarization); void setInput(t_satellite_position satellitePosition, uint32_t frequency, uint8_t polarization);

View File

@@ -41,9 +41,8 @@ extern int repeatUsals;
extern transponder_list_t transponders; extern transponder_list_t transponders;
extern bool highVoltage; extern bool highVoltage;
extern bool voltageOff; extern bool voltageOff;
extern bool playing;
extern int motorRotationSpeed; extern int motorRotationSpeed;
extern CEventServer *eventServer; extern int feTimeout;
extern int zapit_debug; extern int zapit_debug;
extern int uni_scr; extern int uni_scr;
@@ -55,6 +54,7 @@ extern int uni_qrg;
#define WEST 1 #define WEST 1
#define USALS #define USALS
#define CLEAR 0
// Common properties // Common properties
#define FREQUENCY 1 #define FREQUENCY 1
#define MODULATION 2 #define MODULATION 2
@@ -66,16 +66,13 @@ extern int uni_qrg;
#define PILOTS 7 #define PILOTS 7
#define ROLLOFF 8 #define ROLLOFF 8
static struct dtv_property clr_cmdargs[] = { #define FE_COMMON_PROPS 2
{ DTV_CLEAR, {0,0,0}, { 0 },0 }, #define FE_DVBS_PROPS 6
}; #define FE_DVBS2_PROPS 8
#define FE_DVBC_PROPS 6
static struct dtv_properties clr_cmdseq = {
sizeof(clr_cmdargs) / sizeof(struct dtv_property), clr_cmdargs,
};
/* stolen from dvb.c from vlc */ /* stolen from dvb.c from vlc */
static struct dtv_property dvbs_cmdargs[] = { static const struct dtv_property dvbs_cmdargs[] = {
{ DTV_CLEAR, {0,0,0}, { 0 },0 }, { DTV_CLEAR, {0,0,0}, { 0 },0 },
{ DTV_FREQUENCY, {0,0,0}, { 0 },0 }, { DTV_FREQUENCY, {0,0,0}, { 0 },0 },
{ DTV_MODULATION, {0,0,0}, { QPSK },0 }, { DTV_MODULATION, {0,0,0}, { QPSK },0 },
@@ -86,11 +83,7 @@ static struct dtv_property dvbs_cmdargs[] = {
{ DTV_TUNE, {0,0,0}, { 0 },0 }, { DTV_TUNE, {0,0,0}, { 0 },0 },
}; };
static struct dtv_properties dvbs_cmdseq = { static const struct dtv_property dvbs2_cmdargs[] = {
sizeof(dvbs_cmdargs) / sizeof(struct dtv_property), dvbs_cmdargs
};
static struct dtv_property dvbs2_cmdargs[] = {
{ DTV_CLEAR, {0,0,0}, { 0 },0 }, { DTV_CLEAR, {0,0,0}, { 0 },0 },
{ DTV_FREQUENCY, {}, { 0 },0 }, { DTV_FREQUENCY, {}, { 0 },0 },
{ DTV_MODULATION, {}, { PSK_8 } ,0}, { DTV_MODULATION, {}, { PSK_8 } ,0},
@@ -103,12 +96,8 @@ static struct dtv_property dvbs2_cmdargs[] = {
{ DTV_TUNE, {}, { 0 } ,0 }, { DTV_TUNE, {}, { 0 } ,0 },
}; };
static struct dtv_properties dvbs2_cmdseq = { static const struct dtv_property dvbc_cmdargs[] = {
sizeof(dvbs2_cmdargs) / sizeof(struct dtv_property), dvbs2_cmdargs { DTV_CLEAR, {0,0,0}, { 0 } ,0},
};
static struct dtv_property dvbc_cmdargs[] = {
{ DTV_CLEAR, {0,0,0}, { 0 },0 },
{ DTV_FREQUENCY, {}, { 0 } ,0}, { DTV_FREQUENCY, {}, { 0 } ,0},
{ DTV_MODULATION, {}, { QAM_AUTO } ,0}, { DTV_MODULATION, {}, { QAM_AUTO } ,0},
{ DTV_INVERSION, {}, { INVERSION_AUTO } ,0}, { DTV_INVERSION, {}, { INVERSION_AUTO } ,0},
@@ -118,21 +107,9 @@ static struct dtv_property dvbc_cmdargs[] = {
{ DTV_TUNE, {}, { 0 }, 0}, { DTV_TUNE, {}, { 0 }, 0},
}; };
static struct dtv_properties dvbc_cmdseq = {
sizeof(dvbc_cmdargs) / sizeof(struct dtv_property), dvbc_cmdargs
};
#define diff(x,y) (max(x,y) - min(x,y)) #define diff(x,y) (max(x,y) - min(x,y))
extern bool current_is_nvod;
extern t_channel_id live_channel_id;
extern int useGotoXX;
int stopPlayBack(bool stopemu);
int startPlayBack(CZapitChannel * thisChannel);
int zapit(const t_channel_id channel_id, bool in_nvod, bool forupdate = 0, bool nowait = 0);
#define TIMER_INIT() \ #define TIMER_INIT() \
static unsigned int tmin = 2000, tmax = 0; \ static unsigned int tmin = 2000, tmax = 0; \
struct timeval tv, tv2; \ struct timeval tv, tv2; \
@@ -150,14 +127,41 @@ int zapit(const t_channel_id channel_id, bool in_nvod, bool forupdate = 0, bool
printf("%s: %u msec (min %u max %u)\n", \ printf("%s: %u msec (min %u max %u)\n", \
label, timer_msec, tmin, tmax); label, timer_msec, tmin, tmax);
CFrontend::CFrontend(int num) // Internal Inner FEC representation
{ typedef enum dvb_fec {
printf("[fe0] New frontend\n"); fAuto,
fd = -1; f1_2,
f2_3,
f3_4,
f5_6,
f7_8,
f8_9,
f3_5,
f4_5,
f9_10,
fNone = 15
} dvb_fec_t;
fenumber = num; // Global fe instance
slave = fenumber; // FIXME CFrontend *CFrontend::currentFe = NULL;
diseqcType = NO_DISEQC;
CFrontend *CFrontend::getInstance(int Number, int Adapter)
{
if (!currentFe)
currentFe = new CFrontend(Number, Adapter);
return currentFe;
}
CFrontend::CFrontend(int Number, int Adapter)
{
printf("[fe%d] New frontend on adapter %d\n", Number, Adapter);
fd = -1;
fenumber = Number;
adapter = Adapter;
slave = fenumber; // FIXME
diseqcType = NO_DISEQC;
standby = true;
Open(); Open();
@@ -172,16 +176,20 @@ CFrontend::~CFrontend(void)
if (diseqcType > MINI_DISEQC) if (diseqcType > MINI_DISEQC)
sendDiseqcStandby(); sendDiseqcStandby();
close(fd); close(fd);
currentFe = NULL;
} }
void CFrontend::Open(void) void CFrontend::Open(void)
{ {
printf("[fe0] open frontend\n"); if(!standby)
return;
printf("[fe%d] open frontend\n", fenumber);
char filename[128]; char filename[128];
snprintf(filename, sizeof(filename), "/dev/dvb/adapter%d/frontend%d", adapter, fenumber);
printf("[fe%d] open %s\n", fenumber, filename);
sprintf(filename, "/dev/dvb/adapter0/frontend%d", fenumber);
printf("[fe0] open %s\n", filename);
if (fd < 0) { if (fd < 0) {
if ((fd = open(filename, O_RDWR | O_NONBLOCK)) < 0) { if ((fd = open(filename, O_RDWR | O_NONBLOCK)) < 0) {
ERROR(filename); ERROR(filename);
@@ -189,27 +197,28 @@ void CFrontend::Open(void)
fop(ioctl, FE_GET_INFO, &info); fop(ioctl, FE_GET_INFO, &info);
printf("[fe0] frontend fd %d type %d\n", fd, info.type); printf("[fe0] frontend fd %d type %d\n", fd, info.type);
} }
//FIXME info.type = FE_QAM;
//FIXME info.type = FE_QAM;
currentVoltage = SEC_VOLTAGE_OFF; currentVoltage = SEC_VOLTAGE_OFF;
secSetVoltage(SEC_VOLTAGE_13, 15); secSetVoltage(SEC_VOLTAGE_13, 15);
secSetTone(SEC_TONE_OFF, 15); secSetTone(SEC_TONE_OFF, 15);
sendDiseqcPowerOn(); sendDiseqcPowerOn();
tuned = false; tuned = false;
uncommitedInput = 255; uncommitedInput = 255;
diseqc = 255; diseqc = 255;
currentTransponder.polarization = 1; currentTransponder.polarization = 1;
currentTransponder.feparams.frequency = 0; currentTransponder.feparams.frequency = 0;
currentTransponder.TP_id = 0; currentTransponder.TP_id = 0;
currentTransponder.diseqc = 255; currentTransponder.diseqc = 255;
//diseqcType = NO_DISEQC; standby = false;
//currentSatellitePosition = 0xFFFF;
standby = false;
} }
void CFrontend::Close(void) void CFrontend::Close(void)
{ {
if(standby)
return;
if (!slave && diseqcType > MINI_DISEQC) if (!slave && diseqcType > MINI_DISEQC)
sendDiseqcStandby(); sendDiseqcStandby();
@@ -221,6 +230,7 @@ void CFrontend::Close(void)
void CFrontend::reset(void) void CFrontend::reset(void)
{ {
// No-op
} }
fe_code_rate_t CFrontend::getCFEC() fe_code_rate_t CFrontend::getCFEC()
@@ -232,20 +242,6 @@ fe_code_rate_t CFrontend::getCFEC()
} }
} }
typedef enum dvb_fec {
fAuto,
f1_2,
f2_3,
f3_4,
f5_6,
f7_8,
f8_9,
f3_5,
f4_5,
f9_10,
fNone = 15
} dvb_fec_t;
fe_code_rate_t CFrontend::getCodeRate(const uint8_t fec_inner, int system) fe_code_rate_t CFrontend::getCodeRate(const uint8_t fec_inner, int system)
{ {
dvb_fec_t fec = (dvb_fec_t) fec_inner; dvb_fec_t fec = (dvb_fec_t) fec_inner;
@@ -398,7 +394,6 @@ uint32_t CFrontend::getUncorrectedBlocks(void) const
} }
#define TIME_STEP 200 #define TIME_STEP 200
extern int feTimeout;
#define TIMEOUT_MAX_MS (feTimeout*100) #define TIMEOUT_MAX_MS (feTimeout*100)
struct dvb_frontend_event CFrontend::getEvent(void) struct dvb_frontend_event CFrontend::getEvent(void)
{ {
@@ -566,7 +561,7 @@ void CFrontend::getDelSys(int f, int m, char *&fec, char *&sys, char *&mod)
} }
} }
int CFrontend::setFrontend(const struct dvb_frontend_parameters *feparams, bool /*nowait*/) bool CFrontend::buildProperties(const struct dvb_frontend_parameters *feparams, struct dtv_properties& cmdseq)
{ {
fe_delivery_system delsys = SYS_DVBS; fe_delivery_system delsys = SYS_DVBS;
fe_modulation_t modulation = QPSK; fe_modulation_t modulation = QPSK;
@@ -575,8 +570,6 @@ int CFrontend::setFrontend(const struct dvb_frontend_parameters *feparams, bool
int fec; int fec;
fe_code_rate_t fec_inner; fe_code_rate_t fec_inner;
tuned = false;
/* Decode the needed settings */ /* Decode the needed settings */
switch (info.type) { switch (info.type) {
case FE_QPSK: case FE_QPSK:
@@ -595,9 +588,7 @@ int CFrontend::setFrontend(const struct dvb_frontend_parameters *feparams, bool
return 0; return 0;
} }
/* the ugly cast avoids a compiler warning, because the Coolstream switch (fec_inner) {
* private values are *not* fe_code_rate_t values */
switch ((int)fec_inner) {
case FEC_1_2: case FEC_1_2:
case FEC_S2_QPSK_1_2: case FEC_S2_QPSK_1_2:
case FEC_S2_8PSK_1_2: case FEC_S2_8PSK_1_2:
@@ -660,71 +651,80 @@ int CFrontend::setFrontend(const struct dvb_frontend_parameters *feparams, bool
break; break;
} }
char *f, *s, *m; int nrOfProps = 0;
getDelSys(fec_inner, modulation, f, s, m);
//printf("[fe0] DEMOD: FEC %s system %s modulation %s pilot %s\n", f, s, m, pilot == PILOT_ON ? "on" : "off");
if(0) {
//TIMER_INIT();
//TIMER_START();
if ((ioctl(fd, FE_SET_PROPERTY, &clr_cmdseq)) == -1) {
perror("FE_SET_PROPERTY failed");
return 0;
}
//TIMER_STOP("[fe0] FE_SET_PROPERTY clear took");
}
struct dtv_properties *p;
switch (info.type) { switch (info.type) {
case FE_QPSK: case FE_QPSK:
if (delsys == SYS_DVBS2) { if (delsys == SYS_DVBS2) {
p = &dvbs2_cmdseq; nrOfProps = FE_DVBS2_PROPS;
p->props[MODULATION].u.data = modulation; memcpy(cmdseq.props, dvbs2_cmdargs, sizeof(dvbs2_cmdargs));
p->props[ROLLOFF].u.data = rolloff;
p->props[PILOTS].u.data = pilot; cmdseq.props[MODULATION].u.data = modulation;
cmdseq.props[ROLLOFF].u.data = rolloff;
cmdseq.props[PILOTS].u.data = pilot;
} else { } else {
p = &dvbs_cmdseq; memcpy(cmdseq.props, dvbs_cmdargs, sizeof(dvbs_cmdargs));
nrOfProps = FE_DVBS_PROPS;
} }
p->props[FREQUENCY].u.data = feparams->frequency; cmdseq.props[FREQUENCY].u.data = feparams->frequency;
p->props[SYMBOL_RATE].u.data = feparams->u.qpsk.symbol_rate; cmdseq.props[SYMBOL_RATE].u.data= feparams->u.qpsk.symbol_rate;
p->props[INNER_FEC].u.data = fec; /*_inner*/ ; cmdseq.props[INNER_FEC].u.data = fec; /*_inner*/ ;
break; break;
case FE_QAM: case FE_QAM:
p = &dvbc_cmdseq; memcpy(cmdseq.props, dvbc_cmdargs, sizeof(dvbc_cmdargs));
p->props[FREQUENCY].u.data = feparams->frequency; cmdseq.props[FREQUENCY].u.data = feparams->frequency;
p->props[MODULATION].u.data = modulation; cmdseq.props[MODULATION].u.data = modulation;
p->props[SYMBOL_RATE].u.data = feparams->u.qam.symbol_rate; cmdseq.props[SYMBOL_RATE].u.data= feparams->u.qam.symbol_rate;
p->props[INNER_FEC].u.data = fec_inner; cmdseq.props[INNER_FEC].u.data = fec_inner;
nrOfProps = FE_DVBC_PROPS;
break; break;
default: default:
printf("frontend: unknown frontend type, exiting\n"); printf("frontend: unknown frontend type, exiting\n");
return 0; return false;
} }
struct dvb_frontend_event ev;
if (uni_scr >= 0)
cmdseq.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.*/
cmdseq.num += nrOfProps;
return true;
}
int CFrontend::setFrontend(const struct dvb_frontend_parameters *feparams, bool /*nowait*/)
{
struct dtv_property cmdargs[FE_COMMON_PROPS + FE_DVBS2_PROPS]; // WARNING: increase when needed more space
struct dtv_properties cmdseq;
cmdseq.num = FE_COMMON_PROPS;
cmdseq.props = cmdargs;
tuned = false;
//printf("[fe0] DEMOD: FEC %s system %s modulation %s pilot %s\n", f, s, m, pilot == PILOT_ON ? "on" : "off");
struct dvb_frontend_event ev;
{ {
//TIMER_INIT(); // Erase previous events
//TIMER_START();
while (1) { while (1) {
if (ioctl(fd, FE_GET_EVENT, &ev) < 0) if (ioctl(fd, FE_GET_EVENT, &ev) < 0)
break; break;
printf("[fe0] DEMOD: event status %d\n", ev.status); printf("[fe0] DEMOD: event status %d\n", ev.status);
} }
//TIMER_STOP("[fe0] clear events took");
} }
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); //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);
if (!buildProperties(feparams, cmdseq))
return 0;
{ {
TIMER_INIT(); TIMER_INIT();
TIMER_START(); TIMER_START();
if ((ioctl(fd, FE_SET_PROPERTY, p)) < 0) { if ((ioctl(fd, FE_SET_PROPERTY, &cmdseq)) < 0) {
perror("FE_SET_PROPERTY failed"); perror("FE_SET_PROPERTY failed");
return false; return false;
} }
@@ -1005,7 +1005,7 @@ uint32_t CFrontend::sendEN50494TuningCommand(const uint32_t frequency, const int
unsigned int t = (frequency / 1000 + bpf + 2) / 4 - 350; unsigned int t = (frequency / 1000 + bpf + 2) / 4 - 350;
if (t < 1024 && uni_scr >= 0 && uni_scr < 8) 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); 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 */ cmd.msg[3] = (t >> 8) | /* highest 3 bits of t */
(uni_scr << 5) | /* adress */ (uni_scr << 5) | /* adress */
(bank << 4) | /* not implemented yet */ (bank << 4) | /* not implemented yet */