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:
Mateusz Szafoni
2017-09-02 19:52:21 +00:00
committed by Gregory Nutt
parent 8ffb103adb
commit daac3bd7f8
3 changed files with 164 additions and 14 deletions
+145 -7
View File
@@ -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);