|
|
@ -2,6 +2,7 @@ |
|
|
|
#include <httpd.h> |
|
|
|
#include <httpd.h> |
|
|
|
#include "page_waveform.h" |
|
|
|
#include "page_waveform.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "ftoa.h" |
|
|
|
#include "sampling.h" |
|
|
|
#include "sampling.h" |
|
|
|
#include "serial.h" |
|
|
|
#include "serial.h" |
|
|
|
#include "payload_parser.h" |
|
|
|
#include "payload_parser.h" |
|
|
@ -17,9 +18,24 @@ typedef struct { |
|
|
|
} tplReadSamplesJSON_state; |
|
|
|
} tplReadSamplesJSON_state; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int FLASH_FN tplSamplesJSON(MEAS_FORMAT fmt, HttpdConnData *connData, char *token, void **arg); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int FLASH_FN tplWaveformJSON(HttpdConnData *connData, char *token, void **arg) |
|
|
|
int FLASH_FN tplWaveformJSON(HttpdConnData *connData, char *token, void **arg) |
|
|
|
{ |
|
|
|
{ |
|
|
|
char buff20[20]; |
|
|
|
return tplSamplesJSON(RAW, connData, token, arg); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int FLASH_FN tplFourierJSON(HttpdConnData *connData, char *token, void **arg) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return tplSamplesJSON(FFT, connData, token, arg); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int FLASH_FN tplSamplesJSON(MEAS_FORMAT fmt, HttpdConnData *connData, char *token, void **arg) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
char buff[128]; |
|
|
|
int len; |
|
|
|
int len; |
|
|
|
|
|
|
|
|
|
|
|
tplReadSamplesJSON_state *st = *arg; |
|
|
|
tplReadSamplesJSON_state *st = *arg; |
|
|
@ -37,53 +53,59 @@ int FLASH_FN tplWaveformJSON(HttpdConnData *connData, char *token, void **arg) |
|
|
|
|
|
|
|
|
|
|
|
// check how many samples are requested
|
|
|
|
// check how many samples are requested
|
|
|
|
uint16_t count = 1; |
|
|
|
uint16_t count = 1; |
|
|
|
len = httpdFindArg(connData->getArgs, "n", buff20, sizeof(buff20)); |
|
|
|
len = httpdFindArg(connData->getArgs, "n", buff, sizeof(buff)); |
|
|
|
if (len != -1) count = (uint16_t)atoi(buff20); |
|
|
|
if (len != -1) count = (uint16_t)atoi(buff); |
|
|
|
if (count > 4096) { |
|
|
|
if (count == 0) { |
|
|
|
warn("Requested %d samples, capping at 4096.", count); |
|
|
|
error("Count == 0"); |
|
|
|
count = 4096; |
|
|
|
st->success = false; |
|
|
|
|
|
|
|
return HTTPD_CGI_DONE; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint32_t freq = 4096; |
|
|
|
uint32_t freq = 0; |
|
|
|
len = httpdFindArg(connData->getArgs, "fs", buff20, sizeof(buff20)); |
|
|
|
len = httpdFindArg(connData->getArgs, "fs", buff, sizeof(buff)); |
|
|
|
if (len != -1) freq = (uint32_t)atoi(buff20); |
|
|
|
if (len != -1) freq = (uint32_t)atoi(buff); |
|
|
|
if (freq > 5000000) { |
|
|
|
|
|
|
|
warn("Requested fs %d Hz, capping at 5 MHz.", freq); |
|
|
|
|
|
|
|
freq = 5000000; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (freq == 0) { |
|
|
|
if (freq == 0) { |
|
|
|
error("Requested fs 0 Hz, using 1 Hz"); |
|
|
|
error("Freq == 0"); |
|
|
|
freq = 1; |
|
|
|
st->success = false; |
|
|
|
|
|
|
|
return HTTPD_CGI_DONE; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
st->total_count = count; |
|
|
|
st->total_count = count; |
|
|
|
st->done_count = 0; |
|
|
|
st->done_count = 0; |
|
|
|
st->success = true; // success true by default
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// REQUEST THE DATA
|
|
|
|
// --- REQUEST THE DATA ---
|
|
|
|
meas_request_data(count, freq); |
|
|
|
// This actually asks the STM32 over SBMP to start the ADC DMA,
|
|
|
|
|
|
|
|
// and we'll wait for the data to arrive.
|
|
|
|
|
|
|
|
st->success = meas_request_data(fmt, count, freq); |
|
|
|
|
|
|
|
if (!st->success) { |
|
|
|
|
|
|
|
error("Failed to start sampling"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// the "success" field is after the data,
|
|
|
|
// the "success" field is after the data,
|
|
|
|
// so if readout fails, success can be set to false.
|
|
|
|
// so if readout fails, success can be set to false.
|
|
|
|
|
|
|
|
|
|
|
|
if (strcmp(token, "values") == 0) { |
|
|
|
if (strcmp(token, "values") == 0) { |
|
|
|
|
|
|
|
if (!st->success) { |
|
|
|
|
|
|
|
// failed to start sampling
|
|
|
|
|
|
|
|
return HTTPD_CGI_DONE; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Wait for a chunk
|
|
|
|
// Wait for a chunk
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t *chunk = NULL; |
|
|
|
uint8_t *chunk = NULL; |
|
|
|
uint16_t chunk_len = 0; |
|
|
|
uint16_t chunk_len = 0; |
|
|
|
|
|
|
|
|
|
|
|
// 5 secs or 500 ms
|
|
|
|
// 10 secs or 100 ms - longer wait for intial data.
|
|
|
|
for (int i = 0; i < (st->done_count == 0 ? 5000*100: 500*100); i++) { |
|
|
|
for (int i = 0; i < (st->done_count == 0 ? SAMPLING_TMEO*100: SAMP_READOUT_TMEO*100); i++) { |
|
|
|
uart_poll(); |
|
|
|
uart_poll(); |
|
|
|
if (meas_chunk_ready()) break; |
|
|
|
if (meas_chunk_ready() || meas_is_closed()) break; // We have some data! --- or transaction aborted by peer :(
|
|
|
|
os_delay_us(10); // 1 ms
|
|
|
|
os_delay_us(10); // 1 ms
|
|
|
|
system_soft_wdt_feed(); |
|
|
|
system_soft_wdt_feed(); // Feed the dog, or it'll bite.
|
|
|
|
} |
|
|
|
} |
|
|
|
chunk = meas_get_chunk(&chunk_len); |
|
|
|
chunk = meas_get_chunk(&chunk_len); |
|
|
|
|
|
|
|
|
|
|
|
if (!chunk) { |
|
|
|
if (chunk == NULL) { |
|
|
|
// abort, proceed to the next field.
|
|
|
|
// abort, proceed to the next field.
|
|
|
|
meas_close(); |
|
|
|
meas_close(); |
|
|
|
st->success = false; |
|
|
|
st->success = false; |
|
|
@ -99,15 +121,13 @@ int FLASH_FN tplWaveformJSON(HttpdConnData *connData, char *token, void **arg) |
|
|
|
httpdSend(connData, ", ", 2); |
|
|
|
httpdSend(connData, ", ", 2); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint32_t samp = pp_u32(&pp); |
|
|
|
float samp = pp_float(&pp); |
|
|
|
|
|
|
|
my_ftoa(buff, samp, 3); |
|
|
|
// print the number
|
|
|
|
httpdSend(connData, buff, -1); |
|
|
|
os_sprintf(buff20, "%d", samp); |
|
|
|
|
|
|
|
httpdSend(connData, buff20, -1); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// wait for more in this substitution
|
|
|
|
// wait for more data in this % tag
|
|
|
|
if (st->done_count < st->total_count) { |
|
|
|
if (!meas_is_last_chunk()) { |
|
|
|
meas_request_next_chunk(); |
|
|
|
meas_request_next_chunk(); |
|
|
|
return HTTPD_CGI_MORE; // more numbers to come
|
|
|
|
return HTTPD_CGI_MORE; // more numbers to come
|
|
|
|
} else { |
|
|
|
} else { |
|
|
@ -116,6 +136,46 @@ int FLASH_FN tplWaveformJSON(HttpdConnData *connData, char *token, void **arg) |
|
|
|
return HTTPD_CGI_DONE; |
|
|
|
return HTTPD_CGI_DONE; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else if (strcmp(token, "stats") == 0) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// the STATS json block
|
|
|
|
|
|
|
|
if (!st->success) { |
|
|
|
|
|
|
|
httpdSend(connData, "null", 4); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// no %f in sprintf :(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MeasStats *stats = meas_get_stats(); |
|
|
|
|
|
|
|
httpdSend(connData, "{", 1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sprintf(buff, "\"count\": %d, ", stats->count); |
|
|
|
|
|
|
|
httpdSend(connData, buff, -1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
httpdSend(connData, "\"freq\": ", -1); |
|
|
|
|
|
|
|
my_ftoa(buff, stats->freq, 3); |
|
|
|
|
|
|
|
httpdSend(connData, buff, -1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
httpdSend(connData, ", \"min\": ", -1); |
|
|
|
|
|
|
|
my_ftoa(buff, stats->min, 3); |
|
|
|
|
|
|
|
httpdSend(connData, buff, -1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
httpdSend(connData, ", \"max\": ", -1); |
|
|
|
|
|
|
|
my_ftoa(buff, stats->max, 3); |
|
|
|
|
|
|
|
httpdSend(connData, buff, -1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
httpdSend(connData, ", \"rms\": ", -1); |
|
|
|
|
|
|
|
my_ftoa(buff, stats->rms, 3); |
|
|
|
|
|
|
|
httpdSend(connData, buff, -1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fmt == FFT) { |
|
|
|
|
|
|
|
// ... maybe something special for fft ...
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sprintf(buff, ", \"format\": \"%s\"", fmt == RAW ? "RAW" : fmt == FFT ? "FFT" : "UNKNOWN"); |
|
|
|
|
|
|
|
httpdSend(connData, buff, -1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
httpdSend(connData, "}", 1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} else if (strcmp(token, "success") == 0) { |
|
|
|
} else if (strcmp(token, "success") == 0) { |
|
|
|
// success status
|
|
|
|
// success status
|
|
|
|
httpdSend(connData, (st->success ? "true" : "false"), -1); |
|
|
|
httpdSend(connData, (st->success ? "true" : "false"), -1); |
|
|
|