triggering works, also autotrig

adc
Ondřej Hruška 6 years ago
parent 21d9e97653
commit a4e04dc04e
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 5
      framework/unit_registry.c
  2. 48
      units/adc/_adc_core.c
  3. 21
      units/adc/unit_adc.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) {

@ -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);
}

@ -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;

Loading…
Cancel
Save