From 835423099b3b739f6dd49ed37baa6039254be642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Wed, 7 Feb 2018 17:17:56 +0100 Subject: [PATCH] fixeng stuff up , block capture verified and implemented in python --- comm/msg_responses.c | 30 ++++++------- units/adc/_adc_core.c | 95 +++++++++++++++++++++++++++++++-------- units/adc/_adc_internal.h | 10 ++++- units/adc/unit_adc.c | 2 - 4 files changed, 99 insertions(+), 38 deletions(-) diff --git a/comm/msg_responses.c b/comm/msg_responses.c index 44df67d..d1887dd 100644 --- a/comm/msg_responses.c +++ b/comm/msg_responses.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) { - TF_Msg msg; - TF_ClearMsg(&msg); - { - msg.type = type; - msg.frame_id = frame_id; - msg.data = buf; - msg.len = (TF_LEN) len; - } + TF_Msg msg = { + .type = type, + .frame_id = frame_id, + .data = buf, + .len = (TF_LEN) len, + }; + 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) { - TF_Msg msg; - TF_ClearMsg(&msg); - { - msg.type = MSG_UNIT_REPORT; - msg.data = buf; - msg.len = (TF_LEN) len; - msg.type = type; - } + TF_Msg msg = { + .type = MSG_UNIT_REPORT, + .data = buf, + .len = (TF_LEN) len, + .type = type, + }; + TF_Send(comm, &msg); // no listener } diff --git a/units/adc/_adc_core.c b/units/adc/_adc_core.c index bf7ef98..c092f2e 100644 --- a/units/adc/_adc_core.c +++ b/units/adc/_adc_core.c @@ -10,9 +10,61 @@ #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) { - 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) @@ -62,22 +114,24 @@ void UADC_DMA_Handler(void *arg) priv->trig_stream_remain -= sgcount; } - dbg("Would send %d groups (u16 offset %d -> %d)", (int) sgcount, - (int) start, (int) (start + sgcount * priv->nb_channels)); - - // TODO send the data together with remaining count (used to detect end of transmission) - - if (m_trigd || m_fixcpt) { // Trig'd or Block capture - check for the max count condition - if (priv->trig_stream_remain == 0) { - dbg("End of capture"); - UADC_ReportEndOfStream(unit); - - // If auto-arm enabled, we need to re-arm again. - // 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); - } + bool close = !m_stream && priv->trig_stream_remain == 0; + + Job j = { + .unit = unit, + .data1 = start, + .data2 = sgcount * priv->nb_channels, + .data3 = (uint32_t) close, + .cb = UADC_JobSendBlockChunk + }; + scheduleJob(&j); + + if (close) { + dbg("End of capture"); + // If auto-arm enabled, we need to re-arm again. + // 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 { 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; } - // TODO Send pre-trigger - priv->stream_startpos = (uint16_t) DMA_POS(priv); 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); @@ -222,6 +277,7 @@ void UADC_StartBlockCapture(Unit *unit, uint32_t len, TF_ID frame_id) priv->stream_frame_id = frame_id; priv->stream_startpos = (uint16_t) DMA_POS(priv); priv->trig_stream_remain = len; + priv->stream_serial = 0; 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_startpos = (uint16_t) DMA_POS(priv); + priv->stream_serial = 0; dbg("Start streaming."); UADC_SwitchMode(unit, ADC_OPMODE_STREAM); } diff --git a/units/adc/_adc_internal.h b/units/adc/_adc_internal.h index b212739..c850536 100644 --- a/units/adc/_adc_internal.h +++ b/units/adc/_adc_internal.h @@ -17,10 +17,17 @@ enum uadc_opmode { 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_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 }; +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 */ struct priv { // settings @@ -62,6 +69,7 @@ struct priv { 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 TF_ID stream_frame_id; //!< Session ID for multi-part stream (response or report) + uint8_t stream_serial; }; /** Allocate data structure and set defaults */ diff --git a/units/adc/unit_adc.c b/units/adc/unit_adc.c index 51dee51..a01ff02 100644 --- a/units/adc/unit_adc.c +++ b/units/adc/unit_adc.c @@ -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++) { if (priv->extended_channels_mask & (1 << i)) { - pb_u8(&pb, 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++) { if (priv->extended_channels_mask & (1 << i)) { - pb_u8(&pb, i); pb_float(&pb, priv->averaging_bins[i]); } }