fixed buffer sizing and added buf size to config

adc
Ondřej Hruška 7 years ago
parent 3ebc19fc2d
commit d8933cbf81
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 13
      units/adc/_adc_init.c
  2. 1
      units/adc/_adc_internal.h
  3. 16
      units/adc/_adc_settings.c

@ -30,7 +30,8 @@ error_t UADC_preInit(Unit *unit)
priv->enable_tsense = false; priv->enable_tsense = false;
priv->enable_vref = false; priv->enable_vref = false;
priv->sample_time = 0b010; // 13.5c priv->sample_time = 0b010; // 13.5c
priv->frequency = 4; //1000 priv->frequency = 1000;
priv->buffer_size = 512;
return E_SUCCESS; return E_SUCCESS;
} }
@ -160,6 +161,7 @@ error_t UADC_init(Unit *unit)
LL_TIM_SetAutoReload(priv->TIMx, count - 1); LL_TIM_SetAutoReload(priv->TIMx, count - 1);
LL_TIM_EnableARRPreload(priv->TIMx); LL_TIM_EnableARRPreload(priv->TIMx);
LL_TIM_EnableUpdateEvent(priv->TIMx); LL_TIM_EnableUpdateEvent(priv->TIMx);
LL_TIM_SetTriggerOutput(priv->TIMx, LL_TIM_TRGO_UPDATE);
LL_TIM_GenerateEvent_UPDATE(priv->TIMx); // load the prescaller value LL_TIM_GenerateEvent_UPDATE(priv->TIMx); // load the prescaller value
} }
@ -195,9 +197,9 @@ error_t UADC_init(Unit *unit)
// --------------------- CONFIGURE DMA ------------------------------- // --------------------- CONFIGURE DMA -------------------------------
dbg("Setting up DMA"); dbg("Setting up DMA");
{ {
// The length must be a 2*multiple of the number of channels // The length must be a 2*multiple of the number of channels, in bytes
// this is a horrible way to do it but will work uint16_t itemcount = (uint16_t) ((priv->nb_channels) * (uint16_t) (priv->buffer_size / (2 * priv->nb_channels)));
uint16_t itemcount = (uint16_t) (priv->nb_channels * (uint16_t) (UADC_DMA_MAX_BUF_LEN / (2 * priv->nb_channels))); if (itemcount % 2 == 1) itemcount -= priv->nb_channels;
priv->dma_buffer_size = (uint16_t) (itemcount * 2); priv->dma_buffer_size = (uint16_t) (itemcount * 2);
dbg("DMA item count is %d (%d bytes)", itemcount, priv->dma_buffer_size); dbg("DMA item count is %d (%d bytes)", itemcount, priv->dma_buffer_size);
@ -236,6 +238,7 @@ error_t UADC_init(Unit *unit)
dbg("ADC inited, starting the timer ..."); dbg("ADC inited, starting the timer ...");
// FIXME - temporary demo - counter start... // FIXME - temporary demo - counter start...
LL_ADC_REG_StartConversion(priv->ADCx); // the first conversion must be started manually
LL_TIM_EnableCounter(priv->TIMx); LL_TIM_EnableCounter(priv->TIMx);
return E_SUCCESS; return E_SUCCESS;
@ -254,7 +257,7 @@ void UADC_deInit(Unit *unit)
LL_ADC_CommonDeInit(priv->ADCx_Common); LL_ADC_CommonDeInit(priv->ADCx_Common);
LL_TIM_DeInit(priv->TIMx); LL_TIM_DeInit(priv->TIMx);
irqd_detach(priv->DMAx, UADC_DMA_Handler); irqd_detach(priv->DMA_CHx, UADC_DMA_Handler);
LL_DMA_DeInit(priv->DMAx, priv->dma_chnum); LL_DMA_DeInit(priv->DMAx, priv->dma_chnum);
free_ck(priv->dma_buffer); free_ck(priv->dma_buffer);

@ -19,6 +19,7 @@ struct priv {
bool enable_vref; //!< append a signal from the internal voltage reference bool enable_vref; //!< append a signal from the internal voltage reference
uint8_t sample_time; //!< 0-7 (corresponds to 1.5-239.5 cycles) - time for the sampling capacitor to charge uint8_t sample_time; //!< 0-7 (corresponds to 1.5-239.5 cycles) - time for the sampling capacitor to charge
uint32_t frequency; //!< Timer frequency in Hz. Note: not all frequencies can be achieved accurately uint32_t frequency; //!< Timer frequency in Hz. Note: not all frequencies can be achieved accurately
uint16_t buffer_size; //!< Buffer size in bytes (count 2 bytes per channel per measurement) - faster sampling freq needs bigger buffer
// TODO averaging (maybe a separate component?) // TODO averaging (maybe a separate component?)
// TODO threshold watchdog with hysteresis (maybe a separate component?) // TODO threshold watchdog with hysteresis (maybe a separate component?)

@ -21,6 +21,10 @@ void UADC_loadBinary(Unit *unit, PayloadParser *pp)
priv->enable_vref = pp_bool(pp); priv->enable_vref = pp_bool(pp);
priv->sample_time = pp_u8(pp); priv->sample_time = pp_u8(pp);
priv->frequency = pp_u32(pp); priv->frequency = pp_u32(pp);
if (version >= 1) {
priv->buffer_size = pp_u16(pp);
}
} }
/** Write to a binary buffer for storing in Flash */ /** Write to a binary buffer for storing in Flash */
@ -28,13 +32,14 @@ void UADC_writeBinary(Unit *unit, PayloadBuilder *pb)
{ {
struct priv *priv = unit->data; struct priv *priv = unit->data;
pb_u8(pb, 0); // version pb_u8(pb, 1); // version
pb_u16(pb, priv->channels); pb_u16(pb, priv->channels);
pb_bool(pb, priv->enable_tsense); pb_bool(pb, priv->enable_tsense);
pb_bool(pb, priv->enable_vref); pb_bool(pb, priv->enable_vref);
pb_u8(pb, priv->sample_time); pb_u8(pb, priv->sample_time);
pb_u32(pb, priv->frequency); pb_u32(pb, priv->frequency);
pb_u16(pb, priv->buffer_size);
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -61,6 +66,9 @@ error_t UADC_loadIni(Unit *unit, const char *key, const char *value)
else if (streq(key, "frequency")) { else if (streq(key, "frequency")) {
priv->frequency = (uint32_t) avr_atoi(value); priv->frequency = (uint32_t) avr_atoi(value);
} }
else if (streq(key, "buffer_size")) {
priv->buffer_size = (uint16_t) avr_atoi(value);
}
else { else {
return E_BAD_KEY; return E_BAD_KEY;
} }
@ -89,5 +97,11 @@ void UADC_writeIni(Unit *unit, IniWriter *iw)
iw_comment(iw, "Sampling frequency (Hz)"); iw_comment(iw, "Sampling frequency (Hz)");
iw_entry(iw, "frequency", "%d", (int)priv->frequency); iw_entry(iw, "frequency", "%d", (int)priv->frequency);
iw_comment(iw, "Sample buffer size (bytes, 2 per channels per sample)");
iw_comment(iw, "- a report is sent when 1/2 of the circular buffer is filled");
iw_comment(iw, "- the buffer is shared by all channels");
iw_comment(iw, "- insufficient buffer size can lead to data loss");
iw_entry(iw, "buffer_size", "%d", (int)priv->buffer_size);
} }

Loading…
Cancel
Save