FreeCalypso > hg > freecalypso-tools
changeset 280:36922911e6bb
librftab started with rftablerd.c and rftablewr.c from rvinterf/tmsh
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 17 Nov 2017 23:43:38 +0000 |
parents | 36ae854536e8 |
children | feb2ee302d25 |
files | librftab/rftablerd.c librftab/rftablewr.c |
diffstat | 2 files changed, 663 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/librftab/rftablerd.c Fri Nov 17 23:43:38 2017 +0000 @@ -0,0 +1,453 @@ +/* + * Reading RF tables from formatted ASCII files for the rftw command + */ + +#include <sys/types.h> +#include <ctype.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include "localtypes.h" +#include "l1tm.h" +#include "exitcodes.h" + +#define MAX_FIELDS_PER_LINE 64 + +static char *filename; +static FILE *rdfile; +static unsigned lineno; +static char linebuf[256], *line_fields[MAX_FIELDS_PER_LINE]; +static unsigned line_nfields, line_field_ptr; +static char *format; +static u_char *writeptr; +static unsigned written_size; + +static int +read_line() +{ + char *cp; + + if (!fgets(linebuf, sizeof linebuf, rdfile)) + return(0); + lineno++; + cp = linebuf; + for (line_nfields = 0; ; ) { + while (isspace(*cp)) + cp++; + if (*cp == '\0' || *cp == '#') + break; + if (line_nfields >= MAX_FIELDS_PER_LINE) { + printf("%s line %d: too many fields on one line\n", + filename, lineno); + return(-1); + } + line_fields[line_nfields++] = cp; + while (*cp && !isspace(*cp)) + cp++; + if (*cp) + *cp++ = '\0'; + } + return(1); +} + +static +get_field(retp) + char **retp; +{ + int rc; + + if (line_field_ptr < line_nfields) { + *retp = line_fields[line_field_ptr++]; + return(1); + } + do { + rc = read_line(); + if (rc <= 0) + return(rc); + } while (!line_nfields); + *retp = line_fields[0]; + line_field_ptr = 1; + return(1); +} + +static +process_number(size) +{ + char *field; + int rc; + u_long number; + + rc = get_field(&field); + if (rc < 0) + return(ERROR_USAGE); + if (!rc) { + printf("error: %s is too short for table format %s\n", + filename, format); + return(ERROR_USAGE); + } + if (field[0] == '-') + number = strtol(field, 0, 0); + else + number = strtoul(field, 0, 0); + switch (size) { + case 1: + *writeptr++ = number; + break; + case 2: + *writeptr++ = number; + *writeptr++ = number >> 8; + break; + case 4: + *writeptr++ = number; + *writeptr++ = number >> 8; + *writeptr++ = number >> 16; + *writeptr++ = number >> 24; + break; + default: + abort(); + } + written_size += size; + return(0); +} + +static +ensure_eof() +{ + char *field; + int rc; + + rc = get_field(&field); + if (rc < 0) + return(ERROR_USAGE); + if (rc) { + printf("error: %s is too long for table format %s\n", + filename, format); + return(ERROR_USAGE); + } + return(0); +} + +static +read_agc_table() +{ + int i, rc; + + for (i = 0; i < 20; i++) { + rc = process_number(2); + if (rc) + return(rc); + } + return ensure_eof(); +} + +static +read_afcparams() +{ + int i, rc; + + for (i = 0; i < 4; i++) { + rc = process_number(4); + if (rc) + return(rc); + } + for (i = 0; i < 4; i++) { + rc = process_number(2); + if (rc) + return(rc); + } + return ensure_eof(); +} + +static +read_agc_global_params() +{ + int i, rc; + + for (i = 0; i < 4; i++) { + rc = process_number(2); + if (rc) + return(rc); + } + return ensure_eof(); +} + +static +read_il2agc() +{ + int i, rc; + + for (i = 0; i < 121; i++) { + rc = process_number(1); + if (rc) + return(rc); + } + return ensure_eof(); +} + +static +read_tx_levels() +{ + int i, rc; + + for (i = 0; i < 32; i++) { + rc = process_number(2); + if (rc) + return(rc); + rc = process_number(1); + if (rc) + return(rc); + rc = process_number(1); + if (rc) + return(rc); + } + return ensure_eof(); +} + +static +read_tx_calchan() +{ + int i, rc; + + for (i = 0; i < 64; i++) { + rc = process_number(2); + if (rc) + return(rc); + } + return ensure_eof(); +} + +static +read_tx_caltemp() +{ + int i, rc; + + for (i = 0; i < 20; i++) { + rc = process_number(2); + if (rc) + return(rc); + } + return ensure_eof(); +} + +static +read_rx_calchan() +{ + int i, rc; + + for (i = 0; i < 20; i++) { + rc = process_number(2); + if (rc) + return(rc); + } + return ensure_eof(); +} + +static +read_rx_caltemp() +{ + int i, rc; + + for (i = 0; i < 22; i++) { + rc = process_number(2); + if (rc) + return(rc); + } + return ensure_eof(); +} + +static +read_rx_agc_params() +{ + int i, rc; + + for (i = 0; i < 4; i++) { + rc = process_number(2); + if (rc) + return(rc); + } + return ensure_eof(); +} + +static +read_raw_table() +{ + int rc; + char *field; + u_long number; + + for (;;) { + rc = get_field(&field); + if (rc < 0) + return(ERROR_USAGE); + if (!rc) + break; + number = strtoul(field, 0, 16); + if (written_size >= MAX_RF_TABLE_SIZE) { + printf("error: raw table %s exceeds maximum size\n", + filename); + return(ERROR_USAGE); + } + *writeptr++ = number; + written_size++; + } + if (!written_size) { + printf("error: raw table %s is empty\n", filename); + return(ERROR_USAGE); + } + return(0); +} + +static struct table_format { + char *kw; + int (*handler)(); +} table_formats[] = { + {"agc-table", read_agc_table}, + {"afcparams", read_afcparams}, + {"agc-global-params", read_agc_global_params}, + {"il2agc", read_il2agc}, + {"tx-levels", read_tx_levels}, + {"tx-calchan", read_tx_calchan}, + {"tx-caltemp", read_tx_caltemp}, + {"rx-calchan", read_rx_calchan}, + {"rx-caltemp", read_rx_caltemp}, + {"rx-agc-params", read_rx_agc_params}, + {"raw", read_raw_table}, + {0, 0} +}; + +read_rf_table(filename_arg, rdbuf, format_ret, size_ret) + char *filename_arg; + u_char *rdbuf; + char **format_ret; + unsigned *size_ret; +{ + char *field; + int rc; + struct table_format *tp; + + filename = filename_arg; + rdfile = fopen(filename, "r"); + if (!rdfile) { + perror(filename); + return(ERROR_UNIX); + } + lineno = 0; + line_nfields = 0; + rc = get_field(&field); + if (rc <= 0) { +not_valid_rftable: + printf("error: %s is not a valid RF table file\n", filename); + fclose(rdfile); + return(ERROR_USAGE); + } + if (strcmp(field, "rf_table")) + goto not_valid_rftable; + rc = get_field(&field); + if (rc <= 0) + goto not_valid_rftable; + for (tp = table_formats; tp->kw; tp++) + if (!strcmp(tp->kw, field)) + break; + if (!tp->kw) { + printf("error: table format \"%s\" not recognized\n", field); + fclose(rdfile); + return(ERROR_USAGE); + } + format = tp->kw; + if (format_ret) + *format_ret = format; + writeptr = rdbuf; + written_size = 0; + rc = tp->handler(); + fclose(rdfile); + if (size_ret) + *size_ret = written_size; + return(rc); +} + +static +process_txramp_number() +{ + char *field; + int rc; + u_long number; + + rc = get_field(&field); + if (rc < 0) + return(ERROR_USAGE); + if (!rc) { + printf("error: %s is too short for a Tx ramp template\n", + filename); + return(ERROR_USAGE); + } + number = strtoul(field, 0, 0); + *writeptr++ = number; + return(0); +} + +static +read_txramp_16num() +{ + int i, rc; + + for (i = 0; i < 16; i++) { + rc = process_txramp_number(); + if (rc) + return(rc); + } + return(0); +} + +read_tx_ramp_template(filename_arg, rdbuf) + char *filename_arg; + u_char *rdbuf; +{ + char *field; + int rc; + + filename = filename_arg; + rdfile = fopen(filename, "r"); + if (!rdfile) { + perror(filename); + return(ERROR_UNIX); + } + lineno = 0; + line_nfields = 0; + rc = get_field(&field); + if (rc <= 0) { +not_valid_ramp_file: + printf("error: %s is not a valid Tx ramp template file\n", + filename); + fclose(rdfile); + return(ERROR_USAGE); + } + if (strcmp(field, "ramp-up")) + goto not_valid_ramp_file; + writeptr = rdbuf; + rc = read_txramp_16num(); + if (rc) { + fclose(rdfile); + return(rc); + } + rc = get_field(&field); + if (rc <= 0) + goto not_valid_ramp_file; + if (strcmp(field, "ramp-down")) + goto not_valid_ramp_file; + rc = read_txramp_16num(); + if (rc) { + fclose(rdfile); + return(rc); + } + rc = get_field(&field); + fclose(rdfile); + if (rc < 0) + return(ERROR_USAGE); + if (rc) { + printf("error: %s is too long for a Tx ramp template\n", + filename); + return(ERROR_USAGE); + } + return(0); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/librftab/rftablewr.c Fri Nov 17 23:43:38 2017 +0000 @@ -0,0 +1,210 @@ +/* + * Here we implement the writing of RF tables into ASCII text files + * in our defined format. This module will also be linked by the + * standalone fc-cal2text utility, hence our code here needs to be + * independent of rvinterf and fc-tmsh specifics. + */ + +#include <sys/types.h> +#include <stdio.h> +#include <stdint.h> +#include <endian.h> + +static unsigned +get_u32(bin) + u_char *bin; +{ + return le32toh(*(uint32_t *)bin); +} + +static unsigned +get_u16(bin) + u_char *bin; +{ + return le16toh(*(uint16_t *)bin); +} + +static int +get_s16(bin) + u_char *bin; +{ + int i; + + i = le16toh(*(uint16_t *)bin); + if (i >= 32768) + i -= 65536; + return(i); +} + +void +write_afcparams_table(bin, outf) + u_char *bin; + FILE *outf; +{ + fputs("rf_table afcparams\n\n", outf); + /* 32-bit parameters */ + fprintf(outf, "%10u\t# psi_sta_inv\n", get_u32(bin)); + fprintf(outf, "%10u\t# psi_st\n", get_u32(bin + 4)); + fprintf(outf, "%10u\t# psi_st_32\n", get_u32(bin + 8)); + fprintf(outf, "%10u\t# psi_st_inv\n\n", get_u32(bin + 12)); + /* 16-bit parameters */ + fprintf(outf, "%10d\t# dac_center\n", get_s16(bin + 16)); + fprintf(outf, "%10d\t# dac_min\n", get_s16(bin + 18)); + fprintf(outf, "%10d\t# dac_max\n", get_s16(bin + 20)); + fprintf(outf, "%10d\t# snr_thr\n", get_s16(bin + 22)); +} + +void +write_agcwords_table(bin, outf) + u_char *bin; + FILE *outf; +{ + int i, j; + u_char *p = bin; + + fputs("rf_table agc-table\n\n", outf); + for (i = 0; i < 4; i++) { + for (j = 0; j < 5; j++) { + if (j) + putc(' ', outf); + fprintf(outf, "0x%04X", get_u16(p)); + p += 2; + } + putc('\n', outf); + } +} + +void +write_agcglobals_table(bin, outf) + u_char *bin; + FILE *outf; +{ + fputs("rf_table agc-global-params\n\n", outf); + fprintf(outf, "%5u\t# low_agc_noise_thr\n", get_u16(bin)); + fprintf(outf, "%5u\t# high_agc_sat_thr\n", get_u16(bin + 2)); + fprintf(outf, "%5u\t# low_agc\n", get_u16(bin + 4)); + fprintf(outf, "%5u\t# high_agc\n", get_u16(bin + 6)); +} + +void +write_il2agc_table(bin, outf) + u_char *bin; + FILE *outf; +{ + int idx; + + fputs("rf_table il2agc\n\n", outf); + for (idx = 0; idx < 121; idx++) + fprintf(outf, "%3u\t# IL=%d\n", bin[idx], -idx); +} + +void +write_tx_levels_table(bin, outf) + u_char *bin; + FILE *outf; +{ + int i; + u_char *p = bin; + + fputs("rf_table tx-levels\n\n", outf); + fputs("# Fields in each entry: apc, ramp_index, chan_cal_index\n\n", + outf); + for (i = 0; i < 32; i++) { + fprintf(outf, "%5u %3u %3u\t# entry %d\n", + get_u16(p), p[2], p[3], i); + p += 4; + } +} + +void +write_tx_calchan_table(bin, outf) + u_char *bin; + FILE *outf; +{ + int i, j; + u_char *p = bin; + + fputs("rf_table tx-calchan\n", outf); + for (i = 0; i < 4; i++) { + fprintf(outf, "\n# Channel calibration table %d:\n\n", i); + for (j = 0; j < 8; j++) { + fprintf(outf, "%5u %6d\n", get_u16(p), get_s16(p + 2)); + p += 4; + } + } +} + +void +write_tx_caltemp_table(bin, outf) + u_char *bin; + FILE *outf; +{ + int i; + u_char *p = bin; + + fputs("rf_table tx-caltemp\n\n", outf); + for (i = 0; i < 5; i++) { + fprintf(outf, "%6d %6d %6d %6d\n", get_s16(p), get_s16(p + 2), + get_s16(p + 4), get_s16(p + 6)); + p += 8; + } +} + +void +write_rx_calchan_table(bin, outf) + u_char *bin; + FILE *outf; +{ + int i; + u_char *p = bin; + + fputs("rf_table rx-calchan\n\n", outf); + for (i = 0; i < 10; i++) { + fprintf(outf, "%5u %6d\n", get_u16(p), get_s16(p + 2)); + p += 4; + } +} + +void +write_rx_caltemp_table(bin, outf) + u_char *bin; + FILE *outf; +{ + int i; + u_char *p = bin; + + fputs("rf_table rx-caltemp\n\n", outf); + for (i = 0; i < 11; i++) { + fprintf(outf, "%6d %6d\n", get_s16(p), get_s16(p + 2)); + p += 4; + } +} + +void +write_rx_agcparams_table(bin, outf) + u_char *bin; + FILE *outf; +{ + fputs("rf_table rx-agc-params\n\n", outf); + fprintf(outf, "%5u\t# g_magic\n", get_u16(bin)); + fprintf(outf, "%5u\t# lna_att\n", get_u16(bin + 2)); + fprintf(outf, "%5u\t# lna_switch_thr_low\n", get_u16(bin + 4)); + fprintf(outf, "%5u\t# lna_switch_thr_high\n", get_u16(bin + 6)); +} + +void +write_tx_ramp(bin, outf) + u_char *bin; + FILE *outf; +{ + int i; + + fputs("ramp-up ", outf); + for (i = 0; i < 16; i++) + fprintf(outf, " %3u", bin[i]); + putc('\n', outf); + fputs("ramp-down", outf); + for (i = 0; i < 16; i++) + fprintf(outf, " %3u", bin[i+16]); + putc('\n', outf); +}