# HG changeset patch # User Mychaela Falconia # Date 1502947663 0 # Node ID 15a2a308fb31867c80868334d8b4fd1f8d9c9330 # Parent 4cee70d429bfe53bc4d2a8307427fa91df3e2d87 fc-rfcal-tools now public, old frozen rfcal code can be removed diff -r 4cee70d429bf -r 15a2a308fb31 .hgignore --- a/.hgignore Sat Aug 12 17:37:02 2017 +0000 +++ b/.hgignore Thu Aug 17 05:27:43 2017 +0000 @@ -27,12 +27,6 @@ ^miscutil/fc-vm2hex$ ^miscutil/imei-luhn$ -^rfcal/cmu200/fc-cmu200d$ -^rfcal/cmu200/fc-serscpi$ -^rfcal/tsid-test/fc-tsid-shell$ -^rfcal/vcxo-manual/fc-vcxo-linear$ -^rfcal/vcxo-manual/fc-vcxo-param$ - ^ringtools/fc-e1decode$ ^ringtools/fc-e1gen$ diff -r 4cee70d429bf -r 15a2a308fb31 doc/RF-cal/Architecture --- a/doc/RF-cal/Architecture Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -The RF calibration process fundamentally consists of 3 parts: - -1: The FreeCalypso GSM MS device under test (DUT) to be calibrated; - -2: An RF test station to which the DUT is connected via an RF coax cable, - performing the RF signal analyzer and signal generator functions required - for the calibration procedures; - -3: A program that communicates with both the DUT and the RF test station and - orchestrates all of the signal generation, measurement and computation steps - to arrive at the final calibration results to be stored in the flash file - system of the DUT. The steps are too numerous, tedious and repetitive to be - performed manually, hence automation is required in order to make the process - practical. - -The goal of the FreeCalypso RF calibration subproject is to produce a set of -tools for performing part 3 of the above breakdown. The current vision is that -our automated calibration software will be broken down into two interfacing -components: - -1: There will be a Test System Interface Daemon (TSID) that encapsulates the - magic specific to a particular brand of RF test station, e.g., R&S CMU200. - The TSID will only talk to the CMU200 or other RF test station, but not to - the Calypso DUT, and the intent is that the TSID only needs to be started - once at the beginning of a calibration work shift and then stay running as a - hundred or more FreeCalypso GSM devices may be calibrated on the production - line. The TSID will present a local socket interface (can be changed to - TCP/IP if operation over a network is required) to which the other component - below will connect as a client. - -2: There will be a set of 3 programs (fc-rfcal-vcxo, fc-rfcal-rxband and - fc-rfcal-txband) that perform the 3 required calibration groups for each - individual FreeCalypso device unit on the production line. The production - automation script will need to run fc-rfcal-vcxo first, then fc-rfcal-rxband - for each of the hardware-supported bands (e.g., 900, 1800 and 1900 on - FCDEV3B-900), then fc-rfcal-txband for each of the same bands. Each of these - programs will talk both to the DUT (via rvinterf) and to the RF test system - (via the TSID), i.e., will need to connect to an already-running rvinterf - process and to an already-running TSID via local sockets. - -The programs in the second group above will contain no knowledge specific to -R&S CMU200 or any other particular brand of RF test station, instead this -knowledge is to be encapsulated in the TSID. The interface between the TSID -and its clients will be of a command-response nature, and will be defined from -the perspective of the needs of the FreeCalypso calibration process, rather than -from the perspective of the capabilities of the CMU200 - in other words, the -calibration automation program will command the TSID to the effect of "I need -this", and it will be the responsibility of the TSID to figure out how to -perform the required measurement or signal generation on the given type of test -equipment. - -See the Test-system-interface document for the details of the TSID socket -interface. diff -r 4cee70d429bf -r 15a2a308fb31 doc/RF-cal/CMU200-notes --- a/doc/RF-cal/CMU200-notes Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -R&S CMU200 is the RF tester used for production RF calibration of FreeCalypso -GSM devices. The CMU200 can be operated in three ways: manually via the front -panel, programmatically via GPIB and programmatically via SCPI commands over -RS-232. GPIB is the industry standard, but for FreeCalypso the Mother has -adopted the RS-232 control interface method instead in order to avoid the -exotic hardware and equally exotic drivers and libraries required for GPIB: -using the RS-232 interface requires absolutely no special hardware or drivers -or libraries, just userspace C code without any dependencies talking to a -serial port just like we do when communicating with Calypso target serial ports. - -Initialization commands -======================= - -Our Test System Interface Daemon for the CMU200 will issue the following SCPI -commands to the instrument on start-up: - -*SEC 0 -*RST;*OPC? -SYST:NONV:DIS -SYST:REM:ADDR:SEC 1,"RF_NSig" -SYST:REM:ADDR:SEC 2,"GSM900MS_NSig" -SYST:REM:ADDR:SEC 3,"GSM1800MS_NSig" -SYST:REM:ADDR:SEC 4,"GSM1900MS_NSig" -SYST:REM:ADDR:SEC 5,"GSM850MS_NSig" - -VCXO calibration -================ - -When commanded to prepare for VCXO calibration, our TSID will command the -CMU200 as follows: - -*SEC 2 -RFAN:CHAN 40CH -RFAN:TSEQ GSM5 - -Command to read frequency offset: - -READ:MOD? - -Signal generator mode -===================== - -Turn signal generator on: - -*SEC 1 -SOUR:RFG:LEV -SOUR:RFG:FREQ -INIT:RFG - -Turn signal generator off: - -ABORT:RFG diff -r 4cee70d429bf -r 15a2a308fb31 doc/RF-cal/Test-system-interface --- a/doc/RF-cal/Test-system-interface Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -The Test System Interface Daemon (TSID) will provide a connection-oriented -(SOCK_STREAM) UNIX domain local socket at /tmp/fc_rftest_socket, and will speak -an ASCII line-based command-response protocol on this socket. All command and -response lines will end with \n only (no \r), and each TSID response including -the initial greeting on connection establishment will begin with a '+' or '-' -character to indicate OK or error, respectively, like in POP3. - -The following commands are currently defined: - -vcxo-cal-setup band arfcn - -This command is sent to the TSID to prepare the RF test system for the VCXO -calibration procedure. The first argument after the command keyword is the -band to be used (850, 900, 1800 or 1900) and the second argument is the ARFCN -in that band on which the DUT will be transmitting. - -freq-meas hint - -This command directs the RF test system to take a frequency offset measurement -(vcxo-cal-setup must have been performed previously) and report it back to the -client in the response line. The hint argument after the freq-meas keyword will -be sent by the VCXO calibration program (fc-rfcal-vcxo) to tell the RF test -system what kind of frequency offset measurement is being made, i.e., which step -in the VCXO calibration sequence is being performed; the hint keywords remain -to be defined. - -signal-gen-setup band - -This command is sent to the TSID to prepare the RF test system for tests in -which the latter acts as a signal generator. The argument after the command -keyword is the band number (850, 900, 1800 or 1900), and it selects the -downlink frequency band in which the signal generator will need to operate. - -signal-gen-sine arfcn offset level - -This command directs the RF test system to turn on its signal generator and put -out a pure sine wave at the frequency corresponding to the specified ARFCN (in -the downlink band previously selected with signal-get-setup) plus the specified -offset in kHz (-67 or +67 with TI's Rx path calibration procedures), and at the -specified Tx power level in dBm. - -signal-gen-off - -Turn off the signal generator. - -The commands for Tx power level calibration remain to be defined. diff -r 4cee70d429bf -r 15a2a308fb31 doc/RF-cal/VCXO-notes --- a/doc/RF-cal/VCXO-notes Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,227 +0,0 @@ -How to calibrate the VCXO on your FreeCalypso development board -=============================================================== - -The process of calibrating the VCXO on a Calypso+Iota+Rita GSM MS consists of -the following fundamental parts: - -* The antenna needs to be disconnected and the FreeCalypso device's RF output - (SMA on the FCDEV3B) needs to be connected to an RF test station such as an - R&S CMU200. - -* The DUT is commanded to transmit semi-continuously as if it were transmitting - on TCH: Tx in one timeslot out of 8, but with the DUT running its own notion - of the TDMA frame not synchronized to anything, and keep transmitting - endlessly in 1/8 out of every 4.615 ms. - -* The RF test station connected to the DUT is used in the RF analyzer mode to - measure the frequency offset of the DUT's signal, relative to the ideal uplink - frequency corresponding to the selected ARFCN. - -* The above frequency offset measurement is performed with the AFC DAC on the - Calypso device set to different values, the results of the initial - measurements are used to guide some additional measurements, some computations - are made from these results, and the computed values are written into the - FreeCalypso device's FFS. - -This procedure is meant to be automated by way of a program that talks both to -the FreeCalypso DUT and to the RF test station and orchestrates all of the -measurement and computation steps, but until this program gets written (we -weren't able to get a hold of TI's original, hence we have to develop our own), -use the following instructions to perform the VCXO calibration procedure -manually. You still need a CMU200 or equivalent, though - it is not possible -to do any kind of calibration on a Calypso device by itself, without connecting -it to some appropriate RF test equipment. - -Reference documentation -======================= - -We have the following two TI documents which describe some of the RF calibration -procedures including the one for the VCXO: - -ftp://ftp.freecalypso.org/pub/GSM/Calypso/rf_calibration.pdf - -https://www.freecalypso.org/LoCosto-docs/Production%20test%20and%20calibration/i_sample_rf_test_and_calibration_13_03_04_01991%20-%20v026.pdf - -Unfortunately neither of them corresponds to the exact evolutionary time point -of interest to us: the first one corresponds to some chipset much earlier than -the one we are working with, and to firmware versions much earlier than ours, -whereas the second one is for TI's later LoCosto chipset. - -Commanding the DUT to transmit semi-continuously -================================================ - -There is only one VCXO calibration that is subsequently used for all bands in -normal MS operation. Both of the calibration instruction documents above -instruct the operator to run the Tx in GSM900 mode on ARFCN 40, hence we shall -do likewise until and unless we find some good reason to do differently. - -Issue the following commands through fc-tmsh to start the semi-continuous Tx: - -tms 1 # enter RF Test Mode -rfpw 7 6 0 # select GSM 900+1800 band pair, GSM900 band within the pair -rfpw 2 40 # set ARFCN to 40 -rfpw 8 0 # disable AFC algorithm, i.e., control the AFC DAC manually -txpw 1 12 # Tx power level -rfe 3 # start Rx & Tx without network sync - -WARNING: Before issuing the above commands, ensure that the antenna is -disconnected and that the RF output will be going into your test equipment, -not on the air! Do not EVER issue these commands with a real antenna connected, -unless your intent is to operate a rogue transmitter or jammer. - -At this point your CMU200 or equivalent should detect the uplink signal -generated by the DUT (on the CMU200 one needs to set TSC to 5, dunno about -other test equipment), and you should see some frequency offset. - -The actual calibration procedure -================================ - -1. Set the AFC DAC to -2048: - - rfpw 9 -2048 - - and measure the frequency offset. Note it down. - -2. Set the AFC DAC to +2048: - - rfpw 9 2048 - - and again measure the frequency offset. Note it down. - -Now you need to create an ASCII text file with your frequency offset -measurements. Each line represents one measurement and consists of two fields: -the first field is the DAC value and the second field is the measured frequency -offset in Hz. On my FCDEV3B S/N 001 the first two measurements were: - --2048 -30008 -+2048 +21394 - -Next you need to apply a linear model to the VCXO frequency offset as a function -of the DAC input: if x is the DAC value and F is the resulting frequency offset, -then the linear model is F = ax + b, where a and b need to be determined from -two measured points (x1, F1) and (x2, F2). Then once you have a and b, find the -x value that should produce F = 0. The fc-vcxo-linear utility will do this math -for you: run it with the name of your text file with measurements as its only -argument. - -With my measurements, the DAC_CENTER value computed by fc-vcxo-linear is 343. -However, the linear model is not perfect, thus when you write this computed -value into the DAC with the rfpw 9 command, the resulting frequency offset on -the CMU200 screen may be quite far from 0. - -TI's instructions in the LoCosto document direct the calibration operator to do -two more measurements at DAC_CENTER-100 and DAC_CENTER+100, where DAC_CENTER is -the value we just computed by applying the linear model to the first two -measurements. However, in my case the frequency offset at DAC=343 (DAC_CENTER) -was so negative that at DAC=443 (DAC_CENTER+100) it was still negative - and I -assume that TI's intent was to capture a close range around the zero crossing. - -Therefore, when I get to writing the automated calibration program, I intend to -change this part of the algorithm as follows: instead of adding or subtracting -100 right now, first do an rfpw 9 with the DAC_CENTER value as computed from -the linear model, make a frequency offset measurement, and see if it is negative -or positive. Then step the DAC value in the appropriate direction by some -reasonable increment (e.g., 100) until the frequency offset changes sign. Then -take the two DAC values closest to the output frequency offset sign change. - -After doing the above, my measurement notes file became: - --2048 -30008 -+2048 +21394 -443 -669 -543 634 - -This file needs to contain all four measurements, with the first two being at -the extreme DAC values and with the second two hugging the empirically located -zero crossing, when you feed it to the next step: - -fc-vcxo-param myvcxo.meas - -The fc-vcxo-param utility will compute the final math steps to produce the -actual calibration values which will need to be uploaded to the FreeCalypso -device and stored in its FFS. With my measurements above, I got the following -output: - -rf_table afcparams - - 3434 # Psi_sta_inv - 15 # Psi_st - 1000341 # Psi_st_32 - 4293 # Psi_st_inv - - 3954 # DAC_INIT * 8 - -5860 # DAC_MIN * 8 - 11351 # DAC_MAX * 8 - 2560 # snr_thr - -# DAC_INIT: rfpw 10 494 - -The output from fc-vcxo-param is in the rf_table format which our implementation -of the rftw command takes as input, and the latter is the fc-tmsh command which -you will need to issue in order to send this table to the FreeCalypso firmware -in the DUT. - -Explanation of the numbers: - -* The Psi constants are computed from the slope of the VCXO, and are - subsequently used for the steering: when the DSP reports a particular - frequency offset (in the form of an angle in radians), by how much should the - DAC value be adjusted? The slope I use for computing these Psi constants is - the one from the first two measurements at the extreme DAC values, as the - LoCosto document seems to indicate. - -* DAC_INIT is the DAC value at which the resulting frequency offset should be 0; - it is computed per the linear model from the second pair of measurements. - -* DAC_MIN and DAC_MAX are the DAC values which should produce frequency offsets - of -15 and +15 ppm, respectively, according to the LoCosto document. I - compute them per the linear model from the first pair of measurements (the - extreme DAC ones), as that is what the LoCosto document says. - -* The SNR threshold is a constant that never needs to change. - -The 3 dac_* values in the afcparams structure are stored in the times 8 form. -Examination of the afcparams values read out of several Openmoko-made GTA02 -units shows that the low 3 bits aren't necessarily zeros, indicating that TI's -calibration program probably multiplied by 8 before converting from floating -point to integer; I do likewise in fc-vcxo-param. - -Examination of the same afcparams values read out of Openmoko-made units also -shows that the center, min and max DAC values do vary quite a bit from one unit -to the next, whereas the Psi constants change very little. The Psi constants -which my program computed from my manual measurements on FCDEV3B S/N 001 are in -the same range as those read out of Openmoko-made units, which is definitely a -reassuring sign. - -Writing your VCXO calibration into FFS -====================================== - -Save the fc-vcxo-param output in a file, e.g.: - -fc-vcxo-param myvcxo.meas myvcxo.param - -Upload the generated afcparams table to your FreeCalypso device: - -rftw 9 myvcxo.param - -There is one more variable in the firmware, outside of the afcparams structure, -which also holds the DAC_INIT value. Set it with an rfpw 10 command as -instructed in the last comment line emitted by fc-vcxo-param; in my case it was: - -rfpw 10 494 - -Now save all of these values in the non-volatile flash file system: - -me 102 -me 103 - -Cleaning up -=========== - -To shut off the transmitter you started earlier, issue this command: - -rfe 0 - -Now power off your FreeCalypso device, disconnect the RF test setup, connect the -antenna back, insert a SIM, do a fresh boot and see if you can connect to a real -live GSM network with your VCXO calibration! diff -r 4cee70d429bf -r 15a2a308fb31 rfcal.note --- a/rfcal.note Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -The development of FreeCalypso RF calibration software (sw that requires a -Rohde&Schwarz CMU200 RF test machine, cannot do anything useful without one, -and is of any use only to those who engage in *physical production* of Calypso -hardware devices) was started in the present freecalypso-tools source -repository, but it is now being moved to a new FC production tools repository. -The latter repository is currently kept private for business reasons, but it -WILL be made public hopefully soon, as soon as our present-time business -complication is resolved one way or another. - -When our new FC production tools repository becomes public, all rfcal tools -will be removed from freecalypso-tools, replaced with a pointer to the new -public repository containing current versions of these tools; until then, the -rfcal and doc/RF-cal subdirectories contain the last frozen versions of these -tools and docs from before the beginning of private development. diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/Makefile --- a/rfcal/Makefile Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -SUBDIR= cmu200 tsid-test vcxo-manual - -all: ${SUBDIR} - -${SUBDIR}: FRC - cd $@; ${MAKE} ${MFLAGS} - -clean: FRC - rm -f a.out core errs - for i in ${SUBDIR}; do (cd $$i; ${MAKE} ${MFLAGS} clean); done - -install: FRC - for i in ${SUBDIR}; do (cd $$i; ${MAKE} ${MFLAGS} install); done - -FRC: diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/cmu200/Makefile --- a/rfcal/cmu200/Makefile Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -CC= gcc -CFLAGS= -O2 -PROGS= fc-cmu200d fc-serscpi -INSTBIN=/opt/freecalypso/bin - -CMU200D_OBJS= dispatch.o init.o main.o openport.o sercmd.o session.o socket.o -SERSCPI_OBJS= openport.o sertool.o - -all: ${PROGS} - -fc-cmu200d: ${CMU200D_OBJS} - ${CC} ${CFLAGS} -o $@ ${CMU200D_OBJS} - -fc-serscpi: ${SERSCPI_OBJS} - ${CC} ${CFLAGS} -o $@ ${SERSCPI_OBJS} - -install: - mkdir -p ${INSTBIN} - install -c ${PROGS} ${INSTBIN} - -clean: - rm -f *.o *.out *errs ${PROGS} diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/cmu200/dispatch.c --- a/rfcal/cmu200/dispatch.c Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * This module contains the code that dispatches client commands. - */ - -#include -#include -#include -#include - -extern char *client_cmd_fields[]; -extern int client_cmd_nfields; - -cmd_ping() -{ - send_socket_response("+Pong\n"); - return(0); -} - -static struct cmdtab { - char *cmd_kw; - int (*handler)(); -} cmdtab[] = { - {"ping", cmd_ping}, - {0, 0} -}; - -dispatch_client_command() -{ - struct cmdtab *tp; - - for (tp = cmdtab; tp->cmd_kw; tp++) - if (!strcmp(client_cmd_fields[0], tp->cmd_kw)) - break; - if (tp->handler) - return tp->handler(); - send_socket_response("-Unknown or unimplemented command\n"); - return(0); -} diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/cmu200/init.c --- a/rfcal/cmu200/init.c Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * This module contains the code that fc-cmu200d runs at startup, - * to put the CMU200 into a known state at the global level. - */ - -#include -#include -#include -#include -#include "secaddr.h" - -extern char instrument_response[]; - -static char id_string[] = "Rohde&Schwarz,CMU"; - -static void -assign_secondary_addr(addr, func) - char *func; -{ - char cmdbuf[80]; - - sprintf(cmdbuf, "SYST:REM:ADDR:SEC %d,\"%s\"\n", addr, func); - send_scpi_cmd(cmdbuf); -} - -init_cmu200() -{ - /* Test if we are connected to a CMU */ - send_scpi_cmd("*IDN?\n"); - collect_instr_response(); - if (strncasecmp(instrument_response, id_string, strlen(id_string))) { - fprintf(stderr, "error: not connected to a CMU200\n"); - exit(1); - } - /* init commands */ - send_scpi_cmd("*SEC 0\n"); - send_scpi_cmd("*RST;*OPC?\n"); - collect_staropc_response(); - send_scpi_cmd("SYST:NONV:DIS\n"); - assign_secondary_addr(SECADDR_RF_NSIG, "RF_NSig"); - assign_secondary_addr(SECADDR_GSM900MS_NSIG, "GSM900MS_NSig"); - assign_secondary_addr(SECADDR_GSM1800MS_NSIG, "GSM1800MS_NSig"); - assign_secondary_addr(SECADDR_GSM1900MS_NSIG, "GSM1900MS_NSig"); - assign_secondary_addr(SECADDR_GSM850MS_NSIG, "GSM850MS_NSig"); - send_scpi_cmd("*OPC?\n"); - collect_staropc_response(); - printf("CMU200 init complete\n"); -} diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/cmu200/main.c --- a/rfcal/cmu200/main.c Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * This module contains the main() function for fc-cmu200d. - */ - -#include -#include - -int target_fd; - -static char default_socket_pathname[] = "/tmp/fc_rftest_socket"; - -char *bind_socket_pathname; - -main(argc, argv) - char **argv; -{ - if (argc < 3 || argc > 4) { - fprintf(stderr, - "usage: %s serial-port baud [socket-pathname]\n", - argv[0]); - exit(1); - } - open_target_serial(argv[1], argv[2]); - set_serial_nonblock(0); - init_cmu200(); - if (argc > 3) - bind_socket_pathname = argv[3]; - else - bind_socket_pathname = default_socket_pathname; - create_listener_socket(); - for (;;) { - get_socket_connection(); - handle_session(); - } -} diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/cmu200/openport.c --- a/rfcal/cmu200/openport.c Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Serial port opening code for talking to CMU200 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern int target_fd; - -static struct baudrate { - char *name; - speed_t termios_code; -} baud_rate_table[] = { - {"1200", B1200}, - {"2400", B2400}, - {"4800", B4800}, - {"9600", B9600}, - {"19200", B19200}, - {"38400", B38400}, - {"57600", B57600}, - {"115200", B115200}, - /* table search terminator */ - {NULL, B0} -}; - -open_target_serial(ttydev, baudname) - char *ttydev, *baudname; -{ - struct termios target_termios; - struct baudrate *br; - - for (br = baud_rate_table; br->name; br++) - if (!strcmp(br->name, baudname)) - break; - if (!br->name) { - fprintf(stderr, "baud rate \"%s\" unknown/unsupported\n", - baudname); - exit(1); - } - target_fd = open(ttydev, O_RDWR|O_NONBLOCK); - if (target_fd < 0) { - perror(ttydev); - exit(1); - } - target_termios.c_iflag = IGNBRK; - target_termios.c_oflag = 0; - target_termios.c_cflag = CLOCAL|HUPCL|CREAD|CS8|CRTSCTS; - target_termios.c_lflag = 0; - target_termios.c_cc[VMIN] = 1; - target_termios.c_cc[VTIME] = 0; - cfsetispeed(&target_termios, br->termios_code); - cfsetospeed(&target_termios, br->termios_code); - if (tcsetattr(target_fd, TCSAFLUSH, &target_termios) < 0) { - perror("initial tcsetattr on target"); - exit(1); - } - return 0; -} - -set_serial_nonblock(state) - int state; -{ - ioctl(target_fd, FIONBIO, &state); -} diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/cmu200/secaddr.h --- a/rfcal/cmu200/secaddr.h Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -/* - * The assignment of secondary addresses to CMU200 function groups is - * arbitrary, but we need *some* assignment in order to access the SCPI - * objects that correspond to useful functions. We define our secondary - * address assignments in this header file, set them up on the CMU200 - * at start-up, and then use them to access the functions we need - * when we need them. - */ - -#define SECADDR_RF_NSIG 1 -#define SECADDR_GSM900MS_NSIG 2 -#define SECADDR_GSM1800MS_NSIG 3 -#define SECADDR_GSM1900MS_NSIG 4 -#define SECADDR_GSM850MS_NSIG 5 diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/cmu200/sercmd.c --- a/rfcal/cmu200/sercmd.c Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * This module contains the functions that send serial commands to the CMU200 - * and collect the instrument's serial responses. - */ - -#include -#include -#include -#include -#include -#include -#include - -extern int target_fd; - -char instrument_response[4096]; - -send_scpi_cmd(cmd) - char *cmd; -{ - printf("Command to CMU: %s", cmd); - write(target_fd, cmd, strlen(cmd)); -} - -collect_instr_response() -{ - char buf[BUFSIZ]; - int cc, pos; - - for (pos = 0; ; ) { - cc = read(target_fd, buf, sizeof buf); - if (cc <= 0) { - perror("error reading from serial port"); - exit(1); - } - if (pos + cc > sizeof instrument_response) { - fprintf(stderr, - "error: response from CMU200 exceeds our buffer size\n"); - exit(1); - } - bcopy(buf, instrument_response + pos, cc); - pos += cc; - if (instrument_response[pos-1] == '\n') - break; - } - instrument_response[pos-1] = '\0'; - printf("Instrument response: %s\n", instrument_response); -} - -collect_staropc_response() -{ - collect_instr_response(); - if (instrument_response[0] != '1' || - instrument_response[1] && !isspace(instrument_response[1])) { - fprintf(stderr, "error: unexpected response to *OPC?\n"); - exit(1); - } -} diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/cmu200/sertool.c --- a/rfcal/cmu200/sertool.c Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/* - * This module contains the main() function for fc-serscpi, a manual tool - * intended for learning how to control the CMU200 with SCPI commands - * over RS-232. - */ - -#include -#include -#include -#include -#include -#include - -extern int errno; - -int target_fd; - -static void -safe_output(buf, cc) - u_char *buf; -{ - int i, c; - - for (i = 0; i < cc; i++) { - c = buf[i]; - if (c == '\r' || c == '\n' || c == '\t' || c == '\b') { - putchar(c); - continue; - } - if (c & 0x80) { - putchar('M'); - putchar('-'); - c &= 0x7F; - } - if (c < 0x20) { - putchar('^'); - putchar(c + '@'); - } else if (c == 0x7F) { - putchar('^'); - putchar('?'); - } else - putchar(c); - } - fflush(stdout); -} - -main(argc, argv) - char **argv; -{ - char buf[BUFSIZ]; - fd_set fds, fds1; - register int i, cc, max; - - if (argc != 3) { - fprintf(stderr, "usage: %s ttyname baudrate\n", argv[0]); - exit(1); - } - open_target_serial(argv[1], argv[2]); - set_serial_nonblock(0); - FD_ZERO(&fds); - FD_SET(0, &fds); - FD_SET(target_fd, &fds); - max = target_fd + 1; - for (;;) { - bcopy(&fds, &fds1, sizeof(fd_set)); - i = select(max, &fds1, NULL, NULL, NULL); - if (i < 0) { - if (errno == EINTR) - continue; - perror("select"); - exit(1); - } - if (FD_ISSET(0, &fds1)) { - cc = read(0, buf, sizeof buf); - if (cc <= 0) - exit(0); - write(target_fd, buf, cc); - } - if (FD_ISSET(target_fd, &fds1)) { - cc = read(target_fd, buf, sizeof buf); - if (cc <= 0) { - fprintf(stderr, "EOF/error on target tty\n"); - exit(1); - } - safe_output(buf, cc); - } - } -} diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/cmu200/session.c --- a/rfcal/cmu200/session.c Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * This module contains the code that handles a single local socket - * connection session. - */ - -#include -#include -#include -#include -#include - -extern int activesock; - -#define MAX_FIELDS 10 - -char client_cmd[256], *client_cmd_fields[MAX_FIELDS+1]; -int client_cmd_nfields; - -parse_cmd_into_fields() -{ - char *cp; - - client_cmd_nfields = 0; - for (cp = client_cmd; ; ) { - while (isspace(*cp)) - cp++; - if (*cp == '\0') - break; - if (client_cmd_nfields >= MAX_FIELDS) { - send_socket_response("-Command has too many fields\n"); - return(1); - } - client_cmd_fields[client_cmd_nfields++] = cp; - while (*cp && !isspace(*cp)) - cp++; - if (*cp) - *cp++ = '\0'; - } - client_cmd_fields[client_cmd_nfields] = 0; - return(0); -} - -handle_command() -{ - char readbuf[256]; - int cc, pos, rc; - - for (pos = 0; ; ) { - cc = read(activesock, readbuf, sizeof readbuf); - if (cc <= 0) { - printf("Client program closed connection\n"); - return(1); - } - if (pos + cc > sizeof client_cmd) { - send_socket_response("-Command too long\n"); - return(1); - } - bcopy(readbuf, client_cmd + pos, cc); - pos += cc; - if (client_cmd[pos-1] == '\n') - break; - } - client_cmd[pos-1] = '\0'; - printf("Client command: %s\n", client_cmd); - rc = parse_cmd_into_fields(); - if (rc) - return(0); - if (!client_cmd_nfields) { - send_socket_response("+Empty command OK\n"); - return(0); - } - return dispatch_client_command(); -} - -handle_session() -{ - int rc; - - send_socket_response("+CMU200 interface daemon ready\n"); - for (;;) { - rc = handle_command(); - if (rc) - break; - } - close(activesock); -} diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/cmu200/socket.c --- a/rfcal/cmu200/socket.c Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* - * This module handles the local UNIX domain socket interface for fc-cmu200d. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -int listener, activesock; - -extern char *bind_socket_pathname; - -create_listener_socket() -{ - /* local socket binding voodoo copied from osmocon */ - struct sockaddr_un local; - unsigned int namelen; - int rc; - - listener = socket(AF_UNIX, SOCK_STREAM, 0); - if (listener < 0) { - perror("socket(AF_UNIX, SOCK_STREAM, 0)"); - exit(1); - } - - local.sun_family = AF_UNIX; - strncpy(local.sun_path, bind_socket_pathname, sizeof(local.sun_path)); - local.sun_path[sizeof(local.sun_path) - 1] = '\0'; - unlink(local.sun_path); - - /* we use the same magic that X11 uses in Xtranssock.c for - * calculating the proper length of the sockaddr */ -#if defined(BSD44SOCKETS) || defined(__UNIXWARE__) - local.sun_len = strlen(local.sun_path); -#endif -#if defined(BSD44SOCKETS) || defined(SUN_LEN) - namelen = SUN_LEN(&local); -#else - namelen = strlen(local.sun_path) + - offsetof(struct sockaddr_un, sun_path) + 1; -#endif - - rc = bind(listener, (struct sockaddr *) &local, namelen); - if (rc != 0) { - perror("bind on local socket"); - exit(1); - } - rc = listen(listener, 1); - if (rc != 0) { - perror("listen"); - exit(1); - } - return(0); -} - -get_socket_connection() -{ - struct sockaddr_un un_addr; - socklen_t len; - - len = sizeof(un_addr); - activesock = accept(listener, (struct sockaddr *) &un_addr, &len); - if (activesock < 0) { - perror("socket accept"); - exit(1); - } - printf("Accepted local socket connection\n"); - return(0); -} - -send_socket_response(str) - char *str; -{ - printf("Msg to client: %s", str); - write(activesock, str, strlen(str)); -} diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/tsid-test/Makefile --- a/rfcal/tsid-test/Makefile Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -CC= gcc -CFLAGS= -O2 -PROGS= fc-tsid-shell -INSTBIN=/opt/freecalypso/bin - -all: ${PROGS} - -fc-tsid-shell: fc-tsid-shell.c - ${CC} ${CFLAGS} -o $@ $@.c - -install: - mkdir -p ${INSTBIN} - install -c ${PROGS} ${INSTBIN} - -clean: - rm -f *.o *.out *errs ${PROGS} diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/tsid-test/fc-tsid-shell.c --- a/rfcal/tsid-test/fc-tsid-shell.c Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +0,0 @@ -/* - * This program connects to the RF calibration Test System Interface Daemon - * (TSID) over the local socket interface and allows manual human interaction - * with the TSID for development. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern int errno; - -static char default_socket_pathname[] = "/tmp/fc_rftest_socket"; - -char *socket_pathname; -int sock; - -connect_local_socket() -{ - /* local socket binding voodoo copied from osmocon */ - struct sockaddr_un local; - unsigned int namelen; - int rc; - - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - perror("socket(AF_UNIX, SOCK_STREAM, 0)"); - exit(1); - } - - local.sun_family = AF_UNIX; - strncpy(local.sun_path, socket_pathname, sizeof(local.sun_path)); - local.sun_path[sizeof(local.sun_path) - 1] = '\0'; - - /* we use the same magic that X11 uses in Xtranssock.c for - * calculating the proper length of the sockaddr */ -#if defined(BSD44SOCKETS) || defined(__UNIXWARE__) - local.sun_len = strlen(local.sun_path); -#endif -#if defined(BSD44SOCKETS) || defined(SUN_LEN) - namelen = SUN_LEN(&local); -#else - namelen = strlen(local.sun_path) + - offsetof(struct sockaddr_un, sun_path) + 1; -#endif - - rc = connect(sock, (struct sockaddr *) &local, namelen); - if (rc != 0) { - perror(socket_pathname); - exit(1); - } - - return(0); -} - -main(argc, argv) - char **argv; -{ - char buf[BUFSIZ]; - fd_set fds, fds1; - register int i, cc, max; - - switch (argc) { - case 1: - socket_pathname = default_socket_pathname; - break; - case 2: - socket_pathname = argv[1]; - break; - default: - fprintf(stderr, "usage: %s [socket-pathname]\n", argv[0]); - exit(1); - } - connect_local_socket(); - FD_ZERO(&fds); - FD_SET(0, &fds); - FD_SET(sock, &fds); - max = sock + 1; - for (;;) { - bcopy(&fds, &fds1, sizeof(fd_set)); - i = select(max, &fds1, NULL, NULL, NULL); - if (i < 0) { - if (errno == EINTR) - continue; - perror("select"); - exit(1); - } - if (FD_ISSET(0, &fds1)) { - cc = read(0, buf, sizeof buf); - if (cc <= 0) - exit(0); - write(sock, buf, cc); - } - if (FD_ISSET(sock, &fds1)) { - cc = read(sock, buf, sizeof buf); - if (cc <= 0) { - fprintf(stderr, "EOF/error on socket read\n"); - exit(1); - } - write(1, buf, cc); - } - } -} diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/vcxo-manual/Makefile --- a/rfcal/vcxo-manual/Makefile Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -CC= gcc -CFLAGS= -O2 -PROGS= fc-vcxo-linear fc-vcxo-param -INSTBIN=/opt/freecalypso/bin - -LINEAR_OBJS= linear.o readmeas.o -GENPARAMS_OBJS= genparams.o readmeas.o - -all: ${PROGS} - -fc-vcxo-linear: ${LINEAR_OBJS} - ${CC} ${CFLAGS} -o $@ ${LINEAR_OBJS} - -fc-vcxo-param: ${GENPARAMS_OBJS} - ${CC} ${CFLAGS} -o $@ ${GENPARAMS_OBJS} - -install: - mkdir -p ${INSTBIN} - install -c ${PROGS} ${INSTBIN} - -clean: - rm -f *.o *.out *errs ${PROGS} diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/vcxo-manual/genparams.c --- a/rfcal/vcxo-manual/genparams.c Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -#include -#include -#include -#include "meas.h" - -struct meas meas[4]; -float lin_a, lin_b, lin_a2, lin_b2; -float dac_min, dac_max, dac_init; -float Psi_sta, Psi_st; - -write_output(filename) - char *filename; -{ - FILE *outf; - - if (filename) { - outf = fopen(filename, "w"); - if (!outf) { - perror(filename); - exit(1); - } - } else - outf = stdout; - - fputs("rf_table afcparams\n\n", outf); - /* Psi parameters */ - fprintf(outf, "%10u\t# Psi_sta_inv\n", (unsigned)(1.0f / Psi_sta)); - fprintf(outf, "%10u\t# Psi_st\n", (unsigned)(Psi_st * 65536.0f)); - fprintf(outf, "%10u\t# Psi_st_32\n", - (unsigned)(Psi_st * 65536.0f * 65536.0f)); - fprintf(outf, "%10u\t# Psi_st_inv\n\n", (unsigned)(1.0f / Psi_st)); - /* DAC settings */ - fprintf(outf, "%10d\t# DAC_INIT * 8\n", (int)(dac_init * 8.0f)); - fprintf(outf, "%10d\t# DAC_MIN * 8\n", (int)(dac_min * 8.0f)); - fprintf(outf, "%10d\t# DAC_MAX * 8\n", (int)(dac_max * 8.0f)); - fprintf(outf, "%10d\t# snr_thr\n", 2560); - /* rfpw 10 setting in a comment line */ - fprintf(outf, "\n# DAC_INIT: rfpw 10 %d\n", (int)dac_init); - - if (filename) - fclose(outf); -} - -main(argc, argv) - char **argv; -{ - if (argc < 2 || argc > 3) { - fprintf(stderr, "usage: %s meas-file [outfile]\n", argv[0]); - exit(1); - } - read_meas_file(argv[1], meas, 4); - - /* first linear approximation */ - lin_a = (float)(meas[1].freq_offset - meas[0].freq_offset) / - (float)(meas[1].dac_value - meas[0].dac_value); - lin_b = (float)meas[1].freq_offset - lin_a * meas[1].dac_value; - - /* second linear approximation */ - lin_a2 = (float)(meas[3].freq_offset - meas[2].freq_offset) / - (float)(meas[3].dac_value - meas[2].dac_value); - lin_b2 = (float)meas[3].freq_offset - lin_a2 * meas[3].dac_value; - - /* DAC settings */ - dac_min = (-13500.0f - lin_b) / lin_a; - dac_max = (13500.0f - lin_b) / lin_a; - dac_init = -lin_b2 / lin_a2; - - /* Psi computations */ - Psi_sta = 2.0f * (float)M_PI * - (float)(meas[1].freq_offset - meas[0].freq_offset) / - ((float)(meas[1].dac_value - meas[0].dac_value) * 270833.0f); - Psi_st = Psi_sta * 0.8f; - - /* spit it all out */ - write_output(argv[2]); - exit(0); -} diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/vcxo-manual/linear.c --- a/rfcal/vcxo-manual/linear.c Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -#include -#include -#include "meas.h" - -struct meas meas[2]; -float lin_a, lin_b, target_off; -int target_dac; - -main(argc, argv) - char **argv; -{ - if (argc < 2 || argc > 3) { - fprintf(stderr, "usage: %s meas-file [target]\n", argv[0]); - exit(1); - } - read_meas_file(argv[1], meas, 2); - if (argc > 2) - target_off = atof(argv[2]); - else - target_off = 0; - lin_a = (float)(meas[1].freq_offset - meas[0].freq_offset) / - (float)(meas[1].dac_value - meas[0].dac_value); - lin_b = (float)meas[1].freq_offset - lin_a * meas[1].dac_value; - target_dac = (target_off - lin_b) / lin_a; - printf("%d\n", target_dac); - exit(0); -} diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/vcxo-manual/meas.h --- a/rfcal/vcxo-manual/meas.h Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -struct meas { - int dac_value; - int freq_offset; -}; diff -r 4cee70d429bf -r 15a2a308fb31 rfcal/vcxo-manual/readmeas.c --- a/rfcal/vcxo-manual/readmeas.c Sat Aug 12 17:37:02 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -#include -#include -#include -#include "meas.h" - -read_meas_file(filename, meas_table, nmeas) - char *filename; - struct meas *meas_table; -{ - FILE *f; - char linebuf[256], *cp, *np; - int lineno; - struct meas *mtp; - int got_meas; - - f = fopen(filename, "r"); - if (!f) { - perror(filename); - exit(1); - } - mtp = meas_table; - got_meas = 0; - for (lineno = 1; fgets(linebuf, sizeof linebuf, f); lineno++) { - for (cp = linebuf; isspace(*cp); cp++) - ; - if (*cp == '\0' || *cp == '#') - continue; - if (!isdigit(*cp) && *cp != '-' && *cp != '+') { -inv: fprintf(stderr, "%s line %d: invalid syntax\n", - filename, lineno); - exit(1); - } - np = cp++; - while (isdigit(*cp)) - cp++; - if (!isspace(*cp)) - goto inv; - mtp->dac_value = atoi(np); - while (isspace(*cp)) - cp++; - if (!isdigit(*cp) && *cp != '-' && *cp != '+') - goto inv; - np = cp++; - while (isdigit(*cp)) - cp++; - if (*cp && !isspace(*cp)) - goto inv; - mtp->freq_offset = atoi(np); - mtp++; - got_meas++; - if (got_meas >= nmeas) - break; - } - fclose(f); - if (got_meas < nmeas) { - fprintf(stderr, "error: need %d measurements, got %d in %s\n", - nmeas, got_meas, filename); - exit(1); - } - return 0; -}