mirror of
https://github.com/apache/nuttx.git
synced 2026-05-26 10:46:28 +08:00
Merged in raiden00/nuttx (pull request #476)
Master * stm32_dac.c: fix compilation when DMA disabled for channel * smps.h: update some comments * smps.c: more sanity checks Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
committed by
Gregory Nutt
parent
8ffb103adb
commit
daac3bd7f8
@@ -493,13 +493,13 @@
|
||||
|
||||
/* DMA buffers default size */
|
||||
|
||||
#ifndef CONFIG_STM32_DAC1CH1_DMA_BUFFER_SIZE
|
||||
#if !defined(CONFIG_STM32_DAC1CH1_DMA_BUFFER_SIZE) && defined(CONFIG_STM32_DAC1CH1_DMA)
|
||||
# error "DAC1CH1 buffer size must be provided"
|
||||
#endif
|
||||
#ifndef CONFIG_STM32_DAC1CH2_DMA_BUFFER_SIZE
|
||||
#if !defined(CONFIG_STM32_DAC1CH2_DMA_BUFFER_SIZE) && defined(CONFIG_STM32_DAC1CH2_DMA)
|
||||
# error "DAC1CH2 buffer size must be provided"
|
||||
#endif
|
||||
#ifndef CONFIG_STM32_DAC2CH1_DMA_BUFFER_SIZE
|
||||
#if !defined(CONFIG_STM32_DAC2CH1_DMA_BUFFER_SIZE) && defined(CONFIG_STM32_DAC2CH1_DMA)
|
||||
# error "DAC2CH1 buffer size must be provided"
|
||||
#endif
|
||||
|
||||
|
||||
+145
-7
@@ -229,18 +229,74 @@ static int smps_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
FAR struct inode *inode = filep->f_inode;
|
||||
FAR struct smps_dev_s *dev = inode->i_private;
|
||||
FAR struct smps_s *smps = (FAR struct smps_s *)dev->priv;
|
||||
int ret;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case PWRIOC_START:
|
||||
{
|
||||
/* TODO: sanity checking:
|
||||
* - absolute limits
|
||||
* - SMPS parameters
|
||||
* - SMPS mode
|
||||
/* Allow SMPS start only when some limits available
|
||||
* and strucutre is locked.
|
||||
* REVISIT: not sure if it is needed here
|
||||
*/
|
||||
|
||||
if ((smps->limits.lock == false) ||
|
||||
(smps->limits.v_in <= 0 && smps->limits.v_out <= 0 &&
|
||||
smps->limits.i_in <= 0 && smps->limits.i_out <= 0 &&
|
||||
smps->limits.p_in <= 0 && smps->limits.p_out <= 0 ))
|
||||
{
|
||||
pwrerr("ERROR: SMPS limits data must be set"
|
||||
" and locked before SMPS start\n", ret);
|
||||
|
||||
ret = -EPERM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Check SMPS mode */
|
||||
|
||||
if (smps->opmode == SMPS_OPMODE_INIT)
|
||||
{
|
||||
pwrerr("ERROR: SMPS operation mode not specified\n");
|
||||
|
||||
ret = -EPERM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* When constan current mode, then output current must be provided */
|
||||
|
||||
if (smps->opmode == SMPS_OPMODE_CC && smps->param.i_out <= 0)
|
||||
{
|
||||
pwrerr("ERROR: CC selected but i_out not specified!\n");
|
||||
|
||||
ret = -EPERM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* When constan voltage mode, then output voltage must be provided */
|
||||
|
||||
if (smps->opmode == SMPS_OPMODE_CV && smps->param.v_out <= 0)
|
||||
{
|
||||
pwrerr("ERROR: CV selected but v_out not specified!\n");
|
||||
|
||||
ret = -EPERM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* When constan power mode, then output power must be provided */
|
||||
|
||||
if (smps->opmode == SMPS_OPMODE_CP && smps->param.p_out <= 0)
|
||||
{
|
||||
pwrerr("ERROR: CP selected but p_out not specified!\n");
|
||||
|
||||
ret = -EPERM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* REVISIT: something else ?? */
|
||||
|
||||
/* Finally, call start from lower-half driver */
|
||||
|
||||
ret = dev->ops->start(dev);
|
||||
if (ret != OK)
|
||||
{
|
||||
@@ -276,7 +332,15 @@ static int smps_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
FAR struct smps_limits_s *limits =
|
||||
(FAR struct smps_limits_s *)((uintptr_t)arg);
|
||||
|
||||
/* TODO: lock mechanism */
|
||||
if (smps->limits.lock == true)
|
||||
{
|
||||
pwrerr("ERROR: SMPS limits locked!\n");
|
||||
|
||||
ret = -EPERM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* NOTE: this call must set the smps_limits_s structure */
|
||||
|
||||
ret = dev->ops->limits_set(dev, limits);
|
||||
if (ret != OK)
|
||||
@@ -340,7 +404,58 @@ static int smps_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
FAR struct smps_params_s *params =
|
||||
(FAR struct smps_params_s *)((uintptr_t)arg);
|
||||
|
||||
/* TODO: lock mechanism */
|
||||
if (smps->param.lock == true)
|
||||
{
|
||||
pwrerr("ERROR: SMPS params locked!\n");
|
||||
|
||||
ret = -EPERM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if ((smps->limits.lock == false) ||
|
||||
(smps->limits.v_in <= 0 && smps->limits.v_out <= 0 &&
|
||||
smps->limits.i_in <= 0 && smps->limits.i_out <= 0 &&
|
||||
smps->limits.p_in <= 0 && smps->limits.p_out <= 0 ))
|
||||
{
|
||||
pwrerr("ERROR: limits must be set prior to params!\n");
|
||||
|
||||
ret = -EPERM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Check output voltage configuration */
|
||||
|
||||
if (smps->limits.v_out > 0 && params->v_out > smps->limits.v_out)
|
||||
{
|
||||
pwrerr("ERROR: params->v_out > limits.v_out: %d > %d\n",
|
||||
params->v_out, smps->limits.v_out);
|
||||
|
||||
ret = -EPERM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Check output current configuration */
|
||||
|
||||
if (smps->limits.i_out > 0 && params->i_out > smps->limits.i_out)
|
||||
{
|
||||
pwrerr("ERROR: params->i_out > limits.i_out: %d > %d\n",
|
||||
params->i_out, smps->limits.i_out);
|
||||
|
||||
ret = -EPERM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Check output power configuration */
|
||||
|
||||
if (smps->limits.p_out > 0 && params->p_out > smps->limits.p_out)
|
||||
{
|
||||
pwrerr("ERROR: params->p_out > limits.p_out: %d > %d\n",
|
||||
params->p_out, smps->limits.p_out);
|
||||
|
||||
ret = -EPERM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* TODO: limits */
|
||||
|
||||
ret = dev->ops->params_set(dev, params);
|
||||
@@ -359,6 +474,7 @@ static int smps_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
}
|
||||
}
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -374,6 +490,28 @@ int smps_register(FAR const char *path, FAR struct smps_dev_s *dev, FAR void *lo
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(path != NULL && dev != NULL && lower != NULL);
|
||||
DEBUGASSERT(dev->ops != NULL);
|
||||
|
||||
/* For safety reason, when some necessary low-level logic is not provided,
|
||||
* system should fail before low-level hardware initialization, so:
|
||||
* - all ops are checked here, before character driver registration
|
||||
* - all ops must be provided, even if not used
|
||||
*/
|
||||
|
||||
DEBUGASSERT(dev->ops->setup != NULL);
|
||||
DEBUGASSERT(dev->ops->shutdown != NULL);
|
||||
DEBUGASSERT(dev->ops->stop != NULL);
|
||||
DEBUGASSERT(dev->ops->start != NULL);
|
||||
DEBUGASSERT(dev->ops->params_set != NULL);
|
||||
DEBUGASSERT(dev->ops->mode_set != NULL);
|
||||
DEBUGASSERT(dev->ops->limits_set != NULL);
|
||||
DEBUGASSERT(dev->ops->fault_set != NULL);
|
||||
DEBUGASSERT(dev->ops->state_get != NULL);
|
||||
DEBUGASSERT(dev->ops->fault_get != NULL);
|
||||
DEBUGASSERT(dev->ops->fault_clean != NULL);
|
||||
DEBUGASSERT(dev->ops->ioctl != NULL);
|
||||
|
||||
/* Initialize the HRTIM device structure */
|
||||
|
||||
dev->ocount = 0;
|
||||
@@ -388,7 +526,7 @@ int smps_register(FAR const char *path, FAR struct smps_dev_s *dev, FAR void *lo
|
||||
|
||||
/* Register the SMPS character driver */
|
||||
|
||||
ret = register_driver(path, &smps_fops, 0444, dev);
|
||||
ret = register_driver(path, &smps_fops, 0444, dev);
|
||||
if (ret < 0)
|
||||
{
|
||||
sem_destroy(&dev->closesem);
|
||||
|
||||
@@ -47,6 +47,10 @@
|
||||
* - analog peripherals configuration such as ADC, DAC and comparators,
|
||||
* - control algorithm for SMPS action (eg. PID loop)
|
||||
*
|
||||
* NOTE: This driver can also be used as "upper half" driver for programmable
|
||||
* digital PWM controllers (eg. ADP1046), but it is not the main goal of
|
||||
* current development.
|
||||
*
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
@@ -146,11 +150,16 @@ struct smps_state_s
|
||||
struct smps_feedback_s fb; /* Feedback from SMPS */
|
||||
};
|
||||
|
||||
/* SMPS absolute limits. Exceeding this limits should cause critical error */
|
||||
/* SMPS absolute limits. Exceeding this limits should cause critical error.
|
||||
* This structure must be configured before SMPS params_set call.
|
||||
* When limit is set to 0 then it is ignored.
|
||||
*/
|
||||
|
||||
struct smps_limits_s
|
||||
{
|
||||
bool lock; /* */
|
||||
bool lock; /* This bit must be set after
|
||||
* limits configuration.
|
||||
*/
|
||||
float v_in; /* Maximum input voltage */
|
||||
float v_out; /* Maximum output voltage */
|
||||
float i_in; /* Maximum input current */
|
||||
@@ -163,7 +172,10 @@ struct smps_limits_s
|
||||
|
||||
struct smps_params_s
|
||||
{
|
||||
bool lock;
|
||||
bool lock; /* Lock this structure. Set this bit
|
||||
* if there is no need to change SMPS
|
||||
* parameter during run-time.
|
||||
*/
|
||||
float v_out; /* */
|
||||
float i_out; /* */
|
||||
float p_out; /* */
|
||||
@@ -175,7 +187,7 @@ struct smps_s
|
||||
{
|
||||
uint8_t opmode; /* SMPS operation mode */
|
||||
uint8_t opflags; /* SMPS operation flags */
|
||||
const struct smps_limits_s limits; /* SMPS absolute limits */
|
||||
struct smps_limits_s limits; /* SMPS absolute limits */
|
||||
struct smps_params_s param; /* SMPS settings */
|
||||
struct smps_state_s state; /* SMPS state */
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user