26
26
#include " OnixSourceEditor.h"
27
27
28
28
29
+ OnixSource::OnixSource (SourceNode* sn) :
30
+ DataThread(sn),
31
+ ctx(NULL ),
32
+ devicesFound(false )
33
+ {
34
+ LOGD (" ONIX Source creating ONI context." );
35
+
36
+ ctx = oni_create_ctx (" riffa" ); // "riffa" is the PCIe driver name
37
+
38
+ if (!ctx) { LOGE (" Failed to create context." ); return ; }
39
+
40
+ // Initialize context and discover hardware
41
+ int errorCode = oni_init_ctx (ctx, 0 );
42
+
43
+ if (errorCode) { LOGE (oni_error_str (errorCode)); return ; }
44
+
45
+ oni_size_t num_devs = 0 ;
46
+ oni_device_t * devices = NULL ;
47
+
48
+ // Examine device table
49
+ size_t num_devs_sz = sizeof (num_devs);
50
+ oni_get_opt (ctx, ONI_OPT_NUMDEVICES, &num_devs, &num_devs_sz);
51
+
52
+ size_t devices_sz = sizeof (oni_device_t ) * num_devs;
53
+ devices = (oni_device_t *)realloc (devices, devices_sz);
54
+ if (devices == NULL ) { LOGE (" No devices found." ); return ; }
55
+ oni_get_opt (ctx, ONI_OPT_DEVICETABLE, devices, &devices_sz);
56
+
57
+ devicesFound = true ;
58
+
59
+ // print device info
60
+ printf (" +--------------------+-------+-------+-------+-------+---------------------\n " );
61
+ printf (" | \t\t | \t |Firm.\t |Read\t |Wrt. \t | \n " );
62
+ printf (" |Dev. idx\t\t |ID\t |ver. \t |size\t |size \t |Desc.\n " );
63
+ printf (" +--------------------+-------+-------+-------+-------+---------------------\n " );
64
+
65
+ for (size_t dev_idx = 0 ; dev_idx < num_devs; dev_idx++) {
66
+ if (devices[dev_idx].id != ONIX_NULL) {
67
+
68
+ const char * dev_str = onix_device_str (devices[dev_idx].id );
69
+
70
+ printf (" %02zd |%05zd: 0x%02x.0x%02x\t |%d\t |%d\t |%u\t |%u\t |%s\n " ,
71
+ dev_idx,
72
+ devices[dev_idx].idx ,
73
+ (uint8_t )(devices[dev_idx].idx >> 8 ),
74
+ (uint8_t )devices[dev_idx].idx ,
75
+ devices[dev_idx].id ,
76
+ devices[dev_idx].version ,
77
+ devices[dev_idx].read_size ,
78
+ devices[dev_idx].write_size ,
79
+ dev_str);
80
+ }
81
+ }
82
+
83
+ oni_size_t frame_size = 0 ;
84
+ size_t frame_size_sz = sizeof (frame_size);
85
+ oni_get_opt (ctx, ONI_OPT_MAXREADFRAMESIZE, &frame_size, &frame_size_sz);
86
+ printf (" Max. read frame size: %u bytes\n " , frame_size);
87
+
88
+ oni_get_opt (ctx, ONI_OPT_MAXWRITEFRAMESIZE, &frame_size, &frame_size_sz);
89
+ printf (" Max. write frame size: %u bytes\n " , frame_size);
90
+
91
+ size_t block_size_sz = sizeof (block_read_size);
92
+
93
+ // oni_set_opt(ctx, ONI_OPT_RESET, &val, sizeof(val));
94
+ oni_set_opt (ctx, ONI_OPT_BLOCKREADSIZE, &block_read_size, block_size_sz);
95
+
96
+ // Enable memory usage device
97
+ oni_write_reg (ctx, DEVICE_MEMORY, 0 , 1 );
98
+
99
+ oni_reg_val_t hzVal = 0 ;
100
+ oni_read_reg (ctx, DEVICE_MEMORY, 2 , &hzVal);
101
+
102
+ // set memory device refresh rate to 100 Hz
103
+ oni_write_reg (ctx, DEVICE_MEMORY, 1 , hzVal/100 );
104
+
105
+ oni_reg_val_t memSize = 0 ;
106
+ oni_read_reg (ctx, DEVICE_MEMORY, 3 , &memSize);
107
+
108
+ LOGD (" Hardware buffer size in 32-bit words: " , (int )memSize);
109
+ }
110
+
29
111
DataThread* OnixSource::createDataThread (SourceNode *sn)
30
112
{
31
113
return new OnixSource (sn);
@@ -44,7 +126,7 @@ void OnixSource::updateSettings(OwnedArray<ContinuousChannel>* continuousChannel
44
126
OwnedArray<EventChannel>* eventChannels,
45
127
OwnedArray<SpikeChannel>* spikeChannels,
46
128
OwnedArray<DataStream>* dataStreams,
47
- OwnedArray<DeviceInfo>* devices ,
129
+ OwnedArray<DeviceInfo>* deviceInfos ,
48
130
OwnedArray<ConfigurationObject>* configurationObjects)
49
131
{
50
132
@@ -54,87 +136,138 @@ void OnixSource::updateSettings(OwnedArray<ContinuousChannel>* continuousChannel
54
136
eventChannels->clear ();
55
137
continuousChannels->clear ();
56
138
spikeChannels->clear ();
57
- devices ->clear ();
139
+ deviceInfos ->clear ();
58
140
configurationObjects->clear ();
59
141
60
142
sources.clear ();
61
143
sourceBuffers.clear ();
62
144
63
- if (ctx == NULL )
145
+ if (devicesFound )
64
146
{
65
- LOGD (" ONIX Source creating ONI context." );
66
-
67
- ctx = oni_create_ctx (" riffa" ); // "riffa" is the PCIe driver name
68
-
69
- if (!ctx) { LOGE (" Failed to create context." ); return ; }
70
-
71
- // Initialize context and discover hardware
72
- int errorCode = oni_init_ctx (ctx, 0 );
73
-
74
- if (errorCode) { LOGE (oni_error_str (errorCode)); return ; }
75
-
76
- oni_size_t num_devs = 0 ;
77
- oni_device_t * devices = NULL ;
78
-
79
- // Examine device table
80
- size_t num_devs_sz = sizeof (num_devs);
81
- oni_get_opt (ctx, ONI_OPT_NUMDEVICES, &num_devs, &num_devs_sz);
82
-
83
- size_t devices_sz = sizeof (oni_device_t ) * num_devs;
84
- devices = (oni_device_t *)realloc (devices, devices_sz);
85
- if (devices == NULL ) { LOGE (" No devices found." ); return ; }
86
- oni_get_opt (ctx, ONI_OPT_DEVICETABLE, devices, &devices_sz);
87
-
88
- // print device info
89
- for (size_t dev_idx = 0 ; dev_idx < num_devs; dev_idx++) {
90
- if (devices[dev_idx].id != ONIX_NULL) {
91
-
92
- const char * dev_str = onix_device_str (devices[dev_idx].id );
93
-
94
- printf (" %02zd |%05zd: 0x%02x.0x%02x\t |%d\t |%d\t |%u\t |%u\t |%s\n " ,
95
- dev_idx,
96
- devices[dev_idx].idx ,
97
- (uint8_t )(devices[dev_idx].idx >> 8 ),
98
- (uint8_t )devices[dev_idx].idx ,
99
- devices[dev_idx].id ,
100
- devices[dev_idx].version ,
101
- devices[dev_idx].read_size ,
102
- devices[dev_idx].write_size ,
103
- dev_str);
104
- }
147
+ sourceBuffers.add (new DataBuffer (1 , 10000 )); // Memory device
148
+ // sourceBuffers.add(new DataBuffer(1, 10000)); // Heartbeat device
149
+
150
+ // Memory usage device
151
+ DataStream::Settings memStreamSettings
152
+ {
153
+ " Memory Usage" , // stream name
154
+ " Hardware buffer usage on an acquisition board" , // stream description
155
+ " onix-pcie-device.memory" , // stream identifier
156
+ 100 // sample rate
157
+
158
+ };
159
+
160
+ DataStream* stream = new DataStream (memStreamSettings);
161
+ dataStreams->add (stream);
162
+
163
+ {
164
+ ContinuousChannel::Settings channelSettings{
165
+ ContinuousChannel::AUX,
166
+ " MEM" ,
167
+ " Hardware buffer usage" ,
168
+ " onix-pcie-device.continuous.mem" ,
169
+ 1 .0f ,
170
+ stream
171
+ };
172
+ continuousChannels->add (new ContinuousChannel (channelSettings));
105
173
}
106
174
}
107
175
108
-
109
-
110
-
111
176
// detect available devices and create source objects for each
112
177
113
178
}
114
179
115
180
116
181
bool OnixSource::foundInputSource ()
117
182
{
118
- return false ;
183
+ return devicesFound ;
119
184
}
120
185
121
186
bool OnixSource::startAcquisition ()
122
187
{
123
188
124
- for (auto source : sources)
125
- source->buffer ->clear ();
189
+ // for (auto source : sources)
190
+ // source->buffer->clear();
191
+
192
+ // for (auto source : sources)
193
+ // source->startThread();
194
+ if (!devicesFound)
195
+ return false ;
196
+
197
+ oni_reg_val_t reg = 2 ;
198
+ int res = oni_set_opt (ctx, ONI_OPT_RESETACQCOUNTER, ®, sizeof (oni_size_t ));
199
+ if (res < ONI_ESUCCESS)
200
+ {
201
+ LOGE (" Error starting acquisition: " , oni_error_str (res), " code " , res);
202
+ return false ;
203
+ }
126
204
127
- for (auto source : sources)
128
- source->startThread ();
205
+ startThread ();
129
206
130
207
return true ;
131
208
}
132
209
133
210
bool OnixSource::stopAcquisition ()
134
211
{
212
+ if (isThreadRunning ())
213
+ signalThreadShouldExit ();
214
+
215
+ waitForThreadToExit (2000 );
216
+
217
+ if (devicesFound)
218
+ {
219
+ oni_size_t reg = 0 ;
220
+ int res = oni_set_opt (ctx, ONI_OPT_RUNNING, ®, sizeof (reg));
221
+ if (res < ONI_ESUCCESS)
222
+ {
223
+ LOGE (" Error stopping acquisition: " , oni_error_str (res), " code " , res);
224
+ return false ;
225
+ }
226
+
227
+ uint32_t val = 1 ;
228
+ oni_set_opt (ctx, ONI_OPT_RESET, &val, sizeof (val));
229
+ oni_set_opt (ctx, ONI_OPT_BLOCKREADSIZE, &block_read_size, sizeof (block_read_size));
230
+ }
231
+ sourceBuffers[0 ]->clear ();
135
232
136
- for (auto source : sources)
137
- source->signalThreadShouldExit ();
233
+ return true ;
234
+ }
235
+
236
+ bool OnixSource::updateBuffer ()
237
+ {
238
+ const int nSamps = 192 ;
239
+ oni_frame_t * frame;
240
+ unsigned char * bufferPtr;
241
+
242
+ for (int samp = 0 ; samp < nSamps; samp++)
243
+ {
244
+ int res = oni_read_frame (ctx, &frame);
245
+
246
+ if (res < ONI_ESUCCESS)
247
+ {
248
+ LOGE (" Error reading ONI frame: " , oni_error_str (res), " code " , res);
249
+ return false ;
250
+ }
251
+
252
+ if (frame->dev_idx == DEVICE_MEMORY)
253
+ {
254
+ bufferPtr = (unsigned char *)frame->data + 8 ; // skip ONI timestamps
255
+ uint32 membytes = (uint32 (*(uint16*)bufferPtr) << 16 ) + (uint32 (*(uint16*)(bufferPtr + 2 )));
256
+ float memf = membytes * sizeof (membytes);
257
+ uint64 zero = 0 ;
258
+ int64 tst = frame->time ;
259
+ double tsd = -1 ;
260
+ sourceBuffers[0 ]->addToBuffer (
261
+ &memf,
262
+ &tst,
263
+ &tsd,
264
+ &zero,
265
+ 1
266
+ );
267
+ }
268
+
269
+ oni_destroy_frame (frame);
270
+ }
138
271
139
272
return true ;
140
273
}
0 commit comments