triggering works, also autotrig

adc
Ondřej Hruška 7 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) { if (pUnit->callsign == callsign && pUnit->status == E_SUCCESS) {
error_t rv = pUnit->driver->handleRequest(pUnit, msg->frame_id, command, &pp); 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. // send extra SUCCESS confirmation message.
// error is expected to have already been reported. // error is expected to have already been reported.
if (rv == E_SUCCESS) { if (rv == E_SUCCESS) {

@ -51,27 +51,37 @@ void UADC_DMA_Handler(void *arg)
LL_DMA_ClearFlag_TC(priv->DMAx, priv->dma_chnum); 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) { if (m_trig || m_fixcpt) {
sgcount = MIN(priv->trig_stream_remain, sgcount); sgcount = MIN(priv->trig_stream_remain, sgcount);
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)); dbg("Would send %d groups (u16 offset %d -> %d)", (int) sgcount,
// TODO send the data together with remaining count (used to detect end of transmission) (int) start, (int) (start + sgcount * priv->nb_channels));
if (m_trig || m_fixcpt) { // TODO send the data together with remaining count (used to detect end of transmission)
if (priv->trig_stream_remain == 0) {
dbg("End of capture"); if (m_trig || m_fixcpt) {
UADC_ReportEndOfStream(unit); if (priv->trig_stream_remain == 0) {
UADC_SwitchMode(unit, (priv->auto_rearm && m_trig) ? ADC_OPMODE_ARMED : ADC_OPMODE_IDLE); 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; priv->stream_startpos = 0;
} }
else { else {
@ -181,11 +191,13 @@ void UADC_HandleTrigger(Unit *unit, uint8_t edge_type, uint64_t timestamp)
unit->_tick_cnt = 0; unit->_tick_cnt = 0;
} }
dbg("Trigger condition hit, edge=%d", edge_type);
// TODO Send pre-trigger // 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;
dbg("Trigger condition hit, edge=%d, startpos %d", edge_type, (int)priv->stream_startpos);
UADC_SwitchMode(unit, ADC_OPMODE_TRIGD); 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); LL_DMA_DisableIT_TC(priv->DMAx, priv->dma_chnum);
// Use End Of Sequence to recover results for averaging from the DMA buffer and DR // 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); LL_ADC_EnableIT_EOS(priv->ADCx);
if (priv->opmode == ADC_OPMODE_UNINIT) { 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); LL_ADC_DisableIT_EOS(priv->ADCx);
// Enable the DMA buffer interrupts // 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_HT(priv->DMAx, priv->dma_chnum);
LL_DMA_EnableIT_TC(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. * Response: bytes with indices of enabled channels, ascending order.
*/ */
case CMD_GET_ENABLED_CHANNELS: case CMD_GET_ENABLED_CHANNELS:
dbg("> Query channels");
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_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 * pld: u16:factor
*/ */
case CMD_SET_SMOOTHING_FACTOR: case CMD_SET_SMOOTHING_FACTOR:
dbg("> Set smoothing"); {
uint16_t fac = pp_u16(pp); uint16_t fac = pp_u16(pp);
if (fac > 1000) return E_BAD_VALUE; if (fac > 1000) return E_BAD_VALUE;
priv->avg_factor_as_float = fac/1000.0f; priv->avg_factor_as_float = fac / 1000.0f;
}
return E_SUCCESS; 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 * Response: interleaved (u8:channel, u16:value) for all channels
*/ */
case CMD_READ_RAW: case CMD_READ_RAW:
dbg("> Read raw");
if(priv->opmode != ADC_OPMODE_IDLE && priv->opmode != ADC_OPMODE_ARMED) { if(priv->opmode != ADC_OPMODE_IDLE && priv->opmode != ADC_OPMODE_ARMED) {
return E_BUSY; 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]); pb_u16(&pb, priv->last_samples[i]);
} }
} }
assert_param(pb.ok);
com_respond_pb(frame_id, MSG_SUCCESS, &pb); com_respond_pb(frame_id, MSG_SUCCESS, &pb);
return E_SUCCESS; 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 * Response: interleaved (u8:channel, f32:value) for all channels
*/ */
case CMD_READ_SMOOTHED: case CMD_READ_SMOOTHED:
dbg("> Read smoothed");
if(priv->opmode != ADC_OPMODE_IDLE && priv->opmode != ADC_OPMODE_ARMED) { if(priv->opmode != ADC_OPMODE_IDLE && priv->opmode != ADC_OPMODE_ARMED) {
return E_BUSY; 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]); pb_float(&pb, priv->averaging_bins[i]);
} }
} }
assert_param(pb.ok);
com_respond_pb(frame_id, MSG_SUCCESS, &pb); com_respond_pb(frame_id, MSG_SUCCESS, &pb);
return E_SUCCESS; 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: * Payload:
* u8 - source channel * 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: case CMD_SETUP_TRIGGER:
dbg("> 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); 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; 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); UADC_SwitchMode(unit, ADC_OPMODE_ARMED);
return E_SUCCESS; return E_SUCCESS;

Loading…
Cancel
Save