diff --git a/esp_meas.pro.user b/esp_meas.pro.user index f6c0c09..afc7e68 100644 --- a/esp_meas.pro.user +++ b/esp_meas.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/user/page_waveform.c b/user/page_waveform.c index f3f2876..47abb46 100644 --- a/user/page_waveform.c +++ b/user/page_waveform.c @@ -101,11 +101,12 @@ static int FLASH_FN tplSamplesJSON(MEAS_FORMAT fmt, HttpdConnData *connData, cha // 10 secs or 100 ms - longer wait for intial data. - int timeout = (st->done_count == 0 ? (int)meas_estimate_duration(st->total_count, st->freq): SAMP_READOUT_TMEO); + int timeout = (st->done_count == 0 ? (int)meas_estimate_duration(st->total_count, st->freq): SAMP_RD_TMEO_TOTAL); + dbg("Chunk read total timeout = %d ms", timeout); for (int i = 0; i < timeout*100; i++) { uart_poll(); 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); system_soft_wdt_feed(); // Feed the dog, or it'll bite. } chunk = meas_get_chunk(&chunk_len); diff --git a/user/sampling.c b/user/sampling.c index c121152..99eef99 100644 --- a/user/sampling.c +++ b/user/sampling.c @@ -11,9 +11,13 @@ // the FIFO has 128 bytes, and should accomodate ideally the whole frame. #define CHUNK_LEN 100 +static void setReadoutTmeoTimer(int ms); + + // Only one readout can happen at a time. static struct { + bool waiting_for_measure; /*!< Still waiting for first data packet */ bool pending; /*!< Flag that data is currently being read */ uint16_t sesn; /*!< SBMP session of the readout sequence */ bool chunk_ready; /*!< Chunk was received and is ready for reading */ @@ -21,6 +25,7 @@ static struct { uint16_t received_chunk_size; /*!< Size of the chunk in latest_chunk_copy */ // the readout state + uint8_t retry_count; uint32_t pos; uint32_t total; ETSTimer abortTimer; @@ -39,7 +44,7 @@ bool FLASH_FN meas_is_closed(void) uint32_t FLASH_FN meas_estimate_duration(uint32_t count, uint32_t freq) { - return (uint32_t)((count*1000.0f) / freq) + 1000; + return (uint32_t)((count*1000.0f) / freq) + SAMP_RD_TMEO_TOTAL; } @@ -48,13 +53,30 @@ uint32_t FLASH_FN meas_estimate_duration(uint32_t count, uint32_t freq) static void FLASH_FN abortTimerCb(void *arg) { (void)arg; - warn("Sampling aborted due to timeout."); - // try to abort the readout - sbmp_bulk_abort(dlnk_ep, rd.sesn); + if (rd.waiting_for_measure) { + error("Sampling aborted due to timeout."); - // release resources and stop - meas_close(); + // try to abort the readout + sbmp_bulk_abort(dlnk_ep, rd.sesn); + + // release resources and stop + meas_close(); + } else { + warn("Data chunk not rx in time"); + + // data chunk not received in time (may be lost ?) + if (rd.retry_count < SAMP_RD_RETRY_COUNT) { + rd.retry_count++; + + dbg("Requesting again (try %d of %d).", rd.retry_count, SAMP_RD_RETRY_COUNT); + setReadoutTmeoTimer(SAMP_RD_TMEO); // re-start the timer + sbmp_bulk_request(dlnk_ep, rd.pos, CHUNK_LEN, rd.sesn); + } else { + error("Retry count exhausted!"); + meas_close(); + } + } } static void FLASH_FN setReadoutTmeoTimer(int ms) @@ -80,6 +102,7 @@ void FLASH_FN meas_request_next_chunk(void) { if (!rd.pending) return; rd.chunk_ready = false; // invalidate the current chunk, so waiting for chunk is possible. + rd.retry_count = 0; // reset retry counter sbmp_bulk_request(dlnk_ep, rd.pos, CHUNK_LEN, rd.sesn); } @@ -89,6 +112,8 @@ bool FLASH_FN meas_chunk_ready(void) return rd.pending && rd.chunk_ready; } + + /** * @brief Get received chunk. NULL if none. * @@ -149,6 +174,7 @@ static void FLASH_FN request_data_sesn_listener(SBMP_Endpoint *ep, SBMP_Datagram rd.pos = 0; rd.total = pp_u32(&pp); + rd.waiting_for_measure = false; // "pending" flag remains set // --- here start the user data (common) --- rd.stats.count = pp_u32(&pp); @@ -163,9 +189,10 @@ static void FLASH_FN request_data_sesn_listener(SBMP_Endpoint *ep, SBMP_Datagram } // renew the timeout - setReadoutTmeoTimer(SAMP_READOUT_TMEO); + setReadoutTmeoTimer(SAMP_RD_TMEO); // request first chunk + rd.retry_count = 0; sbmp_bulk_request(ep, rd.pos, CHUNK_LEN, dg->session); break; @@ -176,11 +203,12 @@ static void FLASH_FN request_data_sesn_listener(SBMP_Endpoint *ep, SBMP_Datagram memcpy(rd.received_chunk, dg->payload, dg->length); rd.chunk_ready = true; rd.received_chunk_size = dg->length; + rd.retry_count = 0; // move the pointer for next request rd.pos += dg->length; - setReadoutTmeoTimer(SAMP_READOUT_TMEO); // timeout to retrieve the data & ask for more + setReadoutTmeoTimer(SAMP_RD_TMEO); // timeout to retrieve the data & ask for more // --- Now we wait for the CGI func to retrieve the chunk and send it to the browser. --- @@ -229,6 +257,7 @@ bool FLASH_FN meas_request_data(MEAS_FORMAT format, uint16_t count, uint32_t fre rd.total = 0; rd.pending = true; rd.format = format; + rd.retry_count = 0; memset(&rd.stats, 0, sizeof(MeasStats)); // clear the stats obj // start the abort timer - timeout @@ -248,6 +277,7 @@ bool FLASH_FN meas_request_data(MEAS_FORMAT format, uint16_t count, uint32_t fre } rd.sesn = sesn; + rd.waiting_for_measure = true; // waiting for acquisition module to start sending data // request N values sbmp_ep_send_u16(dlnk_ep, count); diff --git a/user/sampling.h b/user/sampling.h index 27ad33d..05b9f17 100644 --- a/user/sampling.h +++ b/user/sampling.h @@ -5,7 +5,10 @@ #include #include "datalink.h" -#define SAMP_READOUT_TMEO 500 +// ms +#define SAMP_RD_TMEO 300 +#define SAMP_RD_RETRY_COUNT 3 +#define SAMP_RD_TMEO_TOTAL (SAMP_RD_TMEO*SAMP_RD_RETRY_COUNT+200) typedef struct { uint32_t count;