fixeng stuff up , block capture verified and implemented in python

adc
Ondřej Hruška 6 years ago
parent 72b331bce5
commit 835423099b
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 30
      comm/msg_responses.c
  2. 95
      units/adc/_adc_core.c
  3. 10
      units/adc/_adc_internal.h
  4. 2
      units/adc/unit_adc.c

@ -21,14 +21,13 @@ void com_respond_snprintf(TF_ID frame_id, TF_TYPE type, const char *format, ...)
void com_respond_buf(TF_ID frame_id, TF_TYPE type, const uint8_t *buf, uint32_t len) void com_respond_buf(TF_ID frame_id, TF_TYPE type, const uint8_t *buf, uint32_t len)
{ {
TF_Msg msg; TF_Msg msg = {
TF_ClearMsg(&msg); .type = type,
{ .frame_id = frame_id,
msg.type = type; .data = buf,
msg.frame_id = frame_id; .len = (TF_LEN) len,
msg.data = buf; };
msg.len = (TF_LEN) len;
}
TF_Respond(comm, &msg); TF_Respond(comm, &msg);
} }
@ -57,14 +56,13 @@ void com_send_pb(TF_TYPE type, PayloadBuilder *pb)
void com_send_buf(TF_TYPE type, const uint8_t *buf, uint32_t len) void com_send_buf(TF_TYPE type, const uint8_t *buf, uint32_t len)
{ {
TF_Msg msg; TF_Msg msg = {
TF_ClearMsg(&msg); .type = MSG_UNIT_REPORT,
{ .data = buf,
msg.type = MSG_UNIT_REPORT; .len = (TF_LEN) len,
msg.data = buf; .type = type,
msg.len = (TF_LEN) len; };
msg.type = type;
}
TF_Send(comm, &msg); // no listener TF_Send(comm, &msg); // no listener
} }

@ -10,9 +10,61 @@
#define DMA_POS(priv) ((priv)->dma_buffer_itemcount - (priv)->DMA_CHx->CNDTR) #define DMA_POS(priv) ((priv)->dma_buffer_itemcount - (priv)->DMA_CHx->CNDTR)
static void UADC_JobSendBlockChunk(Job *job)
{
Unit *unit = job->unit;
assert_param(unit);
struct priv *priv = unit->data;
assert_param(priv);
uint32_t start = job->data1;
uint32_t count = job->data2;
bool close = (bool) job->data3;
dbg("Send indices [%d -> %d)", (int)start, (int)(start+count));
TF_TYPE type = close ? EVT_CAPT_DONE : EVT_CAPT_MORE;
TF_Msg msg = {
.frame_id = priv->stream_frame_id,
.len = (TF_LEN) (1 + count*sizeof(uint16_t)),
.type = type,
};
TF_Respond_Multipart(comm, &msg);
TF_Multipart_Payload(comm, &priv->stream_serial, 1);
TF_Multipart_Payload(comm, (uint8_t *) (priv->dma_buffer + start), count * sizeof(uint16_t));
TF_Multipart_Close(comm);
priv->stream_serial++;
}
static void UADC_JobSendEndOfStreamMsg(Job *job)
{
Unit *unit = job->unit;
assert_param(unit);
struct priv *priv = unit->data;
assert_param(priv);
TF_Msg msg = {
.type = EVT_CAPT_DONE,
.frame_id = (TF_ID) job->data1
};
TF_Respond(comm, &msg);
}
void UADC_ReportEndOfStream(Unit *unit) void UADC_ReportEndOfStream(Unit *unit)
{ {
dbg("~~End Of Stream msg~~"); assert_param(unit);
struct priv *priv = unit->data;
assert_param(priv);
Job j = {
.unit = unit,
.data1 = priv->stream_frame_id,
.cb = UADC_JobSendEndOfStreamMsg
};
scheduleJob(&j);
} }
void UADC_DMA_Handler(void *arg) void UADC_DMA_Handler(void *arg)
@ -62,22 +114,24 @@ void UADC_DMA_Handler(void *arg)
priv->trig_stream_remain -= sgcount; priv->trig_stream_remain -= sgcount;
} }
dbg("Would send %d groups (u16 offset %d -> %d)", (int) sgcount, bool close = !m_stream && priv->trig_stream_remain == 0;
(int) start, (int) (start + sgcount * priv->nb_channels));
Job j = {
// TODO send the data together with remaining count (used to detect end of transmission) .unit = unit,
.data1 = start,
if (m_trigd || m_fixcpt) { // Trig'd or Block capture - check for the max count condition .data2 = sgcount * priv->nb_channels,
if (priv->trig_stream_remain == 0) { .data3 = (uint32_t) close,
dbg("End of capture"); .cb = UADC_JobSendBlockChunk
UADC_ReportEndOfStream(unit); };
scheduleJob(&j);
// If auto-arm enabled, we need to re-arm again.
// However, EOS irq is disabled during the capture. if (close) {
// We have to wait for the next EOS interrupt to occur. dbg("End of capture");
// TODO verify if keeping the EOS irq enabled during capture has significant performance penalty. If not, we can leave it enabled. // If auto-arm enabled, we need to re-arm again.
UADC_SwitchMode(unit, (priv->auto_rearm && m_trigd) ? ADC_OPMODE_REARM_PENDING : ADC_OPMODE_IDLE); // However, EOS irq is disabled during the capture.
} // We have to wait for the next EOS interrupt to occur.
// TODO verify if keeping the EOS irq enabled during capture has significant performance penalty. If not, we can leave it enabled.
UADC_SwitchMode(unit, (priv->auto_rearm && m_trigd) ? ADC_OPMODE_REARM_PENDING : ADC_OPMODE_IDLE);
} }
} else { } else {
dbg("start==end, skip this irq"); dbg("start==end, skip this irq");
@ -203,10 +257,11 @@ void UADC_HandleTrigger(Unit *unit, uint8_t edge_type, uint64_t timestamp)
unit->_tick_cnt = 0; unit->_tick_cnt = 0;
} }
// TODO Send pre-trigger
priv->stream_startpos = (uint16_t) DMA_POS(priv); priv->stream_startpos = (uint16_t) DMA_POS(priv);
priv->trig_stream_remain = priv->trig_len; priv->trig_stream_remain = priv->trig_len;
priv->stream_serial = 0;
// TODO Send pre-trigger
dbg("Trigger condition hit, edge=%d, startpos %d", edge_type, (int)priv->stream_startpos); dbg("Trigger condition hit, edge=%d, startpos %d", edge_type, (int)priv->stream_startpos);
@ -222,6 +277,7 @@ void UADC_StartBlockCapture(Unit *unit, uint32_t len, TF_ID frame_id)
priv->stream_frame_id = frame_id; priv->stream_frame_id = frame_id;
priv->stream_startpos = (uint16_t) DMA_POS(priv); priv->stream_startpos = (uint16_t) DMA_POS(priv);
priv->trig_stream_remain = len; priv->trig_stream_remain = len;
priv->stream_serial = 0;
UADC_SwitchMode(unit, ADC_OPMODE_BLCAP); UADC_SwitchMode(unit, ADC_OPMODE_BLCAP);
} }
@ -234,6 +290,7 @@ void UADC_StartStream(Unit *unit, TF_ID frame_id)
priv->stream_frame_id = frame_id; priv->stream_frame_id = frame_id;
priv->stream_startpos = (uint16_t) DMA_POS(priv); priv->stream_startpos = (uint16_t) DMA_POS(priv);
priv->stream_serial = 0;
dbg("Start streaming."); dbg("Start streaming.");
UADC_SwitchMode(unit, ADC_OPMODE_STREAM); UADC_SwitchMode(unit, ADC_OPMODE_STREAM);
} }

@ -17,10 +17,17 @@ enum uadc_opmode {
ADC_OPMODE_REARM_PENDING, //!< Idle, waiting for the next sample to re-arm (auto trigger). ADC_OPMODE_REARM_PENDING, //!< Idle, waiting for the next sample to re-arm (auto trigger).
ADC_OPMODE_ARMED, //!< Armed for a trigger. Direct access and averaging are disabled. ADC_OPMODE_ARMED, //!< Armed for a trigger. Direct access and averaging are disabled.
ADC_OPMODE_TRIGD, //!< Triggered, sending pre-trigger and streaming captured data. ADC_OPMODE_TRIGD, //!< Triggered, sending pre-trigger and streaming captured data.
ADC_OPMODE_BLCAP,//!< Capture of fixed length without a trigger ADC_OPMODE_BLCAP, //!< Capture of fixed length without a trigger
ADC_OPMODE_STREAM, //!< Unlimited capture ADC_OPMODE_STREAM, //!< Unlimited capture
}; };
enum uadc_event {
EVT_CAPT_START = 50, //!< Capture start (used in event in the first frame when trigger is detected)
EVT_CAPT_MORE = 51, //!< Capture data payload (used as TYPE for all capture types)
EVT_CAPT_DONE = 52, //!< End of trig'd or block capture payload (last frame with data),
//!< or a farewell message after closing stream using abort(), in this case without data.
};
/** Private data structure */ /** Private data structure */
struct priv { struct priv {
// settings // settings
@ -62,6 +69,7 @@ struct priv {
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
TF_ID stream_frame_id; //!< Session ID for multi-part stream (response or report) TF_ID stream_frame_id; //!< Session ID for multi-part stream (response or report)
uint8_t stream_serial;
}; };
/** Allocate data structure and set defaults */ /** Allocate data structure and set defaults */

@ -70,7 +70,6 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P
for (uint8_t i = 0; i < 18; i++) { for (uint8_t i = 0; i < 18; i++) {
if (priv->extended_channels_mask & (1 << i)) { if (priv->extended_channels_mask & (1 << i)) {
pb_u8(&pb, i);
pb_u16(&pb, priv->last_samples[i]); pb_u16(&pb, priv->last_samples[i]);
} }
} }
@ -88,7 +87,6 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P
for (uint8_t i = 0; i < 18; i++) { for (uint8_t i = 0; i < 18; i++) {
if (priv->extended_channels_mask & (1 << i)) { if (priv->extended_channels_mask & (1 << i)) {
pb_u8(&pb, i);
pb_float(&pb, priv->averaging_bins[i]); pb_float(&pb, priv->averaging_bins[i]);
} }
} }

Loading…
Cancel
Save