quite reliable, fixed bugs in bulk

master
Ondřej Hruška 9 years ago
parent c0e091945c
commit a55c25ddca
  1. 2
      Makefile
  2. 9
      esp_meas.pro
  3. 2
      esp_meas.pro.user
  4. 2
      sbmp
  5. 83
      user/ftoa.c
  6. 10
      user/ftoa.h
  7. 93
      user/sampling.c
  8. 12
      user/sbmp_config.h
  9. 8
      user/serial.c
  10. 2
      user/timeout.h

@ -66,7 +66,7 @@ LIBS += esphttpd
# compiler flags using during compilation of source files
CFLAGS = -Os -ggdb -std=gnu99 -Werror -Wpointer-arith -Wundef -Wall -Wl,-EL -fno-inline-functions \
-nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH \
-Wno-address -ffunction-sections
-Wno-address -ffunction-sections -Wno-unused-value
#-Wno-strict-aliasing
# linker flags used to generate the main object file

@ -13,7 +13,8 @@ INCLUDEPATH = . \
libesphttpd/espfs \
libesphttpd/core \
libesphttpd/lib/heatshrink \
sbmp/library
sbmp/library \
/home/ondra/devel/esp/sdk/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include
SOURCES += \
libesphttpd/core/auth.c \
@ -55,7 +56,8 @@ SOURCES += \
user/uptime.c \
sbmp/library/payload_parser.c \
user/sampling.c \
user/page_home.c
user/page_home.c \
user/ftoa.c
HEADERS += \
include/uart_hw.h \
@ -134,7 +136,8 @@ HEADERS += \
user/page_home.h \
user/timeout.h \
user/sbmp_config.h \
sbmp/library/sbmp_config.example.h
sbmp/library/sbmp_config.example.h \
user/ftoa.h
DISTFILES += \
style.astylerc \

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.6.0, 2016-03-25T13:33:55. -->
<!-- Written by QtCreator 3.6.0, 2016-03-25T19:36:56. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>

@ -1 +1 @@
Subproject commit 6495ad6474dbd7a5e7198fbb998a247efed368a2
Subproject commit 8e7a1cbff148745f2d9b21e3585606a7c2555f04

@ -0,0 +1,83 @@
#include <esp8266.h>
/* reverse: reverse string s in place */
static void str_reverse(char *s)
{
for (int i = 0, j = (int)(strlen(s) - 1); i < j; i++, j--) {
char c = s[i];
s[i] = s[j];
s[j] = c;
}
}
/* itoa: convert n to characters in s. returns length */
int my_itoa(int n, char *s)
{
int i, sign;
if ((sign = n) < 0) /* record sign */
n = -n; /* make n positive */
i = 0;
do { /* generate digits in reverse order */
s[i++] = n % 10 + '0'; /* get next digit */
} while ((n /= 10) > 0); /* delete it */
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
str_reverse(s);
return i;
}
int my_ftoa(char *buffer, float f, int precision)
{
// add 0.5 * 10^-precision
float rounder = 0.5;
for (int i = 0; i < precision; i++) rounder *= 0.1;
f += rounder;
int wholePart = (int) f;
// Deposit the whole part of the number.
int length = my_itoa(wholePart, buffer);
// Now work on the faction if we need one.
if (precision > 0) {
// We do, so locate the end of the string and insert
// a decimal point.
char *endOfString = buffer + length;
//while (*endOfString != '\0') endOfString++;
*endOfString++ = '.';
length++;
// Now work on the fraction, be sure to turn any negative
// values positive.
if (f < 0) {
f *= -1;
wholePart *= -1;
}
float fraction = f - wholePart;
while (precision > 0) {
// Multiply by ten and pull out the digit.
fraction *= 10;
int dig = (int) fraction;
*endOfString++ = (char)('0' + dig);
// Update the fraction and move on to the
// next digit.
fraction -= dig;
precision--;
length++;
}
// Terminate the string.
*endOfString = 0;
}
return length;
}

@ -0,0 +1,10 @@
#ifndef FTOA_H
#define FTOA_H
#include <esp8266.h>
/* itoa: convert n to characters in s. returns length */
int my_itoa(int n, char *s);
int my_ftoa(char *buffer, float f, int precision);
#endif // FTOA_H

@ -14,20 +14,37 @@
#define CHUNK_LEN (CHUNK_LEN_32*4)
static bool acquire_pending = false;
static uint16_t acquire_session;
static volatile bool acquire_pending = false;
static volatile uint16_t acquire_session;
static ETSTimer prSampleAbortTimer;
static void FLASH_FN prSampleAbortTimerCb(void *arg) {
static void FLASH_FN prSampleAbortTimerCb(void *arg)
{
warn("Sampling aborted due to timeout.");
acquire_pending = false;
// 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)
{
os_timer_disarm(&prSampleAbortTimer);
os_timer_setfn(&prSampleAbortTimer, prSampleAbortTimerCb, NULL);
os_timer_arm(&prSampleAbortTimer, ms, 0);
}
static void stopReadoutTmeoTimer(void)
{
os_timer_disarm(&prSampleAbortTimer);
}
@ -41,12 +58,12 @@ static void FLASH_FN request_data_sesn_listener(SBMP_Endpoint *ep, SBMP_Datagram
bool suc = false;
dbg("Received msg in session %d, dg type %d", dg->session, dg->type);
DataReadState *state = *obj;
DataReadState *readState = *obj;
// allocate the state struct
if (state == NULL) {
state = malloc(sizeof(DataReadState));
*obj = state;
if (readState == NULL) {
readState = malloc(sizeof(DataReadState));
*obj = readState;
}
PayloadParser pp;
@ -57,39 +74,43 @@ static void FLASH_FN request_data_sesn_listener(SBMP_Endpoint *ep, SBMP_Datagram
// data is ready to be read
pp = pp_start(dg->payload, dg->length);
state->pos = 0;
state->total = pp_u32(&pp);
readState->pos = 0;
readState->total = pp_u32(&pp);
dbg("Total bytes: %d", state->total);
dbg("Total bytes: %d", readState->total);
retry_until_timeout(10, sbmp_bulk_request(ep, state->pos, CHUNK_LEN, dg->session));
retry_TO(100, sbmp_bulk_request(ep, readState->pos, CHUNK_LEN, dg->session));
setReadoutTmeoTimer(500);
break;
case DG_BULK_DATA: // data received
info("--- Received a chunk ---");
info("--- Received a chunk, length %d ---", dg->length);
// Process the received data
pp = pp_start(dg->payload, dg->length);
for (int i = 0; i < dg->length/4; i++) {
float f = pp_float(&pp);
dbg("Rx %.2f", f);
while(pp.ptr < pp.len) {
uint32_t x = pp_u32(&pp);
printf("%d,", x);
}
printf("\n");
// and ask for more
state->pos += dg->length;
readState->pos += dg->length;
if (state->pos >= state->total) {
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)
retry_until_timeout(10, sbmp_bulk_abort(ep, dg->session));
retry_TO(100, sbmp_bulk_abort(ep, dg->session));
goto cleanup;
} else {
// read next part
retry_until_timeout(10, sbmp_bulk_request(ep, state->pos, CHUNK_LEN, dg->session));
retry_TO(100, sbmp_bulk_request(ep, readState->pos, CHUNK_LEN, dg->session));
setReadoutTmeoTimer(500);
}
break;
@ -103,14 +124,20 @@ static void FLASH_FN request_data_sesn_listener(SBMP_Endpoint *ep, SBMP_Datagram
cleanup:
// free the obj
free(state);
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) {
@ -123,32 +150,36 @@ static bool FLASH_FN meas_request_data(uint16_t count)
return false;
}
// start the abort timer - timeout
os_timer_disarm(&prSampleAbortTimer);
os_timer_setfn(&prSampleAbortTimer, prSampleAbortTimerCb, NULL);
os_timer_arm(&prSampleAbortTimer, 5000, 0); // 5 seconds, no repeat
acquire_pending = true;
// start the abort timer - timeout
setReadoutTmeoTimer(6000);
// start a message
uint16_t sesn;
bool suc = sbmp_ep_start_message(dlnk_ep, DG_REQUEST_CAPTURE, sizeof(uint16_t), &sesn);
uint16_t sesn = 0;
retry_TO(100, sbmp_ep_start_message(dlnk_ep, DG_REQUEST_CAPTURE, sizeof(uint16_t), &sesn));
if (!suc) goto fail;
// register the session listener
suc = sbmp_ep_add_listener(dlnk_ep, sesn, request_data_sesn_listener, NULL);
if (!suc) goto fail;
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);
acquire_session = sesn;
return true;
fail:
os_timer_disarm(&prSampleAbortTimer);
stopReadoutTmeoTimer();
acquire_pending = false;
return false;
}

@ -3,6 +3,7 @@
#include <esp8266.h>
/* ---------- CRC32 ---------------- */
/**
@ -54,7 +55,7 @@
/**
* @brief Enable detailed logging (only for debugging, disable for better performance).
*/
#define SBMP_DEBUG 1
#define SBMP_DEBUG 0
// here are the actual logging functions
#define sbmp_error(fmt, ...) (SBMP_DEBUG||SBMP_LOGGING ? os_printf("\x1b[31;1m[SBMP][E] "fmt"\x1b[0m\n", ##__VA_ARGS__) : 0)
@ -63,4 +64,13 @@
#define sbmp_dbg(fmt, ...) (SBMP_DEBUG ? os_printf("[SBMP][ ] "fmt"\n", ##__VA_ARGS__) : 0)
/* ---------- Fix formatting -------------- */
#define PRIu16 "u"
#define PRIu32 "u"
#define PRIu8 "u"
#define PRIi16 "d"
#define PRIi32 "d"
#define PRIi8 "d"
#endif // SBMP_CONFIG_H

@ -34,12 +34,12 @@ void FLASH_FN clear_rxtx(int uart_no)
* @brief Configure UART 115200-8-N-1
* @param uart_no
*/
static void FLASH_FN my_uart_init(UARTn uart_no)
static void FLASH_FN my_uart_init(UARTn uart_no, uint32 baud)
{
UART_SetParity(uart_no, PARITY_NONE);
UART_SetStopBits(uart_no, ONE_STOP_BIT);
UART_SetWordLength(uart_no, EIGHT_BITS);
UART_SetBaudrate(uart_no, BIT_RATE_115200);
UART_SetBaudrate(uart_no, baud);
UART_ResetFifo(uart_no);
}
@ -58,8 +58,8 @@ static void FLASH_FN conf_uart_pins(void)
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
// Configure the UART peripherals
my_uart_init(UART0); // main
my_uart_init(UART1); // debug (output only)
my_uart_init(UART0, BIT_RATE_460800); // main
my_uart_init(UART1, BIT_RATE_115200); // debug (output only)
// Select debug port
UART_SetPrintPort(UART1);

@ -6,7 +6,7 @@
#define until_timeout(to_ms) for(uint32_t _utmeo = system_get_time(); system_get_time() - _utmeo < ((to_ms)*1000);)
/** Retry a call until a timeout. Variable 'suc' is set to the return value. Must be defined. */
#define retry_until_timeout(to_ms, call) \
#define retry_TO(to_ms, call) \
until_timeout(to_ms) { \
suc = call; \
if (suc) break; \

Loading…
Cancel
Save