add a plotter for raw IQ samples from eNB uplink received data
only works for 5MHz (7680 samples per TTI), one transport block (basic FDD thing)
This commit is contained in:
@@ -27,7 +27,7 @@ $(PROG): $(OBJS)
|
||||
T_IDs.h: $(GENIDS) T_messages.txt
|
||||
./$(GENIDS) T_messages.txt T_IDs.h
|
||||
|
||||
main.o: T.h T_IDs.h
|
||||
main.o: T.h T_IDs.h T_defs.h
|
||||
|
||||
clean:
|
||||
rm -f *.o $(PROG) $(GENIDS) core T_IDs.h
|
||||
|
||||
@@ -236,20 +236,7 @@ extern T_cache_t *T_cache;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define T11(t,t0,x0,t1,x1,t2,x2,t3,x3) \
|
||||
do { \
|
||||
if (T_ACTIVE(t)) { \
|
||||
T_LOCAL_DATA \
|
||||
T_HEADER(t); \
|
||||
T_PUT_##t0(2, x0); \
|
||||
T_PUT_##t1(3, x1); \
|
||||
T_PUT_##t2(4, x2); \
|
||||
T_PUT_##t3(5, x3); \
|
||||
T_SEND(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define T13(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4) \
|
||||
#define T11(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4) \
|
||||
do { \
|
||||
if (T_ACTIVE(t)) { \
|
||||
T_LOCAL_DATA \
|
||||
@@ -263,7 +250,7 @@ extern T_cache_t *T_cache;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define T15(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5) \
|
||||
#define T13(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5) \
|
||||
do { \
|
||||
if (T_ACTIVE(t)) { \
|
||||
T_LOCAL_DATA \
|
||||
@@ -278,7 +265,7 @@ extern T_cache_t *T_cache;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define T17(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6) \
|
||||
#define T15(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6) \
|
||||
do { \
|
||||
if (T_ACTIVE(t)) { \
|
||||
T_LOCAL_DATA \
|
||||
@@ -294,7 +281,7 @@ extern T_cache_t *T_cache;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define T19(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7) \
|
||||
#define T17(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7) \
|
||||
do { \
|
||||
if (T_ACTIVE(t)) { \
|
||||
T_LOCAL_DATA \
|
||||
@@ -311,7 +298,7 @@ extern T_cache_t *T_cache;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define T21(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8) \
|
||||
#define T19(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8) \
|
||||
do { \
|
||||
if (T_ACTIVE(t)) { \
|
||||
T_LOCAL_DATA \
|
||||
@@ -329,7 +316,7 @@ extern T_cache_t *T_cache;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define T23(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9) \
|
||||
#define T21(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9) \
|
||||
do { \
|
||||
if (T_ACTIVE(t)) { \
|
||||
T_LOCAL_DATA \
|
||||
@@ -348,7 +335,7 @@ extern T_cache_t *T_cache;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define T25(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10) \
|
||||
#define T23(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10) \
|
||||
do { \
|
||||
if (T_ACTIVE(t)) { \
|
||||
T_LOCAL_DATA \
|
||||
@@ -368,7 +355,7 @@ extern T_cache_t *T_cache;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define T27(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11) \
|
||||
#define T25(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11) \
|
||||
do { \
|
||||
if (T_ACTIVE(t)) { \
|
||||
T_LOCAL_DATA \
|
||||
@@ -389,7 +376,7 @@ extern T_cache_t *T_cache;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define T29(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12) \
|
||||
#define T27(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12) \
|
||||
do { \
|
||||
if (T_ACTIVE(t)) { \
|
||||
T_LOCAL_DATA \
|
||||
@@ -411,7 +398,7 @@ extern T_cache_t *T_cache;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define T31(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13) \
|
||||
#define T29(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13) \
|
||||
do { \
|
||||
if (T_ACTIVE(t)) { \
|
||||
T_LOCAL_DATA \
|
||||
@@ -434,7 +421,7 @@ extern T_cache_t *T_cache;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define T33(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13,t14,x14) \
|
||||
#define T31(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13,t14,x14) \
|
||||
do { \
|
||||
if (T_ACTIVE(t)) { \
|
||||
T_LOCAL_DATA \
|
||||
@@ -458,6 +445,31 @@ extern T_cache_t *T_cache;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define T33(t,t0,x0,t1,x1,t2,x2,t3,x3,t4,x4,t5,x5,t6,x6,t7,x7,t8,x8,t9,x9,t10,x10,t11,x11,t12,x12,t13,x13,t14,x14,t15,x15) \
|
||||
do { \
|
||||
if (T_ACTIVE(t)) { \
|
||||
T_LOCAL_DATA \
|
||||
T_HEADER(t); \
|
||||
T_PUT_##t0(2, x0); \
|
||||
T_PUT_##t1(3, x1); \
|
||||
T_PUT_##t2(4, x2); \
|
||||
T_PUT_##t3(5, x3); \
|
||||
T_PUT_##t4(6, x4); \
|
||||
T_PUT_##t5(7, x5); \
|
||||
T_PUT_##t6(8, x6); \
|
||||
T_PUT_##t7(9, x7); \
|
||||
T_PUT_##t8(10, x8); \
|
||||
T_PUT_##t9(11, x9); \
|
||||
T_PUT_##t10(12, x10); \
|
||||
T_PUT_##t11(13, x11); \
|
||||
T_PUT_##t12(14, x12); \
|
||||
T_PUT_##t13(15, x13); \
|
||||
T_PUT_##t14(16, x14); \
|
||||
T_PUT_##t15(17, x15); \
|
||||
T_SEND(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define T_CALL_ERROR \
|
||||
do { \
|
||||
printf("%s:%d:%s: error calling T, you have to use T_INT() or T_XX()\n", \
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
#define _T_defs_H_
|
||||
|
||||
/* maximum size of a message - increase if needed */
|
||||
#define T_BUFFER_MAX 1024
|
||||
#define T_BUFFER_MAX (1024*64)
|
||||
|
||||
/* size of the local cache for messages (must be pow(2,something)) */
|
||||
#define T_CACHE_SIZE (65536 * 2)
|
||||
#define T_CACHE_SIZE (8192 * 2)
|
||||
|
||||
typedef struct {
|
||||
volatile int busy;
|
||||
|
||||
+26
-1
@@ -1,17 +1,41 @@
|
||||
#PHY logs
|
||||
ID = ENB_INPUT_SIGNAL
|
||||
DESC = eNodeB received signal in the time domain for a duration of 1ms
|
||||
GROUP = PHY:GRAPHIC:HEAVY
|
||||
FORMAT = int,eNB_ID : int,frame : int,subframe : int,antenna : buffer,rxdata
|
||||
|
||||
#legacy logs
|
||||
ID = LEGACY_MAC_INFO
|
||||
DESC = MAC legacy logs
|
||||
DESC = MAC legacy logs - info level
|
||||
GROUP = MAC:INFO:LEGACY
|
||||
ID = LEGACY_MAC_ERROR
|
||||
DESC = MAC legacy logs - error level
|
||||
GROUP = MAC:ERROR:LEGACY
|
||||
ID = LEGACY_MAC_WARNING
|
||||
DESC = MAC legacy logs - warning level
|
||||
GROUP = MAC:WARNING:LEGACY
|
||||
ID = LEGACY_MAC_DEBUG
|
||||
DESC = MAC legacy logs - debug level
|
||||
GROUP = MAC:DEBUG:LEGACY
|
||||
ID = LEGACY_MAC_TRACE
|
||||
DESC = MAC legacy logs - trace level
|
||||
GROUP = MAC:TRACE:LEGACY
|
||||
|
||||
ID = LEGACY_PHY_INFO
|
||||
DESC = PHY legacy logs - info level
|
||||
GROUP = PHY:INFO:LEGACY
|
||||
ID = LEGACY_PHY_ERROR
|
||||
DESC = PHY legacy logs - error level
|
||||
GROUP = PHY:ERROR:LEGACY
|
||||
ID = LEGACY_PHY_WARNING
|
||||
DESC = PHY legacy logs - warning level
|
||||
GROUP = PHY:WARNING:LEGACY
|
||||
ID = LEGACY_PHY_DEBUG
|
||||
DESC = PHY legacy logs - debug level
|
||||
GROUP = PHY:DEBUG:LEGACY
|
||||
ID = LEGACY_PHY_TRACE
|
||||
DESC = PHY legacy logs - trace level
|
||||
GROUP = PHY:TRACE:LEGACY
|
||||
|
||||
ID = LEGACY_S1AP_INFO
|
||||
ID = LEGACY_S1AP_ERROR
|
||||
@@ -137,5 +161,6 @@ ID = LEGACY_CLI_WARNING
|
||||
ID = LEGACY_CLI_DEBUG
|
||||
ID = LEGACY_CLI_TRACE
|
||||
|
||||
#for debug/test - not used
|
||||
ID = first
|
||||
ID = buf_test
|
||||
|
||||
+2
-2
@@ -4,13 +4,13 @@ void print(int n)
|
||||
{
|
||||
int i;
|
||||
printf("#define T%d(t", n);
|
||||
for(i=0; i<(n-3)/2; i++) printf(",t%d,x%d", i, i);
|
||||
for(i=0; i<(n-1)/2; i++) printf(",t%d,x%d", i, i);
|
||||
printf(") \\\n");
|
||||
printf(" do { \\\n");
|
||||
printf(" if (T_ACTIVE(t)) { \\\n");
|
||||
printf(" T_LOCAL_DATA \\\n");
|
||||
printf(" T_HEADER(t); \\\n");
|
||||
for(i=0; i<(n-3)/2; i++) printf(" T_PUT_##t%d(%d, x%d); \\\n", i, i+2, i);
|
||||
for(i=0; i<(n-1)/2; i++) printf(" T_PUT_##t%d(%d, x%d); \\\n", i, i+2, i);
|
||||
printf(" T_SEND(); \\\n");
|
||||
printf(" } \\\n");
|
||||
printf(" } while (0)\n");
|
||||
|
||||
+4
-2
@@ -1,12 +1,14 @@
|
||||
CC=gcc
|
||||
CFLAGS=-Wall -g -O3
|
||||
CFLAGS=-Wall -g -pthread
|
||||
|
||||
LIBS=-lX11 -lm
|
||||
|
||||
#comment those two lines to NOT use shared memory
|
||||
CFLAGS += -DT_USE_SHARED_MEMORY
|
||||
LIBS += -lrt
|
||||
|
||||
PROG=tracer
|
||||
OBJS=main.o
|
||||
OBJS=main.o plot.o
|
||||
|
||||
$(PROG): $(OBJS)
|
||||
$(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LIBS)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef _TRACER_DEFS_H_
|
||||
#define _TRACER_DEFS_H_
|
||||
|
||||
void *make_plot(int width, int height, int bufsize);
|
||||
void plot_set(void *plot, float *data, int len, int pos);
|
||||
void iq_plot_set(void *plot, short *data, int len, int pos);
|
||||
|
||||
#endif /* _TRACER_DEFS_H_ */
|
||||
@@ -8,10 +8,14 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#define T_ID(x) x
|
||||
#include "../T_IDs.h"
|
||||
#include "../T_defs.h"
|
||||
|
||||
void *ul_plot;
|
||||
|
||||
#ifdef T_USE_SHARED_MEMORY
|
||||
|
||||
T_cache_t *T_cache;
|
||||
@@ -195,6 +199,23 @@ void get_message(int s)
|
||||
case T_LEGACY_CLI_WARNING: S("CLI", "WARNING"); break;
|
||||
case T_LEGACY_CLI_DEBUG: S("CLI", "DEBUG"); break;
|
||||
case T_LEGACY_CLI_TRACE: S("CLI", "TRACE"); break;
|
||||
case T_ENB_INPUT_SIGNAL: {
|
||||
unsigned char buf[T_BUFFER_MAX];
|
||||
int size;
|
||||
int eNB, frame, subframe, antenna;
|
||||
GET(s, &eNB, sizeof(int));
|
||||
GET(s, &frame, sizeof(int));
|
||||
GET(s, &subframe, sizeof(int));
|
||||
GET(s, &antenna, sizeof(int));
|
||||
GET(s, &size, sizeof(int));
|
||||
GET(s, buf, size);
|
||||
printf("got T_ENB_INPUT_SIGNAL eNB %d frame %d subframe %d antenna %d size %d %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
|
||||
eNB, frame, subframe, antenna, size, buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9],buf[10],buf[11],buf[12],buf[13],buf[14],buf[15]);
|
||||
if (size != 4 * 7680)
|
||||
{printf("bad T_ENB_INPUT_SIGNAL, only 7680 samples allowed\n");abort();}
|
||||
iq_plot_set(ul_plot, (short*)buf, 7680, subframe*7680);
|
||||
break;
|
||||
}
|
||||
case T_buf_test: {
|
||||
unsigned char buf[T_BUFFER_MAX];
|
||||
int size;
|
||||
@@ -252,6 +273,9 @@ int main(void)
|
||||
if (write(s, &l, sizeof(int)) != sizeof(int)) abort();
|
||||
for (l = 0; l < T_NUMBER_OF_IDS; l++)
|
||||
if (write(s, &l, sizeof(int)) != sizeof(int)) abort();
|
||||
|
||||
ul_plot = make_plot(512, 100, 7680*2*10);
|
||||
|
||||
/* read messages */
|
||||
while (1) {
|
||||
#ifdef T_USE_SHARED_MEMORY
|
||||
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
#include "defs.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
|
||||
typedef struct {
|
||||
Display *d;
|
||||
Window w;
|
||||
Pixmap p;
|
||||
int width;
|
||||
int height;
|
||||
float *buf;
|
||||
short *iqbuf;
|
||||
int bufsize;
|
||||
} plot;
|
||||
|
||||
static void *plot_thread(void *_p)
|
||||
{
|
||||
float v;
|
||||
float *s;
|
||||
int i, j;
|
||||
plot *p = _p;
|
||||
while (1) {
|
||||
while (XPending(p->d)) {
|
||||
XEvent e;
|
||||
XNextEvent(p->d, &e);
|
||||
}
|
||||
|
||||
{
|
||||
/* TODO: get white & black GCs at startup */
|
||||
GC gc;
|
||||
XGCValues v;
|
||||
gc = DefaultGC(p->d, DefaultScreen(p->d));
|
||||
v.foreground = WhitePixel(p->d, DefaultScreen(p->d));
|
||||
XChangeGC(p->d, gc, GCForeground, &v);
|
||||
XFillRectangle(p->d, p->p, gc, 0, 0, p->width, p->height);
|
||||
v.foreground = BlackPixel(p->d, DefaultScreen(p->d));
|
||||
XChangeGC(p->d, gc, GCForeground, &v);
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 512*150; i++)
|
||||
p->buf[i] = 10*log10(1.0+(float)(p->iqbuf[2*i]*p->iqbuf[2*i]+
|
||||
p->iqbuf[2*i+1]*p->iqbuf[2*i+1]));
|
||||
}
|
||||
s = p->buf;
|
||||
for (i = 0; i < 512; i++) {
|
||||
v = 0;
|
||||
for (j = 0; j < 150; j++, s++) v += *s;
|
||||
v /= 150;
|
||||
XDrawLine(p->d, p->p, DefaultGC(p->d, DefaultScreen(p->d)), i, 100, i, 100-v);
|
||||
}
|
||||
|
||||
XCopyArea(p->d, p->p, p->w, DefaultGC(p->d, DefaultScreen(p->d)),
|
||||
0, 0, p->width, p->height, 0, 0);
|
||||
usleep(100*1000);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void new_thread(void *(*f)(void *), void *data)
|
||||
{
|
||||
pthread_t t;
|
||||
pthread_attr_t att;
|
||||
|
||||
if (pthread_attr_init(&att))
|
||||
{ fprintf(stderr, "pthread_attr_init err\n"); exit(1); }
|
||||
if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED))
|
||||
{ fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); }
|
||||
if (pthread_create(&t, &att, f, data))
|
||||
{ fprintf(stderr, "pthread_create err\n"); exit(1); }
|
||||
if (pthread_attr_destroy(&att))
|
||||
{ fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); }
|
||||
}
|
||||
|
||||
void *make_plot(int width, int height, int bufsize)
|
||||
{
|
||||
plot *p;
|
||||
Display *d;
|
||||
Window w;
|
||||
Pixmap pm;
|
||||
|
||||
d = XOpenDisplay(0); if (d == NULL) abort();
|
||||
w = XCreateSimpleWindow(d, DefaultRootWindow(d), 0, 0, width, height,
|
||||
0, WhitePixel(d, DefaultScreen(d)), WhitePixel(d, DefaultScreen(d)));
|
||||
XSelectInput(d, w, ExposureMask);
|
||||
XMapWindow(d, w);
|
||||
|
||||
pm = XCreatePixmap(d, w, width, height, DefaultDepth(d, DefaultScreen(d)));
|
||||
|
||||
p = malloc(sizeof(*p)); if (p == NULL) abort();
|
||||
p->width = width;
|
||||
p->height = height;
|
||||
p->buf = malloc(sizeof(float) * bufsize); if (p->buf == NULL) abort();
|
||||
p->iqbuf = malloc(sizeof(short) * 2 * bufsize); if (p->buf == NULL) abort();
|
||||
p->bufsize = bufsize;
|
||||
|
||||
p->d = d;
|
||||
p->w = w;
|
||||
p->p = pm;
|
||||
|
||||
new_thread(plot_thread, p);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void plot_set(void *_plot, float *data, int len, int pos)
|
||||
{
|
||||
plot *p = _plot;
|
||||
memcpy(p->buf + pos, data, len * sizeof(float));
|
||||
}
|
||||
|
||||
void iq_plot_set(void *_plot, short *data, int len, int pos)
|
||||
{
|
||||
plot *p = _plot;
|
||||
memcpy(p->iqbuf + pos * 2, data, len * 2 * sizeof(short));
|
||||
}
|
||||
Reference in New Issue
Block a user