diff options
| author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2014-02-27 01:00:35 -0600 |
|---|---|---|
| committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2014-02-27 01:00:35 -0600 |
| commit | 6ed57d34cab70cfcada21d3b77014f2e834a0cf9 (patch) | |
| tree | 5ea8f7750945b29557ff34ae10147bc61f21fbf3 /servers/logic_analyzer_server_lin/src | |
| parent | 1fbfe130665dc4bce56869ed9158531137406129 (diff) | |
| download | ulab-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.cpp | 140 |
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("<", "<"); + 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"); |
