From 3584830dc5532e1e654f0761c15c1f7f70c9479c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Wed, 7 Feb 2018 21:18:06 +0100 Subject: [PATCH] failing --- platform/hw_utils.c | 5 +++- units/adc/_adc_init.c | 53 +++++++++++++++++++++++++++++---------- units/adc/_adc_internal.h | 4 +++ units/adc/unit_adc.c | 26 ++++++++++++++++--- 4 files changed, 70 insertions(+), 18 deletions(-) diff --git a/platform/hw_utils.c b/platform/hw_utils.c index 9cfb4f1..c082ca4 100644 --- a/platform/hw_utils.c +++ b/platform/hw_utils.c @@ -371,7 +371,10 @@ bool solve_timer(uint32_t base_freq, uint32_t required_freq, bool is16bit, *presc = (uint16_t) wPresc; if (wPresc * wCount == 0) return false; - *real_freq = (base_freq / (wPresc * wCount)); + + if (real_freq != NULL) { + *real_freq = (base_freq / (wPresc * wCount)); + } return true; } diff --git a/units/adc/_adc_init.c b/units/adc/_adc_init.c index e3e129b..1de3f4f 100644 --- a/units/adc/_adc_init.c +++ b/units/adc/_adc_init.c @@ -28,6 +28,30 @@ error_t UADC_preInit(Unit *unit) return E_SUCCESS; } + +/** Configure frequency */ +error_t UADC_SetSampleRate(Unit *unit, uint32_t hertz) +{ + struct priv *priv = unit->data; + + uint16_t presc; + uint32_t count; + if (!solve_timer(PLAT_APB1_HZ, hertz, true, &presc, &count, + &priv->real_frequency)) { + dbg("Failed to resolve timer params."); + return E_BAD_VALUE; + } + dbg("Frequency error %d ppm, presc %d, count %d", + (int) lrintf(1000000.0f * + ((priv->real_frequency - hertz) / (float) hertz)), + (int) presc, (int) count); + + LL_TIM_SetPrescaler(priv->TIMx, (uint32_t) (presc - 1)); + LL_TIM_SetAutoReload(priv->TIMx, count - 1); + + return E_SUCCESS; +} + /** Finalize unit set-up */ error_t UADC_init(Unit *unit) { @@ -103,19 +127,20 @@ error_t UADC_init(Unit *unit) // ------------------- CONFIGURE THE TIMER -------------------------- dbg("Setting up TIMER"); { - // Find suitable timer values - uint16_t presc; - uint32_t count; - float real_freq; - if (!solve_timer(PLAT_APB1_HZ, priv->frequency, true, &presc, &count, &real_freq)) { - dbg("Failed to resolve timer params."); - return E_BAD_VALUE; - } - dbg("Frequency error %d ppm, presc %d, count %d", - (int) lrintf(1000000.0f * ((real_freq - priv->frequency) / (float)priv->frequency)), (int) presc, (int) count); - - LL_TIM_SetPrescaler(priv->TIMx, (uint32_t) (presc - 1)); - LL_TIM_SetAutoReload(priv->TIMx, count - 1); + TRY(UADC_SetSampleRate(unit, priv->frequency)); +// // Find suitable timer values +// uint16_t presc; +// uint32_t count; +// float real_freq; +// if (!solve_timer(PLAT_APB1_HZ, priv->frequency, true, &presc, &count, &real_freq)) { +// dbg("Failed to resolve timer params."); +// return E_BAD_VALUE; +// } +// dbg("Frequency error %d ppm, presc %d, count %d", +// (int) lrintf(1000000.0f * ((real_freq - priv->frequency) / (float)priv->frequency)), (int) presc, (int) count); +// +// LL_TIM_SetPrescaler(priv->TIMx, (uint32_t) (presc - 1)); +// LL_TIM_SetAutoReload(priv->TIMx, count - 1); LL_TIM_EnableARRPreload(priv->TIMx); LL_TIM_EnableUpdateEvent(priv->TIMx); LL_TIM_SetTriggerOutput(priv->TIMx, LL_TIM_TRGO_UPDATE); @@ -208,8 +233,10 @@ error_t UADC_init(Unit *unit) irqd_attach(priv->DMA_CHx, UADC_DMA_Handler, unit); irqd_attach(priv->ADCx, UADC_ADC_EOS_Handler, unit); + dbg("irqs attached"); UADC_SwitchMode(unit, ADC_OPMODE_IDLE); + dbg("ADC done"); return E_SUCCESS; } diff --git a/units/adc/_adc_internal.h b/units/adc/_adc_internal.h index c850536..b46e3a9 100644 --- a/units/adc/_adc_internal.h +++ b/units/adc/_adc_internal.h @@ -40,6 +40,7 @@ struct priv { uint16_t averaging_factor; //!< Exponential averaging factor 0-1000 // internal state + float real_frequency; uint32_t extended_channels_mask; //!< channels bitfield including tsense and vref float avg_factor_as_float; ADC_TypeDef *ADCx; //!< The ADC peripheral used @@ -126,4 +127,7 @@ void UADC_StartStream(Unit *unit, TF_ID frame_id); /** End stream */ void UADC_StopStream(Unit *unit); +/** Configure frequency */ +error_t UADC_SetSampleRate(Unit *unit, uint32_t hertz); + #endif //GEX_F072_ADC_INTERNAL_H diff --git a/units/adc/unit_adc.c b/units/adc/unit_adc.c index a01ff02..f6ddb7c 100644 --- a/units/adc/unit_adc.c +++ b/units/adc/unit_adc.c @@ -15,6 +15,7 @@ enum TplCmd_ { CMD_READ_SMOOTHED = 1, CMD_GET_ENABLED_CHANNELS = 10, + CMD_GET_SAMPLE_RATE = 11, CMD_SETUP_TRIGGER = 20, CMD_ARM = 21, @@ -25,6 +26,7 @@ enum TplCmd_ { CMD_STREAM_START = 26, CMD_STREAM_STOP = 27, CMD_SET_SMOOTHING_FACTOR = 28, + CMD_SET_SAMPLE_RATE = 29, }; /** Handle a request message */ @@ -33,6 +35,8 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P struct priv *priv = unit->data; PayloadBuilder pb = pb_start(unit_tmp512, UNIT_TMP_LEN, NULL); + // TODO toggling individual channels - would require DMA re-init and various changes in the usage of the struct + switch (command) { /** * Get enabled channels. @@ -47,6 +51,23 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P com_respond_pb(frame_id, MSG_SUCCESS, &pb); return E_SUCCESS; + case CMD_SET_SAMPLE_RATE: + { + uint32_t freq = pp_u32(pp); + if (freq == 0) return E_BAD_VALUE; + + TRY(UADC_SetSampleRate(unit, freq)); + } + // Pass through - send back the obtained sample rate + /** + * Read the real used frequency, expressed as float. + * May differ from the configured or requested value due to prescaller limitations. + */ + case CMD_GET_SAMPLE_RATE: + pb_float(&pb, priv->real_frequency); + com_respond_pb(frame_id, MSG_SUCCESS, &pb); + return E_SUCCESS; + /** * Set smoothing factor 0-1000. * pld: u16:factor @@ -117,7 +138,7 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P const uint8_t source = pp_u8(pp); const uint16_t level = pp_u16(pp); const uint8_t edge = pp_u8(pp); - const uint16_t pretrig = pp_u16(pp); // TODO test pre-trigger ... + const uint16_t pretrig = pp_u16(pp); const uint32_t count = pp_u32(pp); const uint16_t holdoff = pp_u16(pp); const bool auto_rearm = pp_bool(pp); @@ -260,7 +281,6 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P * u32 - sample count (for each channel) */ case CMD_BLOCK_CAPTURE: - // TODO test dbg("> Block cpt"); if (priv->opmode != ADC_OPMODE_ARMED && priv->opmode != ADC_OPMODE_REARM_PENDING && @@ -276,7 +296,6 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P * The stream can be terminated by the stop command. */ case CMD_STREAM_START: - // TODO test dbg("> Stream ON"); if (priv->opmode != ADC_OPMODE_ARMED && priv->opmode != ADC_OPMODE_REARM_PENDING && @@ -289,7 +308,6 @@ static error_t UADC_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, P * Stop a stream. */ case CMD_STREAM_STOP: - // TODO test dbg("> Stream OFF"); if (priv->opmode != ADC_OPMODE_STREAM) { com_respond_str(MSG_ERROR, frame_id, "Not streaming");