summaryrefslogtreecommitdiffstats
path: root/servers/logic_analyzer_server_lin/src
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2014-02-27 01:00:35 -0600
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2014-02-27 01:00:35 -0600
commit6ed57d34cab70cfcada21d3b77014f2e834a0cf9 (patch)
tree5ea8f7750945b29557ff34ae10147bc61f21fbf3 /servers/logic_analyzer_server_lin/src
parent1fbfe130665dc4bce56869ed9158531137406129 (diff)
downloadulab-6ed57d34cab70cfcada21d3b77014f2e834a0cf9.tar.gz
ulab-6ed57d34cab70cfcada21d3b77014f2e834a0cf9.zip
First pass of logic analyzer functionality (GPMC interface and server)
Diffstat (limited to 'servers/logic_analyzer_server_lin/src')
-rw-r--r--servers/logic_analyzer_server_lin/src/logic_analyzer_server.cpp140
1 files changed, 129 insertions, 11 deletions
diff --git a/servers/logic_analyzer_server_lin/src/logic_analyzer_server.cpp b/servers/logic_analyzer_server_lin/src/logic_analyzer_server.cpp
index a0f764c..222d685 100644
--- a/servers/logic_analyzer_server_lin/src/logic_analyzer_server.cpp
+++ b/servers/logic_analyzer_server_lin/src/logic_analyzer_server.cpp
@@ -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("<", "&lt;");
+ name.replace(">", "&gt;");
+
+ 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");