From a4e04dc04ebafa0ca4e2de04c4376d3a2a9c2e9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sun, 4 Feb 2018 22:32:22 +0100 Subject: [PATCH] triggering works, also autotrig --- framework/unit_registry.c | 5 ++++ units/adc/_adc_core.c | 48 +++++++++++++++++++++++++++------------ units/adc/unit_adc.c | 21 ++++++++--------- 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/framework/unit_registry.c b/framework/unit_registry.c index ec3e5d3..bb86421 100644 --- a/framework/unit_registry.c +++ b/framework/unit_registry.c @@ -490,6 +490,11 @@ void ureg_deliver_unit_request(TF_Msg *msg) if (pUnit->callsign == callsign && pUnit->status == E_SUCCESS) { error_t rv = pUnit->driver->handleRequest(pUnit, msg->frame_id, command, &pp); + if (!pp.ok) { + com_respond_error(msg->frame_id, E_MALFORMED_COMMAND); + goto quit; + } + // send extra SUCCESS confirmation message. // error is expected to have already been reported. if (rv == E_SUCCESS) { diff --git a/units/adc/_adc_core.c b/units/adc/_adc_core.c index b197d6d..53c0905 100644 --- a/units/adc/_adc_core.c +++ b/units/adc/_adc_core.c @@ -51,27 +51,37 @@ void UADC_DMA_Handler(void *arg) LL_DMA_ClearFlag_TC(priv->DMAx, priv->dma_chnum); } - assert_param(start < end); + dbg("start %d, end %d", (int)start, (int)end); + assert_param(start <= end); - uint32_t sgcount = (end - start) / priv->nb_channels; + if (start != end) { + uint32_t sgcount = (end - start) / priv->nb_channels; - if (m_trig || m_fixcpt) { - sgcount = MIN(priv->trig_stream_remain, sgcount); - priv->trig_stream_remain -= sgcount; - } + if (m_trig || m_fixcpt) { + sgcount = MIN(priv->trig_stream_remain, sgcount); + 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) + dbg("Would send %d groups (u16 offset %d -> %d)", (int) sgcount, + (int) start, (int) (start + sgcount * priv->nb_channels)); - if (m_trig || m_fixcpt) { - if (priv->trig_stream_remain == 0) { - dbg("End of capture"); - UADC_ReportEndOfStream(unit); - UADC_SwitchMode(unit, (priv->auto_rearm && m_trig) ? ADC_OPMODE_ARMED : ADC_OPMODE_IDLE); + // TODO send the data together with remaining count (used to detect end of transmission) + + if (m_trig || m_fixcpt) { + if (priv->trig_stream_remain == 0) { + dbg("End of capture"); + UADC_ReportEndOfStream(unit); + UADC_SwitchMode(unit, ADC_OPMODE_IDLE); + if (priv->auto_rearm && m_trig) { + UADC_SwitchMode(unit, ADC_OPMODE_ARMED); + } + } } + } else { + dbg("start==end, skip this irq"); } - if (end == priv->dma_buffer_itemcount) { + if (tc) { priv->stream_startpos = 0; } else { @@ -181,11 +191,13 @@ void UADC_HandleTrigger(Unit *unit, uint8_t edge_type, uint64_t timestamp) unit->_tick_cnt = 0; } - dbg("Trigger condition hit, edge=%d", edge_type); // TODO Send pre-trigger priv->stream_startpos = (uint16_t) DMA_POS(priv); priv->trig_stream_remain = priv->trig_len; + + dbg("Trigger condition hit, edge=%d, startpos %d", edge_type, (int)priv->stream_startpos); + UADC_SwitchMode(unit, ADC_OPMODE_TRIGD); } @@ -288,6 +300,7 @@ void UADC_SwitchMode(Unit *unit, enum uadc_opmode new_mode) LL_DMA_DisableIT_TC(priv->DMAx, priv->dma_chnum); // Use End Of Sequence to recover results for averaging from the DMA buffer and DR + LL_ADC_ClearFlag_EOS(priv->ADCx); LL_ADC_EnableIT_EOS(priv->ADCx); if (priv->opmode == ADC_OPMODE_UNINIT) { @@ -315,6 +328,11 @@ void UADC_SwitchMode(Unit *unit, enum uadc_opmode new_mode) LL_ADC_DisableIT_EOS(priv->ADCx); // Enable the DMA buffer interrupts + + // we must first clear the flags, otherwise it will cause WEIRD bugs in the handler + LL_DMA_ClearFlag_HT(priv->DMAx, priv->dma_chnum); + LL_DMA_ClearFlag_TC(priv->DMAx, priv->dma_chnum); + LL_DMA_EnableIT_HT(priv->DMAx, priv->dma_chnum); LL_DMA_EnableIT_TC(priv->DMAx, priv->dma_chnum); } diff --git a/units/adc/unit_adc.c b/units/adc/unit_adc.c index f595e30..bc28b71 100644 --- a/units/adc/unit_adc.c +++ b/units/adc/unit_adc.c @@ -39,7 +39,6 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P * 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++) { if (priv->extended_channels_mask & (1 << i)) { pb_u8(&pb, i); @@ -53,10 +52,11 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P * 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; + { + uint16_t fac = pp_u16(pp); + if (fac > 1000) return E_BAD_VALUE; + priv->avg_factor_as_float = fac / 1000.0f; + } return E_SUCCESS; /** @@ -64,7 +64,6 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P * 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) { return E_BUSY; } @@ -75,7 +74,6 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P pb_u16(&pb, priv->last_samples[i]); } } - assert_param(pb.ok); com_respond_pb(frame_id, MSG_SUCCESS, &pb); return E_SUCCESS; @@ -84,7 +82,6 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P * 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) { return E_BUSY; } @@ -95,12 +92,11 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P pb_float(&pb, priv->averaging_bins[i]); } } - assert_param(pb.ok); com_respond_pb(frame_id, MSG_SUCCESS, &pb); return E_SUCCESS; /** - * Configure a trigger. This is legal only if the current state is IDLE. + * Configure a trigger. This is legal only if the current state is IDLE or ARMED (will re-arm). * * Payload: * u8 - source channel @@ -113,7 +109,7 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P */ case CMD_SETUP_TRIGGER: dbg("> Setup trigger"); - if(priv->opmode != ADC_OPMODE_IDLE) return E_BUSY; + if (priv->opmode != ADC_OPMODE_IDLE && priv->opmode != ADC_OPMODE_ARMED) return E_BUSY; { uint8_t source = pp_u8(pp); @@ -175,6 +171,9 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P return E_FAILURE; } + // avoid firing immediately by the value jumping across the scale + priv->trig_prev_level = priv->last_samples[priv->trigger_source]; + UADC_SwitchMode(unit, ADC_OPMODE_ARMED); return E_SUCCESS;