From 41a9626be4919e952dbe337e666fa712f830571a Mon Sep 17 00:00:00 2001 From: none Date: Wed, 7 Apr 2021 19:20:24 +0200 Subject: [PATCH 01/10] remove unnused variable --- ddbridge/ddbridge-modulator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/ddbridge/ddbridge-modulator.c b/ddbridge/ddbridge-modulator.c index c5a9b70..33c2385 100644 --- a/ddbridge/ddbridge-modulator.c +++ b/ddbridge/ddbridge-modulator.c @@ -644,7 +644,6 @@ static int mod_set_sdr_attenuator(struct ddb *dev, u32 value) static int mod_set_sdr_gain(struct ddb *dev, u32 gain) { u32 control = ddbreadl(dev, SDR_CONTROL); - struct ddb_link *link = &dev->link[0]; if (control & 0x01000000) { if (gain > 511) From 35c283bf2f4e6cc069d99edaa20fb45219b313a2 Mon Sep 17 00:00:00 2001 From: none Date: Wed, 7 Apr 2021 19:20:38 +0200 Subject: [PATCH 02/10] remove test command --- ddbridge/ddbridge-modulator.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/ddbridge/ddbridge-modulator.c b/ddbridge/ddbridge-modulator.c index 33c2385..5b4b794 100644 --- a/ddbridge/ddbridge-modulator.c +++ b/ddbridge/ddbridge-modulator.c @@ -658,8 +658,6 @@ static int mod_set_sdr_gain(struct ddb *dev, u32 gain) return -EINVAL; ddbwritel(dev, gain, SDR_GAIN_F); } - if (link->mci_ok) - mci_cmd_val(link, 0xc0, gain); return 0; } From f12fe91b5172da9644916270f16b435f1f5ba49a Mon Sep 17 00:00:00 2001 From: none Date: Wed, 7 Apr 2021 19:21:24 +0200 Subject: [PATCH 03/10] use PCI revision to determine major firmware version --- ddbridge/ddbridge-main.c | 1 + ddbridge/ddbridge-modulator.c | 3 +++ ddbridge/ddbridge.h | 1 + 3 files changed, 5 insertions(+) diff --git a/ddbridge/ddbridge-main.c b/ddbridge/ddbridge-main.c index f84536c..631ad86 100644 --- a/ddbridge/ddbridge-main.c +++ b/ddbridge/ddbridge-main.c @@ -312,6 +312,7 @@ static int __devinit ddb_probe(struct pci_dev *pdev, dev->link[0].ids.subvendor = id->subvendor; dev->link[0].ids.subdevice = pdev->subsystem_device; dev->link[0].ids.devid = (id->device << 16) | id->vendor; + dev->link[0].ids.revision = pdev->revision; dev->link[0].dev = dev; dev->link[0].info = get_ddb_info(id->vendor, id->device, diff --git a/ddbridge/ddbridge-modulator.c b/ddbridge/ddbridge-modulator.c index 5b4b794..986cf2f 100644 --- a/ddbridge/ddbridge-modulator.c +++ b/ddbridge/ddbridge-modulator.c @@ -2029,6 +2029,9 @@ static int mod_init_sdr_iq(struct ddb *dev) ddbwritel(dev, 0x01, 0x240); + if (dev->link[0].ids.revision == 1) + return 0; + //mod3_set_base_frequency(dev, 602000000); dev->mod_base.frequency = 570000000; for (i = 0; i < streams; i++) { diff --git a/ddbridge/ddbridge.h b/ddbridge/ddbridge.h index 7002590..c986e6a 100644 --- a/ddbridge/ddbridge.h +++ b/ddbridge/ddbridge.h @@ -143,6 +143,7 @@ struct ddb_ids { u32 regmapid; u32 devid; u32 mac; + u8 revision; }; struct ddb_info { From 2311b94970cce2a7d8fa9e7e2b0df36fb9c8b63d Mon Sep 17 00:00:00 2001 From: none Date: Wed, 7 Apr 2021 19:25:32 +0200 Subject: [PATCH 04/10] add modulator MCI commands --- apps/modconfig.c | 268 ++++++++++++++++++++++++++++++++++++++++ ddbridge/ddbridge-mci.h | 64 ++++++++++ 2 files changed, 332 insertions(+) create mode 100644 apps/modconfig.c diff --git a/apps/modconfig.c b/apps/modconfig.c new file mode 100644 index 0000000..ce1c95b --- /dev/null +++ b/apps/modconfig.c @@ -0,0 +1,268 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef uint8_t u8; +typedef uint16_t u16; +typedef int16_t s16; +typedef uint32_t u32; +typedef uint64_t u64; + +#include "../ddbridge/ddbridge-mci.h" +#include "../ddbridge/ddbridge-ioctl.h" + +struct mconf { + int set_output; + int set_channels; + int fd; + + struct mci_command channels; + struct mci_command stream; + struct mci_command output; +}; + +void strim(char *s) +{ + int l = strlen(s); + + while (l && isspace(s[l-1])) + l--; + s[l] = 0; +} + +void parse(char *fname, char *sec, void *priv, void (*cb)(void *, char *, char *)) +{ + char line[256], csec[80], par[80], val[80], *p; + FILE *f; + + if ((f = fopen(fname, "r")) == NULL) + return; + while ((p = fgets(line, sizeof(line), f))) { + if (*p == '\r' || *p == '\n' || *p == '#') + continue; + if (*p == '[') { + if ((p = strtok(line + 1, "]")) == NULL) + continue; + strncpy(csec, p, sizeof(csec)); + if (!strcmp(sec, csec) && cb) + cb(priv, NULL, NULL); + continue; + } + if (!(p = strtok(line, "="))) + continue; + while (isspace(*p)) + p++; + strncpy(par, p, sizeof(par)); + strim(par); + if (!(p = strtok(NULL, "="))) + continue; + while (isspace(*p)) + p++; + strncpy (val, p, sizeof(val)); + strim(val); + if (!strcmp(sec, csec) && cb) + cb(priv, par, val); + } + if (!strcmp(sec, csec) && cb) + cb(priv, NULL, NULL); + fclose(f); +} + +int mci_cmd(int dev, struct mci_command *cmd) +{ + int ret; + struct ddb_mci_msg msg; + + msg.link = 0; + memcpy(&msg.cmd, cmd, sizeof(msg.cmd)); + ret = ioctl(dev, IOCTL_DDB_MCI_CMD, &msg); + if (ret < 0) { + printf("mci_cmd error %d\n", errno); + return ret; + } + return ret; +} + +struct mci_command msg_channels = { + .mod_command = MOD_SETUP_CHANNELS, + .mod_channel = 0, + .mod_stream = 0, + .mod_setup_channels[0] = { + .flags = MOD_SETUP_FLAG_FIRST|MOD_SETUP_FLAG_LAST|MOD_SETUP_FLAG_VALID, + .standard = MOD_STANDARD_DVBT_8, + .num_channels = 25, + .frequency = 474000000, + }, +}; + +struct mci_command msg_stream = { + .mod_command = MOD_SETUP_STREAM, + .mod_channel = 1, + .mod_stream = 0, + .mod_setup_stream = { + .standard = MOD_STANDARD_DVBT_8, + .fft_size = 1, + .guard_interval = 0, + }, +}; + +struct mci_command msg_output = { + .mod_command = MOD_SETUP_OUTPUT, + .mod_channel = 0, + .mod_stream = 0, + .mod_setup_output = { + .connector = MOD_CONNECTOR_F, + .num_channels = 16, + .unit = MOD_UNIT_DBUV, + .channel_power = 5000, + }, +}; + +void output_cb(void *priv, char *par, char *val) +{ + struct mconf *mc = (struct mconf *) priv; + + if (!par && !val) { + mc->set_output = 1; + return; + } + if (!strcasecmp(par, "connector")) { + if (!strcasecmp(val, "F")) { + mc->output.mod_setup_output.connector = MOD_CONNECTOR_F; + } else if (!strcasecmp(val, "SMA")) { + mc->output.mod_setup_output.connector = MOD_CONNECTOR_SMA; + } else if (!strcasecmp(val, "OFF")) { + mc->output.mod_setup_output.connector = MOD_CONNECTOR_OFF; + } else + printf("invalid connector\n"); + } else if (!strcasecmp(par, "power")) { + mc->output.mod_setup_output.channel_power = strtol(val, NULL, 10); + } else if (!strcasecmp(par, "channels")) { + mc->output.mod_setup_output.num_channels = strtol(val, NULL, 10); + }else if (!strcasecmp(par, "unit")) { + if (!strcasecmp(val, "DBUV")) { + mc->output.mod_setup_output.unit = MOD_UNIT_DBUV; + } else if (!strcasecmp(val, "DBM")) { + mc->output.mod_setup_output.unit = MOD_UNIT_DBM; + } else + printf("invalid unit\n"); + } else + printf("invalid output parameter: %s\n", par); +} + +void channels_cb(void *priv, char *par, char *val) +{ + struct mconf *mc = (struct mconf *) priv; + + if (!par && !val) { + mc->set_channels = 1; + return; + } + if (!strcasecmp(par, "frequency")) { + mc->channels.mod_setup_channels[0].frequency = strtol(val, NULL, 10); + printf("frequency = %u\n", mc->channels.mod_setup_channels[0].frequency); + } else if (!strcasecmp(par, "channels")) { + mc->channels.mod_setup_channels[0].num_channels = strtol(val, NULL, 10); + } else if (!strcasecmp(par, "standard")) { + mc->channels.mod_setup_channels[0].standard = strtol(val, NULL, 10); + } else if (!strcasecmp(par, "offset")) { + mc->channels.mod_setup_channels[0].offset = strtol(val, NULL, 10); + } else if (!strcasecmp(par, "bandwidth")) { + mc->channels.mod_setup_channels[0].bandwidth = strtol(val, NULL, 10); + mc->channels.mod_setup_channels[0].offset = + mc->channels.mod_setup_channels[0].bandwidth / 2; + } else + printf("invalid channels parameter: %s\n", par); +} + +void streams_cb(void *priv, char *par, char *val) +{ + struct mconf *mc = (struct mconf *) priv; + + if (!par && !val) { + return; + } + if (!strcasecmp(par, "fft_size")) { + mc->stream.mod_setup_stream.fft_size = strtol(val, NULL, 10); + } else if (!strcasecmp(par, "guard_interval")) { + mc->stream.mod_setup_stream.guard_interval = strtol(val, NULL, 10); + } else if (!strcasecmp(par, "standard")) { + mc->stream.mod_setup_stream.standard = strtol(val, NULL, 10); + } else if (!strcasecmp(par, "stream_format")) { + mc->stream.mod_setup_stream.stream_format = strtol(val, NULL, 10); + } else if (!strcasecmp(par, "symbol_rate")) { + mc->stream.mod_setup_stream.symbol_rate = strtol(val, NULL, 10); + } else if (!strcasecmp(par, "stream")) { + mc->stream.mod_stream = strtol(val, NULL, 10); + printf("set stream %u to channel %u\n", mc->stream.mod_stream, mc->stream.mod_channel); + mci_cmd(mc->fd, &mc->stream); + } else if (!strcasecmp(par, "channel")) { + mc->stream.mod_channel = strtol(val, NULL, 10); + } else + printf("invalid streams parameter: %s\n", par); +} + +int main(int argc, char*argv[]) +{ + int fd = -1; + char fn[128]; + uint32_t device = 0; + uint32_t frequency = 0; + char *configname = "modulator.conf"; + struct mconf mc; + + memset(&mc, 0, sizeof(mc)); + mc.channels = msg_channels; + mc.stream = msg_stream; + mc.output = msg_output; + + while (1) { + int cur_optind = optind ? optind : 1; + int option_index = 0; + int c; + static struct option long_options[] = { + {"device", required_argument, 0, 'd'}, + {"config", required_argument, 0, 'c'}, + {0, 0, 0, 0} + }; + c = getopt_long(argc, argv, "d:c:", + long_options, &option_index); + if (c == -1) + break; + switch (c) { + case 'd': + device = strtoul(optarg, NULL, 0); + break; + case 'c': + configname = optarg; + break; + default: + break; + } + } + if (optind < argc) { + printf("too many arguments\n"); + exit(1); + } + snprintf(fn, 127, "/dev/ddbridge/card%u", device); + fd = open(fn, O_RDWR); + if (fd < 0) + return -1; + mc.fd = fd; + parse(configname, "output", (void *) &mc, output_cb); + if (mc.set_output) + mci_cmd(fd, &mc.output); + parse(configname, "channels", (void *) &mc, channels_cb); + if (mc.set_channels) + mci_cmd(fd, &mc.channels); + parse(configname, "streams", (void *) &mc, streams_cb); +} diff --git a/ddbridge/ddbridge-mci.h b/ddbridge/ddbridge-mci.h index d770a6d..5645a9c 100644 --- a/ddbridge/ddbridge-mci.h +++ b/ddbridge/ddbridge-mci.h @@ -185,6 +185,60 @@ #define MCI_SUCCESS(status) ((status & MCI_STATUS_UNSUPPORTED) == 0) +/********************************************************/ + +#define MOD_SETUP_CHANNELS (0x60) +#define MOD_SETUP_OUTPUT (0x61) +#define MOD_SETUP_STREAM (0x62) + +#define MOD_SETUP_FLAG_FIRST (0x01) +#define MOD_SETUP_FLAG_LAST (0x02) +#define MOD_SETUP_FLAG_VALID (0x80) + +#define MOD_STANDARD_GENERIC (0x00) +#define MOD_STANDARD_DVBT_8 (0x01) +#define MOD_STANDARD_DVBT_7 (0x02) +#define MOD_STANDARD_DVBT_6 (0x03) + +#define MOD_CONNECTOR_OFF (0x00) +#define MOD_CONNECTOR_F (0x01) +#define MOD_CONNECTOR_SMA (0x02) + +#define MOD_UNIT_DBUV (0x00) +#define MOD_UNIT_DBM (0x01) + +#define MOD_FORMAT_DEFAULT (0x00) +#define MOD_FORMAT_IQ16 (0x01) +#define MOD_FORMAT_IQ8 (0x02) +#define MOD_FORMAT_IDX8 (0x03) +#define MOD_FORMAT_TS (0x04) + +struct mod_setup_channels { + u8 flags; + u8 standard; + u8 num_channels; + u8 rsvd; + u32 frequency; + u32 offset; /* used only when Standard == 0 */ + u32 bandwidth; /* used only when Standard == 0 */ +}; + +struct mod_setup_stream { + u8 standard; + u8 stream_format; + u8 rsvd[2]; + u32 symbol_rate; /* only used when Standard doesn't define a fixed symbol rate */ + u8 fft_size; /* 0 = 2K, 1 = 8K (2K yet supported) */ + u8 guard_interval; /* 0 = 1/32, 1 = 1/16, 2 = 1/8, 3 = 1/4 (DVB-T Encoding) */ +}; + +struct mod_setup_output { + u8 connector; /* 0 = OFF, 1 = F, 2 = SMA */ + u8 num_channels; /* max active channels, determines max power for each channel. */ + u8 unit; /* 0 = dBµV, 1 = dBm, */ + u8 rsvd; + s16 channel_power; +}; /********************************************************/ @@ -197,6 +251,12 @@ struct mci_command { u8 demod; u8 output; }; + struct { + u8 mod_command; + u8 mod_channel; + u8 mod_stream; + u8 mod_rsvd1; + }; }; union { u32 params[31]; @@ -344,6 +404,10 @@ struct mci_command { struct { u8 select; // 0 = Data PLP, 1 = Common PLP, only DVB-T2 and DVB-C2 } get_bb_header; + + struct mod_setup_channels mod_setup_channels[4]; + struct mod_setup_stream mod_setup_stream; + struct mod_setup_output mod_setup_output; }; }; From 3cb3df51cf2eb43507a56c898bfabca635301e11 Mon Sep 17 00:00:00 2001 From: none Date: Wed, 7 Apr 2021 19:27:21 +0200 Subject: [PATCH 05/10] use correct kernel integer types --- ddbridge/ddbridge-mci.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ddbridge/ddbridge-mci.h b/ddbridge/ddbridge-mci.h index 5645a9c..e38669e 100644 --- a/ddbridge/ddbridge-mci.h +++ b/ddbridge/ddbridge-mci.h @@ -367,27 +367,27 @@ struct mci_command { } get_iq_symbol; struct { - uint8_t flags; /* Bit 0 : 0 = VTM/SDR, 1 = SCAN, + u8 flags; /* Bit 0 : 0 = VTM/SDR, 1 = SCAN, Bit 1: 1 = Disable AGC, Bit 2: 1 = Set Gain. */ - uint8_t roll_off; - uint8_t rsvd1; - uint8_t rsvd2; - uint32_t frequency; - uint32_t symbol_rate; /* Only in VTM/SDR mode, SCAN Mode uses exactly 1550/24 MSymbols/s.*/ - uint8_t gain; /* Gain in 0.25 dB Steps */ + u8 roll_off; + u8 rsvd1; + u8 rsvd2; + u32 frequency; + u32 symbol_rate; /* Only in VTM/SDR mode, SCAN Mode uses exactly 1550/24 MSymbols/s.*/ + u8 gain; /* Gain in 0.25 dB Steps */ /* Frequency, symbolrate and gain can be schanged while running */ } sx8_start_iq; struct { - uint8_t flags; + u8 flags; /* Bit 0:1 Preamp Mode; 0 = Preamp AGC, 1 == Minimum (~ -17dB) , 2 = Medium, 3 = Maximum gain {~ 15dB} Bit 2: Bypass Input LNA (6 dB less gain) (Note this is after Preamp) Bit 4: Set RF Gain Bit 5: Freeze RF Gain (Turn AGC off at current gain, only when already enabled) Bit 7: Optimize RF Gain and freeze for FFT */ - uint8_t rf_gain; /* 0 .. 50 dB */ + u8 rf_gain; /* 0 .. 50 dB */ } sx8_input_enable; struct { @@ -864,7 +864,7 @@ int ddb_mci_get_info(struct mci *mci); int ddb_mci_get_strength(struct dvb_frontend *fe); void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p); int mci_init(struct ddb_link *link); -int mci_cmd_val(struct ddb_link *link, uint32_t cmd, uint32_t val); +int mci_cmd_val(struct ddb_link *link, u32 cmd, u32 val); extern struct mci_cfg ddb_max_sx8_cfg; extern struct mci_cfg ddb_max_m4_cfg; From a5ad0b0584c22c715864a0d4598ffa5b10aefa65 Mon Sep 17 00:00:00 2001 From: none Date: Wed, 7 Apr 2021 19:28:12 +0200 Subject: [PATCH 06/10] show MCI firmware version --- ddbridge/ddbridge-mci.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/ddbridge/ddbridge-mci.c b/ddbridge/ddbridge-mci.c index 4b5bff4..b8b9426 100644 --- a/ddbridge/ddbridge-mci.c +++ b/ddbridge/ddbridge-mci.c @@ -34,10 +34,16 @@ static int mci_reset(struct ddb_link *link) u32 control; u32 status = 0; u32 timeout = 40; - - if (!regmap || ! regmap->mci) + union { + u32 u[4]; + char s[16]; + } version; + u32 vaddr; + + if (!regmap || !regmap->mci) return -EINVAL; control = regmap->mci->base; + vaddr = regmap->mci_buf->base + 0xf0; if ((link->info->type == DDB_OCTOPUS_MCI) && (ddblreadl(link, control) & MCI_CONTROL_START_COMMAND)) { @@ -55,11 +61,17 @@ static int mci_reset(struct ddb_link *link) msleep(50); } dev_info(link->dev->dev, "MCI control port @ %08x\n", control); + if ((status & MCI_CONTROL_READY) == 0) { dev_err(link->dev->dev, "MCI init failed!\n"); return -1; } + version.u[0] = ddblreadl(link, vaddr); + version.u[1] = ddblreadl(link, vaddr + 4); + version.u[2] = ddblreadl(link, vaddr + 8); + version.u[3] = ddblreadl(link, vaddr + 12); dev_info(link->dev->dev, "MCI port OK, init time %u msecs\n", (40 - timeout) * 50); + dev_info(link->dev->dev, "MCI firmware version %s.%d\n", version.s, version.s[15]); return 0; } From c4f82de8b04b62864dd210d5335b5f3417551b38 Mon Sep 17 00:00:00 2001 From: none Date: Wed, 7 Apr 2021 19:28:49 +0200 Subject: [PATCH 07/10] add modconfig --- apps/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/Makefile b/apps/Makefile index 31a1ed5..44ddd15 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -1,4 +1,4 @@ -all: cit citin flashprog modt ddtest setmod ddflash setmod2 pls setmod3 +all: cit citin flashprog modt ddtest setmod ddflash setmod2 pls setmod3 modconfig cit: cit.c $(CC) -o cit cit.c -lpthread @@ -15,6 +15,9 @@ setmod2: setmod2.c setmod3: setmod3.c $(CC) -o setmod3 setmod3.c -I../include/ +modconfig: modconfig.c + $(CC) -o modconfig modconfig.c -I../include/ + %.o: %.c $(CC) $(CFLAGS) -o $@ $< From 03d84ba75a711deb3452583ab531a13dac921e78 Mon Sep 17 00:00:00 2001 From: none Date: Wed, 7 Apr 2021 19:29:18 +0200 Subject: [PATCH 08/10] add example modulator config file --- apps/modulator.conf | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 apps/modulator.conf diff --git a/apps/modulator.conf b/apps/modulator.conf new file mode 100644 index 0000000..1d92b27 --- /dev/null +++ b/apps/modulator.conf @@ -0,0 +1,22 @@ +[output] +connector = F +channels = 16 +unit = DBUV +power = 5000 + +[channels] +standard = 1 +channels = 25 +frequency = 474000000 + +[streams] +guard_interval = 0 +fft_size = 1 + +channel = 1 +stream = 0 + +channel = 0 +stream = 1 + + From 50e354c49a6f7aaef58b759629b7c589ac826714 Mon Sep 17 00:00:00 2001 From: none Date: Wed, 7 Apr 2021 19:29:53 +0200 Subject: [PATCH 09/10] cleanup --- ddbridge/ddbridge-mci.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/ddbridge/ddbridge-mci.c b/ddbridge/ddbridge-mci.c index b8b9426..5cf9da4 100644 --- a/ddbridge/ddbridge-mci.c +++ b/ddbridge/ddbridge-mci.c @@ -120,6 +120,7 @@ static int ddb_mci_cmd_raw_unlocked(struct ddb_link *link, 0xffffff, INTERRUPT_ACK); } } + //print_hex_dump(KERN_INFO, "MCI", DUMP_PREFIX_OFFSET, 16, 1, cmd, cmd_len, false); if (res && res_len) for (i = 0; i < res_len; i++) res[i] = ddblreadl(link, result + i * 4); @@ -178,17 +179,10 @@ int mci_init(struct ddb_link *link) int mci_cmd_val(struct ddb_link *link, uint32_t cmd, uint32_t val) { struct mci_result result; -#if 0 - struct mci_command command = { - .command_word = cmd, - .params = { val }, - }; -#else struct mci_command command; command.command_word = cmd; command.params[0] = val; -#endif return ddb_mci_cmd_link(link, &command, &result); } From 7bafb76461a4cedf5f67e2d8bfef7b5b7498cc5a Mon Sep 17 00:00:00 2001 From: none Date: Fri, 9 Apr 2021 12:53:06 +0200 Subject: [PATCH 10/10] change to floating point for frequency and signal strength add comments to example config --- apps/modconfig.c | 32 +++++++++++++++++++++++++------- apps/modulator.conf | 39 ++++++++++++++++++++++++++++++++++----- 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/apps/modconfig.c b/apps/modconfig.c index ce1c95b..9562ae7 100644 --- a/apps/modconfig.c +++ b/apps/modconfig.c @@ -81,12 +81,24 @@ int mci_cmd(int dev, struct mci_command *cmd) { int ret; struct ddb_mci_msg msg; + uint8_t status; msg.link = 0; memcpy(&msg.cmd, cmd, sizeof(msg.cmd)); ret = ioctl(dev, IOCTL_DDB_MCI_CMD, &msg); if (ret < 0) { - printf("mci_cmd error %d\n", errno); + dprintf(2, "mci_cmd error %d\n", errno); + return ret; + } + status = msg.res.status; + if (status == MCI_STATUS_OK) + return ret; + if (status == MCI_STATUS_UNSUPPORTED) { + dprintf(2, "Unsupported MCI command\n"); + return ret; + } + if (status == MCI_STATUS_INVALID_PARAMETER) { + dprintf(2, "Invalid MCI parameters\n"); return ret; } return ret; @@ -145,7 +157,7 @@ void output_cb(void *priv, char *par, char *val) } else printf("invalid connector\n"); } else if (!strcasecmp(par, "power")) { - mc->output.mod_setup_output.channel_power = strtol(val, NULL, 10); + mc->output.mod_setup_output.channel_power = (uint32_t) (strtod(val, NULL) * 100.0); } else if (!strcasecmp(par, "channels")) { mc->output.mod_setup_output.num_channels = strtol(val, NULL, 10); }else if (!strcasecmp(par, "unit")) { @@ -168,16 +180,16 @@ void channels_cb(void *priv, char *par, char *val) return; } if (!strcasecmp(par, "frequency")) { - mc->channels.mod_setup_channels[0].frequency = strtol(val, NULL, 10); + mc->channels.mod_setup_channels[0].frequency = (uint32_t) (strtod(val, NULL) * 1000000.0); printf("frequency = %u\n", mc->channels.mod_setup_channels[0].frequency); } else if (!strcasecmp(par, "channels")) { mc->channels.mod_setup_channels[0].num_channels = strtol(val, NULL, 10); } else if (!strcasecmp(par, "standard")) { mc->channels.mod_setup_channels[0].standard = strtol(val, NULL, 10); } else if (!strcasecmp(par, "offset")) { - mc->channels.mod_setup_channels[0].offset = strtol(val, NULL, 10); + mc->channels.mod_setup_channels[0].offset = (uint32_t) (strtod(val, NULL) * 1000000.0); } else if (!strcasecmp(par, "bandwidth")) { - mc->channels.mod_setup_channels[0].bandwidth = strtol(val, NULL, 10); + mc->channels.mod_setup_channels[0].bandwidth = (uint32_t) (strtod(val, NULL) * 1000000.0); mc->channels.mod_setup_channels[0].offset = mc->channels.mod_setup_channels[0].bandwidth / 2; } else @@ -200,7 +212,7 @@ void streams_cb(void *priv, char *par, char *val) } else if (!strcasecmp(par, "stream_format")) { mc->stream.mod_setup_stream.stream_format = strtol(val, NULL, 10); } else if (!strcasecmp(par, "symbol_rate")) { - mc->stream.mod_setup_stream.symbol_rate = strtol(val, NULL, 10); + mc->stream.mod_setup_stream.symbol_rate = (uint32_t) (strtod(val, NULL) * 1000000.0); } else if (!strcasecmp(par, "stream")) { mc->stream.mod_stream = strtol(val, NULL, 10); printf("set stream %u to channel %u\n", mc->stream.mod_stream, mc->stream.mod_channel); @@ -232,6 +244,7 @@ int main(int argc, char*argv[]) static struct option long_options[] = { {"device", required_argument, 0, 'd'}, {"config", required_argument, 0, 'c'}, + {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, "d:c:", @@ -245,6 +258,9 @@ int main(int argc, char*argv[]) case 'c': configname = optarg; break; + case 'h': + dprintf(2, "modconfig [-d device_number] [-c config_file]\n"); + break; default: break; } @@ -255,8 +271,10 @@ int main(int argc, char*argv[]) } snprintf(fn, 127, "/dev/ddbridge/card%u", device); fd = open(fn, O_RDWR); - if (fd < 0) + if (fd < 0) { + dprintf(2, "Could not open %s\n", fn); return -1; + } mc.fd = fd; parse(configname, "output", (void *) &mc, output_cb); if (mc.set_output) diff --git a/apps/modulator.conf b/apps/modulator.conf index 1d92b27..1f4cf5c 100644 --- a/apps/modulator.conf +++ b/apps/modulator.conf @@ -1,22 +1,51 @@ [output] +# connector = OFF, SMA or F connector = F +# number of total channels to be used at the same time +# use lower number to have fewer channels but stronger signal per channel channels = 16 +# unit of power in DBUV or DBM unit = DBUV -power = 5000 +# power output in units of above unit +power = 50.0 + + +# define channels: +# channels are frequency slots to which a stream (mod0, mod1 ...) can be assigned [channels] +# standard: 0 = generic, 1 = DVB-T 8MHz, 2 = DVB-T 7 MHz, 3 = DVB-T 6 MHz standard = 1 + +# numbers of channels to allocate, starting from frequency below +# this defines 25 channels at 474, 474+8, 474+16, etc. Mhz channels = 25 -frequency = 474000000 +# frequency of channel 0, following channels are spaced according to set standard +frequency = 474.0 + [streams] +# number of streams depends on the card hardware +# streams correspond to devices mod0, mod1, ... +# channels are defined above in channels section + +# 0 = 1/32, 1 = 1/16, 2 = 1/8, 3 = 1/4 guard_interval = 0 +# 0 = 2K, 1 = 8K (2K not yet supported) fft_size = 1 +# all following streams will be set according to the last set other parameters + +# example: +# this would set mod 1 to 474 MHz and mod0 to 482 MHz (474 + 8 MHz) +# both with guard interval 1/32 and 8K FFT +# and mod2 to 490MHz, guard interval 1/16 and 8K FFT channel = 1 stream = 0 - +# channel = 0 stream = 1 - - +# +guard_interval = 1 +channel = 2 +stream = 2