From 6fd85ff0761a1f229d6657177dc7042573e21c51 Mon Sep 17 00:00:00 2001 From: Mateusz Szafoni Date: Sun, 21 Jan 2018 18:28:09 +0000 Subject: [PATCH] Merged in raiden00/nuttx (pull request #579) Master * stm32_hritm: add interface to get timer clock frequency stm32_hrtim: fix timer freq calculation stm32_hrtim: add compar/capture registers significant bits checking stm32_hrtim: minor changes * stm32f334-disco: add buck converter and boost converter logic Approved-by: Gregory Nutt --- arch/arm/src/stm32/stm32_hrtim.c | 415 +++++++++++++------ arch/arm/src/stm32/stm32_hrtim.h | 38 +- configs/stm32f334-disco/include/board.h | 34 +- configs/stm32f334-disco/src/stm32_smps.c | 493 ++++++++++++++++++++--- 4 files changed, 790 insertions(+), 190 deletions(-) diff --git a/arch/arm/src/stm32/stm32_hrtim.c b/arch/arm/src/stm32/stm32_hrtim.c index 44f78bff6f..121b0e2e4f 100644 --- a/arch/arm/src/stm32/stm32_hrtim.c +++ b/arch/arm/src/stm32/stm32_hrtim.c @@ -375,12 +375,13 @@ struct stm32_hrtim_capture_s struct stm32_hrtim_timcmn_s { uint32_t base; /* The base adress of the timer */ - uint32_t pclk; /* The frequency of the peripheral clock + uint64_t fclk; /* The frequency of the peripheral clock * that drives the timer module. */ + uint8_t prescaler:3; /* Prescaler */ uint8_t mode; /* Timer mode */ uint8_t dac:2; /* DAC triggering */ - uint8_t reserved:6; + uint8_t reserved:3; #ifdef CONFIG_STM32_HRTIM_INTERRUPTS uint16_t irq; /* interrupts configuration */ #endif @@ -623,6 +624,8 @@ static uint32_t hrtim_tim_getreg(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint32_t offset); static FAR struct stm32_hrtim_tim_s *hrtim_tim_get(FAR struct stm32_hrtim_s *priv, uint8_t timer); +static FAR struct stm32_hrtim_slave_priv_s *hrtim_slave_get(FAR struct stm32_hrtim_s *priv, + uint8_t timer); static uint32_t hrtim_base_get(FAR struct stm32_hrtim_s *priv, uint8_t timer); /* Configuration */ @@ -665,7 +668,8 @@ static int hrtim_tim_dma_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer, #ifdef CONFIG_STM32_HRTIM_DEADTIME static int hrtim_deadtime_update(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t dt, uint16_t value); -static uint16_t hrtim_deadtime_get(FAR struct hrtim_dev_s *dev, uint8_t dt); +static uint16_t hrtim_deadtime_get(FAR struct hrtim_dev_s *dev, uint8_t timer, + uint8_t dt); static int hrtim_tim_deadtime_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer); static int hrtim_deadtime_config(FAR struct stm32_hrtim_s *priv); #endif @@ -705,6 +709,7 @@ static int hrtim_per_update(FAR struct hrtim_dev_s *dev, uint8_t timer, static uint16_t hrtim_per_get(FAR struct hrtim_dev_s *dev, uint8_t timer); static uint16_t hrtim_cmp_get(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t index); +static uint64_t hrtim_fclk_get(FAR struct hrtim_dev_s *dev, uint8_t timer); static int hrtim_tim_reset_set(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint32_t reset); static int hrtim_reset_config(FAR struct stm32_hrtim_s *priv); @@ -753,20 +758,21 @@ static struct stm32_hrtim_tim_s g_master = /* If MASTER is disabled, we need only MASTER base */ #ifdef CONFIG_STM32_HRTIM_MASTER - .pclk = HRTIM_CLOCK/(HRTIM_MASTER_PRESCALER+1), - .mode = HRTIM_MASTER_MODE, + .fclk = HRTIM_CLOCK/(1<priv; + +errout: + return slave; +} + /**************************************************************************** * Name: hrtim_base_get * @@ -2049,7 +2108,7 @@ static void hrtim_dumpregs(FAR struct stm32_hrtim_s *priv, uint8_t timer, * priv - A reference to the HRTIM structure * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -2093,7 +2152,7 @@ static int hrtim_dll_cal(FAR struct stm32_hrtim_s *priv) * timer - An HRTIM Timer index * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -2182,7 +2241,7 @@ errout: * priv - A reference to the HRTIM structure * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -2264,7 +2323,7 @@ errout: * priv - A reference to the HRTIM structure * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -2467,7 +2526,7 @@ static int hrtim_gpios_config(FAR struct stm32_hrtim_s *priv) * capture - capture trigers configuration * * Returned Value: - * None + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -2478,7 +2537,9 @@ static int hrtim_tim_capture_cfg(FAR struct stm32_hrtim_s *priv, int ret = OK; uint32_t offset = 0; - if (timer == HRTIM_TIMER_MASTER) + /* Sanity checking */ + + if (timer == HRTIM_TIMER_MASTER || timer == HRTIM_TIMER_COMMON) { ret = -EINVAL; goto errout; @@ -2521,7 +2582,7 @@ errout: * priv - A reference to the HRTIM block * * Returned Value: - * None + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -2574,7 +2635,7 @@ static int hrtim_capture_config(FAR struct stm32_hrtim_s *priv) * index - Capture register index * * Returned Value: - * None + * Timer Capture value on success, 0 on failure * ****************************************************************************/ @@ -2623,7 +2684,7 @@ errout: * priv - A reference to the HRTIM structure * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -2645,37 +2706,26 @@ static int hrtim_synch_config(FAR struct stm32_hrtim_s *priv) * priv - A reference to the HRTIM structure * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ #if defined(CONFIG_STM32_HRTIM_PWM) static int hrtim_tim_outputs_config(FAR struct stm32_hrtim_s *priv, uint8_t timer) { - FAR struct stm32_hrtim_tim_s* tim; FAR struct stm32_hrtim_slave_priv_s* slave; uint32_t regval = 0; int ret = OK; - /* Master Timer has no outputs */ + /* Get Slave Timer data structure */ - if (timer == HRTIM_TIMER_MASTER) + slave = hrtim_slave_get(priv, timer); + if (slave == NULL) { ret = -EINVAL; goto errout; } - /* Get Timer data strucutre */ - - tim = hrtim_tim_get(priv, timer); - if (tim == NULL) - { - ret = -EINVAL; - goto errout; - } - - slave = (struct stm32_hrtim_slave_priv_s*)tim->priv; - /* Configure CH1 SET events */ regval = slave->pwm.ch1.set; @@ -2773,7 +2823,7 @@ errout: * priv - A reference to the HRTIM structure * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -2848,7 +2898,7 @@ errout: * state - Enable/disable operation * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -3009,7 +3059,6 @@ static int hrtim_output_set_set(FAR struct hrtim_dev_s *dev, uint16_t output, uint32_t set) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; - FAR struct stm32_hrtim_tim_s* tim; FAR struct stm32_hrtim_slave_priv_s* slave; uint8_t timer = 0; int ret = OK; @@ -3018,17 +3067,15 @@ static int hrtim_output_set_set(FAR struct hrtim_dev_s *dev, uint16_t output, timer = output_tim_index_get(output); - /* Get Timer data strucutre */ + /* Get Slave Timer data strucutre */ - tim = hrtim_tim_get(priv, timer); - if (tim == NULL) + slave = hrtim_slave_get(priv, timer); + if (slave == NULL) { ret = -EINVAL; goto errout; } - slave = (struct stm32_hrtim_slave_priv_s*)tim->priv; - /* Set new SET value */ switch (output_tim_ch_get(output)) @@ -3065,7 +3112,6 @@ static int hrtim_output_rst_set(FAR struct hrtim_dev_s *dev, uint16_t output, uint32_t rst) { FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; - FAR struct stm32_hrtim_tim_s* tim; FAR struct stm32_hrtim_slave_priv_s* slave; uint8_t timer = 0; int ret = OK; @@ -3074,17 +3120,15 @@ static int hrtim_output_rst_set(FAR struct hrtim_dev_s *dev, uint16_t output, timer = output_tim_index_get(output); - /* Get Timer data strucutre */ + /* Get Salve Timer data strucutre */ - tim = hrtim_tim_get(priv, timer); - if (tim == NULL) + slave = hrtim_slave_get(priv, timer); + if (slave == NULL) { ret = -EINVAL; goto errout; } - slave = (struct stm32_hrtim_slave_priv_s*)tim->priv; - /* Set new RST value */ switch (output_tim_ch_get(output)) @@ -3124,7 +3168,7 @@ errout: * priv - A reference to the HRTIM structure * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -3172,7 +3216,7 @@ static int hrtim_adc_config(FAR struct stm32_hrtim_s *priv) * dac - DAC synchronisation event configuration * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -3203,7 +3247,7 @@ static int hrtim_tim_dac_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer, * priv - A reference to the HRTIM structure * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -3268,6 +3312,14 @@ static int hrtim_tim_dma_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer, int ret = OK; uint32_t regval = 0; + /* Sanity checking */ + + if (timer == HRTIM_TIMER_COMMON) + { + ret = -EINVAL; + goto errout; + } + if (timer == HRTIM_TIMER_MASTER) { /* Master support first 7 DMA requests */ @@ -3397,7 +3449,8 @@ errout: * Name: hrtim_deadtime_get ****************************************************************************/ -static uint16_t hrtim_deadtime_get(FAR struct hrtim_dev_s *dev, uint8_t dt) +static uint16_t hrtim_deadtime_get(FAR struct hrtim_dev_s *dev, uint8_t timer, + uint8_t dt) { #warning missing logic } @@ -3408,30 +3461,27 @@ static uint16_t hrtim_deadtime_get(FAR struct hrtim_dev_s *dev, uint8_t dt) static int hrtim_tim_deadtime_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer) { - FAR struct stm32_hrtim_tim_s* tim; FAR struct stm32_hrtim_slave_priv_s* slave; uint32_t regval = 0; int ret = OK; - /* Master Timer has no outputs */ + /* Sanity checking */ - if (timer == HRTIM_TIMER_MASTER) + if (timer == HRTIM_TIMER_MASTER || timer == HRTIM_TIMER_COMMON) { ret = -EINVAL; goto errout; } - /* Get Timer data strucutre */ + /* Get Slave Timer data strucutre */ - tim = hrtim_tim_get(priv, timer); - if (tim == NULL) + slave = hrtim_slave_get(priv, timer); + if (slave == NULL) { ret = -EINVAL; goto errout; } - slave = (struct stm32_hrtim_slave_priv_s*)tim->priv; - /* Configure deadtime prescaler */ regval |= slave->pwm.dt.prescaler << HRTIM_TIMDT_DTPRSC_SHIFT; @@ -3550,7 +3600,7 @@ static int hrtim_deadtime_config(FAR struct stm32_hrtim_s *priv) * state - Enable/disable operation * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -3610,31 +3660,28 @@ errout: static int hrtim_tim_chopper_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer) { - FAR struct stm32_hrtim_tim_s* tim; FAR struct stm32_hrtim_slave_priv_s* slave; int ret = OK; uint32_t regval = 0; - /* Master Timer has no outputs */ + /* Sanity checking */ - if (timer == HRTIM_TIMER_MASTER) + if (timer == HRTIM_TIMER_MASTER || timer == HRTIM_TIMER_COMMON) { ret = -EINVAL; goto errout; } - /* Get Timer data strucutre */ + /* Get Slave Timer data strucutre */ - tim = hrtim_tim_get(priv, timer); - if (tim == NULL) + slave = hrtim_slave_get(priv, timer); + if (slave == NULL) { ret = -EINVAL; goto errout; } - slave = (struct stm32_hrtim_slave_priv_s*)tim->priv; - /* Configure start pulsewidth */ regval |= slave->pwm.chp.start_pulse << HRTIM_TIMCHP_STRTPW_SHIFT; @@ -3891,19 +3938,22 @@ static int hrtim_burst_config(FAR struct stm32_hrtim_s *priv) * timer - timer index * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ static int hrtim_tim_faults_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer) { - FAR struct stm32_hrtim_tim_s *tim; FAR struct stm32_hrtim_slave_priv_s *slave; uint32_t regval = 0; + int ret = OK; - tim = hrtim_tim_get(priv, timer); - - slave = tim->priv; + slave = hrtim_slave_get(priv, timer); + if (slave == NULL) + { + ret = -EINVAL; + goto errout; + } /* Get lock configuration */ @@ -3917,7 +3967,8 @@ static int hrtim_tim_faults_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer) hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_FLTR_OFFSET, regval); - return OK; +errout: + return ret; } /**************************************************************************** @@ -3931,7 +3982,7 @@ static int hrtim_tim_faults_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer) * index - Fault index * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -4073,7 +4124,7 @@ errout: * priv - A reference to the HRTIM structure * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -4147,7 +4198,7 @@ static int hrtim_faults_config(FAR struct stm32_hrtim_s *priv) * index - External Event index * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -4322,7 +4373,7 @@ errout: * priv - A reference to the HRTIM structure * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -4392,7 +4443,7 @@ static int hrtim_events_config(FAR struct stm32_hrtim_s *priv) * priv - A reference to the HRTIM structure * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -4483,7 +4534,7 @@ static void hrtim_tim_mode_set(FAR struct stm32_hrtim_s *priv, uint8_t timer, * priv - A reference to the HRTIM structure * * Returned Value: - * None + * None * ****************************************************************************/ @@ -4514,6 +4565,77 @@ static void hrtim_mode_config(FAR struct stm32_hrtim_s *priv) #endif } +/**************************************************************************** + * Name: hrtim_cmpcap_mask_get + * + * Description: + * This function returns not significant bits in counter/capture + * regsiters for given HRTIM Timer index. + * + * Input Parameters: + * priv - A reference to the HRTIM structure + * timer - HRTIM Timer index + * + * Returned Value: + * Not significant bits for counter/capture registers + * + ****************************************************************************/ + +static uint8_t hrtim_cmpcap_mask_get(FAR struct stm32_hrtim_s *priv, + uint8_t timer) +{ + FAR struct stm32_hrtim_tim_s* tim; + uint8_t mask = 0; + + /* Get Timer data strucutre */ + + tim = hrtim_tim_get(priv, timer); + if (tim == NULL) + { + mask = 0; + goto errout; + } + + /* Not significant bits depens on timer prescaler */ + + switch(tim->tim.prescaler) + { + case HRTIM_PRESCALER_1: + { + mask = 0b11111; + break; + } + case HRTIM_PRESCALER_2: + { + mask = 0b1111; + break; + } + case HRTIM_PRESCALER_4: + { + mask = 0b111; + break; + } + case HRTIM_PRESCALER_8: + { + mask = 0b11; + break; + } + case HRTIM_PRESCALER_16: + { + mask = 0b1; + break; + } + default: + { + mask = 0; + break; + } + } + +errout: + return mask; +} + /**************************************************************************** * Name: hrtim_cmp_update * @@ -4527,7 +4649,7 @@ static void hrtim_mode_config(FAR struct stm32_hrtim_s *priv) * cmp - New compare register value * * Returned Value: - * Zero on success; a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -4537,6 +4659,7 @@ static int hrtim_cmp_update(FAR struct hrtim_dev_s *dev, uint8_t timer, FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; int ret = OK; uint32_t offset = 0; + uint8_t mask = 0; switch (index) { @@ -4571,6 +4694,16 @@ static int hrtim_cmp_update(FAR struct hrtim_dev_s *dev, uint8_t timer, } } + /* REVISIT: what should we do if cmp value is not significant ? + * At this moment we set compare register to the nearest significant value. + */ + + mask = hrtim_cmpcap_mask_get(priv, timer); + if (cmp <= mask) + { + cmp = mask + 1; + } + hrtim_tim_putreg(priv, timer, offset, cmp); errout: @@ -4589,7 +4722,7 @@ errout: * per - New period register value * * Returned Value: - * Zero on success; a negated errno value on failure + * 0 on success; a negated errno value on failure * ****************************************************************************/ @@ -4613,7 +4746,7 @@ static int hrtim_per_update(FAR struct hrtim_dev_s *dev, uint8_t timer, * timer - HRTIM Timer index * * Returned Value: - * Zero on success; a negated errno value on failure + * Timer period value * ****************************************************************************/ @@ -4636,7 +4769,7 @@ static uint16_t hrtim_per_get(FAR struct hrtim_dev_s *dev, uint8_t timer) * index - Compare register timer * * Returned Value: - * Zero on success; a negated errno value on failure + * Timer compare value * ****************************************************************************/ @@ -4686,6 +4819,42 @@ errout: return cmpx; } +/**************************************************************************** + * Name: hrtim_fclk_get + * + * Description: + * Get HRTIM Timer clock value + * + * Input parameters: + * dev - HRTIM device structure + * timer - HRTIM Timer index + * + * Returned Value: + * Timer clock value + * + ****************************************************************************/ + +static uint64_t hrtim_fclk_get(FAR struct hrtim_dev_s *dev, uint8_t timer) +{ + FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv; + FAR struct stm32_hrtim_tim_s *tim; + uint64_t fclk = 0; + + /* Get Slave Timer data structure */ + + tim = hrtim_tim_get(priv, timer); + if (tim == NULL) + { + fclk = 0; + goto errout; + } + + fclk = tim->tim.fclk; + +errout: + return fclk; +} + /**************************************************************************** * Name: hrtim_tim_reset_set * @@ -4707,7 +4876,9 @@ static int hrtim_tim_reset_set(FAR struct stm32_hrtim_s *priv, uint8_t timer, { int ret = OK; - if (timer == HRTIM_TIMER_MASTER) + /* Sanity checking */ + + if (timer == HRTIM_TIMER_MASTER || timer == HRTIM_TIMER_COMMON) { ret = -EINVAL; goto errout; @@ -4811,7 +4982,7 @@ static int hrtim_update_config(FAR struct stm32_hrtim_s *priv) * priv - A reference to the HRTIM structure * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ diff --git a/arch/arm/src/stm32/stm32_hrtim.h b/arch/arm/src/stm32/stm32_hrtim.h index 40ffe37b8d..da02364460 100644 --- a/arch/arm/src/stm32/stm32_hrtim.h +++ b/arch/arm/src/stm32/stm32_hrtim.h @@ -187,7 +187,7 @@ # error "APB2 prescaler factor can not be greater than 2" # else # define HRTIM_HAVE_CLK_FROM_PLL 1 -# define HRTIM_CLOCK 2*STM32_PLL_FREQUENCY +# define HRTIM_MAIN_CLOCK 2*STM32_PLL_FREQUENCY # endif # else # error "Clock system must be set to PLL" @@ -195,19 +195,27 @@ #else # error "Not supported yet: system freezes when no PLL selected." # define HRTIM_HAVE_CLK_FROM_APB2 1 -# if STM32_RCC_CFGR_PPRE2 == RCC_CFGR_PPRE2_HCLK -# define HRTIM_CLOCK STM32_PCLK2_FREQUENCY +# if STM32_RCC_CFGR_PPRE2 == RCC_CFGR_PPRE2_HCLK +# define HRTIM_MAIN_CLOCK STM32_PCLK2_FREQUENCY # else -# define HRTIM_CLOCK 2*STM32_PCLK2_FREQUENCY +# define HRTIM_MAIN_CLOCK 2*STM32_PCLK2_FREQUENCY # endif #endif +/* High-resolution equivalent clock */ + +#define HRTIM_CLOCK (HRTIM_MAIN_CLOCK*32ull) + /* Helpers **************************************************************************/ #define HRTIM_CMP_SET(hrtim, tim, index, cmp) \ (hrtim)->hd_ops->cmp_update(hrtim, tim, index, cmp) #define HRTIM_PER_SET(hrtim, tim, per) \ (hrtim)->hd_ops->per_update(hrtim, tim, per) +#define HRTIM_PER_GET(hrtim, tim) \ + (hrtim)->hd_ops->per_get(hrtim, tim) +#define HRTIM_FCLK_GET(hrtim, tim) \ + (hrtim)->hd_ops->fclk_get(hrtim, tim) #define HRTIM_OUTPUTS_ENABLE(hrtim, outputs, state) \ (hrtim)->hd_ops->outputs_enable(hrtim, outputs, state) #define HRTIM_OUTPUT_SET_SET(hrtim, output, set) \ @@ -225,6 +233,11 @@ #define HRTIM_DEADTIME_UPDATE(hrtim, tim, dt, val) \ (hrtim)->hd_ops->deadtime_update(hrtim, tim, dt, val) +#define HRTIM_PER_MAX 0xFFFF +#define HRTIM_CMP_MAX 0xFFFF +#define HRTIM_CPT_MAX 0xFFFF +#define HRTIM_REP_MAX 0xFF + /************************************************************************************ * Public Types ************************************************************************************/ @@ -384,14 +397,14 @@ enum stm32_hrtim_tim_rst_e enum stm32_hrtim_tim_prescaler_e { - HRTIM_PRESCALER_1, - HRTIM_PRESCALER_2, - HRTIM_PRESCALER_4, - HRTIM_PRESCALER_8, - HRTIM_PRESCALER_16, - HRTIM_PRESCALER_32, - HRTIM_PRESCALER_64, - HRTIM_PRESCALER_128 + HRTIM_PRESCALER_1, /* CKPSC = 0 */ + HRTIM_PRESCALER_2, /* CKPSC = 1 */ + HRTIM_PRESCALER_4, /* CKPSC = 2 */ + HRTIM_PRESCALER_8, /* CKPSC = 3 */ + HRTIM_PRESCALER_16, /* CKPSC = 4 */ + HRTIM_PRESCALER_32, /* CKPSC = 5 */ + HRTIM_PRESCALER_64, /* CKPSC = 6 */ + HRTIM_PRESCALER_128 /* CKPSC = 7 */ }; /* HRTIM Timer Master/Slave mode */ @@ -971,6 +984,7 @@ struct stm32_hrtim_ops_s uint16_t (*per_get)(FAR struct hrtim_dev_s *dev, uint8_t timer); uint16_t (*cmp_get)(FAR struct hrtim_dev_s *dev, uint8_t timer, uint8_t index); + uint64_t (*fclk_get)(FAR struct hrtim_dev_s *dev, uint8_t timer); #ifdef CONFIG_STM32_HRTIM_INTERRUPTS void (*irq_ack)(FAR struct hrtim_dev_s *dev, uint8_t timer, int source); #endif diff --git a/configs/stm32f334-disco/include/board.h b/configs/stm32f334-disco/include/board.h index 115b02abd4..c138e01cab 100644 --- a/configs/stm32f334-disco/include/board.h +++ b/configs/stm32f334-disco/include/board.h @@ -277,12 +277,42 @@ /* HRTIM configuration ******************************************************/ -#define HRTIM_TIMA_PRESCALER HRTIM_PRESCALER_32 +/* Timer A configuration - Buck operations */ + +#define HRTIM_TIMA_PRESCALER HRTIM_PRESCALER_1 #define HRTIM_TIMA_MODE HRTIM_MODE_CONT -#define HRTIM_TIMB_PRESCALER HRTIM_PRESCALER_32 +#define HRTIM_TIMA_CH1_SET HRTIM_OUT_SET_NONE +#define HRTIM_TIMA_CH1_RST HRTIM_OUT_RST_NONE +#define HRTIM_TIMA_CH2_SET HRTIM_OUT_SET_NONE +#define HRTIM_TIMA_CH2_RST HRTIM_OUT_RST_NONE + +#define HRTIM_TIMA_DT_FSLOCK HRTIM_DT_LOCK +#define HRTIM_TIMA_DT_RSLOCK HRTIM_DT_LOCK +#define HRTIM_TIMA_DT_FVLOCK HRTIM_DT_RW +#define HRTIM_TIMA_DT_RVLOCK HRTIM_DT_RW +#define HRTIM_TIMA_DT_FSIGN HRTIM_DT_SIGN_POSITIVE +#define HRTIM_TIMA_DT_RSIGN HRTIM_DT_SIGN_POSITIVE +#define HRTIM_TIMA_DT_PRESCALER HRTIM_DEADTIME_PRESCALER_1 + +/* Timer B configuration - Boost operations */ + +#define HRTIM_TIMB_PRESCALER HRTIM_PRESCALER_1 #define HRTIM_TIMB_MODE HRTIM_MODE_CONT +#define HRTIM_TIMB_CH1_SET HRTIM_OUT_SET_NONE +#define HRTIM_TIMB_CH1_RST HRTIM_OUT_RST_NONE +#define HRTIM_TIMB_CH2_SET HRTIM_OUT_SET_NONE +#define HRTIM_TIMB_CH2_RST HRTIM_OUT_RST_NONE + +#define HRTIM_TIMB_DT_FSLOCK HRTIM_DT_LOCK +#define HRTIM_TIMB_DT_RSLOCK HRTIM_DT_LOCK +#define HRTIM_TIMB_DT_FVLOCK HRTIM_DT_RW +#define HRTIM_TIMB_DT_RVLOCK HRTIM_DT_RW +#define HRTIM_TIMB_DT_FSIGN HRTIM_DT_SIGN_POSITIVE +#define HRTIM_TIMB_DT_RSIGN HRTIM_DT_SIGN_POSITIVE +#define HRTIM_TIMB_DT_PRESCALER HRTIM_DEADTIME_PRESCALER_1 + #define HRTIM_ADC_TRG2 HRTIM_ADCTRG24_AC4 /* DMA channels *************************************************************/ diff --git a/configs/stm32f334-disco/src/stm32_smps.c b/configs/stm32f334-disco/src/stm32_smps.c index 952af64c1b..b1ae43e216 100644 --- a/configs/stm32f334-disco/src/stm32_smps.c +++ b/configs/stm32f334-disco/src/stm32_smps.c @@ -105,8 +105,8 @@ /* ADC1 injected channels numeration */ -#define VIN_ADC_INJ_CHANNEL 0 -#define VOUT_ADC_INJ_CHANNEL 1 +#define V_IN_ADC_INJ_CHANNEL 0 +#define V_OUT_ADC_INJ_CHANNEL 1 /* Voltage reference for ADC */ @@ -118,11 +118,11 @@ /* Input voltage convertion ratio - 6.8k/(6.8k + 27k) */ -#define VIN_RATIO (float)((float)(6800+27000)/(float)6800) +#define V_IN_RATIO (float)((float)(6800+27000)/(float)6800) /* Output voltage convertion ratio - 3.3k/(3.3k + 13.3k) */ -#define VOUT_RATIO (float)((float)(3300+13300)/(float)3300) +#define V_OUT_RATIO (float)((float)(3300+13300)/(float)3300) /* Some absolute limits */ @@ -130,6 +130,61 @@ #define SMPS_ABSOLUTE_OUT_VOLTAGE_LIMIT_mV 15000 #define SMPS_ABSOLUTE_IN_VOLTAGE_LIMIT_mV 15000 +#if CONFIG_EXAMPLES_SMPS_OUT_CURRENT_LIMIT > SMPS_ABSOLUTE_OUT_CURRENT_LIMIT_mA +# error "Output current limit great than absolute limit!" +#endif +#if CONFIG_EXAMPLES_SMPS_OUT_VOLTAGE_LIMIT > SMPS_ABSOLUTE_OUT_VOLTAGE_LIMIT_mV +# error "Output voltage limit greater than absolute limit!" +#endif +#if CONFIG_EXAMPLES_SMPS_IN_VOLTAGE_LIMIT > SMPS_ABSOLUTE_IN_VOLTAGE_LIMIT_mV +# error "Input voltage limit greater than absolute limit!" +#endif + +/* Maximum output voltage for boost conveter in float */ + +#define BOOST_VOLT_MAX ((float)CONFIG_EXAMPLES_SMPS_OUT_VOLTAGE_LIMIT/1000.0) + +/* Current limit table dimmension */ + +#define SMPS_CURRENT_LIMIT_TAB_DIM 15 + +/* At this time only PID controller implemented */ + +#define SMPS_CONTROLLER_PID 1 + +/* Converter's finite accuracy */ + +#define SMPS_VOLTAGE_ACCURACY ((float)0.01) + +/* Buck-boost mode threshold */ + +#define SMPS_BUCKBOOST_RANGE ((float)0.5) + +/* PID controller configuration */ + +#define PID_KP ((float)1.0) +#define PID_KI ((float)0.1) +#define PID_KD ((float)0.0) + +/* Converter frequncies: + * - TIMA_PWM_FREQ - buck converter 250kHz + * - TIMB_PWM_FREQ - boost converter 250kHz + */ + +#define TIMA_PWM_FREQ 250000 +#define TIMB_PWM_FREQ 250000 + +/* Deadtime configuration */ + +#define DT_RISING 0x0A0 +#define DT_FALLING 0x0A0 + +/* Helper macros */ + +#define HRTIM_ALL_OUTPUTS_ENABLE(hrtim, state) \ + HRTIM_OUTPUTS_ENABLE(hrtim, HRTIM_OUT_TIMA_CH1|HRTIM_OUT_TIMA_CH2| \ + HRTIM_OUT_TIMB_CH1|HRTIM_OUT_TIMB_CH2, state); + /**************************************************************************** * Private Types ****************************************************************************/ @@ -138,6 +193,7 @@ enum converter_mode_e { + CONVERTER_MODE_INIT, /* Initial mode */ CONVERTER_MODE_BUCK, /* Buck mode operations (V_in > V_out) */ CONVERTER_MODE_BOOST, /* Boost mode operations (V_in < V_out) */ CONVERTER_MODE_BUCKBOOST, /* Buck-boost operations (V_in near V_out)*/ @@ -159,11 +215,13 @@ struct smps_lower_dev_s struct smps_priv_s { uint8_t conv_mode; /* Converter mode */ - uint16_t vin_raw; /* Voltage input RAW value */ - uint16_t vout_raw; /* Voltage output RAW value */ - float vin; /* Voltage input real value in V */ - float vout; /* Voltage output real value in V */ + uint16_t v_in_raw; /* Voltage input RAW value */ + uint16_t v_out_raw; /* Voltage output RAW value */ + float v_in; /* Voltage input real value in V */ + float v_out; /* Voltage output real value in V */ bool running; /* Running flag */ + float state[3]; /* Controller state vartiables */ + float *c_limit_tab; /* Current limit tab */ }; /**************************************************************************** @@ -215,8 +273,9 @@ struct smps_ops_s g_smps_ops = struct smps_dev_s g_smps_dev = { - .ops = &g_smps_ops, - .priv = &g_smps + .ops = &g_smps_ops, + .priv = &g_smps, + .lower = NULL }; /* ADC configuration: @@ -232,16 +291,16 @@ struct smps_dev_s g_smps_dev = * Transistors configuration in boost mode: * - T4 - ON * - T11 - OFF - * - T5 and T15 - boost operation + * - T5 and T12 - boost operation * Transistors configuration in buck-boost mode: * - T4, T11 - buck operation - * - T5 and T15 - boost operation + * - T5 and T12 - boost operation * * HRTIM outputs configuration: * - T4 -> PA8 -> HRTIM_CHA1 * - T5 -> PA11 -> HRTIM_CHB2 * - T11 -> PA9 -> HRTIM_CHA2 - * - T15 -> PA10 -> HRTIM_CHB1 + * - T12 -> PA10 -> HRTIM_CHB1 * */ @@ -257,8 +316,8 @@ static const uint8_t g_adc1chan[ADC1_NCHANNELS] = static const uint32_t g_adc1pins[ADC1_NCHANNELS] = { - GPIO_ADC1_IN2, /* PA1 - VIN */ - GPIO_ADC1_IN4, /* PA3 - VOUT */ + GPIO_ADC1_IN2, /* PA1 - V_IN */ + GPIO_ADC1_IN4, /* PA3 - V_OUT */ }; /**************************************************************************** @@ -290,7 +349,7 @@ static int smps_shutdown(FAR struct smps_dev_s *dev) * Description: * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/ @@ -300,6 +359,7 @@ static int smps_setup(FAR struct smps_dev_s *dev) FAR struct smps_s *smps = (FAR struct smps_s *)dev->priv; FAR struct hrtim_dev_s *hrtim = NULL; FAR struct adc_dev_s *adc = NULL; + FAR struct smps_priv_s *priv; /* Initialize smps structure */ @@ -321,6 +381,8 @@ static int smps_setup(FAR struct smps_dev_s *dev) printf("ERROR: failed to get ADC lower level interface"); } + /* TODO: create current limit table */ + errout: return OK; } @@ -331,28 +393,89 @@ static int smps_start(FAR struct smps_dev_s *dev) FAR struct stm32_adc_dev_s *stm32_adc = (FAR struct stm32_adc_dev_s *) lower->adc->ad_priv; FAR struct smps_s *smps = (FAR struct smps_s *)dev->priv; + FAR struct smps_priv_s *priv = (struct smps_priv_s *)smps->priv; FAR struct hrtim_dev_s *hrtim = lower->hrtim; + volatile uint64_t per = 0; + uint64_t fclk = 0; + int ret = OK; - /* Stop HRTIM PWM */ + /* Disable HRTIM outputs */ - HRTIM_OUTPUTS_ENABLE(hrtim, HRTIM_OUT_TIMA_CH1, false); - HRTIM_OUTPUTS_ENABLE(hrtim, HRTIM_OUT_TIMA_CH2, false); + HRTIM_ALL_OUTPUTS_ENABLE(hrtim, false); - HRTIM_OUTPUTS_ENABLE(hrtim, HRTIM_OUT_TIMB_CH1, false); - HRTIM_OUTPUTS_ENABLE(hrtim, HRTIM_OUT_TIMB_CH2, false); + /* Reset SMPS private structure */ - /* 1 period is 4us - 100% time */ + memset(priv, 0, sizeof(struct smps_priv_s)); - HRTIM_PER_SET(hrtim, HRTIM_TIMER_TIMA, 18432); - HRTIM_PER_SET(hrtim, HRTIM_TIMER_TIMB, 18432); + /* Get TIMA period value for given frequency */ + + fclk = HRTIM_FCLK_GET(hrtim, HRTIM_TIMER_TIMA); + per = fclk/TIMA_PWM_FREQ; + if (per > HRTIM_PER_MAX) + { + printf("ERROR: can not achieve tima pwm freq=%u if fclk=%llu\n", + (uint32_t)TIMA_PWM_FREQ, (uint64_t)fclk); + ret = -EINVAL; + goto errout; + } + + /* Set TIMA period value */ + + HRTIM_PER_SET(hrtim, HRTIM_TIMER_TIMA, (uint16_t)per); + + /* Get TIMB period value for given frequency */ + + fclk = HRTIM_FCLK_GET(hrtim, HRTIM_TIMER_TIMB); + per = fclk/TIMB_PWM_FREQ; + if (per > HRTIM_PER_MAX) + { + printf("ERROR: can not achieve timb pwm freq=%u if fclk=%llu\n", + (uint32_t)TIMB_PWM_FREQ, (uint64_t)fclk); + ret = -EINVAL; + goto errout; + } + + /* Set TIMB period value */ + + HRTIM_PER_SET(hrtim, HRTIM_TIMER_TIMB, (uint16_t)per); /* ADC trigger on TIMA CMP4 */ HRTIM_CMP_SET(hrtim, HRTIM_TIMER_TIMA, HRTIM_CMP4, 10000); + /* Configure TIMER A and TIMER B deadtime mode + * + * NOTE: In deadtime mode we have to configure output 1 only (SETx1, RSTx1), + * output 2 configuration is not significant. + */ + + HRTIM_DEADTIME_UPDATE(hrtim, HRTIM_TIMER_TIMA, HRTIM_DT_EDGE_RISING, DT_RISING); + HRTIM_DEADTIME_UPDATE(hrtim, HRTIM_TIMER_TIMA, HRTIM_DT_EDGE_FALLING, DT_FALLING); + HRTIM_DEADTIME_UPDATE(hrtim, HRTIM_TIMER_TIMB, HRTIM_DT_EDGE_RISING, DT_RISING); + HRTIM_DEADTIME_UPDATE(hrtim, HRTIM_TIMER_TIMB, HRTIM_DT_EDGE_FALLING, DT_FALLING); + + /* Set T4 and T12 to a low state. + * Deadtime mode force T11 and T5 to a high state. + */ + + HRTIM_OUTPUT_SET_SET(hrtim, HRTIM_OUT_TIMA_CH1, HRTIM_OUT_SET_NONE); + HRTIM_OUTPUT_RST_SET(hrtim, HRTIM_OUT_TIMA_CH1, HRTIM_OUT_RST_PER); + + HRTIM_OUTPUT_SET_SET(hrtim, HRTIM_OUT_TIMB_CH1, HRTIM_OUT_SET_NONE); + HRTIM_OUTPUT_RST_SET(hrtim, HRTIM_OUT_TIMB_CH1, HRTIM_OUT_RST_PER); + + /* Set running flag */ + + priv->running = true; + + HRTIM_ALL_OUTPUTS_ENABLE(hrtim, true); + /* Enable ADC interrupts */ stm32_adc->ops->int_en(stm32_adc, ADC_INT_JEOS); + +errout: + return ret; } static int smps_stop(FAR struct smps_dev_s *dev) @@ -366,11 +489,7 @@ static int smps_stop(FAR struct smps_dev_s *dev) /* Disable HRTIM outputs */ - HRTIM_OUTPUTS_ENABLE(hrtim, HRTIM_OUT_TIMA_CH1, false); - HRTIM_OUTPUTS_ENABLE(hrtim, HRTIM_OUT_TIMA_CH2, false); - - HRTIM_OUTPUTS_ENABLE(hrtim, HRTIM_OUT_TIMB_CH1, false); - HRTIM_OUTPUTS_ENABLE(hrtim, HRTIM_OUT_TIMB_CH2, false); + HRTIM_ALL_OUTPUTS_ENABLE(hrtim, false); /* Disable ADC interrupts */ @@ -459,27 +578,27 @@ static int smps_limits_set(FAR struct smps_dev_s *dev, goto errout; } - if (limits->v_out * 1000 > SMPS_ABSOLUTE_OUT_VOLTAGE_LIMIT_mV) + if (limits->v_out * 1000 > CONFIG_EXAMPLES_SMPS_OUT_VOLTAGE_LIMIT) { - limits->v_out = (float)SMPS_ABSOLUTE_OUT_VOLTAGE_LIMIT_mV/1000.0; + limits->v_out = (float)CONFIG_EXAMPLES_SMPS_OUT_VOLTAGE_LIMIT/1000.0; printf("SMPS output voltage limiit > SMPS absoulute output voltage limit." - " Set output voltage limit to %d.\n", + " Set output voltage limit to %.2f.\n", limits->v_out); } - if (limits->v_in * 1000 > SMPS_ABSOLUTE_IN_VOLTAGE_LIMIT_mV) + if (limits->v_in * 1000 > CONFIG_EXAMPLES_SMPS_IN_VOLTAGE_LIMIT) { - limits->v_in = (float)SMPS_ABSOLUTE_IN_VOLTAGE_LIMIT_mV/1000.0; + limits->v_in = (float)CONFIG_EXAMPLES_SMPS_IN_VOLTAGE_LIMIT/1000.0; printf("SMPS input voltage limiit > SMPS absoulute input voltage limit." - " Set input voltage limit to %d.\n", + " Set input voltage limit to %.2f.\n", limits->v_in); } - if (limits->i_out * 1000 > SMPS_ABSOLUTE_OUT_CURRENT_LIMIT_mA) + if (limits->i_out * 1000 > CONFIG_EXAMPLES_SMPS_OUT_CURRENT_LIMIT) { - limits->i_out = (float)SMPS_ABSOLUTE_OUT_CURRENT_LIMIT_mA/1000.0; + limits->i_out = (float)CONFIG_EXAMPLES_SMPS_OUT_CURRENT_LIMIT/1000.0; printf("SMPS output current limiit > SMPS absoulute output current limit." - " Set output current limit to %d.\n", + " Set output current limit to %.2f.\n", limits->i_out); } @@ -510,8 +629,8 @@ static int smps_state_get(FAR struct smps_dev_s *dev, /* Copy localy stored feedbacks data to status structure */ - smps->state.fb.v_in = g_smps_priv.vin; - smps->state.fb.v_out = g_smps_priv.vout; + smps->state.fb.v_in = g_smps_priv.v_in; + smps->state.fb.v_out = g_smps_priv.v_out; /* Return state structure to caller */ @@ -544,36 +663,302 @@ static int smps_ioctl(FAR struct smps_dev_s *dev, int cmd, unsigned long arg) return OK; } +/**************************************************************************** + * Name: pid_controller + ****************************************************************************/ + +static float pid_controller(struct smps_priv_s *priv, float err) +{ + float out; + float A0 = PID_KP + PID_KD + PID_KI; + float A1 = -PID_KP - 2.0*PID_KD; + float A2 = PID_KD; + + /* Get PID controller output */ + + out = (A0 * err) + (A1 * priv->state[0]) + (A2 * priv->state[1]) + priv->state[2]; + + /* Store PID contrroller variables */ + + priv->state[1] = priv->state[0]; + priv->state[0] = err; + priv->state[2] = out; + + return out; +} + +/**************************************************************************** + * Name: smps_controller + ****************************************************************************/ + +static float smps_controller(struct smps_priv_s *priv, float err) +{ +#ifdef SMPS_CONTROLLER_PID + return pid_controller(priv, err); +#else +# error "At this time only PID controller implemented" +#endif +} + +/**************************************************************************** + * Name: smps_duty_set + ****************************************************************************/ + +static void smps_duty_set(struct smps_priv_s *priv, struct smps_lower_dev_s *lower, + float out) +{ + FAR struct hrtim_dev_s *hrtim = lower->hrtim; + uint8_t mode = priv->conv_mode; + uint16_t cmp = 0; + float duty = 0.0; + uint16_t per = 0; + + switch (mode) + { + case CONVERTER_MODE_INIT: + { + /* Do nothing */ + + break; + } + + case CONVERTER_MODE_BUCK: + { + if (out >= priv->v_in) out = priv->v_in; + if (out < 0.0) out = 0.0; + + duty = out/priv->v_in; + +#warning TODO: current limit in buck mode + + per = HRTIM_PER_GET(hrtim, HRTIM_TIMER_TIMA); + + cmp = (uint16_t)(per * duty); + + if (cmp > per-30) cmp = per - 30; + + /* Set T4 duty cycle. T11 is complementary to T4 */ + + HRTIM_CMP_SET(hrtim, HRTIM_TIMER_TIMA, HRTIM_CMP1, cmp); + + break; + } + + case CONVERTER_MODE_BOOST: + { + per = HRTIM_PER_GET(hrtim, HRTIM_TIMER_TIMA); + + + if (out < priv->v_in) out = priv->v_in; + if (out >= BOOST_VOLT_MAX) out = BOOST_VOLT_MAX; + + duty = 1.0 - priv->v_in/out; + +#warning TODO: current limit in boost mode + + cmp = (uint16_t)(per * duty); + + /* Set T12 duty cycle. T5 is complementary to T12 */ + + HRTIM_CMP_SET(hrtim, HRTIM_TIMER_TIMB, HRTIM_CMP1, cmp); + + break; + } + + case CONVERTER_MODE_BUCKBOOST: + { + /* do something */ + +#warning TODO: buck boost mode + + break; + } + + default: + { + printf("ERROR: unknown converter mode %d!\n", mode); + break; + } + } +} + +/**************************************************************************** + * Name: smps_conv_mode_set + * + * Description: + * Change converter mode (buck/boost/buck-boost). + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void smps_conv_mode_set(struct smps_priv_s *priv, struct smps_lower_dev_s *lower, + uint8_t mode) +{ + FAR struct hrtim_dev_s *hrtim = lower->hrtim; + + /* Disable all outputs */ + + HRTIM_ALL_OUTPUTS_ENABLE(hrtim, false); + + switch (mode) + { + case CONVERTER_MODE_INIT: + { + + break; + } + + case CONVERTER_MODE_BUCK: + { + /* Set T12 low (T5 high) on the next PER */ + + HRTIM_OUTPUT_SET_SET(hrtim, HRTIM_OUT_TIMB_CH1, HRTIM_OUT_SET_NONE); + HRTIM_OUTPUT_RST_SET(hrtim, HRTIM_OUT_TIMB_CH1, HRTIM_OUT_RST_PER); + + + /* Set T4 to a high state on PER and reset on CMP1. + T11 is complementary to T4. */ + + HRTIM_OUTPUT_SET_SET(hrtim, HRTIM_OUT_TIMA_CH1, HRTIM_OUT_SET_PER); + HRTIM_OUTPUT_RST_SET(hrtim, HRTIM_OUT_TIMA_CH1, HRTIM_OUT_RST_CMP1); + + break; + } + + case CONVERTER_MODE_BOOST: + { + /* Set T4 high (T11 low) on the next PER */ + + HRTIM_OUTPUT_SET_SET(hrtim, HRTIM_OUT_TIMA_CH1, HRTIM_OUT_SET_PER); + HRTIM_OUTPUT_RST_SET(hrtim, HRTIM_OUT_TIMA_CH1, HRTIM_OUT_RST_NONE); + + /* Set T12 to a high state on PER and reset on CMP1. + T5 is complementary to T12. */ + + HRTIM_OUTPUT_SET_SET(hrtim, HRTIM_OUT_TIMB_CH1, HRTIM_OUT_SET_PER); + HRTIM_OUTPUT_RST_SET(hrtim, HRTIM_OUT_TIMB_CH1, HRTIM_OUT_RST_CMP1); + + break; + } + + case CONVERTER_MODE_BUCKBOOST: + { + /* Set T4 to a high state on PER and reset on CMP1. + T11 is complementary to T4. */ + + HRTIM_OUTPUT_SET_SET(hrtim, HRTIM_OUT_TIMA_CH1, HRTIM_OUT_SET_PER); + HRTIM_OUTPUT_RST_SET(hrtim, HRTIM_OUT_TIMA_CH1, HRTIM_OUT_RST_CMP1); + + /* Set T12 to a high state on PER and reset on CMP1. + T5 is complementary to T12. */ + + HRTIM_OUTPUT_SET_SET(hrtim, HRTIM_OUT_TIMB_CH1, HRTIM_OUT_SET_PER); + HRTIM_OUTPUT_RST_SET(hrtim, HRTIM_OUT_TIMB_CH1, HRTIM_OUT_RST_CMP1); + + break; + } + + default: + { + printf("ERROR: unknown converter mode %d!\n", mode); + break; + } + } + + /* Set mode in private data */ + + priv->conv_mode = mode; + + /* Enable outputs */ + + HRTIM_ALL_OUTPUTS_ENABLE(hrtim, true); + +} + +/**************************************************************************** + * Name: adc12_handler + ****************************************************************************/ + static void adc12_handler(void) { - FAR struct smps_lower_dev_s *lower = g_smps_dev.lower; - FAR struct stm32_adc_dev_s *stm32_adc = + FAR struct smps_dev_s *dev = &g_smps_dev; + FAR struct smps_s *smps = (FAR struct smps_s *)dev->priv; + FAR struct smps_priv_s *priv = (struct smps_priv_s *)smps->priv; + FAR struct smps_lower_dev_s *lower = dev->lower; + FAR struct stm32_adc_dev_s *adc = (FAR struct stm32_adc_dev_s*)lower->adc->ad_priv; + uint32_t pending; float ref = ADC_REF_VOLTAGE; float bit = ADC_VAL_MAX; - uint32_t pending; + float err; + float out; + uint8_t mode; - pending = stm32_adc->ops->int_get(stm32_adc); + pending = adc->ops->int_get(adc); - if (pending & ADC_INT_JEOC) + if (pending & ADC_INT_JEOC && priv->running == true) { /* Get raw ADC values */ - g_smps_priv.vout_raw = stm32_adc->ops->inj_get(stm32_adc, VOUT_ADC_INJ_CHANNEL); - g_smps_priv.vin_raw = stm32_adc->ops->inj_get(stm32_adc, VIN_ADC_INJ_CHANNEL); + priv->v_out_raw = adc->ops->inj_get(adc, V_OUT_ADC_INJ_CHANNEL); + priv->v_in_raw = adc->ops->inj_get(adc, V_IN_ADC_INJ_CHANNEL); /* Convert raw values to real values */ - g_smps_priv.vout = (g_smps_priv.vout_raw * ref / bit) * VOUT_RATIO; - g_smps_priv.vin = (g_smps_priv.vin_raw * ref / bit) * VIN_RATIO; + priv->v_out = (priv->v_out_raw * ref / bit) * V_OUT_RATIO; + priv->v_in = (priv->v_in_raw * ref / bit) * V_IN_RATIO; -#warning "missing regulator logic!" + /* According to measured voltages we set converter in appropriate mode */ + if (smps->param.v_out > (priv->v_in+SMPS_BUCKBOOST_RANGE)) + { + /* Desired output voltage greather than input voltage - set boost converter */ + + mode = CONVERTER_MODE_BOOST; + } + + else if (smps->param.v_out < (priv->v_in-SMPS_BUCKBOOST_RANGE)) + { + /* Desired output voltage lower than input voltage - set buck converter */ + + mode = CONVERTER_MODE_BUCK; + } + + else + { + /* Desired output voltage close to input voltage - set buck-boost converter */ + + mode = CONVERTER_MODE_BUCKBOOST; + } + + /* Configure converter to the new mode if needed */ + + if (priv->conv_mode != mode) + { + smps_conv_mode_set(priv, lower, mode); + } + + /* Get regualtor error */ + + err = smps->param.v_out - priv->v_out; + + if (err >= SMPS_VOLTAGE_ACCURACY || err <= (-SMPS_VOLTAGE_ACCURACY)) + { + /* PID controller */ + + out = smps_controller(priv, err); + + /* Update duty cycle */ + + smps_duty_set(priv, lower, out); + } } /* Clear pending */ - stm32_adc->ops->int_ack(stm32_adc, pending); + adc->ops->int_ack(adc, pending); } /**************************************************************************** @@ -584,12 +969,12 @@ static void adc12_handler(void) * Name: stm32_smps_setup * * Description: - * Initialize SMPS driver. + * Initialize SMPS driver. * - * This function should be call by board_app_initialize(). + * This function should be call by board_app_initialize(). * * Returned Value: - * 0 on success, a negated errno value on failure + * 0 on success, a negated errno value on failure * ****************************************************************************/