diff --git a/apps/Makefile b/apps/Makefile index 44ddd15..16860c0 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -1,4 +1,4 @@ -all: cit citin flashprog modt ddtest setmod ddflash setmod2 pls setmod3 modconfig +all: cit citin flashprog modt ddtest setmod ddflash setmod2 pls setmod3 modconfig ddinfo cit: cit.c $(CC) -o cit cit.c -lpthread @@ -18,6 +18,9 @@ setmod3: setmod3.c modconfig: modconfig.c $(CC) -o modconfig modconfig.c -I../include/ -%.o: %.c - $(CC) $(CFLAGS) -o $@ $< +%: %.c + $(CC) $(CFLAGS) -I../ddbridge -I../include/ $< -o $@ + +%.o: %.c + $(CC) $(CFLAGS) -I../ddbridge -o $@ $< diff --git a/apps/ddinfo.c b/apps/ddinfo.c new file mode 100644 index 0000000..14555c7 --- /dev/null +++ b/apps/ddinfo.c @@ -0,0 +1,457 @@ +#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" + +char *Rolloff[8] = { + "0.35", + "0.25", + "0.20", + "0.10", + "0.05", + "0.15", + "rsvd", + "rsvd", +}; + +void print_temp(struct mci_result *res) +{ + printf("Die temperature = %u\n", res->sx8_bist.temperature); +} + +int temp_info(int dev) +{ + struct ddb_mci_msg msg = { + .link = 0, + .cmd.command = SX8_CMD_GETBIST, + }; + int ret; + int i; + + ret = ioctl(dev, IOCTL_DDB_MCI_CMD, &msg); + if (ret < 0) { + printf("Error: %d %d\n", ret, errno); + return ret; + } + if (msg.res.status & 0x80) { + printf("MCI errror %02x\n", msg.res.status); + return ret; + } + + print_temp(&msg.res); + return ret; +} + + +#define SIZE_OF_ARRAY(a) (sizeof(a)/sizeof(a[0])) + +char *DemodStatus[] = { + "Idle", + "IQ Mode", + "Wait for Signal", + "DVB-S2 Wait for MATYPE", + "DVB-S2 Wait for FEC", + "DVB-S1 Wait for FEC", + "Wait for TS", + "Unknown 7", + "Unknown 8", + "Unknown 9", + "Unknown 10", + "Unknown 11", + "Unknown 12", + "Unknown 13", + "Timeout", + "Locked", + "C2 Scan", +}; + +char* S2ModCods[32] = { +/* 0x00 */ "DummyPL" , + +// Legacy S2: index is S2_Modcod * 2 + short + +/* 0x01 */ "QPSK 1/4" , +/* 0x02 */ "QPSK 1/3" , +/* 0x03 */ "QPSK 2/5" , +/* 0x04 */ "QPSK 1/2" , +/* 0x05 */ "QPSK 3/5" , +/* 0x06 */ "QPSK 2/3" , +/* 0x07 */ "QPSK 3/4" , +/* 0x08 */ "QPSK 4/5" , +/* 0x09 */ "QPSK 5/6" , +/* 0x0A */ "QPSK 8/9" , +/* 0x0B */ "QPSK 9/10" , + +/* 0x0C */ "8PSK 3/5" , +/* 0x0D */ "8PSK 2/3" , +/* 0x0E */ "8PSK 3/4" , +/* 0x0F */ "8PSK 5/6" , +/* 0x10 */ "8PSK 8/9" , +/* 0x11 */ "8PSK 9/10" , + +/* 0x12 */ "16APSK 2/3" , +/* 0x13 */ "16APSK 3/4" , +/* 0x14 */ "16APSK 4/5" , +/* 0x15 */ "16APSK 5/6" , +/* 0x16 */ "16APSK 8/9" , +/* 0x17 */ "16APSK 9/10" , + +/* 0x18 */ "32APSK 3/4" , +/* 0x19 */ "32APSK 4/5" , +/* 0x1A */ "32APSK 5/6" , +/* 0x1B */ "32APSK 8/9" , +/* 0x1C */ "32APSK 9/10" , + +/* 0x1D */ "rsvd 0x1D" , +/* 0x1E */ "rsvd 0x1E" , +/* 0x1F */ "rsvd 0x1F" , +}; + + +///* 129 */ "VLSNR1" , +///* 131 */ "VLSNR2" , + +char* S2XModCods[59] = { +/* 0x42 */ "QPSK 13/45" , +/* 0x43 */ "QPSK 9/20" , +/* 0x44 */ "QPSK 11/20" , + +/* 0x45 */ "8APSK 5/9-L" , +/* 0x46 */ "8APSK 26/45-L" , +/* 0x47 */ "8PSK 23/36" , +/* 0x48 */ "8PSK 25/36" , +/* 0x49 */ "8PSK 13/18" , + +/* 0x4A */ "16APSK 1/2-L" , +/* 0x4B */ "16APSK 8/15-L" , +/* 0x4C */ "16APSK 5/9-L" , +/* 0x4D */ "16APSK 26/45" , +/* 0x4E */ "16APSK 3/5" , +/* 0x4F */ "16APSK 3/5-L" , +/* 0x50 */ "16APSK 28/45" , +/* 0x51 */ "16APSK 23/36" , +/* 0x52 */ "16APSK 2/3-L" , +/* 0x53 */ "16APSK 25/36" , +/* 0x54 */ "16APSK 13/18" , + +/* 0x55 */ "16APSK 7/9" , +/* 0x56 */ "16APSK 77/90" , + +/* 0x57 */ "32APSK 2/3-L" , +/* 0x58 */ "rsvd 32APSK" , +/* 0x59 */ "32APSK 32/45" , +/* 0x5A */ "32APSK 11/15" , +/* 0x5B */ "32APSK 7/9" , + +/* 0x5C */ "64APSK 32/45-L" , +/* 0x5D */ "64APSK 11/15" , +/* 0x5E */ "rsvd 64APSK" , +/* 0x5F */ "64APSK 7/9" , + +/* 0x60 */ "rsvd 64APSK" , +/* 0x61 */ "64APSK 4/5" , +/* 0x62 */ "rsvd 64APSK" , +/* 0x63 */ "64APSK 5/6" , + +/* 0x64 */ "128APSK 3/4" , +/* 0x65 */ "128APSK 7/9" , + +/* 0x66 */ "256APSK 29/45-L" , +/* 0x67 */ "256APSK 2/3-L" , +/* 0x68 */ "256APSK 31/45-L" , +/* 0x69 */ "256APSK 32/45" , +/* 0x6A */ "256APSK 11/15-L" , +/* 0x6B */ "256APSK 3/4" , + +/* 0x6C */ "QPSK 11/45-S" , +/* 0x6D */ "QPSK 4/15-S" , +/* 0x6E */ "QPSK 14/45-S" , +/* 0x6F */ "QPSK 7/15-S" , +/* 0x70 */ "QPSK 8/15-S" , +/* 0x71 */ "QPSK 32/45-S" , + +/* 0x72 */ "8PSK 7/15-S" , +/* 0x73 */ "8PSK 8/15-S" , +/* 0x74 */ "8PSK 26/45-S" , +/* 0x75 */ "8PSK 32/45-S" , + +/* 0x76 */ "16APSK 7/15-S" , +/* 0x77 */ "16APSK 8/15-S" , +/* 0x78 */ "16APSK 26/45-S" , +/* 0x79 */ "16APSK 3/5-S" , +/* 0x7A */ "16APSK 32/45-S" , + +/* 0x7B */ "32APSK 2/3-S" , +/* 0x7C */ "32APSK 32/45-S" , +}; + +char* S2Xrsvd[] = { +/* 250 */ "rsvd 8PSK" , +/* 251 */ "rsvd 16APSK" , +/* 252 */ "rsvd 32APSK" , +/* 253 */ "rsvd 64APSK" , +/* 254 */ "rsvd 256APSK" , +/* 255 */ "rsvd 1024APSK" , +}; + +char* PunctureRates[32] = { +/* 0x00 */ "QPSK 1/2", // DVB-S1 +/* 0x01 */ "QPSK 2/3", // DVB-S1 +/* 0x02 */ "QPSK 3/4", // DVB-S1 +/* 0x03 */ "QPSK 5/6", // DVB-S1 +/* 0x04 */ "QPSK 6/7", // DSS +/* 0x05 */ "QPSK 7/8", // DVB-S1 +/* 0x06 */ "rsvd 6.0", +/* 0x07 */ "rsvd 7.0", +}; + +void print_info(struct mci_result *res, uint8_t demod) +{ + if (res->status == MCI_DEMOD_STOPPED) { + printf("\nDemod %u: stopped\n", demod); + return; + } + + printf("\nDemod %u:\n", demod); + if (res->status == MCI_DEMOD_LOCKED) { + switch (res->mode) { + case M4_MODE_DVBSX: + if (res->dvbs2_signal_info.standard == 2) { + int short_frame = 0; + + if ((res->dvbs2_signal_info.pls_code >= 128) || + ((res->dvbs2_signal_info.roll_off & 0x7f) > 2)) + printf("Demod Locked: DVB-S2X\n"); + else + printf("Demod Locked: DVB-S2\n"); + printf("PLS-Code: %u\n", res->dvbs2_signal_info.pls_code); + printf("Roll-Off: %s\n", Rolloff[res->dvbs2_signal_info.roll_off]); + printf("Inversion: %s\n", (res->dvbs2_signal_info.roll_off & 0x80) ? "on": "off"); + printf("\n"); + } else { + printf("Demod Locked: DVB-S\n"); + printf("PR: %s\n", + PunctureRates[res->dvbs2_signal_info.pls_code & 0x07]); + + } + case M4_MODE_DVBT: + printf("Locked DVB-T\n"); + break; + case M4_MODE_DVBT2: + printf("Locked DVB-T2\n"); + break; + } + printf("SNR: %.2f dB\n", (float) res->dvbs2_signal_info.signal_to_noise / 100); + printf("Packet Errors: %u\n", res->dvbs2_signal_info.packet_errors); + printf("BER Numerator: %u\n", res->dvbs2_signal_info.ber_numerator); + printf("BER Denom.: %u\n", res->dvbs2_signal_info.ber_denominator); + } else { + printf("Demod State: %s\n", + res->status < SIZE_OF_ARRAY(DemodStatus) ? DemodStatus[res->status] : "?"); + + } + printf("Frequency: %u Hz\n", res->dvbs2_signal_info.frequency); + printf("Symbol Rate: %u Symbols/s\n", res->dvbs2_signal_info.symbol_rate); + printf("Channel Power: %.2f dBm\n", (float) res->dvbs2_signal_info.channel_power / 100); + if (res->dvbs2_signal_info.band_power > -10000) + printf("Band Power: %.2f dBm\n", (float) res->dvbs2_signal_info.band_power / 100); + +} + +int mci_info(int dev, uint8_t demod) +{ + struct ddb_mci_msg msg = { + .link = 0, + .cmd.command = MCI_CMD_GETSIGNALINFO, + .cmd.demod = demod + }; + int ret; + int i; + + ret = ioctl(dev, IOCTL_DDB_MCI_CMD, &msg); + if (ret < 0) { + printf("Error: %d %d\n", ret, errno); + return ret; + } + + print_info(&msg.res, demod); + return ret; +} + +static int get_id(int fd, int link, struct ddb_id *id) +{ + struct ddb_reg ddbreg; + + if (link == 0) { + if (ioctl(fd, IOCTL_DDB_ID, id) < 0) + return -1; + return 0; + } + ddbreg.reg = 8 + (link << 28); + if (ioctl(fd, IOCTL_DDB_READ_REG, &ddbreg) < 0) + return -1; + id->vendor = ddbreg.val; + id->device = ddbreg.val >> 16; + + ddbreg.reg = 12 + (link << 28); + if (ioctl(fd, IOCTL_DDB_READ_REG, &ddbreg) < 0) + return -1; + id->subvendor = ddbreg.val; + id->subdevice = ddbreg.val >> 16; + + ddbreg.reg = 0 + (link << 28); + if (ioctl(fd, IOCTL_DDB_READ_REG, &ddbreg) < 0) + return -1; + id->hw = ddbreg.val; + + ddbreg.reg = 4 + (link << 28); + if (ioctl(fd, IOCTL_DDB_READ_REG, &ddbreg) < 0) + return -1; + id->regmap = ddbreg.val; + return 0; +} + +static char *id2name(uint16_t id) +{ + switch (id) { + case 0x222: + return "MOD"; + case 0x0009: + return "MAX SX8"; + case 0x000b: + return "MAX SX8 Basic"; + case 0x000a: + return "MAX M4"; + default: + return " "; + } +} + +static int card_info(int ddbnum, int demod) +{ + char ddbname[80]; + struct ddb_id ddbid; + int ddb, ret, link, links = 1, i; + struct ddb_id id; + + sprintf(ddbname, "/dev/ddbridge/card%d", ddbnum); + ddb = open(ddbname, O_RDWR); + if (ddb < 0) + return -3; + + for (link = 0; link < links; link++) { + ret = get_id(ddb, link, &id); + if (ret < 0) + goto out; + if (!link) { + switch (id.device) { + case 0x20: + links = 4; + break; + case 0x300: + case 0x301: + case 0x307: + links = 2; + break; + + default: + break; + } + } + printf("\n\nCard %s link %u id %04x (%s):\n", + ddbname, link, id.device, id2name(id.device)); + printf("HW %08x REGMAP %08x FW %u.%u\n", + id.hw, id.regmap, (id.hw & 0xff0000) >> 16, (id.hw & 0xffff)); + switch (id.device) { + case 0x0009: + if (demod >= 0) + mci_info(ddb, demod); + else { + for (i = 0; i < 8; i++) + mci_info(ddb, i); + } + temp_info(ddb); + break; + case 0x000a: + if (demod >= 0) + mci_info(ddb, demod); + else { + for (i = 0; i < 4; i++) + mci_info(ddb, i); + } + break; + default: + break; + } + } + +out: + close(ddb); + return ret; +} + +int main(int argc, char*argv[]) +{ + int fd = -1, all = 1, i, ret = 0; + char fn[128]; + int32_t device = -1, demod = -1; + + while (1) { + int cur_optind = optind ? optind : 1; + int option_index = 0; + int c; + static struct option long_options[] = { + {"device", required_argument, 0, 'd'}, + {"demod", required_argument, 0, 'n'}, + {0, 0, 0, 0} + }; + c = getopt_long(argc, argv, "ad:n:", + long_options, &option_index); + if (c == -1) + break; + switch (c) { + case 'd': + device = strtoul(optarg, NULL, 0); + break; + case 'n': + demod = strtoul(optarg, NULL, 0); + break; + case 'a': + all = 1; + break; + default: + break; + } + } + if (optind < argc) { + printf("too many arguments\n"); + exit(1); + } + if (device >=0) + ret = card_info(device, demod); + else + for (i = 0; i < 100; i++) { + ret = card_info(i, -1); + + if (ret == -3) /* could not open, no more cards! */ + break; + if (ret < 0) + return i; /* fatal error */ + } +} diff --git a/apps/modconfig.c b/apps/modconfig.c index 9562ae7..d20ea07 100644 --- a/apps/modconfig.c +++ b/apps/modconfig.c @@ -24,7 +24,7 @@ struct mconf { int set_output; int set_channels; int fd; - + struct mci_command channels; struct mci_command stream; struct mci_command output; @@ -77,6 +77,98 @@ void parse(char *fname, char *sec, void *priv, void (*cb)(void *, char *, char * fclose(f); } +struct param_table_entry { + int value; + char* name; +}; + +struct param_table_entry mod_standard_table[] = { + { .name = "GENERIC", .value = MOD_STANDARD_GENERIC }, + { .name = "DVBT_8", .value = MOD_STANDARD_DVBT_8 }, + { .name = "DVBT_7", .value = MOD_STANDARD_DVBT_7 }, + { .name = "DVBT_6", .value = MOD_STANDARD_DVBT_6 }, + { .name = "DVBT_5", .value = MOD_STANDARD_DVBT_5 }, + { .name = "DVBT2_8", .value = MOD_STANDARD_DVBT_8 }, + { .name = "DVBT2_7", .value = MOD_STANDARD_DVBT_7 }, + { .name = "DVBT2_6", .value = MOD_STANDARD_DVBT_6 }, + { .name = "DVBT2_5", .value = MOD_STANDARD_DVBT_5 }, + { .name = "0", .value = MOD_STANDARD_GENERIC }, + { .name = "1", .value = MOD_STANDARD_DVBT_8 }, + { .name = "2", .value = MOD_STANDARD_DVBT_7 }, + { .name = "3", .value = MOD_STANDARD_DVBT_6 }, + { .name = "4", .value = MOD_STANDARD_DVBT_5 }, + { .name = NULL, .value = 0 } +}; + +struct param_table_entry stream_format_table[] = { + { .name = "default", .value = MOD_FORMAT_DEFAULT }, + { .name = "IQ16", .value = MOD_FORMAT_IQ16 }, + { .name = "IQ8", .value = MOD_FORMAT_IQ8 }, + { .name = "IDX8", .value = MOD_FORMAT_IDX8 }, + { .name = "TS", .value = MOD_FORMAT_TS }, + { .name = "0", .value = MOD_FORMAT_DEFAULT }, + { .name = "1", .value = MOD_FORMAT_IQ16 }, + { .name = "2", .value = MOD_FORMAT_IQ8 }, + { .name = "3", .value = MOD_FORMAT_IDX8 }, + { .name = "4", .value = MOD_FORMAT_TS }, + { .name = NULL, .value = 0 } +}; + + +struct param_table_entry guard_interval_table[] = { + { .name = "1/32", .value = MOD_DVBT_GI_1_32 }, + { .name = "1/16", .value = MOD_DVBT_GI_1_16 }, + { .name = "1/8", .value = MOD_DVBT_GI_1_8 }, + { .name = "1/4", .value = MOD_DVBT_GI_1_4 }, + { .name = "0", .value = MOD_DVBT_GI_1_32 }, + { .name = "1", .value = MOD_DVBT_GI_1_16 }, + { .name = "2", .value = MOD_DVBT_GI_1_8 }, + { .name = "3", .value = MOD_DVBT_GI_1_4 }, + { .name = NULL, .value = 0 } +}; + +struct param_table_entry puncture_rate_table[] = { + { .name = "1/2", .value = MOD_DVBT_PR_1_2 }, + { .name = "2/3", .value = MOD_DVBT_PR_2_3 }, + { .name = "3/4", .value = MOD_DVBT_PR_3_4 }, + { .name = "5/6", .value = MOD_DVBT_PR_5_6 }, + { .name = "7/8", .value = MOD_DVBT_PR_7_8 }, + { .name = "1", .value = MOD_DVBT_PR_1_2 }, + { .name = "2", .value = MOD_DVBT_PR_2_3 }, + { .name = "3", .value = MOD_DVBT_PR_3_4 }, + { .name = "5", .value = MOD_DVBT_PR_5_6 }, + { .name = "7", .value = MOD_DVBT_PR_7_8 }, + { .name = NULL, .value = 0 } +}; + +struct param_table_entry dvbt_constellation_table[] = { + { .name = "0", .value = MOD_DVBT_QPSK }, + { .name = "qpsk", .value = MOD_DVBT_QPSK }, + { .name = "1", .value = MOD_DVBT_16QAM }, + { .name = "16qam", .value = MOD_DVBT_16QAM }, + { .name = "qam16", .value = MOD_DVBT_16QAM }, + { .name = "2", .value = MOD_DVBT_64QAM }, + { .name = "64qam", .value = MOD_DVBT_64QAM }, + { .name = "qam64", .value = MOD_DVBT_64QAM }, + { .name = NULL, .value = 0 } +}; + +int parse_param(char *val,struct param_table_entry *table, int *value) { + if (value) { + *value = 0; + if (table) { + while (table->name) { + if( !strcasecmp(val,table->name)) { + *value = table->value; + return 0; + } + table++; + } + } + } + return -1; +} + int mci_cmd(int dev, struct mci_command *cmd) { int ret; @@ -105,7 +197,7 @@ int mci_cmd(int dev, struct mci_command *cmd) } struct mci_command msg_channels = { - .mod_command = MOD_SETUP_CHANNELS, + .mod_command = MOD_SETUP_CHANNELS, .mod_channel = 0, .mod_stream = 0, .mod_setup_channels[0] = { @@ -117,7 +209,7 @@ struct mci_command msg_channels = { }; struct mci_command msg_stream = { - .mod_command = MOD_SETUP_STREAM, + .mod_command = MOD_SETUP_STREAM, .mod_channel = 1, .mod_stream = 0, .mod_setup_stream = { @@ -146,7 +238,7 @@ void output_cb(void *priv, char *par, char *val) 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; @@ -157,7 +249,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 = (uint32_t) (strtod(val, NULL) * 100.0); + mc->output.mod_setup_output.channel_power = (int16_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")) { @@ -174,20 +266,22 @@ void output_cb(void *priv, char *par, char *val) void channels_cb(void *priv, char *par, char *val) { struct mconf *mc = (struct mconf *) priv; + int value; if (!par && !val) { mc->set_channels = 1; return; - } + } if (!strcasecmp(par, "frequency")) { - mc->channels.mod_setup_channels[0].frequency = (uint32_t) (strtod(val, NULL) * 1000000.0); + 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); + if (!parse_param(val,mod_standard_table,&value)) + mc->stream.mod_setup_channels[0].standard = value; } else if (!strcasecmp(par, "offset")) { - mc->channels.mod_setup_channels[0].offset = (uint32_t) (strtod(val, NULL) * 1000000.0); + 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 = (uint32_t) (strtod(val, NULL) * 1000000.0); mc->channels.mod_setup_channels[0].offset = @@ -199,28 +293,40 @@ void channels_cb(void *priv, char *par, char *val) void streams_cb(void *priv, char *par, char *val) { struct mconf *mc = (struct mconf *) priv; + int value; 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); + if (!parse_param(val,guard_interval_table,&value)) + mc->stream.mod_setup_stream.guard_interval = value; + } else if (!strcasecmp(par, "puncture_rate")) { + if (!parse_param(val,puncture_rate_table,&value)) + mc->stream.mod_setup_stream.puncture_rate = value; + } else if (!strcasecmp(par, "constellation")) { + if (!parse_param(val,dvbt_constellation_table,&value)) + mc->stream.mod_setup_stream.constellation = value; + } else if (!strcasecmp(par, "cell_identifier")) { + mc->stream.mod_setup_stream.cell_identifier = strtol(val, NULL, 0); } else if (!strcasecmp(par, "standard")) { - mc->stream.mod_setup_stream.standard = strtol(val, NULL, 10); + if (!parse_param(val,mod_standard_table,&value)) + mc->stream.mod_setup_stream.standard = value; } else if (!strcasecmp(par, "stream_format")) { - mc->stream.mod_setup_stream.stream_format = strtol(val, NULL, 10); + if (!parse_param(val,stream_format_table,&value)) + mc->stream.mod_setup_stream.stream_format = value; } else if (!strcasecmp(par, "symbol_rate")) { mc->stream.mod_setup_stream.symbol_rate = (uint32_t) (strtod(val, NULL) * 1000000.0); + } else if (!strcasecmp(par, "channel")) { + mc->stream.mod_channel = 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); + printf("invalid streams parameter: %s = %s\n", par, val); } int main(int argc, char*argv[]) @@ -236,7 +342,7 @@ int main(int argc, char*argv[]) mc.channels = msg_channels; mc.stream = msg_stream; mc.output = msg_output; - + while (1) { int cur_optind = optind ? optind : 1; int option_index = 0; @@ -247,7 +353,7 @@ int main(int argc, char*argv[]) {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; - c = getopt_long(argc, argv, "d:c:", + c = getopt_long(argc, argv, "d:c:", long_options, &option_index); if (c == -1) break; @@ -276,11 +382,11 @@ int main(int argc, char*argv[]) 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); + parse(configname, "output", (void *) &mc, output_cb); + if (mc.set_output) + mci_cmd(fd, &mc.output); } diff --git a/ddbridge/ddbridge-m4.c b/ddbridge/ddbridge-m4.c index 63bb06e..6203c6f 100644 --- a/ddbridge/ddbridge-m4.c +++ b/ddbridge/ddbridge-m4.c @@ -404,9 +404,11 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status) ddb_mci_get_strength(fe); if (res.status == MCI_DEMOD_WAIT_SIGNAL) *status = 0x01; - if (res.status == M4_DEMOD_WAIT_TS) + else if (res.status == M4_DEMOD_WAIT_TS) *status = 0x03; - if (res.status == MCI_DEMOD_LOCKED) { + else if (res.status == MCI_DEMOD_TIMEOUT) + *status = FE_TIMEDOUT; + else if (res.status == MCI_DEMOD_LOCKED) { *status = 0x1f; ddb_mci_get_snr(fe); } diff --git a/ddbridge/ddbridge-main.c b/ddbridge/ddbridge-main.c index 631ad86..f33e3e4 100644 --- a/ddbridge/ddbridge-main.c +++ b/ddbridge/ddbridge-main.c @@ -337,8 +337,10 @@ static int __devinit ddb_probe(struct pci_dev *pdev, dev->link[0].ids.hwid = ddbreadl(dev, 0); dev->link[0].ids.regmapid = ddbreadl(dev, 4); - dev_info(dev->dev, "HW %08x REGMAP %08x\n", - dev->link[0].ids.hwid, dev->link[0].ids.regmapid); + dev_info(dev->dev, "HW %08x REGMAP %08x FW %u.%u\n", + dev->link[0].ids.hwid, dev->link[0].ids.regmapid, + (dev->link[0].ids.hwid & 0xff0000) >> 16, + dev->link[0].ids.hwid & 0xffff); if ((dev->link[0].ids.hwid & 0xffffff) < dev->link[0].info->hw_min) { u32 min = dev->link[0].info->hw_min; diff --git a/ddbridge/ddbridge-mci.h b/ddbridge/ddbridge-mci.h index e38669e..c68e199 100644 --- a/ddbridge/ddbridge-mci.h +++ b/ddbridge/ddbridge-mci.h @@ -132,6 +132,7 @@ #define MCI_BANDWIDTH_7MHZ (7) #define MCI_BANDWIDTH_8MHZ (8) +#define SX8_CMD_GETBIST (0x0F) #define SX8_CMD_INPUT_ENABLE (0x40) #define SX8_CMD_INPUT_DISABLE (0x41) #define SX8_CMD_START_IQ (0x42) @@ -154,7 +155,7 @@ #define M4_L1INFO_SEL_PLPINFO (2) #define M4_L1INFO_SEL_PLPINFO_C (3) #define M4_L1INFO_SEL_SETID (0x80) - + #define MCI_BANDWIDTH_EXTENSION (0x80) // currently used only for J83B in Japan #define M4_MODE_DVBSX (2) @@ -166,13 +167,13 @@ #define M4_MODE_ISDBT (8) #define M4_MODE_ISDBC (9) #define M4_MODE_ISDBS (10) - + #define M4_DVBC_CONSTELLATION_16QAM (0) #define M4_DVBC_CONSTELLATION_32QAM (1) #define M4_DVBC_CONSTELLATION_64QAM (2) // also valid for J83B and ISDB-C #define M4_DVBC_CONSTELLATION_128QAM (3) #define M4_DVBC_CONSTELLATION_256QAM (4) // also valid for J83B and ISDB-C - + #define M4_SIGNALINFO_FLAG_CHANGE (0x01) #define M4_SIGNALINFO_FLAG_EWS (0x02) @@ -181,7 +182,7 @@ #define SX8_ROLLOFF_20 2 #define SX8_ROLLOFF_15 5 #define SX8_ROLLOFF_10 3 -#define SX8_ROLLOFF_05 4 +#define SX8_ROLLOFF_05 4 #define MCI_SUCCESS(status) ((status & MCI_STATUS_UNSUPPORTED) == 0) @@ -190,6 +191,7 @@ #define MOD_SETUP_CHANNELS (0x60) #define MOD_SETUP_OUTPUT (0x61) #define MOD_SETUP_STREAM (0x62) +#define MOD_SET_STREAM_CHANNEL (0x63) #define MOD_SETUP_FLAG_FIRST (0x01) #define MOD_SETUP_FLAG_LAST (0x02) @@ -199,6 +201,7 @@ #define MOD_STANDARD_DVBT_8 (0x01) #define MOD_STANDARD_DVBT_7 (0x02) #define MOD_STANDARD_DVBT_6 (0x03) +#define MOD_STANDARD_DVBT_5 (0x04) #define MOD_CONNECTOR_OFF (0x00) #define MOD_CONNECTOR_F (0x01) @@ -213,6 +216,22 @@ #define MOD_FORMAT_IDX8 (0x03) #define MOD_FORMAT_TS (0x04) +#define MOD_DVBT_FFT_8K (0x01) +#define MOD_DVBT_GI_1_32 (0x00) +#define MOD_DVBT_GI_1_16 (0x01) +#define MOD_DVBT_GI_1_8 (0x02) +#define MOD_DVBT_GI_1_4 (0x03) + +#define MOD_DVBT_PR_1_2 (0x00) +#define MOD_DVBT_PR_2_3 (0x01) +#define MOD_DVBT_PR_3_4 (0x02) +#define MOD_DVBT_PR_5_6 (0x03) +#define MOD_DVBT_PR_7_8 (0x04) + +#define MOD_DVBT_QPSK (0x00) +#define MOD_DVBT_16QAM (0x01) +#define MOD_DVBT_64QAM (0x02) + struct mod_setup_channels { u8 flags; u8 standard; @@ -220,20 +239,24 @@ struct mod_setup_channels { u8 rsvd; u32 frequency; u32 offset; /* used only when Standard == 0 */ - u32 bandwidth; /* used only when Standard == 0 */ + u32 bandwidth; /* used only when Standard == 0 */ }; struct mod_setup_stream { u8 standard; u8 stream_format; - u8 rsvd[2]; + u8 rsvd1[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) */ + u8 puncture_rate; /* 0 = 1/2, 1 = 2/3, 2 = 3/4, 3 = 5/6, 4 = 7/8 (DVB-T Encoding) */ + u8 constellation; + u8 rsvd2[2]; /* Reserved for DVB-T hierarchical */ + u16 cell_identifier; }; struct mod_setup_output { - u8 connector; /* 0 = OFF, 1 = F, 2 = SMA */ + 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; @@ -275,7 +298,7 @@ struct mci_command { u32 scrambling_sequence_index; u32 frequency_range; u8 channel_bonding_config; /* Bit 7: IsSlave, Bit 5..4: MasterDemod, - bit 0: Num channels - 2. + bit 0: Num channels - 2. (must be set on all channels to same value) */ } dvbs2_search; @@ -296,7 +319,7 @@ struct mci_command { u8 retry; u32 frequency; } dvbc_search; - + struct { u8 flags; /* Bit 0: LP Stream */ u8 bandwidth; @@ -304,7 +327,7 @@ struct mci_command { u8 retry; u32 frequency; } dvbt_search; - + struct { u8 flags; /* Bit 0: T2 Lite Profile, 7: PLP, */ u8 bandwidth; @@ -315,7 +338,7 @@ struct mci_command { u8 plp; u8 rsvd2[3]; } dvbt2_search; - + struct { u8 flags; u8 bandwidth; @@ -327,15 +350,15 @@ struct mci_command { u8 data_slice; u8 rsvd2[2]; } dvbc2_search; - + struct { - u8 flags; + u8 flags; u8 bandwidth; u8 rsvd1; u8 retry; u32 frequency; } isdbt_search; - + struct { u8 flags; /* Bit 0: 0 = TSID is Transport Stream ID, 1 = TSID is relative stream number */ /* Bit 2..1: 0 = force single, 1 = force multi, 2 = auto detect */ @@ -347,7 +370,7 @@ struct mci_command { u16 onid; u16 tsid; } isdbc_search; - + struct { u8 flags; u8 bandwidth; @@ -357,7 +380,7 @@ struct mci_command { } j83b_search; struct { - u8 flags; // Bit 0 : 1 = short info (1st 4 Bytes) + u8 flags; /* Bit 0 : 1 = short info (1st 4 Bytes) */ } get_signalinfo; struct { @@ -378,10 +401,10 @@ struct mci_command { u8 gain; /* Gain in 0.25 dB Steps */ /* Frequency, symbolrate and gain can be schanged while running */ } sx8_start_iq; - + struct { u8 flags; - /* Bit 0:1 Preamp Mode; 0 = Preamp AGC, 1 == Minimum (~ -17dB) , + /* 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 @@ -389,20 +412,20 @@ struct mci_command { Bit 7: Optimize RF Gain and freeze for FFT */ u8 rf_gain; /* 0 .. 50 dB */ } sx8_input_enable; - + struct { - u8 offset; // Offset into list, must be multiple of 64 - u8 select; // 0 = Slices, 1 = PLPs (C2 Only) - u8 data_slice; // DataSlice to get PLPList (C2 Only) + u8 offset; /* Offset into list, must be multiple of 64 */ + u8 select; /* 0 = Slices, 1 = PLPs (C2 Only) */ + u8 data_slice; /* DataSlice to get PLPList (C2 Only) */ } get_ids; struct { - u8 select; // 0 = Base, 1 = DataSilce, 2 = PLP, Bit 7: Set new ID - u8 id; // DataSliceID, PLPId + u8 select; /* 0 = Base, 1 = DataSilce, 2 = PLP, Bit 7: Set new ID */ + u8 id; /* DataSliceID, PLPId */ } get_l1_info; struct { - u8 select; // 0 = Data PLP, 1 = Common PLP, only DVB-T2 and DVB-C2 + 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]; @@ -420,27 +443,27 @@ struct mci_result { u16 time; }; }; - + union { u32 result[27]; u8 result8[27 * 4]; struct { u8 Rsvd0[3]; u8 Flags; - - u32 frequency; // actual frequency in Hz + + u32 frequency; /* actual frequency in Hz */ u32 rsvd1; - s16 channel_power; // channel power in dBm x 100 + s16 channel_power; /* channel power in dBm x 100 */ s16 rsvd2; - s16 signal_to_noise; // SNR in dB x 100, Note: negativ values are valid in DVB-S2 + s16 signal_to_noise; /* SNR in dB x 100, Note: negativ values are valid in DVB-S2 */ s16 rsvd3; u32 rsvd4; - u32 ber_numerator; /* Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X */ - u32 ber_denominator; - u32 ber_rsvd1; // Place holder for modulation bit error rate + u32 ber_numerator; /* Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X */ + u32 ber_denominator; + u32 ber_rsvd1; /* Place holder for modulation bit error rate */ u32 ber_rsvd2; } common_signal_info; - + struct { u8 standard; /* 1 = DVB-S, 2 = DVB-S2X */ u8 pls_code; /* PLS code for DVB-S2/S2X, puncture rate for DVB-S */ @@ -454,7 +477,7 @@ struct mci_result { s16 rsvd2; u32 packet_errors; /* Counter for packet errors. (set to 0 on Start command) */ u32 ber_numerator; /* Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X */ - u32 ber_denominator; + u32 ber_denominator; } dvbs2_signal_info; struct { @@ -469,7 +492,7 @@ struct mci_result { s16 rsvd2; u32 packet_errors; /* Counter for packet errors. (set to 0 on Start command) */ u32 ber_numerator; /* Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X */ - u32 ber_denominator; + u32 ber_denominator; } isdbs_signal_info; struct { @@ -490,8 +513,8 @@ struct mci_result { struct { u8 modulation1; // bit 7..6: Constellation, bit 5..3 Hierachy, bit 2..0 CodeRate High u8 modulation2; // bit 7..5: CodeRate Low, bit 4..3 Guard Interval, bit 2..1 FFT Mode - u8 Rsvd0; - u8 Flags; + u8 rsvd0; + u8 flags; u32 frequency; /* actual frequency in Hz */ u32 rsvd1; s16 channel_power; /* channel power in dBm x 100 */ @@ -520,7 +543,7 @@ struct mci_result { struct { u8 rsvd0[3]; u8 flags; - + u32 frequency; // actual frequency in Hz u32 rsvd1; // s16 channel_power; // channel power in dBm x 100 @@ -529,7 +552,7 @@ struct mci_result { s16 rsvd2; u32 packet_errors; // Counter for packet errors. (set to 0 on Start command) u32 ber_numerator; // Bit error rate: PreBCH - u32 ber_denominator; + u32 ber_denominator; } dvbc2_signal_info; struct { @@ -552,51 +575,51 @@ struct mci_result { } isdbt_signal_info; struct { - u8 Constellation; - u8 Rsvd0[2]; - u8 Flags; - - u32 Frequency; // actual frequency in Hz - u32 SymbolRate; // actual symbolrate in Hz - s16 ChannelPower; // channel power in dBm x 100 - s16 BandPower; // band power in dBm x 100 - s16 SignalToNoise; // SNR in dB x 100, Note: negativ values are valid in DVB-S2 - s16 Rsvd2; - u32 PacketErrors; // Counter for packet errors. (set to 0 on Start command) - u32 BERNumerator; // Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X - u32 BERDenominator; - } ISDBC_SignalInfo; - + u8 constellation; + u8 rsvd0[2]; + u8 flags; + + u32 frequency; // actual frequency in Hz + u32 symbol_rate; // actual symbolrate in Hz + s16 channel_power; // channel power in dBm x 100 + s16 band_power; // band power in dBm x 100 + s16 signal_to_noise; // SNR in dB x 100, Note: negativ values are valid in DVB-S2 + s16 rsvd2; + u32 packet_errors; // Counter for packet errors. (set to 0 on Start command) + u32 ber_numerator; // Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X + u32 ber_denominator; + } isdbc_signal_info; + struct { - u8 Constellation; - u8 Interleaving; - u8 Rsvd0; - u8 Flags; - - u32 Frequency; // actual frequency in Hz - u32 SymbolRate; // actual symbolrate in Hz - s16 ChannelPower; // channel power in dBm x 100 - s16 BandPower; // band power in dBm x 100 - s16 SignalToNoise; // SNR in dB x 100, Note: negativ values are valid in DVB-S2 - s16 Rsvd2; - u32 PacketErrors; // Counter for packet errors. (set to 0 on Start command) - u32 BERNumerator; // Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X - u32 BERDenominator; - } J83B_SignalInfo; - + u8 constellation; + u8 interleaving; + u8 rsvd0; + u8 flags; + + u32 frequency; // actual frequency in Hz + u32 symbol_rate; // actual symbolrate in Hz + s16 channel_power; // channel power in dBm x 100 + s16 band_power; // band power in dBm x 100 + s16 signal_to_noise; // SNR in dB x 100, Note: negativ values are valid in DVB-S2 + s16 rsvd2; + u32 packet_errors; // Counter for packet errors. (set to 0 on Start command) + u32 ber_numerator; // Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X + u32 ber_denominator; + } j83b_signal_info; + struct { s16 i; s16 q; } iq_symbol; - + struct { - u8 TPSInfo[7]; - // uint16_t TPS_CellID; // Cell Identifier + u8 tps_info[7]; + // uint16_t tps_cell_id; } DVBT_TPSInfo; - + struct { struct { - u8 Type; + u8 type; u8 BWExtension; u8 S1; u8 S2; @@ -622,6 +645,7 @@ struct mci_result { u8 T2Version_PostScrambled_BaseLite_Rsvd[2]; // 4,1,1,4 bit u8 CRC32[4]; } DVBT2_L1Pre; + struct { u8 SubSlicesPerFrame[2]; u8 NumPLP; @@ -634,7 +658,7 @@ struct mci_result { u8 FEFInterval; } DVBT2_L1Post; } DVBT2_L1Info; - + struct { u8 PLPID; u8 Type; @@ -654,7 +678,7 @@ struct mci_result { u8 InBandAFlag; u8 InBandBFlag_Rsvd1_Mode_StaticFlag_StaticPaddingFlag[2]; // 1,11,2,1,1 } DVBT2_PLPInfo; - + struct { u8 NetworkID[2]; u8 C2SystemID[2]; @@ -673,13 +697,13 @@ struct mci_result { u8 ReservedTone; u8 Reserved4[2]; // EWS 1 bit, C2_Version 4 bit, Rsvd 11 bit } DVBC2_L1Part2; - + struct { u8 NumIDs; u8 Offset; u8 IDs[64]; } DVBC2_IDList; - + struct { u8 SliceID; u8 TunePosition[2]; @@ -693,7 +717,7 @@ struct mci_result { u8 NumPLP; u8 Reserved2; } DVBC2_SliceInfo; - + struct { u8 PLPID; u8 Bundled; @@ -709,7 +733,7 @@ struct mci_result { u8 OrginalNetworkID[2]; u8 Reserved1; } DVBC2_PLPInfo; - + struct { u8 Valid; u8 MATYPE_1; @@ -744,6 +768,13 @@ struct mci_result { u8 Flags; // Bit 5: EWS flag, bit 4: Site Diversity flag, bit 3..1: Site Diversity information, bit 0: Extension flag u8 Extension[8]; // 61 bits, right aligned } ISDBS_TMCCInfo; + + struct { + uint8_t cut; + uint8_t avs_code; + uint8_t temperature; + uint8_t rsvd[13]; + } sx8_bist; }; u32 version[3]; u8 version_rsvd;