From bef6eae05b959b2ce395b3f949675d2a93053f0d Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 16 Jan 2018 15:42:48 +0100 Subject: Move sysmobts-calib into osmo-bts-sysmo It's prerequisite for jenkins tests fix after migration to stow. The sysmobts-calib uses hand-coded Makefile instead of automake which makes it hard to properly propagate build flags. Also, make it optional to enable excluding it from certain jenkins tests. Change-Id: I3b54bfa5ef1d89092f6cf13dc27de10874b31b18 --- contrib/sysmobts-calib/Makefile | 10 - contrib/sysmobts-calib/sysmobts-calib.c | 537 --------------------- contrib/sysmobts-calib/sysmobts-layer1.c | 800 ------------------------------- contrib/sysmobts-calib/sysmobts-layer1.h | 45 -- 4 files changed, 1392 deletions(-) delete mode 100644 contrib/sysmobts-calib/Makefile delete mode 100644 contrib/sysmobts-calib/sysmobts-calib.c delete mode 100644 contrib/sysmobts-calib/sysmobts-layer1.c delete mode 100644 contrib/sysmobts-calib/sysmobts-layer1.h (limited to 'contrib/sysmobts-calib') diff --git a/contrib/sysmobts-calib/Makefile b/contrib/sysmobts-calib/Makefile deleted file mode 100644 index a5d4b995..00000000 --- a/contrib/sysmobts-calib/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -CFLAGS=`pkg-config --cflags libosmocore` -Wall -Werror -LIBS=`pkg-config --libs libosmocore libosmogsm` - -all: sysmobts-calib - -sysmobts-calib: sysmobts-calib.o sysmobts-layer1.o - $(CC) $(CPPFLAGS) $(LDFLAGS) -o $@ $^ -lrt $(LIBS) - -clean: - @rm -f sysmobts-calib *.o diff --git a/contrib/sysmobts-calib/sysmobts-calib.c b/contrib/sysmobts-calib/sysmobts-calib.c deleted file mode 100644 index a111d1d5..00000000 --- a/contrib/sysmobts-calib/sysmobts-calib.c +++ /dev/null @@ -1,537 +0,0 @@ -/* OCXO/TCXO based calibration utility */ - -/* - * (C) 2012-2013 Holger Hans Peter Freyther - * - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -#include -#include -#include -#include -#include -#include - -#define _GNU_SOURCE -#include - -#include -#include - -#include - -#include - -#include "sysmobts-layer1.h" - -enum actions { - ACTION_SCAN, - ACTION_CALIB, - ACTION_BCCH, - ACTION_BCCH_CCCH, -}; - -static const char *modes[] = { - [ACTION_SCAN] = "scan", - [ACTION_CALIB] = "calibrate", - [ACTION_BCCH] = "bcch", - [ACTION_BCCH_CCCH] = "bcch_ccch", -}; - -static const char *bands[] = { - [GsmL1_FreqBand_850] = "850", - [GsmL1_FreqBand_900] = "900", - [GsmL1_FreqBand_1800] = "1800", - [GsmL1_FreqBand_1900] = "1900", -}; - -struct channel_pair { - int min; - int max; -}; - -static const struct channel_pair arfcns[] = { - [GsmL1_FreqBand_850] = { .min = 128, .max = 251 }, - [GsmL1_FreqBand_900] = { .min = 1, .max = 124 }, - [GsmL1_FreqBand_1800] = { .min = 512, .max = 885 }, - [GsmL1_FreqBand_1900] = { .min = 512, .max = 810 }, - -}; - -static const char *clk_source[] = { - [SuperFemto_ClkSrcId_Ocxo] = "ocxo", - [SuperFemto_ClkSrcId_Tcxo] = "tcxo", - [SuperFemto_ClkSrcId_External] = "external", - [SuperFemto_ClkSrcId_GpsPps] = "gps", - [SuperFemto_ClkSrcId_Trx] = "trx", - [SuperFemto_ClkSrcId_Rx] = "rx", - [SuperFemto_ClkSrcId_Edge] = "edge", - [SuperFemto_ClkSrcId_NetList] = "netlisten", -}; - -static const struct value_string sapi_names[GsmL1_Sapi_NUM+1] = { - { GsmL1_Sapi_Fcch, "FCCH" }, - { GsmL1_Sapi_Sch, "SCH" }, - { GsmL1_Sapi_Sacch, "SACCH" }, - { GsmL1_Sapi_Sdcch, "SDCCH" }, - { GsmL1_Sapi_Bcch, "BCCH" }, - { GsmL1_Sapi_Pch, "PCH" }, - { GsmL1_Sapi_Agch, "AGCH" }, - { GsmL1_Sapi_Cbch, "CBCH" }, - { GsmL1_Sapi_Rach, "RACH" }, - { GsmL1_Sapi_TchF, "TCH/F" }, - { GsmL1_Sapi_FacchF, "FACCH/F" }, - { GsmL1_Sapi_TchH, "TCH/H" }, - { GsmL1_Sapi_FacchH, "FACCH/H" }, - { GsmL1_Sapi_Nch, "NCH" }, - { GsmL1_Sapi_Pdtch, "PDTCH" }, - { GsmL1_Sapi_Pacch, "PACCH" }, - { GsmL1_Sapi_Pbcch, "PBCCH" }, - { GsmL1_Sapi_Pagch, "PAGCH" }, - { GsmL1_Sapi_Ppch, "PPCH" }, - { GsmL1_Sapi_Pnch, "PNCH" }, - { GsmL1_Sapi_Ptcch, "PTCCH" }, - { GsmL1_Sapi_Prach, "PRACH" }, - { 0, NULL } -}; - -static int action = ACTION_SCAN; -static int band = GsmL1_FreqBand_900; -static int calib = SuperFemto_ClkSrcId_Ocxo; -static int source = SuperFemto_ClkSrcId_NetList; -static int dsp_flags = 0x0; -static int cal_arfcn = 0; -static int initial_cor = 0; -static int steps = -1; - -static void print_usage(void) -{ - printf("Usage: sysmobts-calib ARGS\n"); -} - -static void print_help(void) -{ - printf(" -h --help this text\n"); - printf(" -c --clock " - "ocxo|tcxo|external|gps|trx|rx|edge\n"); - printf(" -s --calibration-source " - "ocxo|tcxo|external|gps|trx|rx|edge|netlisten\n"); - printf(" -b --band 850|900|1800|1900\n"); - printf(" -m --mode scan|calibrate|bcch|bcch_ccch\n"); - printf(" -a --arfcn NR arfcn for calibration\n"); - printf(" -d --dsp-flags NR dsp mask for debug log\n"); - printf(" -t --threshold level\n"); - printf(" -i --initial-clock-correction COR.\n"); - printf(" -t --steps STEPS\n"); -} - -static int find_value(const char **array, int size, char *value) -{ - int i = 0; - for (i = 0; i < size; ++i) { - if (array[i] == NULL) - continue; - if (strcmp(value, array[i]) == 0) - return i; - } - - printf("Failed to find: '%s'\n", value); - exit(-2); -} - -static void handle_options(int argc, char **argv) -{ - while (1) { - int option_index = 0, c; - static struct option long_options[] = { - {"help", 0, 0, 'h'}, - {"calibration-source", 1, 0, 's'}, - {"clock", 1, 0, 'c'}, - {"mode", 1, 0, 'm'}, - {"band", 1, 0, 'b'}, - {"dsp-flags", 1, 0, 'd'}, - {"arfcn", 1, 0, 'a'}, - {"initial-clock-correction", 1, 0, 'i'}, - {"steps", 1, 0, 't'}, - {0, 0, 0, 0}, - }; - - c = getopt_long(argc, argv, "hs:c:m:b:d:a:i:t:", - long_options, &option_index); - if (c == -1) - break; - switch (c) { - case 'h': - print_usage(); - print_help(); - exit(0); - case 's': - source = find_value(clk_source, - ARRAY_SIZE(clk_source), optarg); - break; - case 'c': - calib = find_value(clk_source, - ARRAY_SIZE(clk_source), optarg); - break; - case 'm': - action = find_value(modes, - ARRAY_SIZE(modes), optarg); - break; - case 'b': - band = find_value(bands, - ARRAY_SIZE(bands), optarg); - break; - case 'd': - dsp_flags = strtol(optarg, NULL, 16); - break; - case 'a': - cal_arfcn = atoi(optarg); - break; - case 'i': - initial_cor = atoi(optarg); - break; - case 't': - steps = atoi(optarg); - break; - default: - printf("Unhandled option, terminating.\n"); - exit(-1); - } - } - - if (source == calib) { - printf("Clock source and reference clock may not be the same.\n"); - exit(-3); - } - - if (calib == SuperFemto_ClkSrcId_NetList) { - printf("Clock may not be network listen.\n"); - exit(-4); - } - - if (action == ACTION_CALIB && source == SuperFemto_ClkSrcId_NetList) { - if (cal_arfcn == 0) { - printf("Please specify the reference ARFCN.\n"); - exit(-5); - } - - if (cal_arfcn < arfcns[band].min || cal_arfcn > arfcns[band].max) { - printf("ARFCN(%d) is not in the given band.\n", cal_arfcn); - exit(-6); - } - } -} - -#define CHECK_RC(rc) \ - if (rc != 0) \ - return EXIT_FAILURE; - -#define CHECK_RC_MSG(rc, msg) \ - if (rc != 0) { \ - printf("%s: %d\n", msg, rc); \ - return EXIT_FAILURE; \ - } -#define CHECK_COND_MSG(cond, rc, msg) \ - if (cond) { \ - printf("%s: %d\n", msg, rc); \ - return EXIT_FAILURE; \ - } - -struct scan_result -{ - uint16_t arfcn; - float rssi; -}; - -static int scan_cmp(const void *arg1, const void *arg2) -{ - struct scan_result *elem1 = (struct scan_result *) arg1; - struct scan_result *elem2 = (struct scan_result * )arg2; - - float diff = elem1->rssi - elem2->rssi; - if (diff > 0.0) - return 1; - else if (diff < 0.0) - return -1; - else - return 0; -} - -static int scan_band() -{ - int arfcn, rc, i; - - /* Scan results.. at most 400 items */ - struct scan_result results[400]; - memset(&results, 0, sizeof(results)); - int num_scan_results = 0; - - printf("Going to scan bands.\n"); - - for (arfcn = arfcns[band].min; arfcn <= arfcns[band].max; ++arfcn) { - float mean_rssi; - - printf("."); - fflush(stdout); - rc = power_scan(band, arfcn, 10, &mean_rssi); - CHECK_RC_MSG(rc, "Power Measurement failed"); - - results[num_scan_results].arfcn = arfcn; - results[num_scan_results].rssi = mean_rssi; - num_scan_results++; - } - - qsort(results, num_scan_results, sizeof(struct scan_result), scan_cmp); - printf("\nSorted scan results (weakest first):\n"); - for (i = 0; i < num_scan_results; ++i) - printf("ARFCN %3d: %.4f\n", results[i].arfcn, results[i].rssi); - - return 0; -} - -static int calib_get_clock_error(void) -{ - int rc, clkErr, clkErrRes; - - printf("Going to determine the clock offset.\n"); - - rc = rf_clock_info(&clkErr, &clkErrRes); - CHECK_RC_MSG(rc, "Clock info failed.\n"); - - if (clkErr == 0 && clkErrRes == 0) { - printf("Failed to get the clock info. Are both clocks present?\n"); - return -1; - } - - /* - * Empiric gps error determination. With revE and firmware v3.3 - * the clock error for TCXO to GPS appears to have a different - * sign. The device in question doesn't have a networklisten mode - * so it is impossible to verify that this only applies to GPS. - */ - if (source == SuperFemto_ClkSrcId_GpsPps) - clkErr *= -1; - - - /* this is an absolute clock error */ - printf("The calibration value is: %d\n", clkErr); - return 0; -} - -static int calib_clock_after_sync(void) -{ - int rc, clkErr, clkErrRes, iteration, cor; - - iteration = 0; - cor = initial_cor; - - printf("Trying to calibrate now and reducing clock error.\n"); - - for (iteration = 0; iteration < steps || steps <= 0; ++iteration) { - if (steps > 0) - printf("Iteration %d/%d with correction: %d\n", iteration, steps, cor); - else - printf("Iteration %d with correction: %d\n", iteration, cor); - - rc = rf_clock_info(&clkErr, &clkErrRes); - CHECK_RC_MSG(rc, "Clock info failed.\n"); - - /* - * TODO: use the clock error resolution here, implement it as a - * a PID controller.. - */ - - /* Picocell class requires 0.1ppm.. but that is 'too easy' */ - if (fabs(clkErr / 1000.0f) <= 0.05f) { - printf("The calibration value is: %d\n", cor); - return 1; - } - - cor -= clkErr / 2; - rc = set_clock_cor(cor, calib, source); - CHECK_RC_MSG(rc, "Clock correction failed.\n"); - } - - return -1; -} - -static int find_initial_clock(HANDLE layer1, int *clock) -{ - int i; - - printf("Trying to find an initial clock value.\n"); - - for (i = 0; i < 1000; ++i) { - int rc; - int cor = i * 150; - rc = wait_for_sync(layer1, cor, calib, source); - if (rc == 1) { - printf("Found initial clock offset: %d\n", cor); - *clock = cor; - break; - } else { - CHECK_RC_MSG(rc, "Failed to set new clock value.\n"); - } - - cor = i * -150; - rc = wait_for_sync(layer1, cor, calib, source); - if (rc == 1) { - printf("Found initial clock offset: %d\n", cor); - *clock = cor; - break; - } else { - CHECK_RC_MSG(rc, "Failed to set new clock value.\n"); - } - } - - return 0; -} - -static int calib_clock_netlisten(void) -{ - int rc, cor = initial_cor; - float mean_rssi; - HANDLE layer1; - - rc = power_scan(band, cal_arfcn, 10, &mean_rssi); - CHECK_RC_MSG(rc, "ARFCN measurement scan failed"); - if (mean_rssi < -118.0f) - printf("ARFCN has weak signal for calibration: %f\n", mean_rssi); - - /* initial lock */ - rc = follow_sch(band, cal_arfcn, calib, source, &layer1); - if (rc == -23) - rc = find_initial_clock(layer1, &cor); - CHECK_RC_MSG(rc, "Following SCH failed"); - - /* now try to calibrate it */ - rc = set_clock_cor(cor, calib, source); - CHECK_RC_MSG(rc, "Clock setup failed."); - - calib_clock_after_sync(); - - rc = mph_close(layer1); - CHECK_RC_MSG(rc, "MPH-Close"); - - return EXIT_SUCCESS; -} - -static int calib_clock(void) -{ - int rc; - - /* now try to calibrate it */ - rc = set_clock_cor(initial_cor, calib, source); - CHECK_RC_MSG(rc, "Clock setup failed."); - - calib_get_clock_error(); - - return EXIT_SUCCESS; -} - -static int bcch_follow(void) -{ - int rc, cor = initial_cor; - float mean_rssi; - HANDLE layer1; - - rc = power_scan(band, cal_arfcn, 10, &mean_rssi); - CHECK_RC_MSG(rc, "ARFCN measurement scan failed"); - if (mean_rssi < -118.0f) - printf("ARFCN has weak signal for calibration: %f\n", mean_rssi); - - /* initial lock */ - rc = follow_sch(band, cal_arfcn, calib, source, &layer1); - if (rc == -23) - rc = find_initial_clock(layer1, &cor); - CHECK_RC_MSG(rc, "Following SCH failed"); - - /* identify the BSIC and set it as TSC */ - rc = find_bsic(); - CHECK_COND_MSG(rc < 0, rc, "Identifying the BSIC failed"); - rc = set_tsc_from_bsic(layer1, rc); - CHECK_RC_MSG(rc, "Setting the TSC failed"); - - - /* follow the bcch */ - rc = follow_bcch(layer1); - CHECK_RC_MSG(rc, "Follow BCCH"); - - /* follow the pch */ - if (action == ACTION_BCCH_CCCH) { - rc = follow_pch(layer1); - CHECK_RC_MSG(rc, "Follow BCCH/CCCH"); - } - - /* now wait for the PhDataInd */ - for (;;) { - uint32_t fn; - uint8_t block; - uint8_t data[23]; - size_t size; - struct gsm_time gsmtime; - GsmL1_Sapi_t sapi; - - rc = wait_for_data(data, &size, &fn, &block, &sapi); - if (rc == 1) - continue; - CHECK_RC_MSG(rc, "No Data Indication"); - - gsm_fn2gsmtime(&gsmtime, fn); - printf("%02u/%02u/%02u %6s %s\n", - gsmtime.t1, gsmtime.t2, gsmtime.t3, - get_value_string(sapi_names, sapi), - osmo_hexdump(data, size)); - } - - rc = mph_close(layer1); - CHECK_RC_MSG(rc, "MPH-Close"); - - return EXIT_SUCCESS; -} - -int main(int argc, char **argv) -{ - int rc; - - handle_options(argc, argv); - printf("Initializing the Layer1\n"); - rc = initialize_layer1(dsp_flags); - CHECK_RC(rc); - - printf("Fetching system info.\n"); - rc = print_system_info(); - CHECK_RC(rc); - - printf("Opening RF frontend with clock(%d) and correction(%d)\n", - calib, initial_cor); - rc = activate_rf_frontend(calib, initial_cor); - CHECK_RC(rc); - - if (action == ACTION_SCAN) - return scan_band(); - else if (action == ACTION_BCCH || action == ACTION_BCCH_CCCH) - return bcch_follow(); - else { - if (source == SuperFemto_ClkSrcId_NetList) - return calib_clock_netlisten(); - return calib_clock(); - } - - return EXIT_SUCCESS; -} diff --git a/contrib/sysmobts-calib/sysmobts-layer1.c b/contrib/sysmobts-calib/sysmobts-layer1.c deleted file mode 100644 index 4b34f50e..00000000 --- a/contrib/sysmobts-calib/sysmobts-layer1.c +++ /dev/null @@ -1,800 +0,0 @@ -/* Layer1 handling for the DSP/FPGA */ -/* - * (C) 2012-2013 Holger Hans Peter Freyther - * - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "sysmobts-layer1.h" - -#define ARRAY_SIZE(ar) (sizeof(ar)/sizeof((ar)[0])) - -#define BTS_DSP2ARM "/dev/msgq/superfemto_dsp2arm" -#define BTS_ARM2DSP "/dev/msgq/superfemto_arm2dsp" -#define L1_SIG_ARM2DSP "/dev/msgq/gsml1_sig_arm2dsp" -#define L1_SIG_DSP2ARM "/dev/msgq/gsml1_sig_dsp2arm" - -int set_clock_cor(int clock_cor, int calib, int source); -static int wait_read_ignore(int seconds); - -static int sys_dsp2arm = -1, - sys_arm2dsp = -1, - sig_dsp2arm = -1, - sig_arm2dsp = -1; - -static int sync_indicated = 0; -static int time_indicated = 0; - -static int open_devices() -{ - sys_dsp2arm = open(BTS_DSP2ARM, O_RDONLY); - if (sys_dsp2arm == -1) { - perror("Failed to open dsp2arm system queue"); - return -1; - } - - sys_arm2dsp = open(BTS_ARM2DSP, O_WRONLY); - if (sys_arm2dsp == -1) { - perror("Failed to open arm2dsp system queue"); - return -2; - } - - sig_dsp2arm = open(L1_SIG_DSP2ARM, O_RDONLY); - if (sig_dsp2arm == -1) { - perror("Failed to open dsp2arm sig queue"); - return -3; - } - - sig_arm2dsp = open(L1_SIG_ARM2DSP, O_WRONLY); - if (sig_arm2dsp == -1) { - perror("Failed to open arm2dsp sig queue"); - return -4; - } - - return 0; -} - -/** - * Send a primitive to the system queue - */ -static int send_primitive(int primitive, SuperFemto_Prim_t *prim) -{ - prim->id = primitive; - return write(sys_arm2dsp, prim, sizeof(*prim)) != sizeof(*prim); -} - -/** - * Wait for a confirmation - */ -static int wait_primitive(int wait_for, SuperFemto_Prim_t *prim) -{ - memset(prim, 0, sizeof(*prim)); - int rc = read(sys_dsp2arm, prim, sizeof(*prim)); - if (rc != sizeof(*prim)) { - printf("Short read in %s: %d\n", __func__, rc); - return -1; - } - - if (prim->id != wait_for) { - printf("Got primitive %d but waited for %d\n", - prim->id, wait_for); - return -2; - } - - return 0; -} - -/* The Cnf for the Req, assume it is a +1 */ -static int answer_for(int primitive) -{ - return primitive + 1; -} - -static int send_recv_primitive(int p, SuperFemto_Prim_t *prim) -{ - int rc; - rc = send_primitive(p, prim); - if (rc != 0) - return -1; - - rc = wait_primitive(answer_for(p), prim); - if (rc != 0) - return -2; - return 0; -} - -static int answer_for_sig(int prim) -{ - static const GsmL1_PrimId_t cnf[] = { - [GsmL1_PrimId_MphInitReq] = GsmL1_PrimId_MphInitCnf, - [GsmL1_PrimId_MphCloseReq] = GsmL1_PrimId_MphCloseCnf, - [GsmL1_PrimId_MphConnectReq] = GsmL1_PrimId_MphConnectCnf, - [GsmL1_PrimId_MphActivateReq] = GsmL1_PrimId_MphActivateCnf, - [GsmL1_PrimId_MphConfigReq] = GsmL1_PrimId_MphConfigCnf, - [GsmL1_PrimId_MphMeasureReq] = GsmL1_PrimId_MphMeasureCnf, - }; - - if (prim < 0 || prim >= ARRAY_SIZE(cnf)) { - printf("Unknown primitive: %d\n", prim); - exit(-3); - } - - return cnf[prim]; -} - -static int is_indication(int prim) -{ - return - prim == GsmL1_PrimId_MphTimeInd || - prim == GsmL1_PrimId_MphSyncInd || - prim == GsmL1_PrimId_PhConnectInd || - prim == GsmL1_PrimId_PhReadyToSendInd || - prim == GsmL1_PrimId_PhDataInd || - prim == GsmL1_PrimId_PhRaInd; -} - - -static int send_recv_sig_prim(int p, GsmL1_Prim_t *prim) -{ - int rc; - prim->id = p; - rc = write(sig_arm2dsp, prim, sizeof(*prim)); - if (rc != sizeof(*prim)) { - printf("Failed to write: %d\n", rc); - return -1; - } - - do { - rc = read(sig_dsp2arm, prim, sizeof(*prim)); - if (rc != sizeof(*prim)) { - printf("Failed to read: %d\n", rc); - return -2; - } - } while (is_indication(prim->id)); - - if (prim->id != answer_for_sig(p)) { - printf("Wrong L1 result got %d wanted %d for prim: %d\n", - prim->id, answer_for_sig(p), p); - return -3; - } - - return 0; -} - -static int wait_for_indication(int p, GsmL1_Prim_t *prim) -{ - int rc; - memset(prim, 0, sizeof(*prim)); - - struct timespec start_time, now_time; - clock_gettime(CLOCK_MONOTONIC, &start_time); - - /* - * TODO: select.... with timeout. The below will work 99% as we will - * get time indications very soonish after the connect - */ - for (;;) { - clock_gettime(CLOCK_MONOTONIC, &now_time); - if (now_time.tv_sec - start_time.tv_sec > 10) { - printf("Timeout waiting for indication.\n"); - return -4; - } - - rc = read(sig_dsp2arm, prim, sizeof(*prim)); - if (rc != sizeof(*prim)) { - printf("Failed to read.\n"); - return -1; - } - - if (!is_indication(prim->id)) { - printf("No indication: %d\n", prim->id); - return -2; - } - - if (p != prim->id && prim->id == GsmL1_PrimId_MphSyncInd) { - printf("Got sync.\n"); - sync_indicated = 1; - continue; - } - if (p != prim->id && prim->id == GsmL1_PrimId_MphTimeInd) { - time_indicated = 1; - continue; - } - - if (p != prim->id) { - printf("Wrong indication got %d wanted %d\n", - prim->id, p); - return -3; - } - - break; - } - - return 0; -} - -static int set_trace_flags(uint32_t dsp) -{ - SuperFemto_Prim_t prim; - memset(&prim, 0, sizeof(prim)); - - prim.u.setTraceFlagsReq.u32Tf = dsp; - return send_primitive(SuperFemto_PrimId_SetTraceFlagsReq, &prim); -} - -static int reset_and_wait() -{ - int rc; - SuperFemto_Prim_t prim; - memset(&prim, 0, sizeof(prim)); - - rc = send_recv_primitive(SuperFemto_PrimId_Layer1ResetReq, &prim); - if (rc != 0) - return -1; - if (prim.u.layer1ResetCnf.status != GsmL1_Status_Success) - return -2; - return 0; -} - -/** - * Open the message queues and (re-)initialize the DSP and FPGA - */ -int initialize_layer1(uint32_t dsp_flags) -{ - if (open_devices() != 0) { - printf("Failed to open devices.\n"); - return -1; - } - - if (set_trace_flags(dsp_flags) != 0) { - printf("Failed to set dsp flags.\n"); - return -2; - } - if (reset_and_wait() != 0) { - printf("Failed to reset the firmware.\n"); - return -3; - } - return 0; -} - -/** - * Print systems infos - */ -int print_system_info() -{ - int rc; - SuperFemto_Prim_t prim; - memset(&prim, 0, sizeof(prim)); - - rc = send_recv_primitive(SuperFemto_PrimId_SystemInfoReq, &prim); - if (rc != 0) { - printf("Failed to send SystemInfoRequest.\n"); - return -1; - } - - if (prim.u.systemInfoCnf.status != GsmL1_Status_Success) { - printf("Failed to request SystemInfoRequest.\n"); - return -2; - } - -#define INFO_DSP(x) x.u.systemInfoCnf.dspVersion -#define INFO_FPGA(x) x.u.systemInfoCnf.fpgaVersion -#ifdef FEMTOBTS_NO_BOARD_VERSION -#define BOARD_REV(x) -1 -#define BOARD_OPT(x) -1 -#define COMPILED_MAJOR (FEMTOBTS_API_VERSION >> 16) -#define COMPILED_MINOR ((FEMTOBTS_API_VERSION >> 8) & 0xff) -#define COMPILED_BUILD (FEMTOBTS_API_VERSION & 0xff) -#else -#define BOARD_REV(x) x.u.systemInfoCnf.boardVersion.rev -#define BOARD_OPT(x) x.u.systemInfoCnf.boardVersion.option -#define COMPILED_MAJOR (SUPERFEMTO_API_VERSION >> 16) -#define COMPILED_MINOR ((SUPERFEMTO_API_VERSION >> 8) & 0xff) -#define COMPILED_BUILD (SUPERFEMTO_API_VERSION & 0xff) -#endif - - printf("Compiled against: v%u.%u.%u\n", - COMPILED_MAJOR, COMPILED_MINOR, COMPILED_BUILD); - printf("Running DSP v%d.%d.%d FPGA v%d.%d.%d Rev: %d Option: %d\n", - INFO_DSP(prim).major, INFO_DSP(prim).minor, INFO_DSP(prim).build, - INFO_FPGA(prim).major, INFO_FPGA(prim).minor, INFO_FPGA(prim).build, - BOARD_REV(prim), BOARD_OPT(prim)); - - if (COMPILED_MAJOR != INFO_DSP(prim).major || COMPILED_MINOR != INFO_DSP(prim).minor) { - printf("WARNING! WARNING! WARNING! WARNING! WARNING\n"); - printf("You might run this against an incompatible firmware.\n"); - printf("Continuing anyway but the result might be broken\n"); - } -#undef INFO_DSP -#undef INFO_FPGA -#undef BOARD_REV -#undef BOARD_OPT -#undef COMPILED_MAJOR -#undef COMPILED_MINOR -#undef COMPILED_BUILD - return 0; -} - -int activate_rf_frontend(int clock_source, int initial_cor) -{ - int rc; - SuperFemto_Prim_t prim; - memset(&prim, 0, sizeof(prim)); - - prim.u.activateRfReq.timing.u8TimSrc = 1; - prim.u.activateRfReq.msgq.u8UseTchMsgq = 0; - prim.u.activateRfReq.msgq.u8UsePdtchMsgq = 0; - - prim.u.activateRfReq.rfTrx.iClkCor = initial_cor; - prim.u.activateRfReq.rfTrx.clkSrc = clock_source; -#if SUPERFEMTO_API_VERSION < SUPERFEMTO_API(2,4,0) - prim.u.activateRfReq.rfRx.iClkCor = initial_cor; - prim.u.activateRfReq.rfRx.clkSrc = clock_source; -#endif - - rc = send_recv_primitive(SuperFemto_PrimId_ActivateRfReq, &prim); - return rc; -} - -static int mph_init(int band, int arfcn, HANDLE *layer1) -{ - int rc; - GsmL1_Prim_t prim; - memset(&prim, 0, sizeof(prim)); - - prim.u.mphInitReq.deviceParam.devType = GsmL1_DevType_Rxd; - prim.u.mphInitReq.deviceParam.freqBand = band; - prim.u.mphInitReq.deviceParam.u16Arfcn = arfcn; - prim.u.mphInitReq.deviceParam.u16BcchArfcn = arfcn; - prim.u.mphInitReq.deviceParam.fRxPowerLevel = -75.f; - prim.u.mphInitReq.deviceParam.u8AutoTA = 1; - - rc = send_recv_sig_prim(GsmL1_PrimId_MphInitReq, &prim); - if (rc != 0) { - printf("Failed to initialize the physical channel.\n"); - return -1; - } - - if (prim.u.mphInitCnf.status != GsmL1_Status_Success) { - printf("MPH Init failed.\n"); - return -2; - } - -#if 0 - if (prim.u.mphInitCnf.freqBand != band) { - printf("Layer1 ignored the band: %d\n", - prim.u.mphInitCnf.freqBand); - return -3; - } -#endif - - *layer1 = prim.u.mphInitCnf.hLayer1; - return 0; -} - -int mph_close(HANDLE layer1) -{ - int rc; - GsmL1_Prim_t prim; - memset(&prim, 0, sizeof(prim)); - - prim.u.mphCloseReq.hLayer1 = layer1; - rc = send_recv_sig_prim(GsmL1_PrimId_MphCloseReq, &prim); - if (rc != 0) { - printf("Failed to close the MPH\n"); - return -6; - } - if (prim.u.mphCloseCnf.status != GsmL1_Status_Success) { - printf("MPH Close failed.\n"); - return -7; - } - - return 0; -} - -int follow_sch(int band, int arfcn, int clock, int ref, HANDLE *layer1) -{ - int rc; - GsmL1_Prim_t prim; - - time_indicated = 0; - sync_indicated = 0; - - rc = mph_init(band, arfcn, layer1); - if (rc != 0) - return rc; - - /* 1.) Connect */ - memset(&prim, 0, sizeof(prim)); - prim.u.mphConnectReq.hLayer1 = *layer1; - prim.u.mphConnectReq.u8Tn = 0; - prim.u.mphConnectReq.logChComb = GsmL1_LogChComb_IV; - rc = send_recv_sig_prim(GsmL1_PrimId_MphConnectReq, &prim); - if (rc != 0) { - printf("Failed to connect.\n"); - return -1; - } - if (prim.u.mphConnectCnf.status != GsmL1_Status_Success) { - printf("Connect failed.\n"); - return -2; - } - if (prim.u.mphConnectCnf.u8Tn != 0) { - printf("Wrong timeslot.\n"); - return -3; - } - - /* 2.) Activate */ - memset(&prim, 0, sizeof(prim)); - prim.u.mphActivateReq.hLayer1 = *layer1; - prim.u.mphActivateReq.u8Tn = 0; - prim.u.mphActivateReq.sapi = GsmL1_Sapi_Sch; - prim.u.mphActivateReq.dir = GsmL1_Dir_RxDownlink; - rc = send_recv_sig_prim(GsmL1_PrimId_MphActivateReq, &prim); - if (rc != 0) { - printf("Activation failed.\n"); - return -4; - } - if (prim.u.mphActivateCnf.status != GsmL1_Status_Success) { - printf("Activation not successful.\n"); - return -5; - } - - /* 3.) Wait for indication... TODO: check... */ - printf("Waiting for connect indication.\n"); - rc = wait_for_indication(GsmL1_PrimId_PhConnectInd, &prim); - if (rc != 0) { - printf("Didn't get a connect indication.\n"); - return rc; - } - - /* 4.) Indication Syndication TODO: check... */ - if (!sync_indicated) { - printf("Waiting for sync indication.\n"); - rc = wait_for_indication(GsmL1_PrimId_MphSyncInd, &prim); - if (rc < 0) { - printf("Didn't get a sync indication.\n"); - return -23; - } else if (rc == 0) { - if (!prim.u.mphSyncInd.u8Synced) { - printf("Failed to get sync.\n"); - return -23; - } else { - printf("Synced.\n"); - } - } - } else { - printf("Already synced.\n"); - } - - return 0; -} - -static int follow_sapi(HANDLE layer1, const GsmL1_Sapi_t sapi) -{ - int rc; - GsmL1_Prim_t prim; - - /* 1.) Activate BCCH or such... */ - memset(&prim, 0, sizeof(prim)); - prim.u.mphActivateReq.hLayer1 = layer1; - prim.u.mphActivateReq.u8Tn = 0; - prim.u.mphActivateReq.sapi = sapi; - prim.u.mphActivateReq.dir = GsmL1_Dir_RxDownlink; - - rc = send_recv_sig_prim(GsmL1_PrimId_MphActivateReq, &prim); - if (rc != 0) { - printf("Activation failed.\n"); - return -4; - } - if (prim.u.mphActivateCnf.status != GsmL1_Status_Success) { - printf("Activation not successful.\n"); - return -5; - } - - /* 2.) Wait for indication... */ - printf("Waiting for connect indication.\n"); - rc = wait_for_indication(GsmL1_PrimId_PhConnectInd, &prim); - if (rc != 0) { - printf("Didn't get a connect indication.\n"); - return rc; - } - - if (prim.u.phConnectInd.sapi != sapi) { - printf("Got a connect indication for the wrong type: %d\n", - prim.u.phConnectInd.sapi); - return -6; - } - - /* 3.) Wait for PhDataInd... */ - printf("Waiting for data.\n"); - rc = wait_for_indication(GsmL1_PrimId_PhDataInd, &prim); - if (rc != 0) { - printf("Didn't get data.\n"); - return rc; - } - - return 0; -} - -int follow_bcch(HANDLE layer1) -{ - return follow_sapi(layer1, GsmL1_Sapi_Bcch); -} - -int follow_pch(HANDLE layer1) -{ - return follow_sapi(layer1, GsmL1_Sapi_Pch); -} - -int find_bsic(void) -{ - int rc, i; - GsmL1_Prim_t prim; - - printf("Waiting for SCH data.\n"); - for (i = 0; i < 10; ++i) { - uint8_t bsic; - rc = wait_for_indication(GsmL1_PrimId_PhDataInd, &prim); - if (rc < 0) { - printf("Didn't get SCH data.\n"); - return rc; - } - if (prim.u.phDataInd.sapi != GsmL1_Sapi_Sch) - continue; - - bsic = (prim.u.phDataInd.msgUnitParam.u8Buffer[0] >> 2) & 0xFF; - return bsic; - } - - printf("Giving up finding the SCH\n"); - return -1; -} - -int set_tsc_from_bsic(HANDLE layer1, int bsic) -{ - int rc; - int tsc = bsic & 0x7; - GsmL1_Prim_t prim; - - memset(&prim, 0, sizeof(prim)); - prim.u.mphConfigReq.hLayer3 = 0x23; - prim.u.mphConfigReq.hLayer1 = layer1; - prim.u.mphConfigReq.cfgParamId = GsmL1_ConfigParamId_SetNbTsc; - prim.u.mphConfigReq.cfgParams.setNbTsc.u8NbTsc = tsc; - rc = send_recv_sig_prim(GsmL1_PrimId_MphConfigReq, &prim); - if (rc != 0) { - printf("Failed to send configure.\n"); - } - - if (prim.u.mphConfigCnf.status != GsmL1_Status_Success) { - printf("Failed to set the config cnf.\n"); - return -1; - } - - return 0; -} - -int set_clock_cor(int clock_cor, int calib, int source) -{ - int rc; - SuperFemto_Prim_t prim; - memset(&prim, 0, sizeof(prim)); - - prim.u.rfClockSetupReq.rfTrx.iClkCor = clock_cor; - prim.u.rfClockSetupReq.rfTrx.clkSrc = calib; -#if SUPERFEMTO_API_VERSION < SUPERFEMTO_API(2,4,0) - prim.u.rfClockSetupReq.rfRx.iClkCor = clock_cor; - prim.u.rfClockSetupReq.rfRx.clkSrc = calib; -#endif - prim.u.rfClockSetupReq.rfTrxClkCal.clkSrc = source; - - rc = send_recv_primitive(SuperFemto_PrimId_RfClockSetupReq, &prim); - if (rc != 0) { - printf("Failed to set the clock setup.\n"); - return -1; - } - if (prim.u.rfClockSetupCnf.status != GsmL1_Status_Success) { - printf("Clock setup was not successfull.\n"); - return -2; - } - - return 0; -} - -int rf_clock_info(int *clkErr, int *clkErrRes) -{ - SuperFemto_Prim_t prim; - memset(&prim, 0, sizeof(prim)); - - int rc; - - /* reset the counter */ - prim.u.rfClockInfoReq.u8RstClkCal = 1; - rc = send_recv_primitive(SuperFemto_PrimId_RfClockInfoReq, &prim); - if (rc != 0) { - printf("Failed to reset the clock info.\n"); - return -1; - } - - /* wait for a value */ - wait_read_ignore(15); - - /* ask for the current counter/error */ - memset(&prim, 0, sizeof(prim)); - prim.u.rfClockInfoReq.u8RstClkCal = 0; - rc = send_recv_primitive(SuperFemto_PrimId_RfClockInfoReq, &prim); - if (rc != 0) { - printf("Failed to get the clock info.\n"); - return -2; - } - - printf("Error: %d Res: %d\n", - prim.u.rfClockInfoCnf.rfTrxClkCal.iClkErr, - prim.u.rfClockInfoCnf.rfTrxClkCal.iClkErrRes); - *clkErr = prim.u.rfClockInfoCnf.rfTrxClkCal.iClkErr; - *clkErrRes = prim.u.rfClockInfoCnf.rfTrxClkCal.iClkErrRes; - return 0; -} - -int power_scan(int band, int arfcn, int duration, float *mean_rssi) -{ - int rc; - HANDLE layer1; - GsmL1_Prim_t prim; - - /* init */ - rc = mph_init(band, arfcn, &layer1); - if (rc != 0) - return rc; - - /* mph measure request */ - memset(&prim, 0, sizeof(prim)); - prim.u.mphMeasureReq.hLayer1 = layer1; - prim.u.mphMeasureReq.u32Duration = duration; - rc = send_recv_sig_prim(GsmL1_PrimId_MphMeasureReq, &prim); - if (rc != 0) { - printf("Failed to send measurement request.\n"); - return -4; - } - - if (prim.u.mphMeasureCnf.status != GsmL1_Status_Success) { - printf("MphMeasureReq was not confirmed.\n"); - return -5; - } - - *mean_rssi = prim.u.mphMeasureCnf.fMeanRssi; - - /* close */ - rc = mph_close(layer1); - return rc; -} - -/** - * Wait for indication... - */ -int wait_for_sync(HANDLE layer1, int cor, int calib, int source) -{ - GsmL1_Prim_t prim; - int rc; - - rc = set_clock_cor(cor, calib, source); - if (rc != 0) { - printf("Failed to set the clock correction.\n"); - return -1; - } - - sync_indicated = 0; - rc = wait_for_indication(GsmL1_PrimId_MphSyncInd, &prim); - if (rc < 0 && rc != -4) { - return rc; - } else if (rc == 0) { - if (!prim.u.mphSyncInd.u8Synced) { - printf("Failed to get sync.\n"); - return 0; - } - printf("Synced.\n"); - return 1; - } - - return 0; -} - -int wait_for_data(uint8_t *data, size_t *size, uint32_t *fn, uint8_t *block, GsmL1_Sapi_t *sap) -{ - GsmL1_Prim_t prim; - int rc; - - rc = wait_for_indication(GsmL1_PrimId_PhDataInd, &prim); - if (rc < 0) - return rc; - if (prim.u.phDataInd.sapi == GsmL1_Sapi_Sch) - return 1; - - *size = prim.u.phDataInd.msgUnitParam.u8Size; - *fn = prim.u.phDataInd.u32Fn; - *block = prim.u.phDataInd.u8BlockNbr; - *sap = prim.u.phDataInd.sapi; - memcpy(data, prim.u.phDataInd.msgUnitParam.u8Buffer, *size); - return 0; -} - -/** - * Make sure the pipe is not running full. - * - */ -static int wait_read_ignore(int seconds) -{ - int max, rc; - fd_set fds; - struct timeval timeout; - - max = sys_dsp2arm > sig_dsp2arm ? sys_dsp2arm : sig_dsp2arm; - - timeout.tv_sec = seconds; - timeout.tv_usec = 0; - - while (1) { - FD_ZERO(&fds); - FD_SET(sys_dsp2arm, &fds); - FD_SET(sig_dsp2arm, &fds); - - - rc = select(max + 1, &fds, NULL, NULL, &timeout); - if (rc == -1) { - printf("Failed to select.\n"); - return -1; - } else if (rc) { - if (FD_ISSET(sys_dsp2arm, &fds)) { - SuperFemto_Prim_t prim; - rc = read(sys_dsp2arm, &prim, sizeof(prim)); - if (rc != sizeof(prim)) { - perror("Failed to read system primitive"); - return -2; - } - } - if (FD_ISSET(sig_dsp2arm, &fds)) { - GsmL1_Prim_t prim; - rc = read(sig_dsp2arm, &prim, sizeof(prim)); - if (rc != sizeof(prim)) { - perror("Failed to read signal primitiven"); - return -3; - } - } - } else if (timeout.tv_sec <= 0 && timeout.tv_usec <= 0) { - break; - } - -#ifndef __linux__ -#error "Non portable code" -#endif - } - return 0; -} diff --git a/contrib/sysmobts-calib/sysmobts-layer1.h b/contrib/sysmobts-calib/sysmobts-layer1.h deleted file mode 100644 index e7d59c94..00000000 --- a/contrib/sysmobts-calib/sysmobts-layer1.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef SYSMOBTS_LAYER_H -#define SYSMOBTS_LAYER_H - -#include - -#ifdef FEMTOBTS_API_VERSION -#define SuperFemto_PrimId_t FemtoBts_PrimId_t -#define SuperFemto_Prim_t FemtoBts_Prim_t -#define SuperFemto_PrimId_SystemInfoReq FemtoBts_PrimId_SystemInfoReq -#define SuperFemto_PrimId_SystemInfoCnf FemtoBts_PrimId_SystemInfoCnf -#define SuperFemto_SystemInfoCnf_t FemtoBts_SystemInfoCnf_t -#define SuperFemto_PrimId_SystemFailureInd FemtoBts_PrimId_SystemFailureInd -#define SuperFemto_PrimId_ActivateRfReq FemtoBts_PrimId_ActivateRfReq -#define SuperFemto_PrimId_ActivateRfCnf FemtoBts_PrimId_ActivateRfCnf -#define SuperFemto_PrimId_DeactivateRfReq FemtoBts_PrimId_DeactivateRfReq -#define SuperFemto_PrimId_DeactivateRfCnf FemtoBts_PrimId_DeactivateRfCnf -#define SuperFemto_PrimId_SetTraceFlagsReq FemtoBts_PrimId_SetTraceFlagsReq -#define SuperFemto_PrimId_RfClockInfoReq FemtoBts_PrimId_RfClockInfoReq -#define SuperFemto_PrimId_RfClockInfoCnf FemtoBts_PrimId_RfClockInfoCnf -#define SuperFemto_PrimId_RfClockSetupReq FemtoBts_PrimId_RfClockSetupReq -#define SuperFemto_PrimId_RfClockSetupCnf FemtoBts_PrimId_RfClockSetupCnf -#define SuperFemto_PrimId_Layer1ResetReq FemtoBts_PrimId_Layer1ResetReq -#define SuperFemto_PrimId_Layer1ResetCnf FemtoBts_PrimId_Layer1ResetCnf -#define SuperFemto_PrimId_NUM FemtoBts_PrimId_NUM -#define HW_SYSMOBTS_V1 1 -#define SUPERFEMTO_API(x,y,z) FEMTOBTS_API(x,y,z) -#endif - -extern int initialize_layer1(uint32_t dsp_flags); -extern int print_system_info(); -extern int activate_rf_frontend(int clock_source, int clock_cor); -extern int power_scan(int band, int arfcn, int duration, float *mean_rssi); -extern int follow_sch(int band, int arfcn, int calib, int reference, HANDLE *layer1); -extern int follow_bch(HANDLE layer1); -extern int find_bsic(void); -extern int set_tsc_from_bsic(HANDLE layer1, int bsic); -extern int set_clock_cor(int clock_corr, int calib, int source); -extern int rf_clock_info(int *clkErr, int *clkErrRes); -extern int mph_close(HANDLE layer1); -extern int wait_for_sync(HANDLE layer1, int cor, int calib, int source); -extern int follow_bcch(HANDLE layer1); -extern int follow_pch(HANDLE layer1); -extern int wait_for_data(uint8_t *data, size_t *size, uint32_t *fn, uint8_t *block, GsmL1_Sapi_t *sapi); - -#endif -- cgit v1.2.3