Fixed DAC not correctly deinited causing INI crashes

remotes/github/master
Ondřej Hruška 7 years ago
parent 041e4f5b70
commit 396501564a
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 1
      framework/unit_registry.c
  2. 14
      units/adc/_adc_core.c
  3. 7
      units/dac/_dac_init.c

@ -334,6 +334,7 @@ bool ureg_finalize_all_init(void)
uint8_t callsign = 1; uint8_t callsign = 1;
while (li != NULL) { while (li != NULL) {
Unit *const pUnit = &li->unit; Unit *const pUnit = &li->unit;
dbg("+ %s \"%s\"", pUnit->driver->name, pUnit->name);
if (pUnit->status == E_SUCCESS) { if (pUnit->status == E_SUCCESS) {
dbg("! Unit seems already loaded, skipping"); dbg("! Unit seems already loaded, skipping");

@ -4,6 +4,7 @@
// The core functionality of the ADC unit is defined here. // The core functionality of the ADC unit is defined here.
// //
#include <stm32f072xb.h>
#include "platform.h" #include "platform.h"
#include "unit_base.h" #include "unit_base.h"
#include "unit_adc.h" #include "unit_adc.h"
@ -326,6 +327,8 @@ void UADC_DMA_Handler(void *arg)
*/ */
void UADC_ADC_EOS_Handler(void *arg) void UADC_ADC_EOS_Handler(void *arg)
{ {
GPIOC->BSRR = 0x01;//TODO remove
Unit *unit = arg; Unit *unit = arg;
struct priv *priv = unit->data; struct priv *priv = unit->data;
@ -334,7 +337,9 @@ void UADC_ADC_EOS_Handler(void *arg)
if (priv->opmode == ADC_OPMODE_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) {
goto exit;
}
// Wait for the DMA to complete copying the last sample // Wait for the DMA to complete copying the last sample
uint32_t dmapos = DMA_POS(priv); uint32_t dmapos = DMA_POS(priv);
@ -383,9 +388,8 @@ void UADC_ADC_EOS_Handler(void *arg)
} }
priv->trig_prev_level = val; priv->trig_prev_level = val;
} }
// auto-rearm was waiting for the next sample // auto-rearm was waiting for the next sample
if (priv->opmode == ADC_OPMODE_REARM_PENDING) { else 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.
// Let's just switch to IDLE // Let's just switch to IDLE
@ -395,6 +399,10 @@ void UADC_ADC_EOS_Handler(void *arg)
UADC_SwitchMode(unit, ADC_OPMODE_ARMED); UADC_SwitchMode(unit, ADC_OPMODE_ARMED);
} }
} }
exit:
GPIOC->BRR = 0x01;//TODO remove
return;
} }
/** /**

@ -71,10 +71,6 @@ error_t UDAC_init(Unit *unit)
TRY(rsc_claim(unit, R_DAC1)); TRY(rsc_claim(unit, R_DAC1));
// ensure the peripheral is clean (this may be redundant)
__HAL_RCC_DAC1_FORCE_RESET();
__HAL_RCC_DAC1_RELEASE_RESET();
hw_periph_clock_enable(DAC1); hw_periph_clock_enable(DAC1);
hw_periph_clock_enable(priv->TIMx); hw_periph_clock_enable(priv->TIMx);
@ -110,6 +106,7 @@ error_t UDAC_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_GenerateEvent_UPDATE(priv->TIMx); LL_TIM_GenerateEvent_UPDATE(priv->TIMx);
LL_TIM_ClearFlag_UPDATE(priv->TIMx); // prevent irq right after enabling
irqd_attach(priv->TIMx, UDAC_HandleIT, unit); irqd_attach(priv->TIMx, UDAC_HandleIT, unit);
LL_TIM_EnableIT_UPDATE(priv->TIMx); LL_TIM_EnableIT_UPDATE(priv->TIMx);
@ -131,7 +128,7 @@ void UDAC_deInit(Unit *unit)
// de-init peripherals // de-init peripherals
if (unit->status == E_SUCCESS ) { if (unit->status == E_SUCCESS ) {
LL_DAC_DeInit(DAC); LL_DAC_DeInit(DAC);
LL_TIM_DisableCounter(priv->TIMx); LL_TIM_DeInit(priv->TIMx);
hw_periph_clock_disable(DAC1); hw_periph_clock_disable(DAC1);
hw_periph_clock_disable(priv->TIMx); hw_periph_clock_disable(priv->TIMx);

Loading…
Cancel
Save