Added client-side support for recording longer samples, fixed last (?) issues on device-side

This commit is contained in:
Martin Holst Swende 2015-01-29 00:57:22 +01:00
parent 7c676e7269
commit f6d9fb173f
8 changed files with 260 additions and 106 deletions

View file

@ -1051,6 +1051,29 @@ int CmdHpf(const char *Cmd)
RepaintGraphWindow();
return 0;
}
typedef struct {
uint8_t * buffer;
uint32_t numbits;
uint32_t position;
}BitstreamOut;
bool _headBit( BitstreamOut *stream)
{
int bytepos = stream->position >> 3; // divide by 8
int bitpos = (stream->position++) & 7; // mask out 00000111
return (*(stream->buffer + bytepos) >> (7-bitpos)) & 1;
}
uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b)
{
int i;
uint8_t val = 0;
for(i =0 ; i < bits_per_sample; i++)
{
val |= (_headBit(b) << (7-i));
}
return val;
}
int CmdSamples(const char *Cmd)
{
@ -1063,15 +1086,35 @@ int CmdSamples(const char *Cmd)
if (n > sizeof(got))
n = sizeof(got);
PrintAndLog("Reading %d samples from device memory\n", n);
GetFromBigBuf(got,n,0);
WaitForResponse(CMD_ACK,NULL);
for (int j = 0; j < n; j++) {
GraphBuffer[j] = ((int)got[j]) - 128;
}
GraphTraceLen = n;
RepaintGraphWindow();
return 0;
PrintAndLog("Reading %d bytes from device memory\n", n);
GetFromBigBuf(got,n,0);
PrintAndLog("Data fetched");
UsbCommand response;
WaitForResponse(CMD_ACK, &response);
uint8_t bits_per_sample = response.arg[0];
PrintAndLog("Samples packed at %d bits per sample", bits_per_sample);
if(bits_per_sample < 8)
{
PrintAndLog("Unpacking...");
BitstreamOut bout = { got, bits_per_sample * n, 0};
int j =0;
for (j = 0; j * bits_per_sample < n * 8 && j < GraphTraceLen; j++) {
uint8_t sample = getByte(bits_per_sample, &bout);
GraphBuffer[j] = ((int) sample )- 128;
}
GraphTraceLen = j;
PrintAndLog("Unpacked %d samples" , j );
}else
{
for (int j = 0; j < n; j++) {
GraphBuffer[j] = ((int)got[j]) - 128;
}
GraphTraceLen = n;
}
RepaintGraphWindow();
return 0;
}
int CmdTuneSamples(const char *Cmd)

View file

@ -356,24 +356,91 @@ int CmdIndalaClone(const char *Cmd)
return 0;
}
int CmdLFReadUsage()
{
PrintAndLog("Usage: lf read [H|<divisor>] [b <bps>] [d <decim>] [a 0|1]");
PrintAndLog("Options: ");
PrintAndLog(" h This help");
PrintAndLog(" H High frequency (134 KHz). Defaults to 125 KHz");
PrintAndLog(" <divisor> Manually set divisor. 88-> 134KHz, 95-> 125 Hz");
PrintAndLog(" b <bps> Sets resolution of bits per sample. Default (max): 8");
PrintAndLog(" d <decim> Sets decimation. A value of N saves only 1 in N samples. Default: 1");
PrintAndLog(" a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1");
PrintAndLog("Examples:");
PrintAndLog(" lf read");
PrintAndLog(" Samples at 125KHz, 8bps.");
PrintAndLog(" lf read h b 4 d 3");
PrintAndLog(" Samples at 134KHz, averages three samples into one, stored with ");
PrintAndLog(" a resolution of 4 bits per sample.");
return 0;
}
int CmdLFRead(const char *Cmd)
{
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K};
uint8_t divisor = 95;//Frequency divisor
uint8_t bps = 8; // Bits per sample
uint8_t decimation = 1; //How many to keep
bool averaging = 1; // Should we use averaging when discarding samples?
bool errors = FALSE;
// 'h' means higher-low-frequency, 134 kHz
if(*Cmd == 'h') {
c.arg[0] = 1;
} else if (*Cmd == '\0') {
c.arg[0] = 0;
} else if (sscanf(Cmd, "%"lli, &c.arg[0]) != 1) {
PrintAndLog("Samples 1: 'lf read'");
PrintAndLog(" 2: 'lf read h'");
PrintAndLog(" 3: 'lf read <divisor>'");
return 0;
}
SendCommand(&c);
WaitForResponse(CMD_ACK,NULL);
return 0;
uint8_t cmdp =0;
if(param_getchar(Cmd, cmdp) == 'h')
{
return CmdLFReadUsage();
}
// Divisor
if(param_getchar(Cmd, cmdp) == 'H') {
divisor = 88;
cmdp++;
}else if(param_isdec(Cmd,cmdp) )
{
errors |= param_getdec(Cmd,cmdp, &divisor);
}
//BPS
if(param_getchar(Cmd, cmdp) == 'b') {
errors |= param_getdec(Cmd,cmdp+1,&bps);
cmdp+=2;
}
//Decimation
if(param_getchar(Cmd, cmdp) == 'd')
{
errors |= param_getdec(Cmd,cmdp+1,&decimation);
cmdp+=2;
}
//Averaging
if(param_getchar(Cmd, cmdp) == 'a')
{
averaging = param_getchar(Cmd,cmdp+1) == '1';
cmdp+=2;
}
//Validations
if(errors)
{
return CmdLFReadUsage();
}
//Bps is limited to 8, so fits in lower half of arg1
if(bps > 8) bps = 8;
//Feedback
PrintAndLog("Sampling config: ");
PrintAndLog(" divisor: %d ", divisor);
PrintAndLog(" bps: %d ", bps);
PrintAndLog(" decimation: %d ", decimation);
PrintAndLog(" averaging: %d ", averaging);
PrintAndLog("OBS, this is sticky on the device and affects all LF listening operations");
PrintAndLog("To reset, issue 'lf read'");
//And ship it to device
//Averaging is a flag on high-bit of arg[1]
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K};
c.arg[0] = divisor;
c.arg[1] = bps | (averaging << 7) ;
c.arg[2] = decimation;
SendCommand(&c);
WaitForResponse(CMD_ACK,NULL);
return 0;
}
static void ChkBitstream(const char *str)

View file

@ -20,7 +20,8 @@ int GetClock(const char *str, int peak, int verbose);
int GetNRZpskClock(const char *str, int peak, int verbose);
void setGraphBuf(uint8_t *buff, size_t size);
#define MAX_GRAPH_TRACE_LEN (1024*128)
// Max graph trace len: 40000 (bigbuf) * 8 (at 1 bit per sample)
#define MAX_GRAPH_TRACE_LEN (40000 * 8 )
extern int GraphBuffer[MAX_GRAPH_TRACE_LEN];
extern int GraphTraceLen;

View file

@ -227,6 +227,34 @@ uint8_t param_get8(const char *line, int paramnum)
return param_get8ex(line, paramnum, 10, 0);
}
/**
* @brief Reads a decimal integer
* @param line
* @param paramnum
* @return
*/
uint8_t param_getdec(const char *line, int paramnum, uint8_t *destination)
{
uint8_t val = param_get8ex(line, paramnum, 10, 10);
(*destination) = val;
return 0;
}
/**
* @brief Checks if param is decimal
* @param line
* @param paramnum
* @return
*/
uint8_t param_isdec(const char *line, int paramnum)
{
int bg, en;
//TODO, check more thorougly
if (!param_getptr(line, &bg, &en, paramnum)) return 1;
// return strtoul(&line[bg], NULL, 10) & 0xff;
return 0;
}
uint8_t param_get8ex(const char *line, int paramnum, int deflt, int base)
{
int bg, en;

View file

@ -49,6 +49,8 @@ uint8_t param_get8(const char *line, int paramnum);
uint8_t param_get8ex(const char *line, int paramnum, int deflt, int base);
uint32_t param_get32ex(const char *line, int paramnum, int deflt, int base);
uint64_t param_get64ex(const char *line, int paramnum, int deflt, int base);
uint8_t param_getdec(const char *line, int paramnum, uint8_t *destination);
uint8_t param_isdec(const char *line, int paramnum);
int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt);
int param_getstr(const char *line, int paramnum, char * str);