Commit c519650b authored by koennecke's avatar koennecke
Browse files

Merge branch 'master' into develop

parents 42e48101 5634eefe
add_library(site
psi.c
buffer.c
ruli.c
sps.c
pimotor.c
pipiezo.c
sanswave.c
faverage.c
spss7.c
amorstat.c
tasinit.c
ptasdrive.c
tasutil.c
tasscan.c
swmotor.c
polterwrite.c
ecb.c
frame.c
sqlitelog.c
mongolog.c
sicslogquery.c
approxidate.c
el737driv.c
sinqhmdriv.c
tdchm.c
sanscook.c
itc4driv.c
itc4.c
bruker.c
ltc11.c
eurodriv.c
el755driv.c
serial.c
scontroller.c
t_update.c
t_rlp.c
t_conv.c
el737hpdriv.c
el734hp.c
el737hpv2driv.c
swmotor2.c
tricssupport.c
amorcomp.c
amordrive.c
amorset.c
sinqhttp.c
slsecho.c
tabledrive.o
sinqhttpopt.c
ritastorage.c
el737hpdrivsps.c
rebin.c
sanslirebin.c
lmd200.c
slsvme.c
julprot.c
sinqhttpprot.c
pfeifferprot.c
termprot.c
phytron.c
autowin.c
eigera2.c
eigermono.c
sputterprot.c
zwickroll.c
astriumnet.c
poldifold.c
epicsadapter.c
zebraswap.c
fsm.c
sugar.c
pardef.c
ease.c
strobj.c
oxinst.c
ipsdriv.c
ilmdriv.c
itcdriv.c
ighdriv.c
euro2kdriv.c
modbus.c
arrobj.c
linadriv.c
haakedriv.c
seaclientprot.c
dumprot.c
)
set_property(SOURCE epicsadapter.c PROPERTY COMPILE_FLAGS "-I{PROJECT_SOURCE_DIR} -I${EPICS_BASE}/include -I${EPICS_BASE}/include/os/Linux")
include_directories("." ".." "../sics" "hardsup")
add_library(hardsup
el734_utility.c
asynsrv_utility.c
stredit.c
strjoin.c
failinet.c
geterrno.c
el737_utility.c
sinqhm.c
serialsinq.c
itc4util.c
dillutil.c
table.c
el755_utility.c
el755_errorlog.c
makeprint.c
StrMatch.c
)
set_property(SOURCE el734_utility.c APPEND PROPERTY COMPILE_FLAGS "-DLINUX")
set_property(SOURCE el737_utility.c APPEND PROPERTY COMPILE_FLAGS "-DLINUX")
include_directories("." ".." "../../sics")
......@@ -48,6 +48,6 @@ dgrambroadcast.o: dgrambroadcast.h dgrambroadcast.c
sinq.o: sinq.c sinq.h dgrambroadcast.h
$(CC) -I$(TCLINC) $(SINQOPT) -I$(SICSROOT)/sics -g -c sinq.c
EPICSINC=$(EXTRAROOT)/include
EPICSINC=$(EPICSROOT)/include
epicsadapter.o: epicsadapter.c
$(CC) $(SINQOPT) -I$(EPICSINC) -I$(EPICSINC)/os/Linux -I$(EPICSINC)/compiler/gcc -I$(SICSROOT)/sics -c -g epicsadapter.c
\ No newline at end of file
......@@ -63,7 +63,6 @@ void SiteInit(void)
INIT(AddSLSEchoProtocoll);
INIT(AddSeaClientProtocol);
INIT(AddDumProtocol);
INIT(AddJVLProtocoll);
INIT(AddSputterProtocoll);
INIT(AddZwickrollProtocoll);
......
......@@ -535,7 +535,7 @@ static int TASScanPoint(pScanData self, int iPoint)
m4 = GetMonitor(self->pCounterData, 4, self->pCon); // integrated proton charge on target
cnts = GetCounts(self->pCounterData, self->pCon);
fVal = GetCountTime(self->pCounterData, self->pCon);
sprintf(pWork, "%8ld %8ld %9.2f %8ld %8ld %9ld", m1, m2, fVal, cnts, m3, m4);
sprintf(pWork, "%8ld %8ld %9.2f %8ld %8ld %9ld ", m1, m2, fVal, cnts, m3, m4);
strcat(pBueffel, pWork);
/*
......
......@@ -5,6 +5,11 @@
# Mark Koennecke, May 2015
#--------------------------------------------------------------
all: picocontrol picoserverli
picoserverli: picoserverli.o
gcc -g -o picoserverli picoserverli.o /usr/local/lib/libuv.a -L/opt/picoscope/lib -lps2000a -lpthread -lrt
picocontrol: picocontrol.o
gcc -g -o picocontrol picocontrol.o -L/opt/picoscope/lib -lps2000a
......
# Picoscope
The picoscope USB oscilloscope is used as a frequency generator for spin flippers at SINQ.
As USB is not the bus of SINQ, we use a raspberry PI as a server for controlling the spin flipper from
SICS. This is the code for this.
The first interface is the command line program picocontrol which is run via xinetd as a server.
This has the disadvantage that only one connection is possible and connections rejections are possible
because xinetd does not reliably kill picocontrol on a disconnect.
The second interface is a libuv based own server, picoserverli. This is as of now (07/2017) the state of the art.
I start directly from /etc/inittab. An example can be found in the end of the provided inittab file.
On ubuntu you may use the system supplied libuv as installable via apt-get. On the raspberry PI you have
to build libuv from sources.
# /etc/inittab: init(8) configuration.
# $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $
# The default runlevel.
id:2:initdefault:
# Boot-time system configuration/initialization script.
# This is run first except when booting in emergency (-b) mode.
si::sysinit:/etc/init.d/rcS
# What to do in single-user mode.
~~:S:wait:/sbin/sulogin
# /etc/init.d executes the S and K scripts upon change
# of runlevel.
#
# Runlevel 0 is halt.
# Runlevel 1 is single-user.
# Runlevels 2-5 are multi-user.
# Runlevel 6 is reboot.
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
# Normally not reached, but fallthrough in case of emergency.
z6:6:respawn:/sbin/sulogin
# What to do when CTRL-ALT-DEL is pressed.
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
# Action on special keypress (ALT-UpArrow).
#kb::kbrequest:/bin/echo "Keyboard Request--edit /etc/inittab to let this work."
# What to do when the power fails/returns.
pf::powerwait:/etc/init.d/powerfail start
pn::powerfailnow:/etc/init.d/powerfail now
po::powerokwait:/etc/init.d/powerfail stop
# /sbin/getty invocations for the runlevels.
#
# The "id" field MUST be the same as the last
# characters of the device (after "tty").
#
# Format:
# <id>:<runlevels>:<action>:<process>
#
# Note that on most Debian systems tty7 is used by the X Window System,
# so if you want to add more getty's go ahead but skip tty7 if you run X.
#
1:2345:respawn:/sbin/getty --noclear 38400 tty1
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
4:23:respawn:/sbin/getty 38400 tty4
5:23:respawn:/sbin/getty 38400 tty5
6:23:respawn:/sbin/getty 38400 tty6
# Example how to put a getty on a serial line (for a terminal)
#
#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100
# Example how to put a getty on a modem line.
#
#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3
#Spawn a getty on Raspberry Pi serial line
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
# Spawn picoserverli for talking to the picoscope
PC:3:respawn:/home/pi/picoscope/picoserverli
......@@ -28,7 +28,7 @@ static void StopPico(void)
{
ps2000aCloseUnit(handle);
}
/*--------------------------------------------------------------*/
/*--------------------------------------------------------------*/
static void SetGenerator(long freq, float ampl)
{
int status;
......
/*
This is a little server for controling the frequencz generator built into
the picoscope oscilloscope.
It turned out that picocontrol is not sufficient: it is run by xinetd
and does not properly recognized disconnects. Which in turn did not
close picoconetrol and then the port ot the picoscope was blocked.
This is now a little libUV based server which allows multiple clients
to connect to the picoscope and managing the connection to the picoscope.
This is an event based server, thus serialisation of access to the picoscope
is being taken care of by design.
Mark Koennecke, September 2017
*/
#include <sys/types.h>
#include <string.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <libps2000a-1.1/ps2000aApi.h>
#ifndef PICO_STATUS
#include <libps2000a-1.1/PicoStatus.h>
#endif
#include <uv.h>
static short handle;
/*===============================================================
Defaults
=================================================================*/
#define PORT 3030
#define FREQ 1000
#define AMPL 0.0
#define MULT 1000000
#include <sys/types.h>
#include <string.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <libps2000a-1.1/ps2000aApi.h>
#ifndef PICO_STATUS
#include <libps2000a-1.1/PicoStatus.h>
#endif
/*================= Ugly but easy globals ======================*/
static short handle;
static unsigned int glFreq = FREQ;
static double glAmpl = .0;
/*--------------------------------------------------------------*/
static void StopPico(void)
{
ps2000aCloseUnit(handle);
}
/*--------------------------------------------------------------*/
static void SetGenerator(long freq, float ampl)
{
int status;
if(freq == 0){
status = ps2000aSetSigGenBuiltIn(handle,
0,
0,
PS2000A_DC_VOLTAGE,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0);
} else {
status = ps2000aSetSigGenBuiltIn(handle,
0,
(unsigned long)ampl,
PS2000A_SINE,
(float)freq,
(float)freq,
0,
0,
0,
0,
0,
0,
0,
0,
0);
}
if(status != PICO_OK){
printf("Failed to configure signal generator with %d\n", status);
}
}
/*---------------------------------------------------------------------*/
void picoBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
{
size_t pSize;
if(suggested_size > 256){
pSize = suggested_size;
} else {
pSize = 256;
}
*buf = uv_buf_init(malloc(pSize),pSize);
}
/*--------------------------------------------------------------------*/
static void picoWriteCallback(uv_write_t *req, int status)
{
uv_buf_t *buf = (uv_buf_t*)req->data;
free(buf->base);
free(buf);
free(req);
}
/*---------------------------------------------------------------------*/
static void picoSendReply(uv_stream_t *stream, char *reply)
{
uv_write_t *wreq;
uv_buf_t *buf;
wreq = malloc(sizeof(uv_write_t));
buf = malloc(sizeof(uv_buf_t));
*buf = uv_buf_init(malloc(strlen(reply)+1),strlen(reply)+1);
strcpy(buf->base,reply);
wreq->data = buf;
uv_write((uv_write_t*)wreq,stream,buf,1,picoWriteCallback);
}
/*----------------------------------------------------------------------*/
void picoRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
{
char *command, *pPtr, token[50], reply[80];
int status;
float tmp;
int freq;
if(nread < 0){
if(nread == UV_EOF){
uv_close((uv_handle_t*)stream, NULL);
printf("Closing stream\n");
}
} else {
printf("Processing command %s\n",buf->base);
/*
Here we are now in business: our action code!!!
*/
command = buf->base;
pPtr = strchr(command,'\n');
*pPtr = '\0';
if(strstr(command,"freq") != NULL){
status = sscanf(command,"%s %d",token, &freq);
if(status == 2){
glFreq = freq;
SetGenerator(glFreq,glAmpl*MULT);
strcpy(reply,"OK\n");
} else {
snprintf(reply,sizeof(reply),"freq %d\n",glFreq);
}
picoSendReply(stream,reply);
} else if(strstr(command,"ampl") != NULL){
status = sscanf(command,"%s %f",token, &tmp);
if(status == 2){
glAmpl = tmp;
SetGenerator(glFreq,glAmpl*MULT);
strcpy(reply,"OK\n");
} else {
snprintf(reply,sizeof(reply),"ampl %f\n",glAmpl);
}
picoSendReply(stream,reply);
} else {
snprintf(reply,sizeof(reply),"Command %s not understood, use freq, ampl\n", pPtr);
picoSendReply(stream,reply);
}
free(buf->base);
}
}
/*----------------------------------------------------------------------*/
static void picoNewConnection(uv_stream_t *server, int status)
{
uv_tcp_t *client;
if(status < 0) {
printf("New connection error %s\n", uv_strerror(status));
return;
}
client = malloc(sizeof(uv_tcp_t));
uv_tcp_init((uv_loop_t*)server->data,client);
if(uv_accept(server,(uv_stream_t*)client) == 0){
uv_read_start((uv_stream_t*)client,picoBuffer,picoRead);
}
}
/*========================================================================*/
int main(int argc, char *argv[])
{
int status;
long int freq = 1000;
float mult = 1000000, ampl = 1.*mult, tmp;
char line[80], token[80];
uv_loop_t *loop;
uv_tcp_t server;
struct sockaddr_in addr;
status = ps2000aOpenUnit(&handle, NULL);
if(status != PICO_OK){
printf("Failed to open picoscope with %d\n", status);
exit(1);
}
atexit(StopPico);
SetGenerator(FREQ, AMPL*MULT);
glAmpl = AMPL;
loop = malloc(sizeof(uv_loop_t));
if(loop == NULL){
printf("Out of memory allocating UV data structure \n");
exit(1);
}
uv_loop_init(loop);
/*
setup of a server port
*/
uv_tcp_init(loop,&server);
uv_ip4_addr("0.0.0.0",PORT,&addr);
uv_tcp_bind(&server,(const struct sockaddr *)&addr,0);
status = uv_listen((uv_stream_t*)&server, 5,picoNewConnection);
if(status){
printf("Listen error %s\n", uv_strerror(status));
exit(1);
}
server.data = loop;
uv_run(loop,UV_RUN_DEFAULT);
uv_loop_close(loop);
free(loop);
StopPico();
exit(0);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment