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 <gnutt@nuttx.org>
This commit is contained in:
Mateusz Szafoni 2018-01-21 18:28:09 +00:00 committed by Matt Thompson
parent e02a46f1d5
commit 6fd85ff076
4 changed files with 790 additions and 190 deletions

View File

@ -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<<HRTIM_MASTER_PRESCALER),
.prescaler = HRTIM_MASTER_PRESCALER,
.mode = HRTIM_MASTER_MODE,
# ifdef CONFIG_STM32_HRTIM_MASTER_DAC
.dac = HRTIM_MASTER_DAC,
.dac = HRTIM_MASTER_DAC,
# endif
# ifdef CONFIG_STM32_HRTIM_MASTER_IRQ
.irq = HRTIM_MASTER_IRQ
.irq = HRTIM_MASTER_IRQ
# endif
# ifdef CONFIG_STM32_HRTIM_MASTER_DMA
.dma = HRTIM_MASTER_DMA
.dma = HRTIM_MASTER_DMA
# endif
#endif
},
.priv = NULL,
.priv = NULL,
};
#ifdef CONFIG_STM32_HRTIM_TIMA
@ -849,20 +855,21 @@ static struct stm32_hrtim_tim_s g_tima =
{
.tim =
{
.base = STM32_HRTIM1_TIMERA_BASE,
.pclk = HRTIM_CLOCK/(HRTIM_TIMA_PRESCALER+1),
.mode = HRTIM_TIMA_MODE,
.base = STM32_HRTIM1_TIMERA_BASE,
.fclk = HRTIM_CLOCK/(1<<HRTIM_TIMA_PRESCALER),
.prescaler = HRTIM_TIMA_PRESCALER,
.mode = HRTIM_TIMA_MODE,
#ifdef CONFIG_STM32_HRTIM_TIMA_DAC
.dac = HRTIM_TIMA_DAC,
.dac = HRTIM_TIMA_DAC,
#endif
#ifdef CONFIG_STM32_HRTIM_TIMA_IRQ
.irq = HRTIM_TIMA_IRQ,
.irq = HRTIM_TIMA_IRQ,
#endif
#ifdef CONFIG_STM32_HRTIM_TIMA_DMA
.dma = HRTIM_TIMA_DMA
.dma = HRTIM_TIMA_DMA
#endif
},
.priv = &g_tima_priv
.priv = &g_tima_priv
};
#endif
@ -945,20 +952,21 @@ static struct stm32_hrtim_tim_s g_timb =
{
.tim =
{
.base = STM32_HRTIM1_TIMERB_BASE,
.pclk = HRTIM_CLOCK/(HRTIM_TIMB_PRESCALER+1),
.mode = HRTIM_TIMB_MODE,
.base = STM32_HRTIM1_TIMERB_BASE,
.fclk = HRTIM_CLOCK/(1<<HRTIM_TIMB_PRESCALER),
.prescaler = HRTIM_TIMB_PRESCALER,
.mode = HRTIM_TIMB_MODE,
#ifdef CONFIG_STM32_HRTIM_TIMB_DAC
.dac = HRTIM_TIMB_DAC,
.dac = HRTIM_TIMB_DAC,
#endif
#ifdef CONFIG_STM32_HRTIM_TIMB_IRQ
.irq = HRTIM_TIMB_IRQ,
.irq = HRTIM_TIMB_IRQ,
#endif
#ifdef CONFIG_STM32_HRTIM_TIMB_DMA
.dma = HRTIM_TIMB_DMA
.dma = HRTIM_TIMB_DMA
#endif
},
.priv = &g_timb_priv
.priv = &g_timb_priv
};
#endif
@ -1041,20 +1049,21 @@ static struct stm32_hrtim_tim_s g_timc =
{
.tim =
{
.base = STM32_HRTIM1_TIMERC_BASE,
.pclk = HRTIM_CLOCK/(HRTIM_TIMC_PRESCALER+1),
.mode = HRTIM_TIMC_MODE,
.base = STM32_HRTIM1_TIMERC_BASE,
.fclk = HRTIM_CLOCK/(1<<HRTIM_TIMC_PRESCALER),
.prescaler = HRTIM_TIMC_PRESCALER,
.mode = HRTIM_TIMC_MODE,
#ifdef CONFIG_STM32_HRTIM_TIMC_DAC
.dac = HRTIM_TIMC_DAC,
.dac = HRTIM_TIMC_DAC,
#endif
#ifdef CONFIG_STM32_HRTIM_TIMC_IRQ
.irq = HRTIM_TIMC_IRQ,
.irq = HRTIM_TIMC_IRQ,
#endif
#ifdef CONFIG_STM32_HRTIM_TIMC_DMA
.dma = HRTIM_TIMC_DMA
.dma = HRTIM_TIMC_DMA
#endif
},
.priv = &g_timc_priv
.priv = &g_timc_priv
};
#endif
@ -1137,20 +1146,21 @@ static struct stm32_hrtim_tim_s g_timd =
{
.tim =
{
.base = STM32_HRTIM1_TIMERD_BASE,
.pclk = HRTIM_CLOCK/(HRTIM_TIMD_PRESCALER+1),
.mode = HRTIM_TIMD_MODE,
.base = STM32_HRTIM1_TIMERD_BASE,
.fclk = HRTIM_CLOCK/(1<<HRTIM_TIMD_PRESCALER),
.prescaler = HRTIM_TIMD_PRESCALER,
.mode = HRTIM_TIMD_MODE,
#ifdef CONFIG_STM32_HRTIM_TIMD_DAC
.dac = HRTIM_TIMD_DAC,
.dac = HRTIM_TIMD_DAC,
#endif
#ifdef CONFIG_STM32_HRTIM_TIMD_IRQ
.irq = HRTIM_TIMD_IRQ,
.irq = HRTIM_TIMD_IRQ,
#endif
#ifdef CONFIG_STM32_HRTIM_TIMD_DMA
.dma = HRTIM_TIMD_DMA
.dma = HRTIM_TIMD_DMA
#endif
},
.priv = &g_timd_priv
.priv = &g_timd_priv
};
#endif
@ -1233,20 +1243,21 @@ static struct stm32_hrtim_tim_s g_time =
{
.tim =
{
.base = STM32_HRTIM1_TIMERE_BASE,
.pclk = HRTIM_CLOCK/(HRTIM_TIME_PRESCALER+1),
.mode = HRTIM_TIME_MODE,
.base = STM32_HRTIM1_TIMERE_BASE,
.fclk = HRTIM_CLOCK/(1<<HRTIM_TIME_PRESCALER),
.prescaler = HRTIM_TIME_PRESCALER,
.mode = HRTIM_TIME_MODE,
#ifdef CONFIG_STM32_HRTIM_TIME_DAC
.dac = HRTIM_TIME_DAC,
.dac = HRTIM_TIME_DAC,
#endif
#ifdef CONFIG_STM32_HRTIM_TIME_IRQ
.irq = HRTIM_TIME_IRQ,
.irq = HRTIM_TIME_IRQ,
#endif
#ifdef CONFIG_STM32_HRTIM_TIME_DMA
.dma = HRTIM_TIME_DMA
.dma = HRTIM_TIME_DMA
#endif
},
.priv = &g_time_priv
.priv = &g_time_priv
};
#endif
@ -1488,6 +1499,7 @@ static const struct stm32_hrtim_ops_s g_hrtim1ops =
.per_update = hrtim_per_update,
.per_get = hrtim_per_get,
.cmp_get = hrtim_cmp_get,
.fclk_get = hrtim_fclk_get,
#ifdef CONFIG_STM32_HRTIM_INTERRUPTS
.irq_ack = hrtim_irq_ack,
#endif
@ -1701,7 +1713,7 @@ static void hrtim_cmn_modifyreg(FAR struct stm32_hrtim_s *priv,
* timer - An HRTIM Timer index to get
*
* Returned Value:
* Base adress offset for given Timer index
* Pointer to timer structure on success, NULL on failure
*
****************************************************************************/
@ -1768,6 +1780,53 @@ static FAR struct stm32_hrtim_tim_s *
return tim;
}
/****************************************************************************
* Name: hrtim_slave_get
*
* Description:
* Get Slave private data structure for given HRTIM Timer index
*
* Input Parameters:
* priv - A reference to the HRTIM block
* timer - An HRTIM Slave Timer index to get
*
* Returned Value:
* Pointer to slave structure success, NULL on failure
*
****************************************************************************/
static FAR struct stm32_hrtim_slave_priv_s *
hrtim_slave_get(FAR struct stm32_hrtim_s *priv, uint8_t timer)
{
FAR struct stm32_hrtim_tim_s* tim;
FAR struct stm32_hrtim_slave_priv_s* slave;
/* Sanity checking */
if (timer == HRTIM_TIMER_MASTER || timer == HRTIM_TIMER_COMMON)
{
slave = NULL;
goto errout;
}
/* Get Timer data strucutre */
tim = hrtim_tim_get(priv, timer);
if (tim == NULL)
{
slave = NULL;
goto errout;
}
/* Get Slave Timer data */
slave = (struct stm32_hrtim_slave_priv_s*)tim->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
*
****************************************************************************/

View File

@ -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

View File

@ -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 *************************************************************/

View File

@ -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
*
****************************************************************************/