From 21d9e976539b97554fc554bbe7aeb04d93420638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sun, 4 Feb 2018 21:24:24 +0100 Subject: [PATCH] added docs --- units/adc/_adc_core.c | 32 ++++++++++++--------- units/adc/unit_adc.c | 66 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 14 deletions(-) diff --git a/units/adc/_adc_core.c b/units/adc/_adc_core.c index aa56d81..b197d6d 100644 --- a/units/adc/_adc_core.c +++ b/units/adc/_adc_core.c @@ -8,6 +8,8 @@ #define ADC_INTERNAL #include "_adc_internal.h" +#define DMA_POS(priv) ((priv)->dma_buffer_itemcount - (priv)->DMA_CHx->CNDTR) + void UADC_ReportEndOfStream(Unit *unit) { dbg("~~End Of Stream msg~~"); @@ -101,27 +103,29 @@ void UADC_ADC_EOS_Handler(void *arg) uint64_t timestamp = PTIM_GetMicrotime(); Unit *unit = arg; - dbg("ADC EOS ISR hit"); assert_param(unit); struct priv *priv = unit->data; assert_param(priv); + LL_ADC_ClearFlag_EOS(priv->ADCx); + // Wait for the DMA to complete copying the last sample - while (priv->DMA_CHx->CNDTR % priv->nb_channels != 0); + uint16_t dmapos; + while ((dmapos = (uint16_t) DMA_POS(priv)) % priv->nb_channels != 0); uint32_t sample_pos; - if (priv->DMA_CHx->CNDTR == 0) { - sample_pos = (uint32_t) (priv->dma_buffer_itemcount - 1); + if (dmapos == 0) { + sample_pos = (uint32_t) (priv->dma_buffer_itemcount); } else { - sample_pos = priv->DMA_CHx->CNDTR; + sample_pos = dmapos; } sample_pos -= priv->nb_channels; - dbg("Sample pos %d", (int)sample_pos); + int cnt = 0; // index of the sample within the group for (uint32_t i = 0; i < 18; i++) { if (priv->extended_channels_mask & (1 << i)) { - uint16_t val = priv->dma_buffer[sample_pos]; - dbg("Trig line level %d", (int)val); + uint16_t val = priv->dma_buffer[sample_pos+cnt]; + cnt++; priv->averaging_bins[i] = priv->averaging_bins[i] * (1.0f - priv->avg_factor_as_float) + @@ -131,6 +135,8 @@ void UADC_ADC_EOS_Handler(void *arg) if (priv->opmode == ADC_OPMODE_ARMED) { if (i == priv->trigger_source) { + dbg("Trig line level %d", (int)val); + bool trigd = false; uint8_t edge_type = 0; if (priv->trig_prev_level < priv->trig_level && val >= priv->trig_level) { @@ -155,8 +161,6 @@ void UADC_ADC_EOS_Handler(void *arg) } } } - - dbg(" EOS ISR end."); } void UADC_HandleTrigger(Unit *unit, uint8_t edge_type, uint64_t timestamp) @@ -180,7 +184,7 @@ void UADC_HandleTrigger(Unit *unit, uint8_t edge_type, uint64_t timestamp) dbg("Trigger condition hit, edge=%d", edge_type); // TODO Send pre-trigger - priv->stream_startpos = (uint16_t) priv->DMA_CHx->CNDTR; + priv->stream_startpos = (uint16_t) DMA_POS(priv); priv->trig_stream_remain = priv->trig_len; UADC_SwitchMode(unit, ADC_OPMODE_TRIGD); } @@ -192,7 +196,7 @@ void UADC_StartBlockCapture(Unit *unit, uint32_t len, TF_ID frame_id) assert_param(priv); priv->stream_frame_id = frame_id; - priv->stream_startpos = (uint16_t) priv->DMA_CHx->CNDTR; + priv->stream_startpos = (uint16_t) DMA_POS(priv); priv->trig_stream_remain = len; UADC_SwitchMode(unit, ADC_OPMODE_FIXCAPT); } @@ -205,7 +209,7 @@ void UADC_StartStream(Unit *unit, TF_ID frame_id) assert_param(priv); priv->stream_frame_id = frame_id; - priv->stream_startpos = (uint16_t) priv->DMA_CHx->CNDTR; + priv->stream_startpos = (uint16_t) DMA_POS(priv); dbg("Start streaming."); UADC_SwitchMode(unit, ADC_OPMODE_STREAM); } @@ -291,6 +295,8 @@ void UADC_SwitchMode(Unit *unit, enum uadc_opmode new_mode) LL_ADC_Enable(priv->ADCx); LL_DMA_EnableChannel(priv->DMAx, priv->dma_chnum); LL_TIM_EnableCounter(priv->TIMx); + + LL_ADC_REG_StartConversion(priv->ADCx); } } else if (new_mode == ADC_OPMODE_ARMED) { diff --git a/units/adc/unit_adc.c b/units/adc/unit_adc.c index 0e5213f..f595e30 100644 --- a/units/adc/unit_adc.c +++ b/units/adc/unit_adc.c @@ -24,6 +24,7 @@ enum TplCmd_ { CMD_BLOCK_CAPTURE = 25, CMD_STREAM_START = 26, CMD_STREAM_STOP = 27, + CMD_SET_SMOOTHING_FACTOR = 28, }; /** Handle a request message */ @@ -33,6 +34,10 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P PayloadBuilder pb = pb_start(unit_tmp512, UNIT_TMP_LEN, NULL); switch (command) { + /** + * Get enabled channels. + * Response: bytes with indices of enabled channels, ascending order. + */ case CMD_GET_ENABLED_CHANNELS: dbg("> Query channels"); for (uint8_t i = 0; i < 18; i++) { @@ -43,6 +48,21 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P com_respond_pb(frame_id, MSG_SUCCESS, &pb); return E_SUCCESS; + /** + * Set smoothing factor 0-1000. + * pld: u16:factor + */ + case CMD_SET_SMOOTHING_FACTOR: + dbg("> Set smoothing"); + uint16_t fac = pp_u16(pp); + if (fac > 1000) return E_BAD_VALUE; + priv->avg_factor_as_float = fac/1000.0f; + return E_SUCCESS; + + /** + * Read raw values from the last measurement. + * Response: interleaved (u8:channel, u16:value) for all channels + */ case CMD_READ_RAW: dbg("> Read raw"); if(priv->opmode != ADC_OPMODE_IDLE && priv->opmode != ADC_OPMODE_ARMED) { @@ -59,6 +79,10 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P com_respond_pb(frame_id, MSG_SUCCESS, &pb); return E_SUCCESS; + /** + * Read smoothed values. + * Response: interleaved (u8:channel, f32:value) for all channels + */ case CMD_READ_SMOOTHED: dbg("> Read smoothed"); if(priv->opmode != ADC_OPMODE_IDLE && priv->opmode != ADC_OPMODE_ARMED) { @@ -75,9 +99,22 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P com_respond_pb(frame_id, MSG_SUCCESS, &pb); return E_SUCCESS; + /** + * Configure a trigger. This is legal only if the current state is IDLE. + * + * Payload: + * u8 - source channel + * u16 - triggering level + * u8 - edge to trigger on: 1-rising, 2-falling, 3-both + * u16 - pre-trigger samples count + * u32 - post-trigger samples count + * u16 - trigger hold-off in ms (dead time after firing, before it cna fire again if armed) + * u8(bool) - auto re-arm after firing and completing the capture + */ 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); @@ -126,6 +163,9 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P } return E_SUCCESS; + /** + * Arm (permissible only if idle and the trigger is configured) + */ case CMD_ARM: dbg("> Arm"); if(priv->opmode != ADC_OPMODE_IDLE) return E_BUSY; @@ -138,6 +178,10 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P UADC_SwitchMode(unit, ADC_OPMODE_ARMED); return E_SUCCESS; + /** + * Dis-arm. Permissible only when idle or armed. + * Switches to idle. + */ case CMD_DISARM: dbg("> Disarm"); if(priv->opmode == ADC_OPMODE_IDLE) { @@ -149,6 +193,9 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P UADC_SwitchMode(unit, ADC_OPMODE_IDLE); return E_SUCCESS; + /** + * Abort any ongoing capture and dis-arm. + */ case CMD_ABORT:; dbg("> Abort capture"); enum uadc_opmode old_opmode = priv->opmode; @@ -161,6 +208,10 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P } return E_SUCCESS; + /** + * Force a trigger (complete with pre-trigger capture and hold-off) + * The reported edge will be 0b11, here meaning "manual trigger" + */ case CMD_FORCE_TRIGGER: dbg("> Force trigger"); if(priv->opmode == ADC_OPMODE_IDLE) { @@ -172,6 +223,12 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P UADC_HandleTrigger(unit, 0b11, PTIM_GetMicrotime()); return E_SUCCESS; + /** + * Start a block capture (like manual trigger, but without pre-trigger and arming) + * + * Payload: + * u32 - sample count (for each channel) + */ case CMD_BLOCK_CAPTURE: dbg("> Block cpt"); if(priv->opmode != ADC_OPMODE_ARMED && @@ -182,6 +239,10 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P UADC_StartBlockCapture(unit, count, frame_id); return E_SUCCESS; + /** + * Start streaming (like block capture, but unlimited) + * The stream can be terminated by the stop command. + */ case CMD_STREAM_START: dbg("> Stream ON"); if(priv->opmode != ADC_OPMODE_ARMED && @@ -190,6 +251,9 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P UADC_StartStream(unit, frame_id); return E_SUCCESS; + /** + * Stop a stream. + */ case CMD_STREAM_STOP: dbg("> Stream OFF"); if(priv->opmode != ADC_OPMODE_STREAM) { @@ -210,7 +274,7 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P /** Unit template */ const UnitDriver UNIT_ADC = { .name = "ADC", - .description = "Analog/Digital converter", + .description = "Analog/digital converter", // Settings .preInit = UADC_preInit, .cfgLoadBinary = UADC_loadBinary,