|
|
@ -140,38 +140,17 @@ void UADC_ReportEndOfStream(Unit *unit) |
|
|
|
scheduleJob(&j); |
|
|
|
scheduleJob(&j); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void UADC_DMA_Handler(void *arg) |
|
|
|
static void handle_httc(Unit *unit, bool tc) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Unit *unit = arg; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert_param(unit); |
|
|
|
|
|
|
|
struct priv *priv = unit->data; |
|
|
|
struct priv *priv = unit->data; |
|
|
|
assert_param(priv); |
|
|
|
uint16_t start = priv->stream_startpos; |
|
|
|
|
|
|
|
uint16_t end; |
|
|
|
if (priv->opmode == ADC_OPMODE_UNINIT) { |
|
|
|
const bool ht = !tc; |
|
|
|
LL_DMA_ClearFlag_HT(priv->DMAx, priv->dma_chnum); |
|
|
|
|
|
|
|
LL_DMA_ClearFlag_TC(priv->DMAx, priv->dma_chnum); |
|
|
|
|
|
|
|
LL_DMA_ClearFlag_TE(priv->DMAx, priv->dma_chnum); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const uint32_t isrsnapshot = priv->DMAx->ISR; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (LL_DMA_IsActiveFlag_G(isrsnapshot, priv->dma_chnum)) { |
|
|
|
|
|
|
|
const bool tc = LL_DMA_IsActiveFlag_TC(isrsnapshot, priv->dma_chnum); |
|
|
|
|
|
|
|
const bool ht = LL_DMA_IsActiveFlag_HT(isrsnapshot, priv->dma_chnum); |
|
|
|
|
|
|
|
const bool te = LL_DMA_IsActiveFlag_TE(isrsnapshot, priv->dma_chnum); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check what mode we're in
|
|
|
|
|
|
|
|
const bool m_trigd = priv->opmode == ADC_OPMODE_TRIGD; |
|
|
|
const bool m_trigd = priv->opmode == ADC_OPMODE_TRIGD; |
|
|
|
const bool m_stream = priv->opmode == ADC_OPMODE_STREAM; |
|
|
|
const bool m_stream = priv->opmode == ADC_OPMODE_STREAM; |
|
|
|
const bool m_fixcpt = priv->opmode == ADC_OPMODE_BLCAP; |
|
|
|
const bool m_fixcpt = priv->opmode == ADC_OPMODE_BLCAP; |
|
|
|
|
|
|
|
|
|
|
|
if (m_trigd || m_stream || m_fixcpt) { |
|
|
|
|
|
|
|
if (ht || tc) { |
|
|
|
|
|
|
|
const uint16_t start = priv->stream_startpos; |
|
|
|
|
|
|
|
uint16_t end; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ht) { |
|
|
|
if (ht) { |
|
|
|
// dbg("HT");
|
|
|
|
// dbg("HT");
|
|
|
|
end = (uint16_t) (priv->dma_buffer_itemcount / 2); |
|
|
|
end = (uint16_t) (priv->dma_buffer_itemcount / 2); |
|
|
@ -183,10 +162,12 @@ void UADC_DMA_Handler(void *arg) |
|
|
|
LL_DMA_ClearFlag_TC(priv->DMAx, priv->dma_chnum); |
|
|
|
LL_DMA_ClearFlag_TC(priv->DMAx, priv->dma_chnum); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (start > end) { |
|
|
|
if (ht == tc) { |
|
|
|
dbg("start %d, end %d", (int) start, (int) end); |
|
|
|
// This shouldn't happen - looks like we missed the TC flag
|
|
|
|
|
|
|
|
dbg("!! %d -> %d", (int) start, (int) end); |
|
|
|
|
|
|
|
// TODO we could try to catch up. for now, just take what is easy to grab and hope it doesnt matter
|
|
|
|
|
|
|
|
if (end == 64) start = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
assert_param(start <= end); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (start != end) { |
|
|
|
if (start != end) { |
|
|
|
uint32_t sgcount = (end - start) / priv->nb_channels; |
|
|
|
uint32_t sgcount = (end - start) / priv->nb_channels; |
|
|
@ -232,6 +213,49 @@ void UADC_DMA_Handler(void *arg) |
|
|
|
priv->stream_startpos = end; |
|
|
|
priv->stream_startpos = end; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void UADC_DMA_Handler(void *arg) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Unit *unit = arg; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert_param(unit); |
|
|
|
|
|
|
|
struct priv *priv = unit->data; |
|
|
|
|
|
|
|
assert_param(priv); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (priv->opmode == ADC_OPMODE_UNINIT) { |
|
|
|
|
|
|
|
LL_DMA_ClearFlag_HT(priv->DMAx, priv->dma_chnum); |
|
|
|
|
|
|
|
LL_DMA_ClearFlag_TC(priv->DMAx, priv->dma_chnum); |
|
|
|
|
|
|
|
LL_DMA_ClearFlag_TE(priv->DMAx, priv->dma_chnum); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const uint32_t isrsnapshot = priv->DMAx->ISR; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (LL_DMA_IsActiveFlag_G(isrsnapshot, priv->dma_chnum)) { |
|
|
|
|
|
|
|
const bool tc = LL_DMA_IsActiveFlag_TC(isrsnapshot, priv->dma_chnum); |
|
|
|
|
|
|
|
const bool ht = LL_DMA_IsActiveFlag_HT(isrsnapshot, priv->dma_chnum); |
|
|
|
|
|
|
|
const bool te = LL_DMA_IsActiveFlag_TE(isrsnapshot, priv->dma_chnum); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check what mode we're in
|
|
|
|
|
|
|
|
const bool m_trigd = priv->opmode == ADC_OPMODE_TRIGD; |
|
|
|
|
|
|
|
const bool m_stream = priv->opmode == ADC_OPMODE_STREAM; |
|
|
|
|
|
|
|
const bool m_fixcpt = priv->opmode == ADC_OPMODE_BLCAP; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (m_trigd || m_stream || m_fixcpt) { |
|
|
|
|
|
|
|
if (ht || tc) { |
|
|
|
|
|
|
|
if (ht && tc) { |
|
|
|
|
|
|
|
uint16_t half = (uint16_t) (priv->dma_buffer_itemcount / 2); |
|
|
|
|
|
|
|
if (priv->stream_startpos > half) { |
|
|
|
|
|
|
|
handle_httc(unit, true); |
|
|
|
|
|
|
|
handle_httc(unit, false); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
handle_httc(unit, false); |
|
|
|
|
|
|
|
handle_httc(unit, true); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
handle_httc(unit, tc); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// This shouldn't happen, the interrupt should be disabled in this opmode
|
|
|
|
// This shouldn't happen, the interrupt should be disabled in this opmode
|
|
|
|
dbg("(!) not streaming, DMA IT should be disabled"); |
|
|
|
dbg("(!) not streaming, DMA IT should be disabled"); |
|
|
@ -259,13 +283,9 @@ void UADC_ADC_EOS_Handler(void *arg) |
|
|
|
struct priv *priv = unit->data; |
|
|
|
struct priv *priv = unit->data; |
|
|
|
assert_param(priv); |
|
|
|
assert_param(priv); |
|
|
|
|
|
|
|
|
|
|
|
const bool trig_ready4_rising = (priv->trig_prev_level < priv->trig_level) && (bool) (priv->trig_edge & 0b01); |
|
|
|
|
|
|
|
const bool trig_ready4_falling = (priv->trig_prev_level > priv->trig_level) && (bool) (priv->trig_edge & 0b10); |
|
|
|
|
|
|
|
const bool armed = (trig_ready4_rising && trig_ready4_falling) && priv->opmode == ADC_OPMODE_ARMED; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Normally
|
|
|
|
// Normally
|
|
|
|
uint64_t timestamp = 0; |
|
|
|
uint64_t timestamp = 0; |
|
|
|
if (armed) timestamp = PTIM_GetMicrotime(); |
|
|
|
if (priv->opmode == ADC_OPMODE_ARMED) timestamp = PTIM_GetMicrotime(); |
|
|
|
|
|
|
|
|
|
|
|
LL_ADC_ClearFlag_EOS(priv->ADCx); |
|
|
|
LL_ADC_ClearFlag_EOS(priv->ADCx); |
|
|
|
if (priv->opmode == ADC_OPMODE_UNINIT) return; |
|
|
|
if (priv->opmode == ADC_OPMODE_UNINIT) return; |
|
|
@ -284,14 +304,12 @@ void UADC_ADC_EOS_Handler(void *arg) |
|
|
|
|
|
|
|
|
|
|
|
int cnt = 0; // index of the sample within the group
|
|
|
|
int cnt = 0; // index of the sample within the group
|
|
|
|
|
|
|
|
|
|
|
|
const uint8_t trig_source = priv->trigger_source; |
|
|
|
|
|
|
|
const bool can_average = priv->real_frequency_int < UADC_MAX_FREQ_FOR_AVERAGING; |
|
|
|
const bool can_average = priv->real_frequency_int < UADC_MAX_FREQ_FOR_AVERAGING; |
|
|
|
const uint16_t *dma_buffer = priv->dma_buffer; |
|
|
|
|
|
|
|
const uint32_t channels_mask = priv->extended_channels_mask; |
|
|
|
const uint32_t channels_mask = priv->extended_channels_mask; |
|
|
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < 18; i++) { |
|
|
|
for (uint8_t i = 0; i < 18; i++) { |
|
|
|
if (channels_mask & (1 << i)) { |
|
|
|
if (channels_mask & (1 << i)) { |
|
|
|
uint16_t val = dma_buffer[sample_pos+cnt]; |
|
|
|
uint16_t val = priv->dma_buffer[sample_pos+cnt]; |
|
|
|
cnt++; |
|
|
|
cnt++; |
|
|
|
|
|
|
|
|
|
|
|
if (can_average) { |
|
|
|
if (can_average) { |
|
|
@ -301,24 +319,27 @@ void UADC_ADC_EOS_Handler(void *arg) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
priv->last_samples[i] = val; |
|
|
|
priv->last_samples[i] = val; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (priv->opmode == ADC_OPMODE_ARMED) { |
|
|
|
|
|
|
|
uint16_t val = priv->last_samples[priv->trigger_source]; |
|
|
|
|
|
|
|
|
|
|
|
if (armed && i == trig_source) { |
|
|
|
|
|
|
|
// dbg("Trig line level %d", (int)val);
|
|
|
|
// dbg("Trig line level %d", (int)val);
|
|
|
|
if (trig_ready4_rising && val >= priv->trig_level) { |
|
|
|
if ((priv->trig_prev_level < priv->trig_level) && val >= priv->trig_level && (bool) (priv->trig_edge & 0b01)) { |
|
|
|
// dbg("******** Rising edge");
|
|
|
|
// dbg("******** Rising edge");
|
|
|
|
// Rising edge
|
|
|
|
// Rising edge
|
|
|
|
UADC_HandleTrigger(unit, 1, timestamp); |
|
|
|
UADC_HandleTrigger(unit, 1, timestamp); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (trig_ready4_falling && val <= priv->trig_level) { |
|
|
|
else if ((priv->trig_prev_level > priv->trig_level) && val <= priv->trig_level && (bool) (priv->trig_edge & 0b10)) { |
|
|
|
// dbg("******** Falling edge");
|
|
|
|
// dbg("******** Falling edge");
|
|
|
|
// Falling edge
|
|
|
|
// Falling edge
|
|
|
|
UADC_HandleTrigger(unit, 2, timestamp); |
|
|
|
UADC_HandleTrigger(unit, 2, timestamp); |
|
|
|
} |
|
|
|
} |
|
|
|
priv->trig_prev_level = val; |
|
|
|
priv->trig_prev_level = val; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// auto-rearm was waiting for the next sample
|
|
|
|
if (priv->opmode == ADC_OPMODE_REARM_PENDING) { |
|
|
|
if (priv->opmode == ADC_OPMODE_REARM_PENDING) { |
|
|
|
if (!priv->auto_rearm) { |
|
|
|
if (!priv->auto_rearm) { |
|
|
|
// It looks like the flag was cleared by DISARM before we got a new sample.
|
|
|
|
// It looks like the flag was cleared by DISARM before we got a new sample.
|
|
|
|