]> cvs.zerfleddert.de Git - proxmark3-svn/blobdiff - client/cmddata.c
ADD: started with adding a LF AWID26 write function. not done yet.
[proxmark3-svn] / client / cmddata.c
index aa59edc9257e3601d03e8f3fe4f1dc323ea66ac4..0ba04b794218b068daf347fd3c445c3c135ae504 100644 (file)
@@ -1,15 +1,27 @@
+//-----------------------------------------------------------------------------
+// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// Data and Graph commands
+//-----------------------------------------------------------------------------
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
-#include "proxusb.h"
+#include "proxmark3.h"
 #include "data.h"
 #include "ui.h"
 #include "graph.h"
 #include "cmdparser.h"
 #include "data.h"
 #include "ui.h"
 #include "graph.h"
 #include "cmdparser.h"
+#include "util.h"
 #include "cmdmain.h"
 #include "cmddata.h"
 
 #include "cmdmain.h"
 #include "cmddata.h"
 
+
 static int CmdHelp(const char *Cmd);
 
 int CmdAmp(const char *Cmd)
 static int CmdHelp(const char *Cmd);
 
 int CmdAmp(const char *Cmd)
@@ -63,12 +75,14 @@ int Cmdaskdemod(const char *Cmd)
   int i;
   int c, high = 0, low = 0;
 
   int i;
   int c, high = 0, low = 0;
 
-  // TODO: complain if we do not give 2 arguments here !
-  // (AL - this doesn't make sense! we're only using one argument!!!)
   sscanf(Cmd, "%i", &c);
 
   sscanf(Cmd, "%i", &c);
 
-  /* Detect high and lows and clock */
-  // (AL - clock???)
+  if (c != 0 && c != 1) {
+    PrintAndLog("Invalid argument: %s", Cmd);
+    return 0;
+  }
+  
+  /* Detect high and lows */
   for (i = 0; i < GraphTraceLen; ++i)
   {
     if (GraphBuffer[i] > high)
   for (i = 0; i < GraphTraceLen; ++i)
   {
     if (GraphBuffer[i] > high)
@@ -76,11 +90,7 @@ int Cmdaskdemod(const char *Cmd)
     else if (GraphBuffer[i] < low)
       low = GraphBuffer[i];
   }
     else if (GraphBuffer[i] < low)
       low = GraphBuffer[i];
   }
-  if (c != 0 && c != 1) {
-    PrintAndLog("Invalid argument: %s", Cmd);
-    return 0;
-  }
-
+  
   if (GraphBuffer[0] > 0) {
     GraphBuffer[0] = 1-c;
   } else {
   if (GraphBuffer[0] > 0) {
     GraphBuffer[0] = 1-c;
   } else {
@@ -143,22 +153,19 @@ int CmdAutoCorr(const char *Cmd)
 int CmdBitsamples(const char *Cmd)
 {
   int cnt = 0;
 int CmdBitsamples(const char *Cmd)
 {
   int cnt = 0;
-  int n = 3072;
-
-  for (int i = 0; i < n; i += 12) {
-    UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
-    SendCommand(&c);
-    WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
+  uint8_t got[12288];
+  
+  GetFromBigBuf(got,sizeof(got),0);
+  WaitForResponse(CMD_ACK,NULL);
 
 
-    for (int j = 0; j < 48; j++) {
+    for (int j = 0; j < sizeof(got); j++) {
       for (int k = 0; k < 8; k++) {
       for (int k = 0; k < 8; k++) {
-        if(sample_buf[j] & (1 << (7 - k))) {
+        if(got[j] & (1 << (7 - k))) {
           GraphBuffer[cnt++] = 1;
         } else {
           GraphBuffer[cnt++] = 0;
         }
       }
           GraphBuffer[cnt++] = 1;
         } else {
           GraphBuffer[cnt++] = 0;
         }
       }
-    }
   }
   GraphTraceLen = cnt;
   RepaintGraphWindow();
   }
   GraphTraceLen = cnt;
   RepaintGraphWindow();
@@ -378,53 +385,51 @@ int CmdFSKdemod(const char *Cmd)
 int CmdGrid(const char *Cmd)
 {
   sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY);
 int CmdGrid(const char *Cmd)
 {
   sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY);
+  PlotGridXdefault= PlotGridX;
+  PlotGridYdefault= PlotGridY;
   RepaintGraphWindow();
   return 0;
 }
 
 int CmdHexsamples(const char *Cmd)
 {
   RepaintGraphWindow();
   return 0;
 }
 
 int CmdHexsamples(const char *Cmd)
 {
-  int n;
+  int i, j;
   int requested = 0;
   int offset = 0;
   int requested = 0;
   int offset = 0;
+  char string_buf[25];
+  char* string_ptr = string_buf;
+  uint8_t got[40000];
   sscanf(Cmd, "%i %i", &requested, &offset);
   sscanf(Cmd, "%i %i", &requested, &offset);
-  if (offset % 4 != 0) {
-    PrintAndLog("Offset must be a multiple of 4");
-    return 0;
-  }
-  offset = offset/4;                
-
-  int delivered = 0;
 
 
+  /* if no args send something */
   if (requested == 0) {
   if (requested == 0) {
-    n = 12;
-    requested = 12;
-  } else {
-    n = requested/4;
-  }
-
-  for (int i = offset; i < n+offset; i += 12) {
-    UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
-    SendCommand(&c);
-    WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
-    for (int j = 0; j < 48; j += 8) {
-      PrintAndLog("%02x %02x %02x %02x %02x %02x %02x %02x",
-        sample_buf[j+0],
-        sample_buf[j+1],
-        sample_buf[j+2],
-        sample_buf[j+3],
-        sample_buf[j+4],
-        sample_buf[j+5],
-        sample_buf[j+6],
-        sample_buf[j+7],
-        sample_buf[j+8]
-      );
-      delivered += 8;
-      if (delivered >= requested)
-        break;
+    requested = 8;
+  }
+  if (offset + requested > sizeof(got)) {
+    PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > 40000");
+    return 0;
+  } 
+
+  GetFromBigBuf(got,requested,offset);
+  WaitForResponse(CMD_ACK,NULL);
+
+  i = 0;
+  for (j = 0; j < requested; j++) {
+    i++;
+    string_ptr += sprintf(string_ptr, "%02x ", got[j]);
+    if (i == 8) {
+      *(string_ptr - 1) = '\0';    // remove the trailing space
+      PrintAndLog("%s", string_buf);
+      string_buf[0] = '\0';
+      string_ptr = string_buf;
+      i = 0;
     }
     }
-    if (delivered >= requested)
-      break;
+    if (j == requested - 1 && string_buf[0] != '\0') { // print any remaining bytes
+      *(string_ptr - 1) = '\0';
+      PrintAndLog("%s", string_buf);
+      string_buf[0] = '\0';
+    }  
   }
   return 0;
 }
   }
   return 0;
 }
@@ -452,35 +457,90 @@ int CmdHpf(const char *Cmd)
 
 int CmdSamples(const char *Cmd)
 {
 
 int CmdSamples(const char *Cmd)
 {
-  int cnt = 0;
-  int n;
-
-  n = strtol(Cmd, NULL, 0);
-  if (n == 0) n = 128;
-  if (n > 16000) n = 16000;
-
-  PrintAndLog("Reading %d samples\n", n);
-  for (int i = 0; i < n; i += 12) {
-    UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
-    SendCommand(&c);
-    WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
-    for (int j = 0; j < 48; j++) {
-      GraphBuffer[cnt++] = ((int)sample_buf[j]) - 128;
-    }
-  }
-  PrintAndLog("Done!\n");
-  GraphTraceLen = n*4;
-  RepaintGraphWindow();
+       uint8_t got[36440] = {0x00};
+       
+       int n = strtol(Cmd, NULL, 0);
+       if (n == 0) 
+               n = 16000;
+       if (n > sizeof(got)) 
+               n = sizeof(got);
+  
+       PrintAndLog("Reading %d samples from device memory\n", n);
+       GetFromBigBuf(got,n,3560);
+       WaitForResponse(CMD_ACK,NULL);
+       for (int j = 0; j < n; ++j) {
+               GraphBuffer[j] = ((int)got[j]) - 128;
+       }
+       GraphTraceLen = n;
+       RepaintGraphWindow();
+       return 0;
+}
+int CmdTuneSamples(const char *Cmd)
+{
+       int timeout = 0;
+       printf("\nMeasuring antenna characteristics, please wait...");
+
+       UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING};
+       SendCommand(&c);
+
+       UsbCommand resp;
+       while(!WaitForResponseTimeout(CMD_MEASURED_ANTENNA_TUNING,&resp,1000)) {
+               timeout++;
+               printf(".");
+               if (timeout > 7) {
+                       PrintAndLog("\nNo response from Proxmark. Aborting...");
+                       return 1;
+               }
+       }
+
+       int peakv, peakf;
+       int vLf125, vLf134, vHf;
+       vLf125 = resp.arg[0] & 0xffff;
+       vLf134 = resp.arg[0] >> 16;
+       vHf = resp.arg[1] & 0xffff;;
+       peakf = resp.arg[2] & 0xffff;
+       peakv = resp.arg[2] >> 16;
+       PrintAndLog("");
+       PrintAndLog("# LF antenna: %5.2f V @   125.00 kHz", vLf125/1000.0);
+       PrintAndLog("# LF antenna: %5.2f V @   134.00 kHz", vLf134/1000.0);
+       PrintAndLog("# LF optimal: %5.2f V @%9.2f kHz", peakv/1000.0, 12000.0/(peakf+1));
+       PrintAndLog("# HF antenna: %5.2f V @    13.56 MHz", vHf/1000.0);
+       if (peakv<2000)
+               PrintAndLog("# Your LF antenna is unusable.");
+       else if (peakv<10000)
+               PrintAndLog("# Your LF antenna is marginal.");
+       if (vHf<2000)
+               PrintAndLog("# Your HF antenna is unusable.");
+       else if (vHf<5000)
+               PrintAndLog("# Your HF antenna is marginal.");
+
+       for (int i = 0; i < 256; i++) {
+               GraphBuffer[i] = resp.d.asBytes[i] - 128;
+       }
+  
+       PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n");
+       PrintAndLog("\n");
+       GraphTraceLen = 256;
+       ShowGraphWindow();
+
   return 0;
 }
 
   return 0;
 }
 
+
 int CmdLoad(const char *Cmd)
 {
 int CmdLoad(const char *Cmd)
 {
-  FILE *f = fopen(Cmd, "r");
-  if (!f) {
-    PrintAndLog("couldn't open '%s'", Cmd);
-    return 0;
-  }
+   char filename[FILE_PATH_SIZE] = {0x00};
+   int len = 0;
+
+   len = strlen(Cmd);
+   if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+   memcpy(filename, Cmd, len);
+       
+   FILE *f = fopen(filename, "r");
+   if (!f) {
+     PrintAndLog("couldn't open '%s'", filename);
+     return 0;
+   }
 
   GraphTraceLen = 0;
   char line[80];
 
   GraphTraceLen = 0;
   char line[80];
@@ -524,7 +584,7 @@ int CmdManchesterDemod(const char *Cmd)
   int i, j, invert= 0;
   int bit;
   int clock;
   int i, j, invert= 0;
   int bit;
   int clock;
-  int lastval;
+  int lastval = 0;
   int low = 0;
   int high = 0;
   int hithigh, hitlow, first;
   int low = 0;
   int high = 0;
   int hithigh, hitlow, first;
@@ -538,6 +598,7 @@ int CmdManchesterDemod(const char *Cmd)
   {
     PrintAndLog("Inverting output");
     invert = 1;
   {
     PrintAndLog("Inverting output");
     invert = 1;
+    ++Cmd;
     do
       ++Cmd;
     while(*Cmd == ' '); // in case a 2nd argument was given
     do
       ++Cmd;
     while(*Cmd == ' '); // in case a 2nd argument was given
@@ -550,7 +611,7 @@ int CmdManchesterDemod(const char *Cmd)
 
   /* But it does not work if compiling on WIndows: therefore we just allocate a */
   /* large array */
 
   /* But it does not work if compiling on WIndows: therefore we just allocate a */
   /* large array */
-  int BitStream[MAX_GRAPH_TRACE_LEN];
+  uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0x00};
 
   /* Detect high and lows */
   for (i = 0; i < GraphTraceLen; i++)
 
   /* Detect high and lows */
   for (i = 0; i < GraphTraceLen; i++)
@@ -562,8 +623,7 @@ int CmdManchesterDemod(const char *Cmd)
   }
 
   /* Get our clock */
   }
 
   /* Get our clock */
-  clock = GetClock(Cmd, high, 1);
-
+  clock = GetClock(Cmd, high, 1); 
   int tolerance = clock/4;
 
   /* Detect first transition */
   int tolerance = clock/4;
 
   /* Detect first transition */
@@ -581,14 +641,15 @@ int CmdManchesterDemod(const char *Cmd)
       break;
     }
   }
       break;
     }
   }
-
+  
   /* If we're not working with 1/0s, demod based off clock */
   if (high != 1)
   {
   /* If we're not working with 1/0s, demod based off clock */
   if (high != 1)
   {
+       PrintAndLog("Entering path A"); 
     bit = 0; /* We assume the 1st bit is zero, it may not be
               * the case: this routine (I think) has an init problem.
               * Ed.
     bit = 0; /* We assume the 1st bit is zero, it may not be
               * the case: this routine (I think) has an init problem.
               * Ed.
-              */
+                         */
     for (; i < (int)(GraphTraceLen / clock); i++)
     {
       hithigh = 0;
     for (; i < (int)(GraphTraceLen / clock); i++)
     {
       hithigh = 0;
@@ -668,7 +729,9 @@ int CmdManchesterDemod(const char *Cmd)
     // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream
     // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful
     // to stop output at the final bitidx2 value, not bitidx
     // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream
     // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful
     // to stop output at the final bitidx2 value, not bitidx
-    for (i = 0; i < bitidx; i += 2) {
+       
+       //http://www.proxmark.org/forum/viewtopic.php?id=403
+    for (i = 1; i < bitidx; i += 2) {
       if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) {
         BitStream[bit2idx++] = 1 ^ invert;
     } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) {
       if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) {
         BitStream[bit2idx++] = 1 ^ invert;
     } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) {
@@ -677,7 +740,7 @@ int CmdManchesterDemod(const char *Cmd)
       // We cannot end up in this state, this means we are unsynchronized,
       // move up 1 bit:
       i++;
       // We cannot end up in this state, this means we are unsynchronized,
       // move up 1 bit:
       i++;
-        warnings++;
+      warnings++;
       PrintAndLog("Unsynchronized, resync...");
       PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)");
 
       PrintAndLog("Unsynchronized, resync...");
       PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)");
 
@@ -711,28 +774,29 @@ int CmdManchesterDemod(const char *Cmd)
       BitStream[i+14],
       BitStream[i+15]);
   }
       BitStream[i+14],
       BitStream[i+15]);
   }
-  return 0;
+  return bit2idx;
 }
 
 /* Modulate our data into manchester */
 int CmdManchesterMod(const char *Cmd)
 {
   int i, j;
 }
 
 /* Modulate our data into manchester */
 int CmdManchesterMod(const char *Cmd)
 {
   int i, j;
-  int clock;
   int bit, lastbit, wave;
   int bit, lastbit, wave;
-
-  /* Get our clock */
-  clock = GetClock(Cmd, 0, 1);
-
+  int clock = GetClock(Cmd, 0, 1);
+  int clock1 = GetT55x7Clock( GraphBuffer, GraphTraceLen, 0 );
+  PrintAndLog("MAN MOD CLOCKS:  %d  ice %d", clock,clock1);
+  
+  int half = (int)(clock/2);
+  
   wave = 0;
   lastbit = 1;
   for (i = 0; i < (int)(GraphTraceLen / clock); i++)
   {
     bit = GraphBuffer[i * clock] ^ 1;
 
   wave = 0;
   lastbit = 1;
   for (i = 0; i < (int)(GraphTraceLen / clock); i++)
   {
     bit = GraphBuffer[i * clock] ^ 1;
 
-    for (j = 0; j < (int)(clock/2); j++)
+    for (j = 0; j < half; ++j)
       GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave;
       GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave;
-    for (j = (int)(clock/2); j < clock; j++)
+    for (j = half; j < clock; ++j)
       GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave ^ 1;
 
     /* Keep track of how we start our wave and if we changed or not this time */
       GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave ^ 1;
 
     /* Keep track of how we start our wave and if we changed or not this time */
@@ -774,9 +838,17 @@ int CmdPlot(const char *Cmd)
 
 int CmdSave(const char *Cmd)
 {
 
 int CmdSave(const char *Cmd)
 {
-  FILE *f = fopen(Cmd, "w");
+   char filename[FILE_PATH_SIZE] = {0x00};
+   int len = 0;
+
+   len = strlen(Cmd);
+   if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+   memcpy(filename, Cmd, len);
+   
+
+  FILE *f = fopen(filename, "w");
   if(!f) {
   if(!f) {
-    PrintAndLog("couldn't open '%s'", Cmd);
+    PrintAndLog("couldn't open '%s'", filename);
     return 0;
   }
   int i;
     return 0;
   }
   int i;
@@ -807,8 +879,43 @@ int CmdThreshold(const char *Cmd)
     if (GraphBuffer[i] >= threshold)
       GraphBuffer[i] = 1;
     else
     if (GraphBuffer[i] >= threshold)
       GraphBuffer[i] = 1;
     else
-      GraphBuffer[i] =- 1;
+      GraphBuffer[i] = -1;
+  }
+  RepaintGraphWindow();
+  return 0;
+}
+
+int CmdDirectionalThreshold(const char *Cmd)
+{
+       int8_t upThres = param_get8(Cmd, 0);
+       int8_t downThres = param_get8(Cmd, 1);
+  
+  printf("Applying Up Threshold: %d, Down Threshold: %d\n", upThres, downThres);
+  
+  int lastValue = GraphBuffer[0];
+  GraphBuffer[0] = 0; // Will be changed at the end, but init 0 as we adjust to last samples value if no threshold kicks in.
+  
+  for (int i = 1; i < GraphTraceLen; ++i) {
+    // Apply first threshold to samples heading up
+    if (GraphBuffer[i] >= upThres && GraphBuffer[i] > lastValue)
+    {
+      lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
+      GraphBuffer[i] = 1;
+    }
+    // Apply second threshold to samples heading down
+    else if (GraphBuffer[i] <= downThres && GraphBuffer[i] < lastValue)
+    {
+      lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
+      GraphBuffer[i] = -1;
+    }
+    else
+    {
+      lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
+      GraphBuffer[i] = GraphBuffer[i-1];
+
+    }
   }
   }
+  GraphBuffer[0] = GraphBuffer[1]; // Aline with first edited sample.
   RepaintGraphWindow();
   return 0;
 }
   RepaintGraphWindow();
   return 0;
 }
@@ -853,9 +960,10 @@ static command_t CommandTable[] =
   {"buffclear",     CmdBuffClear,       1, "Clear sample buffer and graph window"},
   {"dec",           CmdDec,             1, "Decimate samples"},
   {"detectclock",   CmdDetectClockRate, 1, "Detect clock rate"},
   {"buffclear",     CmdBuffClear,       1, "Clear sample buffer and graph window"},
   {"dec",           CmdDec,             1, "Decimate samples"},
   {"detectclock",   CmdDetectClockRate, 1, "Detect clock rate"},
+  {"dirthreshold",  CmdDirectionalThreshold,   1, "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."},
   {"fskdemod",      CmdFSKdemod,        1, "Demodulate graph window as a HID FSK"},
   {"grid",          CmdGrid,            1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
   {"fskdemod",      CmdFSKdemod,        1, "Demodulate graph window as a HID FSK"},
   {"grid",          CmdGrid,            1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
-  {"hexsamples",    CmdHexsamples,      0, "<blocks> [<offset>] -- Dump big buffer as hex bytes"},  
+  {"hexsamples",    CmdHexsamples,      0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},  
   {"hide",          CmdHide,            1, "Hide graph window"},
   {"hpf",           CmdHpf,             1, "Remove DC offset from trace"},
   {"load",          CmdLoad,            1, "<filename> -- Load trace (to graph window"},
   {"hide",          CmdHide,            1, "Hide graph window"},
   {"hpf",           CmdHpf,             1, "Remove DC offset from trace"},
   {"load",          CmdLoad,            1, "<filename> -- Load trace (to graph window"},
@@ -863,11 +971,12 @@ static command_t CommandTable[] =
   {"mandemod",      CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"},
   {"manmod",        CmdManchesterMod,   1, "[clock rate] -- Manchester modulate a binary stream"},
   {"norm",          CmdNorm,            1, "Normalize max/min to +/-500"},
   {"mandemod",      CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"},
   {"manmod",        CmdManchesterMod,   1, "[clock rate] -- Manchester modulate a binary stream"},
   {"norm",          CmdNorm,            1, "Normalize max/min to +/-500"},
-  {"plot",          CmdPlot,            1, "Show graph window"},
-  {"samples",       CmdSamples,         0, "[128 - 16000] -- Get raw samples for graph window"},
+  {"plot",          CmdPlot,            1, "Show graph window (hit 'h' in window for keystroke help)"},
+  {"samples",       CmdSamples,         0, "[512 - 40000] -- Get raw samples for graph window"},
   {"save",          CmdSave,            1, "<filename> -- Save trace (from graph window)"},
   {"scale",         CmdScale,           1, "<int> -- Set cursor display scale"},
   {"save",          CmdSave,            1, "<filename> -- Save trace (from graph window)"},
   {"scale",         CmdScale,           1, "<int> -- Set cursor display scale"},
-  {"threshold",     CmdThreshold,       1, "Maximize/minimize every value in the graph window depending on threshold"},
+  {"threshold",     CmdThreshold,       1, "<threshold> -- Maximize/minimize every value in the graph window depending on threshold"},
+  {"tune",          CmdTuneSamples,     0, "Get hw tune samples for graph window"},
   {"zerocrossings", CmdZerocrossings,   1, "Count time between zero-crossings"},
   {NULL, NULL, 0, NULL}
 };
   {"zerocrossings", CmdZerocrossings,   1, "Count time between zero-crossings"},
   {NULL, NULL, 0, NULL}
 };
Impressum, Datenschutz