AFHBA404
AFHBA404 connects ACQ2106 to PCI-Express
InlineDataHandlerMuxAO_LLC.cpp
Go to the documentation of this file.
1 /*
2  * InlineDataHandler.cpp
3  *
4  * Created on: 3 Aug 2020
5  * Author: pgm
6  *
7  * export MUXAO=ao_dev,ao_count,ai_count,ai_start,ai_stride,wavelen
8  * ao_dev: ao device number 0..12
9  * ao_count : # ao channels
10  * ai_count : # ai channels
11  * ai_start : index to start ai slice at [0]
12  * ai_stride: subsample AI, eg for 2MSPS AI, 1SMSP AI, set 2
13  * wavelen : max 256 for LLC output. Streaming typical 20000
14  *
15  *
16  * export MUXAO=3,4,16,0,1,256
17  *
18  * ie the AO is a window of 4xAI channels, slides over 16 AI channels..
19  *
20  * Support scripts:
21  * ./scripts/test_mux : changes mux setting on the fly (see getStartStride())
22  * ./scripts/test_mux : sets environment above
23  * ./scripts/monitor_hb00 : monitor the AO data in host buffers.
24  */
25 
26 
27 #include <stdio.h>
28 
29 #include <errno.h>
30 #include <stdlib.h>
31 #include <sys/ioctl.h>
32 #include <sys/mman.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <sys/time.h>
36 
37 #include <sched.h>
38 
39 #include "RTM_T_Device.h"
40 #include "local.h"
41 
42 #include "rtm-t_ioctl.h"
43 
44 #include "InlineDataHandler.h"
45 
47  // TODO Auto-generated constructor stub
48 
49 }
50 
52  // TODO Auto-generated destructor stub
53 }
54 
55 
56 struct ABN abn;
57 int ib;
58 
59 int verbose;
60 
62  int ao_dev;
63  int ao_count;
64  int ai_count;
65  int ai_start;
66  int ai_stride;
67  int wavelen;
68  RTM_T_Device *dev;
69  struct ABN abn;
70  short** ao_va;
71 
72  void getStartStride() {
73  FILE *fp = fopen("/dev/shm/amx_llc_start_stride", "r");
74  if (fp){
75  int _start, _stride;
76  if (fscanf(fp, "%d,%d", &_start, &_stride) == 2 &&
77  _start >= 0 && _start<(ai_count-ao_count) &&
78  _stride >= 1 && _stride <= 100){
79  ai_start = _start;
80  ai_stride = _stride;
81  }
82  fclose(fp);
83  }
84  }
85 public:
86  InlineDataHanderMuxAO_LLC(int _ao_dev, int _ao_count, int _ai_count, int _ai_start, int _ai_stride, int _wavelen) :
87  ao_dev(_ao_dev),
88  ao_count(_ao_count), ai_count(_ai_count), ai_start(_ai_start), ai_stride(_ai_stride),
89  wavelen(_wavelen>=MAXABN? MAXABN: _wavelen)
90  {
91  printf("InlineDataHanderMuxAO_LLC ao_dev=%d ao_count=%d ai_count=%d ai_start=%d ai_stride=%d\n",
92  ao_dev, ao_count, ai_count, ai_start, ai_stride);
93 
94  dev = new RTM_T_Device(ao_dev);
95 
96  for (int ib = 0; ib < wavelen; ++ib){
98  abn.buffers[ib].len = _ao_count * sizeof(short);
99  }
100  abn.ndesc = wavelen;
101 
102  if (ioctl(dev->getDeviceHandle(), AFHBA_START_AO_ABN, &abn)){
103  perror("ioctl AFHBA_START_AO_ABN");
104  exit(1);
105  }
106 
107 
108  ao_va = new short* [wavelen];
109  ao_va[0] = (short*)dev->getHostBufferMappingW();
110 
111  if (verbose){
112  printf("%s [%d] va:%p pa:%08x\n", __FUNCTION__, 0, ao_va[0], abn.buffers[0].pa);
113  }
114  for (int ib = 1; ib < wavelen; ++ib){
115  ao_va[ib] = ao_va[0] + (abn.buffers[ib].pa - abn.buffers[0].pa)/sizeof(short);
116 
117  if (verbose > 1){
118  printf("%s [%d] va:%p pa:%08x\n", __FUNCTION__, ib, ao_va[ib], abn.buffers[ib].pa);
119  }
120  }
121  }
122 
123  virtual void handleBuffer(int ibuf, const void *src, int len)
124  /* take a slice ao_count out of AI buffer and distribute one per descriptor for LLC AO */
125  {
126  getStartStride();
127  const int instep = ai_count*ai_stride;
128  short* ai = (short*)src + ai_start;
129  for (int ib = 0; ib < wavelen; ++ib){
130  memcpy(ao_va[ib], ai, ao_count*sizeof(short));
131  ai += instep;
132  }
133  }
134 };
135 
137 {
138  printf("InlineDataHandler::factory() option InlineDataHanderMuxAO_LLC\n");
139  if (getenv("MUXAO_VERBOSE")){
140  verbose = atoi(getenv("MUXAO_VERBOSE"));
141  }
142  if (const char* value = getenv("MUXAO")){
143  int pr[6];
144  if (sscanf(value, "%d,%d,%d,%d,%d,%d", pr+0, pr+1, pr+2, pr+3, pr+4, pr+5) == 6){
145  return new InlineDataHanderMuxAO_LLC(pr[0], pr[1], pr[2], pr[3], pr[4], pr[5]);
146  }
147  }
148  return new InlineDataHandler;
149 }
150 
InlineDataHandler.h
RTM_T_USE_HOSTBUF
#define RTM_T_USE_HOSTBUF
Definition: rtm-t_ioctl.h:75
InlineDataHandler::factory
static InlineDataHandler * factory(RTM_T_Device *ai_dev)
Definition: InlineDataHandler.cpp:20
abn
struct ABN abn
Definition: InlineDataHandlerMuxAO_LLC.cpp:56
local.h
ABN::ndesc
int ndesc
Definition: rtm-t_ioctl.h:58
InlineDataHandler
Definition: InlineDataHandler.h:13
InlineDataHanderMuxAO_LLC::handleBuffer
virtual void handleBuffer(int ibuf, const void *src, int len)
Definition: InlineDataHandlerMuxAO_LLC.cpp:123
AFHBA_START_AO_ABN
#define AFHBA_START_AO_ABN
ioctl AFHBA_START_AI_ABN LLC, multiple buffers, INPUT
Definition: rtm-t_ioctl.h:106
RTM_T_Device::getHostBufferMappingW
void * getHostBufferMappingW(int ibuf=0)
Definition: RTM_T_Device.h:65
XLLC_DEF::pa
u32 pa
SRC or DST buffer PA - round to 1K RTM_T_USE_HOSTBUF=> use Driver buffer 0.
Definition: rtm-t_ioctl.h:47
XLLC_DEF::len
unsigned len
length in bytes - will round up to next %64
Definition: rtm-t_ioctl.h:46
RTM_T_Device::getDeviceHandle
const int getDeviceHandle(void)
Definition: RTM_T_Device.h:56
rtm-t_ioctl.h
InlineDataHandler::InlineDataHandler
InlineDataHandler()
Definition: InlineDataHandler.cpp:10
ABN
Definition: rtm-t_ioctl.h:57
verbose
int verbose
Definition: InlineDataHandlerMuxAO_LLC.cpp:59
ib
int ib
Definition: InlineDataHandlerMuxAO_LLC.cpp:57
InlineDataHanderMuxAO_LLC::InlineDataHanderMuxAO_LLC
InlineDataHanderMuxAO_LLC(int _ao_dev, int _ao_count, int _ai_count, int _ai_start, int _ai_stride, int _wavelen)
Definition: InlineDataHandlerMuxAO_LLC.cpp:86
InlineDataHanderMuxAO_LLC
Definition: InlineDataHandlerMuxAO_LLC.cpp:61
InlineDataHandler::~InlineDataHandler
virtual ~InlineDataHandler()
Definition: InlineDataHandler.cpp:15
ABN::buffers
struct XLLC_DEF buffers[MAXABN]
Definition: rtm-t_ioctl.h:59
RTM_T_Device.h
RTM_T_Device
Definition: RTM_T_Device.h:17
getenv
int getenv(const char *key, int def, int(*cvt)(const char *key))
Definition: acqproc.cpp:23
MAXABN
#define MAXABN
Definition: rtm-t_ioctl.h:55