ESP8266 part of the f105-motor-demo project (see f105-motor-demo_stm32)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
f105-motor-demo_esp/user/sampling.c

221 lines
4.8 KiB

#include <esp8266.h>
#include <sbmp.h>
#include "datalink.h"
#include "sampling.h"
9 years ago
#include "timeout.h"
// The buffer is big enough for 256 data bytes - 4*64
// chunk size for bulk transfer (must be multiple of 4 - length of uint32 / float)
// NOTE: If too large, strange errors occur (problem with the UART FIFO at high speed)
#define CHUNK_LEN 100
static volatile bool acquire_pending = false;
static volatile uint16_t acquire_session;
static ETSTimer prSampleAbortTimer;
static void FLASH_FN prSampleAbortTimerCb(void *arg)
{
warn("Sampling aborted due to timeout.");
// try to abort the readout
sbmp_bulk_abort(dlnk_ep, acquire_session);
// free the data obj if not NULL
sbmp_ep_free_listener_obj(dlnk_ep, acquire_session);
// release the slot
sbmp_ep_remove_listener(dlnk_ep, acquire_session);
acquire_pending = false;
}
static void setReadoutTmeoTimer(int ms)
{
dbg("Set read timeout %d", ms);
os_timer_disarm(&prSampleAbortTimer);
os_timer_setfn(&prSampleAbortTimer, prSampleAbortTimerCb, NULL);
os_timer_arm(&prSampleAbortTimer, ms, 0);
}
static void stopReadoutTmeoTimer(void)
{
dbg("Stop read timeout");
os_timer_disarm(&prSampleAbortTimer);
}
typedef struct {
uint32_t pos;
uint32_t total;
} DataReadState;
static void FLASH_FN request_data_sesn_listener(SBMP_Endpoint *ep, SBMP_Datagram *dg, void **obj)
{
dbg("Received msg in session %d, dg type %d", dg->session, dg->type);
DataReadState *readState = *obj;
// allocate the state struct
if (readState == NULL) {
readState = malloc(sizeof(DataReadState));
*obj = readState;
}
PayloadParser pp;
switch (dg->type) {
case DG_BULK_OFFER:// Data ready notification
stopReadoutTmeoTimer();
info("--- Data offered for bulk transfer ---");
// data is ready to be read
pp = pp_start(dg->payload, dg->length);
readState->pos = 0;
readState->total = pp_u32(&pp);
dbg("Total bytes: %d", readState->total);
9 years ago
// we choose to request the data immediately
setReadoutTmeoTimer(1000);
sbmp_bulk_request(ep, readState->pos, CHUNK_LEN, dg->session);
break;
case DG_BULK_DATA: // data received
stopReadoutTmeoTimer();
info("--- Received a chunk, length %d ---", dg->length);
// Process the received data
pp = pp_start(dg->payload, dg->length);
while(pp.ptr < pp.len) {
uint32_t x = pp_u32(&pp);
printf("%d,", x);
}
printf("\n");
// and ask for more
readState->pos += dg->length;
if (readState->pos >= readState->total) {
dbg("Transfer is complete.");
// transfer complete
// make sure the peer has freed the buffer
// (may be waiting for us if we wanted to re-read something)
9 years ago
sbmp_bulk_abort(ep, dg->session);
goto cleanup;
} else {
// read next part
setReadoutTmeoTimer(1000);
sbmp_bulk_request(ep, readState->pos, CHUNK_LEN, dg->session);
}
break;
case DG_BULK_ABORT: // Peer resets the readout
// this is unlikely
warn("Bulk transfer aborted by peer.");
goto cleanup;
}
return;
cleanup:
// free the obj
free(readState);
// remove the listener
sbmp_ep_remove_listener(ep, dg->session);
stopReadoutTmeoTimer();
acquire_pending = false;
// In case the error was in SBMP (bad state)
}
static bool FLASH_FN meas_request_data(uint16_t count)
{
bool suc = false;
info("Requesting data capture - %d samples.", count);
if (acquire_pending) {
error("Acquire request already in progress.");
return false;
}
if (sbmp_ep_handshake_status(dlnk_ep) != SBMP_HSK_SUCCESS) {
error("Hsk status not SUCCESS, can't request data.");
return false;
}
acquire_pending = true;
// start the abort timer - timeout
setReadoutTmeoTimer(6000);
// start a message
uint16_t sesn = 0;
suc = sbmp_ep_start_message(dlnk_ep, DG_REQUEST_CAPTURE, sizeof(uint16_t), &sesn);
9 years ago
if (!suc) goto fail;
// register the session listener
9 years ago
suc = sbmp_ep_add_listener(dlnk_ep, sesn, request_data_sesn_listener, NULL);
if (!suc) {
// discard the unfinished outgoing packet
sbmp_frm_reset_tx(&dlnk_ep->frm);
goto fail;
}
acquire_session = sesn;
// request N values
sbmp_ep_send_u16(dlnk_ep, count);
dbg("Request sent, session nr %d", sesn);
return true;
9 years ago
fail:
stopReadoutTmeoTimer();
acquire_pending = false;
9 years ago
return false;
}
// ------ C G I ---------
int FLASH_FN cgiReadSamples(HttpdConnData *connData)
{
char buff[128];
if (connData->conn == NULL) {
//Connection aborted. Clean up.
return HTTPD_CGI_DONE;
}
uint16_t count = 1;
int len = httpdFindArg(connData->getArgs, "n", buff, sizeof(buff));
if (len != -1) {
count = (uint16_t)atoi(buff);
}
dbg("User wants %d samples.", count);
meas_request_data(count);
httpdStartResponse(connData, 200);
httpdHeader(connData, "Content-Type", "text/plain");
httpdEndHeaders(connData);
// body
httpdSend(connData, "OK.", -1);
return HTTPD_CGI_DONE;
}