|
/**
|
|
* \file main.cpp
|
|
*
|
|
* \brief DSP side main routine for DSP Hello World application.
|
|
* The DSP simply sets itself up, and then waits for a
|
|
* message from the ARM, to which it replies.
|
|
*
|
|
* o 0
|
|
* | / Copyright (c) 2005-2010
|
|
* (CL)---o Critical Link, LLC
|
|
* \
|
|
* O
|
|
*/
|
|
|
|
#include <std.h>
|
|
#include <tsk.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <sem.h>
|
|
|
|
#include "core/cl_ipc_inbound.h"
|
|
#include "core/cl_ipc_outbound.h"
|
|
|
|
enum MsgCommand {
|
|
eReadFromARM,
|
|
eWriteToARM,
|
|
eReadFromDSP,
|
|
eWriteToDSP
|
|
};
|
|
|
|
enum MsgTypes {
|
|
eGlobalFixture,
|
|
eLibrary,
|
|
eGlobalUser,
|
|
eGlobalSerialPort,
|
|
eGlobalScannerJog,
|
|
eFeature,
|
|
eFeatureData,
|
|
eFeatureDataSource,
|
|
eFeatureExpressions,
|
|
eFeatureFixture,
|
|
eFeatureMeasurement,
|
|
eFeatureSegmentList,
|
|
eGlobalDigitalInputs,
|
|
eGlobalDigitalOutputs,
|
|
eGlobalFactory,
|
|
eDebugText
|
|
};
|
|
|
|
typedef struct {
|
|
MsgTypes type;
|
|
MsgCommand command;
|
|
} Header;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
char textMessage[100]; // 100 bytes for now
|
|
} DebugText;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
char fixtureName[33];
|
|
int fixtureID;
|
|
int fixtureTencoderpe;
|
|
int fixtureURR;
|
|
int fixtureHomeMethod;
|
|
int fixtureZeroMethod;
|
|
int fixtureMotion;
|
|
int fixtureDirection;
|
|
int fixtureOrientation;
|
|
double fixtureLinearTravel;
|
|
double fixtureRotaryTravel;
|
|
int motorPresent;
|
|
int motorPort;
|
|
int motorRotation;
|
|
double motorGearRatioIn;
|
|
double motorGearRationOut;
|
|
int motorType;
|
|
int motorMaxSpeed;
|
|
int motorStepsPerRevolution;
|
|
char motorAcceleration[16]; // todo
|
|
int encoderPresent;
|
|
int encoderPort;
|
|
int encoderRotation;
|
|
double encoderGearRatioIn;
|
|
double encoderGearRationOut;
|
|
int encoderResolution;
|
|
int encoderIndexPresent;
|
|
int encoderIndexInput;
|
|
int encoderIndexIsHome;
|
|
int encoderIndexIsEndOfTravel;
|
|
int encoderQuadratureMode;
|
|
int homeSensorPresent;
|
|
int homeSensorInput;
|
|
int homeSensorType;
|
|
int homeSensorDirection;
|
|
int endOfTravelSensorPresent;
|
|
int endOfTravelSensorInput;
|
|
int endOfTravelSensorType;
|
|
int endOfTravelSensorDirection;
|
|
char inputMapping[5]; // todo
|
|
char outputMapping[8]; // todo
|
|
double pulleyDiam;
|
|
int pulleyUnits;
|
|
} GlobalFixture_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int SerialNumber;
|
|
double AnalogCalMinValue;
|
|
double AnalogCalMaxValue;
|
|
double AnalogCalGain;
|
|
double AnalogOffset;
|
|
int LowPowerScannerType;
|
|
int LowPowerValue;
|
|
int CalibrationUnits;
|
|
double CalibrationSmallPart;
|
|
double CalibrationLargePart;
|
|
double CalibrationmValue;
|
|
double CalibrationbValue;
|
|
char CalibrationDate[20];
|
|
} GlobalFactory_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int DigInputID;
|
|
int ActivationType;
|
|
int FunctionID;
|
|
} GlobalDigitalInputs_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int DigOutputID;
|
|
int Polarity;
|
|
int Latched;
|
|
int ServerID;
|
|
} GlobalDigitalOutputs_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int SerialPortID;
|
|
int BaudRate;
|
|
int ParityBits;
|
|
int DataBits;
|
|
int StopBits;
|
|
int FlowControl;
|
|
int ProtocolFlag;
|
|
int DataFlag;
|
|
} GlobalSerialPort_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int FeatureID;
|
|
int LibraryToFeatureKey;
|
|
char Name[16];
|
|
int AdvanceMode;
|
|
int AdvanceDelay;
|
|
double SizeOffset;
|
|
double PositionOffset;
|
|
int URRUnits;
|
|
int URRResolution;
|
|
int URRRounding;
|
|
int DataSourceExpressionType;
|
|
int DataSource_op;
|
|
int Sequence;
|
|
double ToleranceRejectPlus;
|
|
double ToleranceRejectMinus;
|
|
double ToleranceWarningPlus;
|
|
double ToleranceWarningMinus;
|
|
double ToleranceNominal;
|
|
bool ToleranceRejectEnablePlus;
|
|
bool ToleranceRejectEnableMinus;
|
|
bool ToleranceWarningEnablePlus;
|
|
bool ToleranceWarningEnableMinus;
|
|
int UseFixtureToCollectData;
|
|
int UseFixtureForAutoPositioning;
|
|
double UserSingleMasterSize;
|
|
} Feature_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int FeatureToDataKey;
|
|
int LibraryToDataKey;
|
|
char Label[16];
|
|
int DisplayLine;
|
|
int SerialPortSelected;
|
|
int UseAsLimits;
|
|
} FeatureData_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int FeatureToDataKey;
|
|
int LibraryToDataKey;
|
|
int TermType;
|
|
double TermConstanst;
|
|
int TermFeatureID;
|
|
int TermID;
|
|
} FeatureDataSource_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int FeatureToDataKey;
|
|
int LibraryToDataKey;
|
|
int Segment ;
|
|
} FeatureSegmentList_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int FeatureToDataKey;
|
|
int LibraryToDataKey;
|
|
int Type;
|
|
int EdgeCount;
|
|
int GlassMode;
|
|
int InternalRefFlag;
|
|
int LowerRefFlag;
|
|
int UpperRefFlag;
|
|
int PartSegmentIndex;
|
|
int PartModeFlag;
|
|
int SamplingMode;
|
|
int AveragingMode;
|
|
int AveragingPeriod;
|
|
int GoodScans;
|
|
int EnterDelayMode;
|
|
int EnterDelayPeriod;
|
|
char FormatString[34];
|
|
int PolledFlag;
|
|
} FeatureMeasurement_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int FeatureToDataKey;
|
|
int LibraryToDataKey;
|
|
int LineOrder;
|
|
char ExpressionText[50];
|
|
} FeatureExpressions_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int FeatureToDataKey;
|
|
int LibraryToDataKey;
|
|
int FixtureID;
|
|
int DisableMotorAfterMove;
|
|
int IDODWALLComputeWall;
|
|
int MeasurementMode;
|
|
int UsageMode;
|
|
int AutomaticShankDiamFlag;
|
|
double Speed;
|
|
int StepMode;
|
|
int ReturnPosition;
|
|
int NumberOfMeasurementPositions;
|
|
double TotalDistance;
|
|
double StartPosition;
|
|
double ShankDiameter;
|
|
} FeatureFixture_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int ScannerJogID;
|
|
double mOffset;
|
|
double bOffset;
|
|
double LowSize;
|
|
double HighSize;
|
|
} GlobalScannerJog_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
char LanguageName[20];
|
|
char LanguagePrefix[5];
|
|
char Password[8];
|
|
int PowerUpLocked;
|
|
int AllowNominalChanges;
|
|
int AllowRemastering;
|
|
int AllowLibraryChanges;
|
|
int AdvancedScreenOperation;
|
|
int AutoScrollEnable;
|
|
int AudibleAlarm;
|
|
int FlipScreen180;
|
|
int ScannerDoubleDiff;
|
|
int LatchScanErrors;
|
|
int IgnoreScanErrors;
|
|
char IPAddress[20];
|
|
int ButtonsDefined;
|
|
int ButtonID_1;
|
|
int ButtonID_2;
|
|
int ButtonID_3;
|
|
} GlobalUser_str ;
|
|
|
|
typedef struct {
|
|
Header header;
|
|
int LibraryID;
|
|
char LibraryName[16];
|
|
double UserDualPointMasterSize1;
|
|
double UserDualPointMasterSize2;
|
|
double AlarmDuration;
|
|
int AlarmEnable;
|
|
int SQCBatchSize;
|
|
int SQCBatchClearAtEndOfBatch;
|
|
int SQCBatchPrintAtEndOfBatch;
|
|
int FeatureCount;
|
|
int SerialDOFAutoSendFlag;
|
|
int SerialDOFAutoSendDelay;
|
|
int SerialDOFDateTimeFlag;
|
|
int SerialDOFLabelFlag;
|
|
int SerialDOFHeaderType;
|
|
int SerialDOFRequestorType;
|
|
char SerialDOFRequestorString[5];
|
|
int SerialDOFSeparatorType;
|
|
char SerialDOFSeparatorString[5];
|
|
int SerialDOFTerminatorType;
|
|
char SerialDOFTerminatorString[5];
|
|
int SerialDOFDecimalFlag;
|
|
int SerialDOFSignFlag;
|
|
double LegacySlideCounterPerInch;
|
|
int ReportSelected1;
|
|
int ReportSelected2;
|
|
int ReportSelected3;
|
|
int ReportSelected4;
|
|
char ReportUserTitle[33];
|
|
int ReportPrinterPort;
|
|
int ReportDisableHeaderAndFooter;
|
|
int ReportDisableFormFeed;
|
|
int URRUnits;
|
|
int URRResolution;
|
|
int URRRounding;
|
|
} Library_str ;
|
|
|
|
typedef union {
|
|
Header header;
|
|
DebugText debugMsg;
|
|
Library_str library;
|
|
GlobalFixture_str globalFixture;
|
|
GlobalUser_str globalUser;
|
|
GlobalScannerJog_str globalScannerJog;
|
|
FeatureFixture_str featureFixture;
|
|
FeatureExpressions_str featureExpressions;
|
|
FeatureMeasurement_str featureMeasurement;
|
|
FeatureSegmentList_str featureSegmentList;
|
|
FeatureDataSource_str featureDataSource;
|
|
FeatureData_str featureData;
|
|
Feature_str feature;
|
|
GlobalFactory_str globalFactory;
|
|
GlobalDigitalInputs_str globalDigitalInputs;
|
|
GlobalDigitalOutputs_str globalDigitalOutputs;
|
|
GlobalSerialPort_str globalSerialPort;
|
|
} allTypes;
|
|
|
|
allTypes messageA2D; // message data between DSP and ARM
|
|
|
|
using namespace MityDSP;
|
|
|
|
// Forward declarations
|
|
void init();
|
|
void debugPrint(char *buffer);
|
|
int handleInboundMessage(void *apBuffer, uint32_t anLength, void *apUserArg) ;
|
|
int handleInboundMessageBM(void *apBuffer, uint32_t anLength, void *apUserArg) ;
|
|
|
|
// Object for sending debug messages (these are received and printed to stdout by tcDspApp)
|
|
tcCL_IPCOutbound* gpDebug;
|
|
// Object for sending GPPMSGQ1 messages that the ARM will receive
|
|
tcCL_IPCOutbound* gpOutbound;
|
|
// Object for receiving DSPMSGQ0 messages that the DSP will receive
|
|
tcCL_IPCInbound* gpInbound;
|
|
// semaphore for waiting on messages
|
|
SEM_Handle msgRecvd;
|
|
|
|
#include "core/DspSerial.h"
|
|
#include "core/DspFpgaSerial.h"
|
|
#define RS232_SERIAL_BASE 0x66000080
|
|
|
|
|
|
/* *********************
|
|
void trySerialPort() {
|
|
int bytes, rv;
|
|
unsigned int my_base_addr = RS232_SERIAL_BASE; // was 0xE000001C;
|
|
unsigned int my_vector = 6;
|
|
char input[32], output[32];
|
|
tcDspFpgaSerial *my_port;
|
|
|
|
// create a serial interface
|
|
my_port = new tcDspFpgaSerial((void *)my_base_addr, my_vector,
|
|
38400, 8, 1, tcDspFpgaSerial::gnUART_NOPARITY);
|
|
// start using the port
|
|
my_port->enable(true);
|
|
|
|
// send something...
|
|
sprintf(output, "Testing..1..2..3..");
|
|
bytes = strlen(output);
|
|
rv = my_port->put((void *)output, bytes);
|
|
if (rv != bytes)
|
|
{
|
|
printf("Failed, only sent %1d of %1d bytes\n", rv, bytes);
|
|
}
|
|
|
|
// receive something...
|
|
bytes = sizeof(input);
|
|
rv = my_port->get((void *)input, bytes);
|
|
printf("Received %1d bytes of data\n", rv);
|
|
|
|
} ****************** */
|
|
extern "C" {
|
|
typedef unsigned int u_8 ;
|
|
MityDSP::tcDspFpgaSerial *Com1;
|
|
MityDSP::tcDspSerial *Com2;
|
|
bool Com1_initialized=false;
|
|
bool Com2_initialized=false;
|
|
|
|
typedef struct serialPort_str {
|
|
MityDSP::tcSerial *Com;
|
|
bool initialized;
|
|
void (*rx_func)(u_8 c, u_8 stat);
|
|
} serialPort;
|
|
|
|
void (*rx_func1)(u_8 c, u_8 stat) = NULL;
|
|
void (*rx_func2)(u_8 c, u_8 stat) = NULL;
|
|
extern "C" int StartMonitorTask1(void);
|
|
extern "C" int StartMonitorTask2(void);
|
|
}
|
|
|
|
serialPort spCom[2];
|
|
|
|
char gBuffer[200];
|
|
|
|
#define Sec2tick(x) (1000*x)
|
|
#define GGE_PRIO 9
|
|
|
|
void ser1_task() {
|
|
int count=0;
|
|
int idx=0;
|
|
static char buf[64];
|
|
|
|
while (!Com1_initialized)
|
|
TSK_sleep(Sec2tick(1));
|
|
|
|
while (1) {
|
|
//if (count == 0) {
|
|
count = strlen(gBuffer); //sprintf(buf,"%s %d\n", gBuffer, idx++);
|
|
int j=0, k=0;
|
|
for (int i=0; i < count; i++){
|
|
if ((int)gBuffer[i] < 32) {
|
|
k=sprintf(&buf[j], "*%2x!", (unsigned char)gBuffer[i]);
|
|
j = j+k;
|
|
} else {
|
|
buf[j] = gBuffer[i];
|
|
j++;
|
|
}
|
|
}
|
|
buf[j]=0;
|
|
count = j;
|
|
//}
|
|
Com1->put(buf, count, 0, 0);
|
|
TSK_sleep(1250);
|
|
/*count = Com1->get(buf, 60, 1000);
|
|
if (count && Com1_initialized && (rx_func1 != NULL)) {
|
|
idx = 0;
|
|
while(idx < count)
|
|
rx_func1(buf[idx++],0);
|
|
} else {
|
|
TSK_sleep(5);
|
|
}*/
|
|
}
|
|
}
|
|
|
|
extern "C" int StartMonitorTask1(void)
|
|
{
|
|
TSK_Handle task;
|
|
TSK_Attrs attrs;
|
|
|
|
attrs = TSK_ATTRS;
|
|
attrs.priority = GGE_PRIO;
|
|
attrs.name = "ser1_task";
|
|
task = TSK_create((Fxn)ser1_task, &attrs);
|
|
if(task)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
void ser2_task() {
|
|
int count;
|
|
int idx=0;
|
|
static int flipper;
|
|
static char buf[64];
|
|
char workingBuffer[100]; // just some junk
|
|
|
|
while (!Com2_initialized)
|
|
TSK_sleep(Sec2tick(1));
|
|
|
|
while (1) {
|
|
/*count = sprintf(buf, "hello world #2 %d\n", idx++);
|
|
Com2->put(buf, count, 0, 0);
|
|
TSK_sleep(1250);*/
|
|
/**/
|
|
count = Com2->get(buf, 64, 500);
|
|
if (count && Com2_initialized && Com1_initialized ) {
|
|
// copy the data to a global buffer and...
|
|
sprintf(gBuffer, "%s", buf);
|
|
unsigned char command = gBuffer[0];
|
|
if (command == 208 && gBuffer[1] == '0' && gBuffer[2] == '2') { // was a byte request..for 02
|
|
// send back some sort of string
|
|
flipper++;
|
|
count = sprintf(workingBuffer, "%c02%02d",0xe0, flipper);
|
|
if (flipper > 5) flipper = 0;
|
|
sprintf(gBuffer, "%s!!!!", workingBuffer);
|
|
Com2->put(workingBuffer,count,0,0);
|
|
} else {
|
|
command = command + 0x10;
|
|
count = sprintf(workingBuffer, "%c%c%c%02d",command, gBuffer[1], gBuffer[2], flipper);
|
|
Com2->put(workingBuffer,count,0,0);
|
|
}
|
|
//} else {
|
|
gBuffer[count] = NULL;
|
|
} else if (count == 0) {
|
|
sprintf(gBuffer, "empty string %d ", idx++);
|
|
}
|
|
if (count && Com2_initialized && (rx_func2 != NULL)) {
|
|
idx = 0;
|
|
while(idx < count)
|
|
rx_func2(buf[idx++],0);
|
|
} else {
|
|
TSK_sleep(5);
|
|
}
|
|
/* */
|
|
}
|
|
}
|
|
|
|
extern "C" int StartMonitorTask2(void)
|
|
{
|
|
TSK_Handle task;
|
|
TSK_Attrs attrs;
|
|
|
|
attrs = TSK_ATTRS;
|
|
attrs.priority = GGE_PRIO;
|
|
attrs.name = "ser1_task";
|
|
task = TSK_create((Fxn)ser2_task, &attrs);
|
|
if(task)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// This routine actually creates the comm port. It is not to be called
|
|
// directly by users.
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
extern "C" void InitSerPort(serialPort *xPort, int style, int baud, u_8 dbits, u_8 parity,
|
|
u_8 sbits, u_8 hnd_shk,
|
|
void (*rx_func)(u_8 c, u_8 stat))
|
|
{
|
|
// PORT tmp;
|
|
|
|
MityDSP::tcDspSerial::tsConfig Cfg;
|
|
|
|
int DBitsCfg,SbitsCfg,PrtyCfg;
|
|
|
|
DBitsCfg = dbits;
|
|
|
|
switch(parity)
|
|
{
|
|
case 'e':
|
|
case 'E':
|
|
PrtyCfg = MityDSP::tcDspFpgaSerial::gnUART_EVENPARITY;
|
|
Cfg.parity = MityDSP::tcDspSerial::tsConfig::even;
|
|
break;
|
|
case 'o':
|
|
case 'O':
|
|
PrtyCfg = MityDSP::tcDspFpgaSerial::gnUART_ODDPARITY;
|
|
Cfg.parity = MityDSP::tcDspSerial::tsConfig::odd;
|
|
break;
|
|
case 'n':
|
|
case 'N':
|
|
PrtyCfg = MityDSP::tcDspFpgaSerial::gnUART_NOPARITY;
|
|
Cfg.parity = MityDSP::tcDspSerial::tsConfig::none;
|
|
|
|
break;
|
|
}
|
|
|
|
SbitsCfg = sbits;
|
|
|
|
if(style == 1)
|
|
{
|
|
xPort->Com = new MityDSP::tcDspFpgaSerial((void *)RS232_SERIAL_BASE,
|
|
baud,
|
|
DBitsCfg,
|
|
SbitsCfg,
|
|
PrtyCfg,
|
|
false);
|
|
|
|
xPort->rx_func = rx_func;
|
|
}
|
|
else
|
|
{
|
|
xPort->Com = MityDSP::tcDspSerial::GetInstance(MityDSP::tcDspSerial::UART0);
|
|
Cfg.baud = baud;
|
|
Cfg.databits = DBitsCfg;
|
|
Cfg.stopbits = SbitsCfg;
|
|
Cfg.hw_flowcontrol = false;
|
|
Com2->configure(&Cfg);
|
|
|
|
xPort->rx_func = rx_func;
|
|
StartMonitorTask2();
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// This is the main initialization call to create the comm ports. It should
|
|
// be called before interrupts are enabled
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
extern "C" void InitSerPortX(serialPort *xPort, int style, int baud)
|
|
{
|
|
xPort->Com = 0;
|
|
xPort->initialized = false;
|
|
InitSerPort(xPort, style, baud, 8, 'n', 1, 0, 0);
|
|
xPort->initialized = true;
|
|
}
|
|
|
|
|
|
|
|
extern "C" void InitSerPortndc(u_8 port, u_8 io, int baud, u_8 dbits, u_8 parity,
|
|
u_8 sbits, u_8 hnd_shk,
|
|
void (*rx_func)(u_8 c, u_8 stat))
|
|
{
|
|
// PORT tmp;
|
|
|
|
MityDSP::tcDspSerial::tsConfig Cfg;
|
|
|
|
int DBitsCfg,SbitsCfg,PrtyCfg;
|
|
|
|
DBitsCfg = dbits;
|
|
|
|
switch(parity)
|
|
{
|
|
case 'e':
|
|
case 'E':
|
|
PrtyCfg = MityDSP::tcDspFpgaSerial::gnUART_EVENPARITY;
|
|
Cfg.parity = MityDSP::tcDspSerial::tsConfig::even;
|
|
break;
|
|
case 'o':
|
|
case 'O':
|
|
PrtyCfg = MityDSP::tcDspFpgaSerial::gnUART_ODDPARITY;
|
|
Cfg.parity = MityDSP::tcDspSerial::tsConfig::odd;
|
|
break;
|
|
case 'n':
|
|
case 'N':
|
|
PrtyCfg = MityDSP::tcDspFpgaSerial::gnUART_NOPARITY;
|
|
Cfg.parity = MityDSP::tcDspSerial::tsConfig::none;
|
|
|
|
break;
|
|
}
|
|
|
|
SbitsCfg = sbits;
|
|
|
|
if(port == 1)
|
|
{
|
|
Com1 = new MityDSP::tcDspFpgaSerial((void *)RS232_SERIAL_BASE,
|
|
baud,
|
|
DBitsCfg,
|
|
SbitsCfg,
|
|
PrtyCfg,
|
|
false);
|
|
|
|
rx_func1 = rx_func;
|
|
StartMonitorTask1();
|
|
}
|
|
else
|
|
{
|
|
Com2 = MityDSP::tcDspSerial::GetInstance(MityDSP::tcDspSerial::UART0);
|
|
Cfg.baud = baud;
|
|
Cfg.databits = DBitsCfg;
|
|
Cfg.stopbits = SbitsCfg;
|
|
Cfg.hw_flowcontrol = false;
|
|
Com2->configure(&Cfg);
|
|
|
|
rx_func2 = rx_func;
|
|
StartMonitorTask2();
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// This is the main initialization call to create the comm ports. It should
|
|
// be called before interrupts are enabled
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
extern "C" void InitSerPorts(int baud1, int baud2)
|
|
{
|
|
Com1 = 0;
|
|
Com2 = 0;
|
|
|
|
Com1_initialized = false;
|
|
Com2_initialized = false;
|
|
InitSerPortndc(1, 0, baud1, 8, 'n', 1, 0, 0);
|
|
InitSerPortndc(2, 0, baud2, 8, 'n', 1, 0, 0);
|
|
Com1_initialized = true;
|
|
Com2_initialized = true;
|
|
|
|
}
|
|
|
|
/**
|
|
* Main routine.
|
|
*/
|
|
int main(int argc, char* argv[])
|
|
{
|
|
|
|
int bWaitForMe = argc;
|
|
int iCounter = 0;
|
|
int iCounter2 = 0;
|
|
while (bWaitForMe) {
|
|
iCounter++; // wait for the debugger here....
|
|
if (iCounter > 10000) {
|
|
iCounter2++;
|
|
iCounter = 0;
|
|
}
|
|
}
|
|
|
|
// initialize the DSPLink system
|
|
tcCL_IPCInit::GetInstance();
|
|
|
|
msgRecvd = SEM_create(0, NULL);
|
|
|
|
// Launch an initialization task
|
|
TSK_Attrs* lpAttrs = new TSK_Attrs;
|
|
*lpAttrs = TSK_ATTRS;
|
|
lpAttrs->name = "Initialize";
|
|
lpAttrs->stacksize = 8192*2;
|
|
lpAttrs->priority = 5;
|
|
TSK_create((Fxn)init,lpAttrs);
|
|
|
|
// according to loc_init.c:loc_init it appears the first port is the 232 and the second one is the 422
|
|
// InitSerPorts(baud232, baud422);
|
|
// This will create a task for each serial port.
|
|
/*
|
|
* InitSerPortX(&spCom[0], 1, 38400); //. TBD use enum for style of serial port either FPGA or plain DSP
|
|
StartMonitorTask1();
|
|
InitSerPortX(&spCom[1], 2, 38400);
|
|
StartMonitorTask2();*/
|
|
|
|
// we're done exit and leave the tasks going...
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Initialize the inbound and outbound IPC objects.
|
|
*
|
|
* \return None.
|
|
*/
|
|
void init()
|
|
{
|
|
// Message to ARM core.
|
|
char lpReturnMessage[] = "DSP Initialization finished.";
|
|
// Buffer for return message
|
|
char* lpMessageBuffer = NULL;
|
|
|
|
// Create the outbound debug link
|
|
gpDebug = new tcCL_IPCOutbound("debug");
|
|
|
|
// Create the inbound link for messages to the DSP
|
|
gpInbound = new tcCL_IPCInbound();
|
|
|
|
gpInbound->Open("DSPMSGQ0", 8);
|
|
|
|
// Create the outbound controller for sending messages to the ARM
|
|
gpOutbound = new tcCL_IPCOutbound("GPPMSGQ1");
|
|
|
|
if (NULL != gpInbound)
|
|
{
|
|
// Register a callback function to handle messages from the ARM
|
|
gpInbound->RegisterCallback(handleInboundMessageBM, (void*)NULL);
|
|
}
|
|
|
|
// Now that initialization is complete, let the ARM know with a message
|
|
|
|
// Obtain a dsplink buffer for the return message
|
|
lpMessageBuffer = (char*)gpOutbound->GetBuffer(sizeof(messageA2D) + 1);
|
|
|
|
// Make sure we received a valid buffer
|
|
if (NULL != lpMessageBuffer)
|
|
{
|
|
|
|
// create a debug message for the first one...
|
|
sprintf(messageA2D.debugMsg.textMessage, "%s", lpReturnMessage);
|
|
messageA2D.debugMsg.header.type = eDebugText;
|
|
// Copy our message to the buffer
|
|
memcpy(lpMessageBuffer, &messageA2D, sizeof(messageA2D));
|
|
|
|
// Send first message to the ARM
|
|
gpOutbound->SendMessage(lpMessageBuffer);
|
|
}
|
|
|
|
// now wait on msgs from the ARM
|
|
bool keepGoing=true;
|
|
while (keepGoing) {
|
|
SEM_pend(msgRecvd, SYS_FOREVER);
|
|
// msg rcv'd... now what...
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Callback function that handles messages from the ARM.
|
|
*
|
|
* \param apBuffer Pointer to message buffer.
|
|
* \param anLength Length of message.
|
|
* \param apUserArg Pointer to user defined argument
|
|
*
|
|
* \return 0 on sucess.
|
|
*/
|
|
int handleInboundMessage(void* apBuffer, uint32_t anLength, void* apUserArg)
|
|
{
|
|
int retval = 0;
|
|
// The return message to the ARM
|
|
char lpReturnMessage[] = "Hello World. DSP Received Message = \'";
|
|
// Buffer for return message
|
|
char* lpMessageBuffer = NULL;
|
|
|
|
// Obtain a dsplink buffer for the return message
|
|
lpMessageBuffer = (char*)gpOutbound->GetBuffer(strlen(lpReturnMessage) + strlen((const char*)apBuffer) + 2);
|
|
|
|
// Make sure we received a valid buffer
|
|
if (NULL != lpMessageBuffer)
|
|
{
|
|
// Copy our message to the buffer
|
|
strcpy(lpMessageBuffer, lpReturnMessage);
|
|
// Append the received message to the buffer
|
|
strcpy((char*)&lpMessageBuffer[strlen(lpReturnMessage)], (const char *)apBuffer);
|
|
// Null terminate the string
|
|
lpMessageBuffer[strlen(lpMessageBuffer)+1] = 0;
|
|
// Append the closing quotation
|
|
lpMessageBuffer[strlen(lpMessageBuffer)] = '\'';
|
|
|
|
// Send the message back to the ARM
|
|
retval = gpOutbound->SendMessage(lpMessageBuffer);
|
|
}
|
|
else
|
|
{
|
|
retval = -1;
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
/**
|
|
* Callback function that handles messages from the ARM.
|
|
*
|
|
* \param apBuffer Pointer to message buffer.
|
|
* \param anLength Length of message.
|
|
* \param apUserArg Pointer to user defined argument
|
|
*
|
|
* \return 0 on sucess.
|
|
*/
|
|
int handleInboundMessageBM(void* apBuffer, uint32_t anLength, void* apUserArg)
|
|
{
|
|
int retval = 0;
|
|
// Buffer for return message
|
|
char* lpMessageBuffer = NULL;
|
|
|
|
// Obtain a dsplink buffer for the return message
|
|
lpMessageBuffer = (char*)gpOutbound->GetBuffer(sizeof(messageA2D));
|
|
|
|
// Make sure we received a valid buffer
|
|
if (NULL != lpMessageBuffer)
|
|
{
|
|
// Process message from ARM here...
|
|
// extract msg type from message
|
|
memcpy(&messageA2D, apBuffer, anLength);
|
|
switch (messageA2D.header.type) {
|
|
case eLibrary:
|
|
// for fun just increment some values and send back to ARM
|
|
messageA2D.library.FeatureCount++;
|
|
messageA2D.library.SQCBatchSize++;
|
|
messageA2D.library.header.command = eWriteToARM;
|
|
break;
|
|
};
|
|
// Copy our message to the buffer
|
|
memcpy(lpMessageBuffer, &messageA2D, sizeof(messageA2D));
|
|
|
|
// Send the message back to the ARM
|
|
retval = gpOutbound->SendMessage(lpMessageBuffer);
|
|
SEM_post(msgRecvd); // trigger that we have recv'd and responded to the ARM Message.
|
|
gpOutbound->ReturnBuffer(apBuffer);
|
|
}
|
|
else
|
|
{
|
|
retval = -1;
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
/**
|
|
* Function for sending debug messages to the ARM.
|
|
*
|
|
* \param buffer Null terminated string to be printed.
|
|
*
|
|
* \return None.
|
|
*/
|
|
void debugPrint(char* pMsg)
|
|
{
|
|
// The length of the message to be sent
|
|
int len = strlen(pMsg);
|
|
// Pointer to dsplink buffer where to write the message
|
|
char* pBuffer;
|
|
|
|
// Make sure the debug IPC outbound object has been initialized
|
|
if (gpDebug == NULL)
|
|
return;
|
|
|
|
// Get a buffer for the message
|
|
pBuffer = (char *)gpDebug->GetBuffer(len+1);
|
|
|
|
// Check that the buffer is valid
|
|
if (pBuffer)
|
|
{
|
|
// Copy the message to the buffer
|
|
strcpy(pBuffer, pMsg);
|
|
// Send the message
|
|
gpDebug->SendMessage(pBuffer);
|
|
}
|
|
}
|
|
|