mirror of
https://github.com/apache/nuttx.git
synced 2026-05-30 21:36: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
+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);
|
||||
|
||||
Reference in New Issue
Block a user