AFHBA404
AFHBA404 connects ACQ2106 to PCI-Express
InlineDataHandlerMuxAO_STREAM_ALL.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  * export MUXAO=3,4,16,0,1,10000
16  *
17  * echo 1,1 2,16 > /dev/shm/amx_ao_map
18  */
19 
20 
21 #include <stdio.h>
22 
23 #include <errno.h>
24 #include <stdlib.h>
25 #include <sys/ioctl.h>
26 #include <sys/mman.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <sys/time.h>
30 
31 #include <sched.h>
32 
33 #include "RTM_T_Device.h"
34 #include "local.h"
35 
36 #include "rtm-t_ioctl.h"
37 
38 #include "InlineDataHandler.h"
39 
40 #include <vector>
41 
43  // TODO Auto-generated constructor stub
44 
45 }
46 
48  // TODO Auto-generated destructor stub
49 }
50 
51 
52 #define AO_MAP_ZERO 0xffff
53 
54 
55 /* /dev/shm/amx_ao_from ai_mapping
56  * aoch=aich // both index from 1 eg
57  * 1=1
58  * 2=17
59  * unmapped channels are set AO_MAP_ZERO
60  */
62  RTM_T_Device* ai_dev;
63  int ao_dev;
64  int ao_count;
65  int ai_count;
66  int ai_start;
67  int ai_stride;
68  int wavelen;
69  RTM_T_Device *dev;
70  unsigned * ao_ai_mapping;
71 
72  int ao_buf_ix;
73 
74  void updateMuxSelection()
75  {
76  FILE *fp = fopen("/dev/shm/amx_ao_map", "r");
77  if (fp){
78  int ai_ch, ao_ch;
79  for (ao_ch = 0; ao_ch < ao_count; ++ao_ch){
80  ao_ai_mapping[ao_ch] = AO_MAP_ZERO;
81  }
82 
83  while (fscanf(fp, "%d,%d", &ao_ch, &ai_ch) == 2 &&
84  ao_ch >= 1 && ao_ch <= ao_count &&
85  ai_ch >= 1 && ai_ch <= ai_count){
86  ao_ai_mapping[ao_ch-1] = ai_ch-1;
87  }
88  fclose(fp);
89  }
90  }
91 public:
92  InlineDataHanderMuxAO_STREAM(int _ao_dev, int _ao_count, int _ai_count, int _ai_start, int _ai_stride, int _wavelen) :
93  ao_dev(_ao_dev),
94  ao_count(_ao_count), ai_count(_ai_count), ai_start(_ai_start), ai_stride(_ai_stride), wavelen(_wavelen),
95  ao_buf_ix(0)
96  {
97  fprintf(stderr, "%s ao_dev:%d ao:%d ai:%d ai_start:%d ai_stride:%d wavelen:%d\n", __FUNCTION__,
98  ao_dev, ao_count, ai_count, ai_start, ai_stride, wavelen);
99 
100  dev = new RTM_T_Device(ao_dev);
101  ao_ai_mapping = new unsigned[ao_count];
102  for (int ao_ch = 0; ao_ch < ao_count; ++ao_ch){
103  ao_ai_mapping[ao_ch] = ao_ch;
104  }
105  if (ioctl(dev->getDeviceHandle(), AFHBA_AO_BURST_INIT, 0)){
106  perror("ioctl AFHBA_AO_BURST_INIT");
107  exit(1);
108  }
109  }
110 
111  virtual void handleBuffer(int ibuf, const void *src, int len)
112  /* take a slice ao_count out of AI buffer and drop the slice into */
113  {
114  const short* ai0 = (const short*)src;
115  const short* ai = ai0;
116  short* ao = (short*)dev->getHostBufferMappingW(ao_buf_ix = !ao_buf_ix);
117  const int instep = ai_count*ai_stride;
118  updateMuxSelection();
119 
120  for (int sample = 0; sample < wavelen; ++sample, ai += instep, ao += ao_count){
121  if ((const char*)(ai+ai_count) - (const char*)ai0 > dev->maxlen){
122  fprintf(stderr, "%s ai overflow at sample:%d\n", __FUNCTION__, sample);
123  exit(1);
124  }
125  for (int ao_ch = 0; ao_ch < ao_count; ++ao_ch){
126  unsigned ai_ch = ao_ai_mapping[ao_ch];
127  ao[ao_ch] = ai_ch==AO_MAP_ZERO? 0 : ai[ai_ch];
128  }
129  }
130  if (ioctl(dev->getDeviceHandle(), AFHBA_AO_BURST_SETBUF, ao_buf_ix)){
131  perror("ioctl AFHBA_AO_BURST_SETBUF");
132  exit(1);
133  }
134  }
135 };
136 
138 {
139  if (const char* value = getenv("MUXAO")){
140  int pr[6];
141  if (sscanf(value, "%d,%d,%d,%d,%d,%d", pr+0, pr+1, pr+2, pr+3, pr+4, pr+5) == 6){
142  return new InlineDataHanderMuxAO_STREAM(pr[0], pr[1], pr[2], pr[3], pr[4], pr[5]);
143  }
144  }
145  return new InlineDataHandler;
146 }
147 
InlineDataHandler.h
AO_MAP_ZERO
#define AO_MAP_ZERO
Definition: InlineDataHandlerMuxAO_STREAM_ALL.cpp:52
InlineDataHandler::factory
static InlineDataHandler * factory(RTM_T_Device *ai_dev)
Definition: InlineDataHandler.cpp:20
local.h
AFHBA_AO_BURST_SETBUF
#define AFHBA_AO_BURST_SETBUF
Definition: rtm-t_ioctl.h:112
InlineDataHandler
Definition: InlineDataHandler.h:13
InlineDataHanderMuxAO_STREAM::InlineDataHanderMuxAO_STREAM
InlineDataHanderMuxAO_STREAM(int _ao_dev, int _ao_count, int _ai_count, int _ai_start, int _ai_stride, int _wavelen)
Definition: InlineDataHandlerMuxAO_STREAM_ALL.cpp:92
RTM_T_Device::getHostBufferMappingW
void * getHostBufferMappingW(int ibuf=0)
Definition: RTM_T_Device.h:65
InlineDataHanderMuxAO_STREAM
Definition: InlineDataHandlerMuxAO_STREAM_ALL.cpp:61
RTM_T_Device::maxlen
const unsigned maxlen
Definition: RTM_T_Device.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
InlineDataHanderMuxAO_STREAM::handleBuffer
virtual void handleBuffer(int ibuf, const void *src, int len)
Definition: InlineDataHandlerMuxAO_STREAM_ALL.cpp:111
InlineDataHandler::~InlineDataHandler
virtual ~InlineDataHandler()
Definition: InlineDataHandler.cpp:15
RTM_T_Device.h
AFHBA_AO_BURST_INIT
#define AFHBA_AO_BURST_INIT
ioctl AFHBA_START_AO_ABN LLC, multiple buffers, OUTPUT
Definition: rtm-t_ioctl.h:110
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