1
|
/**
|
2
|
* \file: main.cpp
|
3
|
*
|
4
|
* \brief ARM side main routine for DSP Hello World application.
|
5
|
* The ARM sets itself up, sends a message to the DSP,
|
6
|
* and then waits for a return message before exiting.
|
7
|
*
|
8
|
* o 0
|
9
|
* | / Copyright (c) 2005-2010
|
10
|
* (CL)---o Critical Link, LLC
|
11
|
* \
|
12
|
* O
|
13
|
*/
|
14
|
|
15
|
#include "dspapp.h"
|
16
|
#include <stdio.h>
|
17
|
#include <string.h>
|
18
|
#include <unistd.h>
|
19
|
|
20
|
#include "ipc_inbound.h"
|
21
|
#include "ipc_outbound.h"
|
22
|
|
23
|
using namespace MityDSP;
|
24
|
|
25
|
enum MsgCommand {
|
26
|
eReadFromARM,
|
27
|
eWriteToARM,
|
28
|
eReadFromDSP,
|
29
|
eWriteToDSP
|
30
|
};
|
31
|
|
32
|
enum MsgTypes {
|
33
|
eGlobalFixture,
|
34
|
eLibrary,
|
35
|
eGlobalUser,
|
36
|
eGlobalSerialPort,
|
37
|
eGlobalScannerJog,
|
38
|
eFeature,
|
39
|
eFeatureData,
|
40
|
eFeatureDataSource,
|
41
|
eFeatureExpressions,
|
42
|
eFeatureFixture,
|
43
|
eFeatureMeasurement,
|
44
|
eFeatureSegmentList,
|
45
|
eGlobalDigitalInputs,
|
46
|
eGlobalDigitalOutputs,
|
47
|
eGlobalFactory,
|
48
|
eDebugText
|
49
|
};
|
50
|
|
51
|
typedef struct {
|
52
|
MsgTypes type;
|
53
|
MsgCommand command;
|
54
|
} Header;
|
55
|
|
56
|
typedef struct {
|
57
|
Header header;
|
58
|
char textMessage[100]; // 100 bytes for now
|
59
|
} DebugText;
|
60
|
|
61
|
typedef struct {
|
62
|
Header header;
|
63
|
char fixtureName[33];
|
64
|
int fixtureID;
|
65
|
int fixtureTencoderpe;
|
66
|
int fixtureURR;
|
67
|
int fixtureHomeMethod;
|
68
|
int fixtureZeroMethod;
|
69
|
int fixtureMotion;
|
70
|
int fixtureDirection;
|
71
|
int fixtureOrientation;
|
72
|
double fixtureLinearTravel;
|
73
|
double fixtureRotaryTravel;
|
74
|
int motorPresent;
|
75
|
int motorPort;
|
76
|
int motorRotation;
|
77
|
double motorGearRatioIn;
|
78
|
double motorGearRationOut;
|
79
|
int motorType;
|
80
|
int motorMaxSpeed;
|
81
|
int motorStepsPerRevolution;
|
82
|
char motorAcceleration[16]; // todo
|
83
|
int encoderPresent;
|
84
|
int encoderPort;
|
85
|
int encoderRotation;
|
86
|
double encoderGearRatioIn;
|
87
|
double encoderGearRationOut;
|
88
|
int encoderResolution;
|
89
|
int encoderIndexPresent;
|
90
|
int encoderIndexInput;
|
91
|
int encoderIndexIsHome;
|
92
|
int encoderIndexIsEndOfTravel;
|
93
|
int encoderQuadratureMode;
|
94
|
int homeSensorPresent;
|
95
|
int homeSensorInput;
|
96
|
int homeSensorType;
|
97
|
int homeSensorDirection;
|
98
|
int endOfTravelSensorPresent;
|
99
|
int endOfTravelSensorInput;
|
100
|
int endOfTravelSensorType;
|
101
|
int endOfTravelSensorDirection;
|
102
|
char inputMapping[5]; // todo
|
103
|
char outputMapping[8]; // todo
|
104
|
double pulleyDiam;
|
105
|
int pulleyUnits;
|
106
|
} GlobalFixture_str ;
|
107
|
|
108
|
typedef struct {
|
109
|
Header header;
|
110
|
int SerialNumber;
|
111
|
double AnalogCalMinValue;
|
112
|
double AnalogCalMaxValue;
|
113
|
double AnalogCalGain;
|
114
|
double AnalogOffset;
|
115
|
int LowPowerScannerType;
|
116
|
int LowPowerValue;
|
117
|
int CalibrationUnits;
|
118
|
double CalibrationSmallPart;
|
119
|
double CalibrationLargePart;
|
120
|
double CalibrationmValue;
|
121
|
double CalibrationbValue;
|
122
|
char CalibrationDate[20];
|
123
|
} GlobalFactory_str ;
|
124
|
|
125
|
typedef struct {
|
126
|
Header header;
|
127
|
int DigInputID;
|
128
|
int ActivationType;
|
129
|
int FunctionID;
|
130
|
} GlobalDigitalInputs_str ;
|
131
|
|
132
|
typedef struct {
|
133
|
Header header;
|
134
|
int DigOutputID;
|
135
|
int Polarity;
|
136
|
int Latched;
|
137
|
int ServerID;
|
138
|
} GlobalDigitalOutputs_str ;
|
139
|
|
140
|
typedef struct {
|
141
|
Header header;
|
142
|
int SerialPortID;
|
143
|
int BaudRate;
|
144
|
int ParityBits;
|
145
|
int DataBits;
|
146
|
int StopBits;
|
147
|
int FlowControl;
|
148
|
int ProtocolFlag;
|
149
|
int DataFlag;
|
150
|
} GlobalSerialPort_str ;
|
151
|
|
152
|
typedef struct {
|
153
|
Header header;
|
154
|
int FeatureID;
|
155
|
int LibraryToFeatureKey;
|
156
|
char Name[16];
|
157
|
int AdvanceMode;
|
158
|
int AdvanceDelay;
|
159
|
double SizeOffset;
|
160
|
double PositionOffset;
|
161
|
int URRUnits;
|
162
|
int URRResolution;
|
163
|
int URRRounding;
|
164
|
int DataSourceExpressionType;
|
165
|
int DataSource_op;
|
166
|
int Sequence;
|
167
|
double ToleranceRejectPlus;
|
168
|
double ToleranceRejectMinus;
|
169
|
double ToleranceWarningPlus;
|
170
|
double ToleranceWarningMinus;
|
171
|
double ToleranceNominal;
|
172
|
bool ToleranceRejectEnablePlus;
|
173
|
bool ToleranceRejectEnableMinus;
|
174
|
bool ToleranceWarningEnablePlus;
|
175
|
bool ToleranceWarningEnableMinus;
|
176
|
int UseFixtureToCollectData;
|
177
|
int UseFixtureForAutoPositioning;
|
178
|
double UserSingleMasterSize;
|
179
|
} Feature_str ;
|
180
|
|
181
|
typedef struct {
|
182
|
Header header;
|
183
|
int FeatureToDataKey;
|
184
|
int LibraryToDataKey;
|
185
|
char Label[16];
|
186
|
int DisplayLine;
|
187
|
int SerialPortSelected;
|
188
|
int UseAsLimits;
|
189
|
} FeatureData_str ;
|
190
|
|
191
|
typedef struct {
|
192
|
Header header;
|
193
|
int FeatureToDataKey;
|
194
|
int LibraryToDataKey;
|
195
|
int TermType;
|
196
|
double TermConstanst;
|
197
|
int TermFeatureID;
|
198
|
int TermID;
|
199
|
} FeatureDataSource_str ;
|
200
|
|
201
|
typedef struct {
|
202
|
Header header;
|
203
|
int FeatureToDataKey;
|
204
|
int LibraryToDataKey;
|
205
|
int Segment ;
|
206
|
} FeatureSegmentList_str ;
|
207
|
|
208
|
typedef struct {
|
209
|
Header header;
|
210
|
int FeatureToDataKey;
|
211
|
int LibraryToDataKey;
|
212
|
int Type;
|
213
|
int EdgeCount;
|
214
|
int GlassMode;
|
215
|
int InternalRefFlag;
|
216
|
int LowerRefFlag;
|
217
|
int UpperRefFlag;
|
218
|
int PartSegmentIndex;
|
219
|
int PartModeFlag;
|
220
|
int SamplingMode;
|
221
|
int AveragingMode;
|
222
|
int AveragingPeriod;
|
223
|
int GoodScans;
|
224
|
int EnterDelayMode;
|
225
|
int EnterDelayPeriod;
|
226
|
char FormatString[34];
|
227
|
int PolledFlag;
|
228
|
} FeatureMeasurement_str ;
|
229
|
|
230
|
typedef struct {
|
231
|
Header header;
|
232
|
int FeatureToDataKey;
|
233
|
int LibraryToDataKey;
|
234
|
int LineOrder;
|
235
|
char ExpressionText[50];
|
236
|
} FeatureExpressions_str ;
|
237
|
|
238
|
typedef struct {
|
239
|
Header header;
|
240
|
int FeatureToDataKey;
|
241
|
int LibraryToDataKey;
|
242
|
int FixtureID;
|
243
|
int DisableMotorAfterMove;
|
244
|
int IDODWALLComputeWall;
|
245
|
int MeasurementMode;
|
246
|
int UsageMode;
|
247
|
int AutomaticShankDiamFlag;
|
248
|
double Speed;
|
249
|
int StepMode;
|
250
|
int ReturnPosition;
|
251
|
int NumberOfMeasurementPositions;
|
252
|
double TotalDistance;
|
253
|
double StartPosition;
|
254
|
double ShankDiameter;
|
255
|
} FeatureFixture_str ;
|
256
|
|
257
|
typedef struct {
|
258
|
Header header;
|
259
|
int ScannerJogID;
|
260
|
double mOffset;
|
261
|
double bOffset;
|
262
|
double LowSize;
|
263
|
double HighSize;
|
264
|
} GlobalScannerJog_str ;
|
265
|
|
266
|
typedef struct {
|
267
|
Header header;
|
268
|
char LanguageName[20];
|
269
|
char LanguagePrefix[5];
|
270
|
char Password[8];
|
271
|
int PowerUpLocked;
|
272
|
int AllowNominalChanges;
|
273
|
int AllowRemastering;
|
274
|
int AllowLibraryChanges;
|
275
|
int AdvancedScreenOperation;
|
276
|
int AutoScrollEnable;
|
277
|
int AudibleAlarm;
|
278
|
int FlipScreen180;
|
279
|
int ScannerDoubleDiff;
|
280
|
int LatchScanErrors;
|
281
|
int IgnoreScanErrors;
|
282
|
char IPAddress[20];
|
283
|
int ButtonsDefined;
|
284
|
int ButtonID_1;
|
285
|
int ButtonID_2;
|
286
|
int ButtonID_3;
|
287
|
} GlobalUser_str ;
|
288
|
|
289
|
typedef struct {
|
290
|
Header header;
|
291
|
int LibraryID;
|
292
|
char LibraryName[16];
|
293
|
double UserDualPointMasterSize1;
|
294
|
double UserDualPointMasterSize2;
|
295
|
double AlarmDuration;
|
296
|
int AlarmEnable;
|
297
|
int SQCBatchSize;
|
298
|
int SQCBatchClearAtEndOfBatch;
|
299
|
int SQCBatchPrintAtEndOfBatch;
|
300
|
int FeatureCount;
|
301
|
int SerialDOFAutoSendFlag;
|
302
|
int SerialDOFAutoSendDelay;
|
303
|
int SerialDOFDateTimeFlag;
|
304
|
int SerialDOFLabelFlag;
|
305
|
int SerialDOFHeaderType;
|
306
|
int SerialDOFRequestorType;
|
307
|
char SerialDOFRequestorString[5];
|
308
|
int SerialDOFSeparatorType;
|
309
|
char SerialDOFSeparatorString[5];
|
310
|
int SerialDOFTerminatorType;
|
311
|
char SerialDOFTerminatorString[5];
|
312
|
int SerialDOFDecimalFlag;
|
313
|
int SerialDOFSignFlag;
|
314
|
double LegacySlideCounterPerInch;
|
315
|
int ReportSelected1;
|
316
|
int ReportSelected2;
|
317
|
int ReportSelected3;
|
318
|
int ReportSelected4;
|
319
|
char ReportUserTitle[33];
|
320
|
int ReportPrinterPort;
|
321
|
int ReportDisableHeaderAndFooter;
|
322
|
int ReportDisableFormFeed;
|
323
|
int URRUnits;
|
324
|
int URRResolution;
|
325
|
int URRRounding;
|
326
|
} Library_str ;
|
327
|
|
328
|
typedef union {
|
329
|
Header header;
|
330
|
DebugText debugMsg;
|
331
|
Library_str library;
|
332
|
GlobalFixture_str globalFixture;
|
333
|
GlobalUser_str globalUser;
|
334
|
GlobalScannerJog_str globalScannerJog;
|
335
|
FeatureFixture_str featureFixture;
|
336
|
FeatureExpressions_str featureExpressions;
|
337
|
FeatureMeasurement_str featureMeasurement;
|
338
|
FeatureSegmentList_str featureSegmentList;
|
339
|
FeatureDataSource_str featureDataSource;
|
340
|
FeatureData_str featureData;
|
341
|
Feature_str feature;
|
342
|
GlobalFactory_str globalFactory;
|
343
|
GlobalDigitalInputs_str globalDigitalInputs;
|
344
|
GlobalDigitalOutputs_str globalDigitalOutputs;
|
345
|
GlobalSerialPort_str globalSerialPort;
|
346
|
} allTypes;
|
347
|
|
348
|
allTypes messageA2D; // message data between DSP and ARM
|
349
|
Library_str library; // message one this side.
|
350
|
|
351
|
// Forward declarations
|
352
|
int handleInboundMessage(void *Buffer, uint16_t Length, void *UserArg);
|
353
|
int handleInboundMessageBM(void *Buffer, uint16_t Length, void *UserArg);
|
354
|
|
355
|
volatile bool gbDone = false;
|
356
|
|
357
|
int main(int argc, char* argv[])
|
358
|
{
|
359
|
// tcDspApp class for booting and loading the DSP
|
360
|
tcDspApp* lpDspApp = NULL;
|
361
|
// Used to setup handling of inbound messages from DSP
|
362
|
tcIPCInbound* lpMessageInbound = NULL;
|
363
|
// Used to send messages to the DSP
|
364
|
tcIPCOutbound* lpMessageOutbound = NULL;
|
365
|
// Message to send to the DSP
|
366
|
char lpMessage[] = "Hello DSP";
|
367
|
// Pointer to buffer obtained from dsplink
|
368
|
char* lpMessageBuffer = NULL;
|
369
|
// Message from standard input
|
370
|
char lpUsrMsg[180] = {0};
|
371
|
|
372
|
// Check application usage
|
373
|
if (argc < 2)
|
374
|
{
|
375
|
fprintf(stderr, "usage: HelloWorld dsp_image.out\n");
|
376
|
return -1;
|
377
|
}
|
378
|
|
379
|
// Create the DspApp object
|
380
|
lpDspApp = new tcDspApp();
|
381
|
if (lpDspApp != NULL) {
|
382
|
fprintf(stderr, "DSP app was created\n");
|
383
|
} else {
|
384
|
fprintf(stderr, "DSP app was not created\n");
|
385
|
}
|
386
|
|
387
|
// Load the DSP.out file
|
388
|
fprintf(stderr, "Loading file %s\n", argv[1]);
|
389
|
int retCode;
|
390
|
retCode = lpDspApp->LoadApp(argv[1], true, argc>2?1:0);
|
391
|
|
392
|
fprintf(stderr, "Return code from Load App = %d\n", retCode);
|
393
|
fprintf(stderr, "Starting application.\n");
|
394
|
|
395
|
// Create the object to handle incoming messages from the DSP
|
396
|
lpMessageInbound = new tcIPCInbound((char*)"GPPMSGQ1");
|
397
|
|
398
|
if (NULL != lpMessageInbound)
|
399
|
{
|
400
|
// Register the callback for handling messages from the DSP
|
401
|
lpMessageInbound->Register(handleInboundMessageBM, (void*)NULL);
|
402
|
|
403
|
// Intialize the inbound controller to create the thread that handles the callbacks
|
404
|
lpMessageInbound->Initialize();
|
405
|
} else {
|
406
|
fprintf(stderr, "lpMessageInBound was null for some reason\n");
|
407
|
}
|
408
|
|
409
|
// Create the object used to send messages to the DSP
|
410
|
lpMessageOutbound = new tcIPCOutbound((char*)"DSPMSGQ0");
|
411
|
|
412
|
// Wait for the DSP to finish initialization (really just waiting for first message, which indicates DSP set up ok)
|
413
|
while(false == gbDone) {
|
414
|
sleep(3); //fprintf(stderr, "waiting for DSP\n");
|
415
|
}
|
416
|
|
417
|
// Reset bool in preparation for next received message from DSP
|
418
|
gbDone = false;
|
419
|
|
420
|
// Get a buffer for a message to the DSP
|
421
|
lpMessageBuffer = (char*)lpMessageOutbound->GetBuffer(sizeof(messageA2D));
|
422
|
|
423
|
allTypes messageA2D;
|
424
|
messageA2D.library.header.command = eWriteToDSP;
|
425
|
messageA2D.library.header.type = eLibrary;
|
426
|
messageA2D.library.FeatureCount = 0;
|
427
|
messageA2D.library.SQCBatchSize = 9;
|
428
|
|
429
|
// Copy the message to the dsplink buffer
|
430
|
memcpy(lpMessageBuffer, &messageA2D, sizeof(messageA2D));
|
431
|
// Send the message to the DSP
|
432
|
fprintf(stderr, "Sending a message to the DSP.\n");
|
433
|
lpMessageOutbound->SendMessage(lpMessageBuffer);
|
434
|
|
435
|
/* original sample code....
|
436
|
* // Copy the message to the dsplink buffer
|
437
|
strcpy(lpMessageBuffer, lpMessage);
|
438
|
|
439
|
// Send the message to the DSP
|
440
|
fprintf(stderr, "Sending a message to the DSP.\n");
|
441
|
lpMessageOutbound->SendMessage(lpMessageBuffer);
|
442
|
****************** */
|
443
|
// Wait for a message to be received from the DSP or for user to quit
|
444
|
fprintf(stderr, "Waiting for DSP response \n");
|
445
|
int counter=0; // lets send a few messages back and forth and then quit
|
446
|
while (gbDone == false ) {
|
447
|
counter++;
|
448
|
// fprintf(stderr, "after first one looping %d\n", counter);
|
449
|
}
|
450
|
gbDone = false; // reset flag
|
451
|
|
452
|
// send the Library msg back to the DSP, it will send it back to us automatically.
|
453
|
fprintf(stderr, "after second one looping %d\n", counter);
|
454
|
// Create the object used to send messages to the DSP
|
455
|
lpMessageOutbound = new tcIPCOutbound((char*)"DSPMSGQ0");
|
456
|
if (NULL != lpMessageOutbound)
|
457
|
{
|
458
|
fprintf(stderr, "\n");
|
459
|
}
|
460
|
// Get a buffer for a message to the DSP
|
461
|
lpMessageBuffer = (char*)lpMessageOutbound->GetBuffer(sizeof(messageA2D));
|
462
|
if (lpMessageBuffer) {
|
463
|
memcpy(lpMessageBuffer, &library, sizeof(messageA2D));
|
464
|
lpMessageOutbound->SendMessage(lpMessageBuffer);
|
465
|
} else {
|
466
|
fprintf(stderr, "did not get 2nd message buffer for some reason\n");
|
467
|
gbDone = true;
|
468
|
}
|
469
|
while (gbDone == false ) {
|
470
|
counter++;
|
471
|
}
|
472
|
gbDone = false; // reset flag
|
473
|
|
474
|
fprintf(stderr, "after third one looping %d\n", counter);
|
475
|
// send the Library msg back to the DSP, it will send it back to us automatically.
|
476
|
// Get a buffer for a message to the DSP
|
477
|
lpMessageBuffer = (char*)lpMessageOutbound->GetBuffer(sizeof(messageA2D));
|
478
|
if (lpMessageBuffer) {
|
479
|
memcpy(lpMessageBuffer, &library, sizeof(messageA2D));
|
480
|
lpMessageOutbound->SendMessage(lpMessageBuffer);
|
481
|
} else {
|
482
|
fprintf(stderr, "did not get 3rd message buffer for some reason\n");
|
483
|
gbDone = true;
|
484
|
}
|
485
|
while (gbDone == false ) {
|
486
|
counter++;
|
487
|
//fprintf(stderr, "after third one looping %d\n", counter);
|
488
|
}
|
489
|
gbDone = false; // reset flag
|
490
|
|
491
|
// Wait for a message to be received from the DSP or for user to quit
|
492
|
fprintf(stderr, "Waiting for DSP response (type \'q\' to quit)...\n");
|
493
|
while(gbDone == false && lpUsrMsg[0] != 'q')
|
494
|
{
|
495
|
fgets(lpUsrMsg, 180, stdin);
|
496
|
}
|
497
|
|
498
|
/*int counter=0;
|
499
|
while(counter++ < 2000) {
|
500
|
sleep(3);
|
501
|
fprintf(stderr, "waiting sending serial messages via DSP? %d\n", i);
|
502
|
}*/
|
503
|
|
504
|
fprintf(stderr, "Exiting application.\n");
|
505
|
|
506
|
// Stop the DSP application from running
|
507
|
lpDspApp->StopApp();
|
508
|
|
509
|
// Cleanup
|
510
|
// Commented out because deletes throw Assert errors.
|
511
|
//delete lpDspApp;
|
512
|
//delete lpMessageInbound;
|
513
|
//delete lpMessageOutbound;
|
514
|
|
515
|
return 0;
|
516
|
}
|
517
|
|
518
|
/**
|
519
|
* Handle inbound messages from the DSP.
|
520
|
*
|
521
|
* \param apBuffer Pointer to the buffer containing the message.
|
522
|
* \param anLength The length of the message.
|
523
|
* \param apUserArg User defined argument.
|
524
|
*
|
525
|
* \return 0.
|
526
|
*/
|
527
|
int handleInboundMessage(void *apBuffer, uint16_t anLength, void *apUserArg)
|
528
|
{
|
529
|
fprintf(stderr, "ARM received a message from the DSP:\n");
|
530
|
|
531
|
// Print the message we received
|
532
|
fprintf(stderr, "\tDSP Message = \"%s\" len = %d\n", (char *)apBuffer, anLength);
|
533
|
|
534
|
// Notify the main function that we have received a message from the DSP and are done
|
535
|
gbDone = true;
|
536
|
|
537
|
return 0;
|
538
|
}
|
539
|
|
540
|
/**
|
541
|
* Handle inbound messages from the DSP.
|
542
|
*
|
543
|
* \param apBuffer Pointer to the buffer containing the message.
|
544
|
* \param anLength The length of the message.
|
545
|
* \param apUserArg User defined argument.
|
546
|
*
|
547
|
* \return 0.
|
548
|
*/
|
549
|
int handleInboundMessageBM(void *apBuffer, uint16_t anLength, void *apUserArg)
|
550
|
{
|
551
|
fprintf(stderr, "handleInboundMessageBM:ARM received a message from the DSP:\n");
|
552
|
|
553
|
// Print the message we received
|
554
|
fprintf(stderr, "\tDSP Messagelen = %d\n", anLength);
|
555
|
allTypes messageA2D;
|
556
|
memcpy(&messageA2D, (char *)apBuffer, sizeof(messageA2D));
|
557
|
switch (messageA2D.header.type) {
|
558
|
case eLibrary:
|
559
|
// for fun just print some values recv'd from the DSP
|
560
|
fprintf(stderr, "messageA2D.library.FeatureCount = %d\n", messageA2D.library.FeatureCount);
|
561
|
fprintf(stderr, "messageA2D.library.SQCBatchSize = %d\n", messageA2D.library.SQCBatchSize);
|
562
|
|
563
|
memcpy(&library, &messageA2D, sizeof(messageA2D)); // save a local copy of the library data...
|
564
|
fprintf(stderr, "after doing memcpy at %d\n", __LINE__);
|
565
|
break;
|
566
|
case eDebugText:
|
567
|
// print message from DSP.
|
568
|
fprintf(stderr, "Message: %s\n", messageA2D.debugMsg.textMessage );
|
569
|
break;
|
570
|
};
|
571
|
|
572
|
// Notify the main function that we have received a message from the DSP and are done
|
573
|
gbDone = true;
|
574
|
|
575
|
fprintf(stderr, "handleInboundMessageBM:leaving ...\n");
|
576
|
return 0;
|
577
|
}
|
578
|
|