experimental ADC front-end with dummy reports

adc
Ondřej Hruška 6 years ago
parent 02f69b0e37
commit 260fcc3e65
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 3
      framework/unit_registry.c
  2. 2
      units/1wire/_ow_api.c
  3. 75
      units/adc/_adc_core.c
  4. 1
      units/adc/_adc_init.c
  5. 36
      units/adc/_adc_internal.h
  6. 17
      units/adc/_adc_settings.c
  7. 186
      units/adc/unit_adc.c
  8. 2
      utils/error.h

@ -495,7 +495,8 @@ void ureg_deliver_unit_request(TF_Msg *msg)
if (rv == E_SUCCESS) { if (rv == E_SUCCESS) {
if (confirmed) com_respond_ok(msg->frame_id); if (confirmed) com_respond_ok(msg->frame_id);
} }
else { else if (rv != E_FAILURE) {
// Failure is returned when the handler already sent an error response.
com_respond_error(msg->frame_id, rv); com_respond_error(msg->frame_id, rv);
} }
goto quit; goto quit;

@ -125,5 +125,5 @@ error_t UU_1WIRE_Search(Unit *unit, bool with_alarm, bool restart,
return priv->searchState.error; return priv->searchState.error;
} }
return E_FAILURE; return E_INTERNAL_ERROR;
} }

@ -8,6 +8,11 @@
#define ADC_INTERNAL #define ADC_INTERNAL
#include "_adc_internal.h" #include "_adc_internal.h"
void UADC_ReportEndOfStream(Unit *unit)
{
dbg("~~End Of Stream msg~~");
}
void UADC_DMA_Handler(void *arg) void UADC_DMA_Handler(void *arg)
{ {
Unit *unit = arg; Unit *unit = arg;
@ -59,6 +64,7 @@ void UADC_DMA_Handler(void *arg)
if (m_trig || m_fixcpt) { if (m_trig || m_fixcpt) {
if (priv->trig_stream_remain == 0) { if (priv->trig_stream_remain == 0) {
dbg("End of capture"); dbg("End of capture");
UADC_ReportEndOfStream(unit);
UADC_SwitchMode(unit, (priv->auto_rearm && m_trig) ? ADC_OPMODE_ARMED : ADC_OPMODE_IDLE); UADC_SwitchMode(unit, (priv->auto_rearm && m_trig) ? ADC_OPMODE_ARMED : ADC_OPMODE_IDLE);
} }
} }
@ -117,32 +123,31 @@ void UADC_ADC_EOS_Handler(void *arg)
uint16_t val = priv->dma_buffer[sample_pos]; uint16_t val = priv->dma_buffer[sample_pos];
dbg("Trig line level %d", (int)val); dbg("Trig line level %d", (int)val);
if (priv->enable_averaging) { priv->averaging_bins[i] =
priv->averaging_bins[i] = priv->averaging_bins[i] * (1.0f - priv->avg_factor_as_float) +
priv->averaging_bins[i] * (1.0f - priv->avg_factor_as_float) + ((float) val) * priv->avg_factor_as_float;
((float) val) * priv->avg_factor_as_float;
} else { priv->last_samples[i] = val;
priv->last_sample[i] = val;
}
if (priv->opmode == ADC_OPMODE_ARMED) { if (priv->opmode == ADC_OPMODE_ARMED) {
if (i == priv->trigger_source) { if (i == priv->trigger_source) {
bool trigd = false; bool trigd = false;
bool rising = false; uint8_t edge_type = 0;
if (priv->trig_prev_level < priv->trig_level && val >= priv->trig_level) { if (priv->trig_prev_level < priv->trig_level && val >= priv->trig_level) {
dbg("******** Rising edge"); dbg("******** Rising edge");
// Rising edge // Rising edge
trigd = (bool) (priv->trig_edge & 0b01); trigd = (bool) (priv->trig_edge & 0b01);
rising = true; edge_type = 1;
} }
else if (priv->trig_prev_level > priv->trig_level && val <= priv->trig_level) { else if (priv->trig_prev_level > priv->trig_level && val <= priv->trig_level) {
dbg("******** Falling edge"); dbg("******** Falling edge");
// Falling edge // Falling edge
trigd = (bool) (priv->trig_edge & 0b10); trigd = (bool) (priv->trig_edge & 0b10);
edge_type = 2;
} }
if (trigd) { if (trigd) {
UADC_HandleTrigger(unit, rising, timestamp); UADC_HandleTrigger(unit, edge_type, timestamp);
} }
priv->trig_prev_level = val; priv->trig_prev_level = val;
@ -154,7 +159,7 @@ void UADC_ADC_EOS_Handler(void *arg)
dbg(" EOS ISR end."); dbg(" EOS ISR end.");
} }
void UADC_HandleTrigger(Unit *unit, bool rising, uint64_t timestamp) void UADC_HandleTrigger(Unit *unit, uint8_t edge_type, uint64_t timestamp)
{ {
assert_param(unit); assert_param(unit);
struct priv *priv = unit->data; struct priv *priv = unit->data;
@ -172,7 +177,7 @@ void UADC_HandleTrigger(Unit *unit, bool rising, uint64_t timestamp)
unit->_tick_cnt = 0; unit->_tick_cnt = 0;
} }
dbg("Trigger condition hit, rising=%d", rising); dbg("Trigger condition hit, edge=%d", edge_type);
// TODO Send pre-trigger // TODO Send pre-trigger
priv->stream_startpos = (uint16_t) priv->DMA_CHx->CNDTR; priv->stream_startpos = (uint16_t) priv->DMA_CHx->CNDTR;
@ -180,6 +185,44 @@ void UADC_HandleTrigger(Unit *unit, bool rising, uint64_t timestamp)
UADC_SwitchMode(unit, ADC_OPMODE_TRIGD); UADC_SwitchMode(unit, ADC_OPMODE_TRIGD);
} }
void UADC_StartBlockCapture(Unit *unit, uint32_t len, TF_ID frame_id)
{
assert_param(unit);
struct priv *priv = unit->data;
assert_param(priv);
priv->stream_frame_id = frame_id;
priv->stream_startpos = (uint16_t) priv->DMA_CHx->CNDTR;
priv->trig_stream_remain = len;
UADC_SwitchMode(unit, ADC_OPMODE_FIXCAPT);
}
/** Start stream */
void UADC_StartStream(Unit *unit, TF_ID frame_id)
{
assert_param(unit);
struct priv *priv = unit->data;
assert_param(priv);
priv->stream_frame_id = frame_id;
priv->stream_startpos = (uint16_t) priv->DMA_CHx->CNDTR;
dbg("Start streaming.");
UADC_SwitchMode(unit, ADC_OPMODE_STREAM);
}
/** End stream */
void UADC_StopStream(Unit *unit)
{
assert_param(unit);
struct priv *priv = unit->data;
assert_param(priv);
dbg("Stop stream.");
UADC_ReportEndOfStream(unit);
UADC_SwitchMode(unit, ADC_OPMODE_IDLE);
}
/** Handle unit update tick - expire the trigger hold-off */
void UADC_updateTick(Unit *unit) void UADC_updateTick(Unit *unit)
{ {
assert_param(unit); assert_param(unit);
@ -234,6 +277,7 @@ void UADC_SwitchMode(Unit *unit, enum uadc_opmode new_mode)
else if (new_mode == ADC_OPMODE_IDLE) { else if (new_mode == ADC_OPMODE_IDLE) {
dbg("ADC switch -> IDLE"); dbg("ADC switch -> IDLE");
// IDLE and ARMED are identical with the exception that the trigger condition is not checked // IDLE and ARMED are identical with the exception that the trigger condition is not checked
// ARMED can be only entered from IDLE, thus we do the init only here.
// In IDLE, we don't need the DMA interrupts // In IDLE, we don't need the DMA interrupts
LL_DMA_DisableIT_HT(priv->DMAx, priv->dma_chnum); LL_DMA_DisableIT_HT(priv->DMAx, priv->dma_chnum);
@ -254,8 +298,11 @@ void UADC_SwitchMode(Unit *unit, enum uadc_opmode new_mode)
assert_param(priv->opmode == ADC_OPMODE_IDLE); assert_param(priv->opmode == ADC_OPMODE_IDLE);
// there's nothing else to do here // there's nothing else to do here
} }
else if (new_mode == ADC_OPMODE_TRIGD || new_mode == ADC_OPMODE_STREAM) { else if (new_mode == ADC_OPMODE_TRIGD ||
dbg("ADC switch -> TRIG'D or STREAM"); new_mode == ADC_OPMODE_STREAM ||
new_mode == ADC_OPMODE_FIXCAPT) {
dbg("ADC switch -> TRIG'D / STREAM / BLOCK");
assert_param(priv->opmode == ADC_OPMODE_ARMED || priv->opmode == ADC_OPMODE_IDLE); assert_param(priv->opmode == ADC_OPMODE_ARMED || priv->opmode == ADC_OPMODE_IDLE);
// during the capture, we disallow direct readout and averaging to reduce overhead // during the capture, we disallow direct readout and averaging to reduce overhead

@ -21,7 +21,6 @@ error_t UADC_preInit(Unit *unit)
priv->sample_time = 0b010; // 13.5c priv->sample_time = 0b010; // 13.5c
priv->frequency = 1000; priv->frequency = 1000;
priv->buffer_size = 512; priv->buffer_size = 512;
priv->enable_averaging = false;
priv->averaging_factor = 500; priv->averaging_factor = 500;
priv->opmode = ADC_OPMODE_UNINIT; priv->opmode = ADC_OPMODE_UNINIT;

@ -29,8 +29,6 @@ struct priv {
uint8_t sample_time; //!< 0-7 (corresponds to 1.5-239.5 cycles) - time for the sampling capacitor to charge uint8_t sample_time; //!< 0-7 (corresponds to 1.5-239.5 cycles) - time for the sampling capacitor to charge
uint32_t frequency; //!< Timer frequency in Hz. Note: not all frequencies can be achieved accurately uint32_t frequency; //!< Timer frequency in Hz. Note: not all frequencies can be achieved accurately
uint16_t buffer_size; //!< Buffer size in bytes (count 2 bytes per channel per measurement) - faster sampling freq needs bigger buffer uint16_t buffer_size; //!< Buffer size in bytes (count 2 bytes per channel per measurement) - faster sampling freq needs bigger buffer
bool enable_averaging; //!< Enable exponential averaging
uint16_t averaging_factor; //!< Exponential averaging factor 0-1000 uint16_t averaging_factor; //!< Exponential averaging factor 0-1000
// internal state // internal state
@ -44,25 +42,25 @@ struct priv {
DMA_Channel_TypeDef *DMA_CHx; //!< DMA channel instance DMA_Channel_TypeDef *DMA_CHx; //!< DMA channel instance
uint16_t *dma_buffer; //!< malloc'd buffer for the samples uint16_t *dma_buffer; //!< malloc'd buffer for the samples
uint8_t nb_channels; //!< nbr of enabled adc channels uint8_t nb_channels; //!< nbr of enabled adc channels
uint16_t dma_buffer_itemcount; //!< real size of the buffer (adjusted from the configured size to evenly encompass 2*size of one sample) uint16_t dma_buffer_itemcount; //!< real size of the buffer in samples (adjusted to fit 2x whole multiple of sample group)
uint32_t trig_stream_remain; //!< Counter of samples remaining to be sent in the post-trigger stream
uint16_t trig_holdoff_remain; //!< Tmp counter for the currently active hold-off
uint16_t trig_prev_level; //!< Value of the previous sample, used to detect trigger edge
uint16_t stream_startpos; //!< Byte offset in the DMA buffer where the next capture for a stream should start.
//!< Updated in TH/TC and on trigger (after the preceding data is sent as a pretrig buffer)
enum uadc_opmode opmode; //!< OpMode (state machine state) enum uadc_opmode opmode; //!< OpMode (state machine state)
union { float averaging_bins[18]; //!< Averaging buffers, enough space to accommodate all channels (16 external + 2 internal)
float averaging_bins[18]; //!< Averaging buffers, enough space to accommodate all channels (16 external + 2 internal) uint16_t last_samples[18]; //!< If averaging is disabled, the last captured sample is stored here.
uint16_t last_sample[18]; //!< If averaging is disabled, the last captured sample is stored here.
};
uint8_t trigger_source; //!< number of the pin selected as a trigger source uint8_t trigger_source; //!< number of the pin selected as a trigger source
uint16_t pretrig_len; //!< Pre-trigger length, nbr of historical samples to report when trigger occurs uint16_t pretrig_len; //!< Pre-trigger length, nbr of historical samples to report when trigger occurs
uint32_t trig_len; //!< Trigger length, nbr of samples to report AFTER a trigger occurs uint32_t trig_len; //!< Trigger length, nbr of samples to report AFTER a trigger occurs
uint16_t trig_level; //!< Triggering level in LSB uint16_t trig_level; //!< Triggering level in LSB
uint16_t trig_prev_level; //!< Value of the previous sample, used to detect trigger edge
uint8_t trig_edge; //!< Which edge we want to trigger on. 1-rising, 2-falling, 3-both uint8_t trig_edge; //!< Which edge we want to trigger on. 1-rising, 2-falling, 3-both
uint32_t trig_stream_remain; //!< Counter of samples remaining to be sent in the post-trigger stream
bool auto_rearm; //!< Flag that the trigger should be re-armed after the stream finishes bool auto_rearm; //!< Flag that the trigger should be re-armed after the stream finishes
uint16_t trig_holdoff; //!< Trigger hold-off time, set when configuring the trigger uint16_t trig_holdoff; //!< Trigger hold-off time, set when configuring the trigger
uint16_t trig_holdoff_remain; //!< Tmp counter for the currently active hold-off TF_ID stream_frame_id; //!< Session ID for multi-part stream (response or report)
uint16_t stream_startpos; //!< Byte offset in the DMA buffer where the next capture for a stream should start.
//!< Updated in TH/TC and on trigger (after the preceding data is sent as a pretrig buffer)
}; };
/** Allocate data structure and set defaults */ /** Allocate data structure and set defaults */
@ -102,9 +100,21 @@ void UADC_ADC_EOS_Handler(void *arg);
void UADC_SwitchMode(Unit *unit, enum uadc_opmode new_mode); void UADC_SwitchMode(Unit *unit, enum uadc_opmode new_mode);
/** Handle trigger - process pre-trigger and start streaming the requested number of samples */ /** Handle trigger - process pre-trigger and start streaming the requested number of samples */
void UADC_HandleTrigger(Unit *unit, bool rising, uint64_t timestamp); void UADC_HandleTrigger(Unit *unit, uint8_t edge_type, uint64_t timestamp);
/** Handle a periodic tick - expiring the hold-off */ /** Handle a periodic tick - expiring the hold-off */
void UADC_updateTick(Unit *unit); void UADC_updateTick(Unit *unit);
/** Send a end-of-stream message to PC's stream listener so it can shut down. */
void UADC_ReportEndOfStream(Unit *unit);
/** Start a block capture */
void UADC_StartBlockCapture(Unit *unit, uint32_t len, TF_ID frame_id);
/** Start stream */
void UADC_StartStream(Unit *unit, TF_ID frame_id);
/** End stream */
void UADC_StopStream(Unit *unit);
#endif //GEX_F072_ADC_INTERNAL_H #endif //GEX_F072_ADC_INTERNAL_H

@ -25,6 +25,9 @@ void UADC_loadBinary(Unit *unit, PayloadParser *pp)
if (version >= 1) { if (version >= 1) {
priv->buffer_size = pp_u16(pp); priv->buffer_size = pp_u16(pp);
} }
if (version >= 2) {
priv->averaging_factor = pp_u16(pp);
}
} }
/** Write to a binary buffer for storing in Flash */ /** Write to a binary buffer for storing in Flash */
@ -32,7 +35,7 @@ void UADC_writeBinary(Unit *unit, PayloadBuilder *pb)
{ {
struct priv *priv = unit->data; struct priv *priv = unit->data;
pb_u8(pb, 1); // version pb_u8(pb, 2); // version
pb_u16(pb, priv->channels); pb_u16(pb, priv->channels);
pb_bool(pb, priv->enable_tsense); pb_bool(pb, priv->enable_tsense);
@ -40,6 +43,7 @@ void UADC_writeBinary(Unit *unit, PayloadBuilder *pb)
pb_u8(pb, priv->sample_time); pb_u8(pb, priv->sample_time);
pb_u32(pb, priv->frequency); pb_u32(pb, priv->frequency);
pb_u16(pb, priv->buffer_size); pb_u16(pb, priv->buffer_size);
pb_u16(pb, priv->averaging_factor);
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -69,6 +73,10 @@ error_t UADC_loadIni(Unit *unit, const char *key, const char *value)
else if (streq(key, "buffer_size")) { else if (streq(key, "buffer_size")) {
priv->buffer_size = (uint16_t) avr_atoi(value); priv->buffer_size = (uint16_t) avr_atoi(value);
} }
else if (streq(key, "avg_factor")) {
priv->averaging_factor = (uint16_t) avr_atoi(value);
if (priv->averaging_factor > 1000) return E_BAD_VALUE;
}
else { else {
return E_BAD_KEY; return E_BAD_KEY;
} }
@ -106,10 +114,9 @@ void UADC_writeIni(Unit *unit, IniWriter *iw)
iw_entry(iw, "buffer_size", "%d", (int)priv->buffer_size); iw_entry(iw, "buffer_size", "%d", (int)priv->buffer_size);
iw_cmt_newline(iw); iw_cmt_newline(iw);
iw_comment(iw, "Enable exponential averaging (only when not streaming)"); iw_comment(iw, "Exponential averaging coefficient (permil, range 0-1000 ~ 0.000-1.000)");
iw_comment(iw, "Used formula: y[t]=(1-k)*y[t-1]+k*u[t]"); iw_comment(iw, "- used formula: y[t]=(1-k)*y[t-1]+k*u[t]");
iw_entry(iw, "averaging", str_yn(priv->enable_averaging)); iw_comment(iw, "- available only for direct readout (i.e. not used in block capture)");
iw_comment(iw, "Averaging factor k (permil, range 0-1000 ~ 0.000-1.000)");
iw_entry(iw, "avg_factor", "%d", priv->averaging_factor); iw_entry(iw, "avg_factor", "%d", priv->averaging_factor);
} }

@ -11,13 +11,195 @@
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
enum TplCmd_ { enum TplCmd_ {
CMD_DUMMY, CMD_READ_RAW = 0,
CMD_READ_SMOOTHED = 1,
CMD_GET_ENABLED_CHANNELS = 10,
CMD_SETUP_TRIGGER = 20,
CMD_ARM = 21,
CMD_DISARM = 22,
CMD_ABORT = 23, // abort any ongoing capture or stream
CMD_FORCE_TRIGGER = 24,
CMD_BLOCK_CAPTURE = 25,
CMD_STREAM_START = 26,
CMD_STREAM_STOP = 27,
}; };
/** Handle a request message */ /** Handle a request message */
static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, PayloadParser *pp) static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, PayloadParser *pp)
{ {
struct priv *priv = unit->data;
PayloadBuilder pb = pb_start(unit_tmp512, UNIT_TMP_LEN, NULL);
switch (command) { switch (command) {
case CMD_GET_ENABLED_CHANNELS:
dbg("> Query channels");
for (uint8_t i = 0; i < 18; i++) {
if (priv->extended_channels_mask & (1 << i)) {
pb_u8(&pb, i);
}
}
com_respond_pb(frame_id, MSG_SUCCESS, &pb);
return E_SUCCESS;
case CMD_READ_RAW:
dbg("> Read raw");
if(priv->opmode != ADC_OPMODE_IDLE && priv->opmode != ADC_OPMODE_ARMED) {
return E_BUSY;
}
for (uint8_t i = 0; i < 18; i++) {
if (priv->extended_channels_mask & (1 << i)) {
pb_u8(&pb, i);
pb_u16(&pb, priv->last_samples[i]);
}
}
assert_param(pb.ok);
com_respond_pb(frame_id, MSG_SUCCESS, &pb);
return E_SUCCESS;
case CMD_READ_SMOOTHED:
dbg("> Read smoothed");
if(priv->opmode != ADC_OPMODE_IDLE && priv->opmode != ADC_OPMODE_ARMED) {
return E_BUSY;
}
for (uint8_t i = 0; i < 18; i++) {
if (priv->extended_channels_mask & (1 << i)) {
pb_u8(&pb, i);
pb_float(&pb, priv->averaging_bins[i]);
}
}
assert_param(pb.ok);
com_respond_pb(frame_id, MSG_SUCCESS, &pb);
return E_SUCCESS;
case CMD_SETUP_TRIGGER:
dbg("> Setup trigger");
if(priv->opmode != ADC_OPMODE_IDLE) return E_BUSY;
{
uint8_t source = pp_u8(pp);
uint16_t level = pp_u16(pp);
uint8_t edge = pp_u8(pp);
uint16_t pretrig = pp_u16(pp);
uint32_t count = pp_u32(pp);
uint16_t holdoff = pp_u16(pp);
bool auto_rearm = pp_bool(pp);
if (source > 17) {
com_respond_str(MSG_ERROR, frame_id, "Invalid trig source");
return E_FAILURE;
}
if (0 == (priv->extended_channels_mask & (1 << source))) {
com_respond_str(MSG_ERROR, frame_id, "Channel not enabled");
return E_FAILURE;
}
if (level > 4095) {
com_respond_str(MSG_ERROR, frame_id, "Level out of range (0-4095)");
return E_FAILURE;
}
if (edge == 0 || edge > 3) {
com_respond_str(MSG_ERROR, frame_id, "Bad edge");
return E_FAILURE;
}
// XXX the max size may be too much
uint16_t max_pretrig = (priv->dma_buffer_itemcount / priv->nb_channels);
if (pretrig > max_pretrig) {
com_respond_snprintf(frame_id, MSG_ERROR,
"Pretrig too large (max %d)", (int) max_pretrig);
return E_FAILURE;
}
priv->trigger_source = source;
priv->trig_level = level;
priv->trig_prev_level = priv->last_samples[source];
priv->trig_edge = edge;
priv->pretrig_len = pretrig;
priv->trig_len = count;
priv->trig_holdoff = holdoff;
priv->auto_rearm = auto_rearm;
}
return E_SUCCESS;
case CMD_ARM:
dbg("> Arm");
if(priv->opmode != ADC_OPMODE_IDLE) return E_BUSY;
if (priv->trig_len == 0) {
com_respond_str(MSG_ERROR, frame_id, "Trigger not configured.");
return E_FAILURE;
}
UADC_SwitchMode(unit, ADC_OPMODE_ARMED);
return E_SUCCESS;
case CMD_DISARM:
dbg("> Disarm");
if(priv->opmode == ADC_OPMODE_IDLE) {
return E_SUCCESS; // already idle, success - no work to do
}
// capture in progress
if(priv->opmode != ADC_OPMODE_ARMED) return E_BUSY;
UADC_SwitchMode(unit, ADC_OPMODE_IDLE);
return E_SUCCESS;
case CMD_ABORT:;
dbg("> Abort capture");
enum uadc_opmode old_opmode = priv->opmode;
UADC_SwitchMode(unit, ADC_OPMODE_IDLE);
if (old_opmode == ADC_OPMODE_FIXCAPT ||
old_opmode == ADC_OPMODE_STREAM ||
old_opmode == ADC_OPMODE_TRIGD) {
UADC_ReportEndOfStream(unit);
}
return E_SUCCESS;
case CMD_FORCE_TRIGGER:
dbg("> Force trigger");
if(priv->opmode == ADC_OPMODE_IDLE) {
com_respond_str(MSG_ERROR, frame_id, "Not armed");
return E_FAILURE;
}
if(priv->opmode != ADC_OPMODE_ARMED) return E_BUSY;
UADC_HandleTrigger(unit, 0b11, PTIM_GetMicrotime());
return E_SUCCESS;
case CMD_BLOCK_CAPTURE:
dbg("> Block cpt");
if(priv->opmode != ADC_OPMODE_ARMED &&
priv->opmode != ADC_OPMODE_IDLE) return E_BUSY;
uint32_t count = pp_u32(pp);
UADC_StartBlockCapture(unit, count, frame_id);
return E_SUCCESS;
case CMD_STREAM_START:
dbg("> Stream ON");
if(priv->opmode != ADC_OPMODE_ARMED &&
priv->opmode != ADC_OPMODE_IDLE) return E_BUSY;
UADC_StartStream(unit, frame_id);
return E_SUCCESS;
case CMD_STREAM_STOP:
dbg("> Stream OFF");
if(priv->opmode != ADC_OPMODE_STREAM) {
com_respond_str(MSG_ERROR, frame_id, "Not streaming");
return E_FAILURE;
}
UADC_StopStream(unit);
return E_SUCCESS;
default: default:
return E_UNKNOWN_COMMAND; return E_UNKNOWN_COMMAND;
} }
@ -28,7 +210,7 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P
/** Unit template */ /** Unit template */
const UnitDriver UNIT_ADC = { const UnitDriver UNIT_ADC = {
.name = "ADC", .name = "ADC",
.description = "Analog inputs", .description = "Analog/Digital converter",
// Settings // Settings
.preInit = UADC_preInit, .preInit = UADC_preInit,
.cfgLoadBinary = UADC_loadBinary, .cfgLoadBinary = UADC_loadBinary,

@ -13,7 +13,7 @@
#define X_ERROR_CODES \ #define X_ERROR_CODES \
/* Shared errors */ \ /* Shared errors */ \
X(SUCCESS, NULL) /* operation succeeded / unit loaded. Must be 0 */ \ X(SUCCESS, NULL) /* operation succeeded / unit loaded. Must be 0 */ \
X(FAILURE, NULL) /* generic error */ \ X(FAILURE, NULL) /* generic error. If returned from a unit handler, does NOT generate a response. */ \
X(INTERNAL_ERROR, NULL) /* a bug */ \ X(INTERNAL_ERROR, NULL) /* a bug */ \
X(LOADING, NULL) /* unit is loading */ \ X(LOADING, NULL) /* unit is loading */ \
X(UNKNOWN_COMMAND, NULL) \ X(UNKNOWN_COMMAND, NULL) \

Loading…
Cancel
Save