|
|
|
@ -60,6 +60,8 @@ struct exit_exception {
|
|
|
|
|
exit_exception(int c):c(c) { }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void gpmc_clear_channel_traces();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
The LogicAnalyzerSocket class provides a socket that is connected with a client.
|
|
|
|
|
For every client that connects to the server, the server creates a new
|
|
|
|
@ -166,7 +168,6 @@ void LogicAnalyzerSocket::finishKerberosHandshake() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int LogicAnalyzerSocket::setupGPMC() {
|
|
|
|
|
int i;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
ret = setup_gpmc_bbb();
|
|
|
|
@ -175,10 +176,11 @@ int LogicAnalyzerSocket::setupGPMC() {
|
|
|
|
|
unsigned char model = read_gpmc(0x00);
|
|
|
|
|
unsigned char version = read_gpmc(0x01);
|
|
|
|
|
if ((model != 0x42) || (version < 1)) {
|
|
|
|
|
printf("A compatible uLab hardware debug interface was not detected! Please verify your configuration.\n");
|
|
|
|
|
printf("A compatible uLab hardware debug interface was not detected! Please verify your configuration.\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
printf("[DEBUG] Detected a compatible uLab hardware debug interface (model number 0x%02x, firmware version 0x%02x)\n", model, version);
|
|
|
|
|
printf("[DEBUG] Detected a compatible uLab hardware debug interface (model number 0x%02x, firmware version 0x%02x)\n", model, version);
|
|
|
|
|
gpmc_clear_channel_traces();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
@ -192,16 +194,65 @@ int gpmc_sample_count() {
|
|
|
|
|
return 2048;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double gpmc_timestep() {
|
|
|
|
|
return ((read_gpmc_uint16_t(0x0e/2))*1e-9);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int gpmc_get_running() {
|
|
|
|
|
return read_gpmc(0x0d) & 0x1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void gpmc_set_running(bool running) {
|
|
|
|
|
if (running) {
|
|
|
|
|
write_gpmc(0x0d, read_gpmc(0x0d) | 0x1);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
write_gpmc(0x0d, read_gpmc(0x0d) & ~0x1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int gpmc_get_channel_name(TQString &name, unsigned int traceNumber) {
|
|
|
|
|
int offset;
|
|
|
|
|
char rawName[32];
|
|
|
|
|
memcpy_from_gpmc(rawName, 0x800 + (traceNumber * 32), 32);
|
|
|
|
|
for (offset=0; offset<32; offset++) {
|
|
|
|
|
if (rawName[offset] != 0) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
name = TQString(rawName + offset);
|
|
|
|
|
name.replace("<", "<");
|
|
|
|
|
name.replace(">", ">");
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void gpmc_clear_channel_traces() {
|
|
|
|
|
unsigned int i;
|
|
|
|
|
int traceLength;
|
|
|
|
|
|
|
|
|
|
traceLength = gpmc_sample_count();
|
|
|
|
|
for (i=0; i<traceLength; i++) {
|
|
|
|
|
write_gpmc_uint64_t(0x800 + i, 0x0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int gpmc_get_channel_traces(TQDoubleArray& traceData, TQDoubleArray& positionData, unsigned int traceNumber) {
|
|
|
|
|
unsigned int i;
|
|
|
|
|
int traceLength;
|
|
|
|
|
double timestep;
|
|
|
|
|
double position;
|
|
|
|
|
|
|
|
|
|
traceLength = gpmc_sample_count();
|
|
|
|
|
timestep = gpmc_timestep();
|
|
|
|
|
traceData.resize(traceLength);
|
|
|
|
|
positionData.resize(traceLength);
|
|
|
|
|
position = 0;
|
|
|
|
|
for (i=0; i<traceLength; i++) {
|
|
|
|
|
traceData[i] = ((read_gpmc_llong(0x800 + i) & (1 << traceNumber)) >> traceNumber);
|
|
|
|
|
positionData[i] = i;
|
|
|
|
|
traceData[i] = ((read_gpmc_uint64_t(0x800 + i) & ((uint64_t)1 << traceNumber)) >> traceNumber);
|
|
|
|
|
positionData[i] = position;
|
|
|
|
|
position = position + timestep;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return traceLength;
|
|
|
|
@ -221,7 +272,16 @@ void LogicAnalyzerSocket::commandLoop() {
|
|
|
|
|
ds >> instrumentCommand;
|
|
|
|
|
|
|
|
|
|
if (instrumentCommand != "") {
|
|
|
|
|
if ((instrumentCommand == "GETLOGICTRACES")) { // Want all channel traces
|
|
|
|
|
if ((instrumentCommand == "LOGICANALYZER")) { // requesting logic analyzer access
|
|
|
|
|
ds << TQString("ACK");
|
|
|
|
|
writeEndOfFrame();
|
|
|
|
|
}
|
|
|
|
|
else if ((instrumentCommand == "RESET")) { // requesting reset
|
|
|
|
|
// Nothing to reset...
|
|
|
|
|
ds << TQString("ACK");
|
|
|
|
|
writeEndOfFrame();
|
|
|
|
|
}
|
|
|
|
|
else if ((instrumentCommand == "GETLOGICTRACES")) { // Want all channel traces
|
|
|
|
|
ds << TQString("ACK");
|
|
|
|
|
int i;
|
|
|
|
|
int channels = gpmc_channel_count();
|
|
|
|
@ -234,11 +294,12 @@ void LogicAnalyzerSocket::commandLoop() {
|
|
|
|
|
}
|
|
|
|
|
writeEndOfFrame();
|
|
|
|
|
}
|
|
|
|
|
else if (instrumentCommand == "GETTRACESAMPLECOUNT") { // Want to get number of samples in a trace
|
|
|
|
|
TQ_INT32 samples = gpmc_sample_count();
|
|
|
|
|
if (samples > 0) {
|
|
|
|
|
else if (instrumentCommand == "GETHORIZONTALDIVCOUNT") { // Want the number of horizontal divisions available
|
|
|
|
|
// One horizontal division per sample
|
|
|
|
|
TQ_INT16 divisions = gpmc_sample_count();
|
|
|
|
|
if (divisions >= 0) {
|
|
|
|
|
ds << TQString("ACK");
|
|
|
|
|
ds << samples;
|
|
|
|
|
ds << divisions;
|
|
|
|
|
writeEndOfFrame();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
@ -246,7 +307,17 @@ void LogicAnalyzerSocket::commandLoop() {
|
|
|
|
|
writeEndOfFrame();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (instrumentCommand == "GETNUMBEROFCHANNELS") { // Want the number of channels available
|
|
|
|
|
else if (instrumentCommand == "GETTRACESAMPLECOUNT") { // Want to get number of samples in a trace
|
|
|
|
|
int i;
|
|
|
|
|
int channels = gpmc_channel_count();
|
|
|
|
|
TQ_INT32 samples = gpmc_sample_count();
|
|
|
|
|
ds << TQString("ACK");
|
|
|
|
|
for (i=0; i<channels; i++) {
|
|
|
|
|
ds << samples;
|
|
|
|
|
}
|
|
|
|
|
writeEndOfFrame();
|
|
|
|
|
}
|
|
|
|
|
else if (instrumentCommand == "GETNUMBEROFCHANNELS") { // Want the number of channels available
|
|
|
|
|
TQ_INT32 channels = gpmc_channel_count();
|
|
|
|
|
if (channels > 0) {
|
|
|
|
|
ds << TQString("ACK");
|
|
|
|
@ -258,6 +329,53 @@ void LogicAnalyzerSocket::commandLoop() {
|
|
|
|
|
writeEndOfFrame();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (instrumentCommand == "GETCHANNELNAME") { // Want to get channel name
|
|
|
|
|
TQString name;
|
|
|
|
|
int i;
|
|
|
|
|
int channels = gpmc_channel_count();
|
|
|
|
|
ds << TQString("ACK");
|
|
|
|
|
for (i=0; i<channels; i++) {
|
|
|
|
|
gpmc_get_channel_name(name, i);
|
|
|
|
|
ds << name;
|
|
|
|
|
}
|
|
|
|
|
writeEndOfFrame();
|
|
|
|
|
}
|
|
|
|
|
else if (instrumentCommand == "GETCHANNELACTIVE") { // Want to get channel activity
|
|
|
|
|
TQ_INT16 state;
|
|
|
|
|
int i;
|
|
|
|
|
int channels = gpmc_channel_count();
|
|
|
|
|
ds << TQString("ACK");
|
|
|
|
|
for (i=0; i<channels; i++) {
|
|
|
|
|
// All channels are always active
|
|
|
|
|
state = 1;
|
|
|
|
|
ds << state;
|
|
|
|
|
}
|
|
|
|
|
writeEndOfFrame();
|
|
|
|
|
}
|
|
|
|
|
else if (instrumentCommand == "GETSECONDSSDIV") { // Want to get seconds per division
|
|
|
|
|
double secondsdiv;
|
|
|
|
|
int i;
|
|
|
|
|
int channels = gpmc_channel_count();
|
|
|
|
|
ds << TQString("ACK");
|
|
|
|
|
for (i=0; i<channels; i++) {
|
|
|
|
|
secondsdiv = gpmc_timestep();
|
|
|
|
|
ds << secondsdiv;
|
|
|
|
|
}
|
|
|
|
|
writeEndOfFrame();
|
|
|
|
|
}
|
|
|
|
|
else if (instrumentCommand == "GETRUNNING") { // Want to get run status
|
|
|
|
|
TQ_INT16 running = gpmc_get_running();
|
|
|
|
|
ds << TQString("ACK");
|
|
|
|
|
ds << running;
|
|
|
|
|
writeEndOfFrame();
|
|
|
|
|
}
|
|
|
|
|
else if (instrumentCommand == "SETRUNNING") { // Want to change run status
|
|
|
|
|
TQ_INT16 value;
|
|
|
|
|
ds >> value;
|
|
|
|
|
gpmc_set_running(value);
|
|
|
|
|
ds << TQString("ACK");
|
|
|
|
|
writeEndOfFrame();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
printf("[WARNING] Received unknown command %s from host %s\n\r", instrumentCommand.ascii(), m_remoteHost.ascii()); fflush(stdout);
|
|
|
|
|
ds << TQString("NCK");
|
|
|
|
|