nuttx-apps/examples/smps/smps_main.c
Xiang Xiao 857158451b Unify the void cast usage
1.Remove void cast for function because many place ignore the returned value witout cast
2.Replace void cast for variable with UNUSED macro

Change-Id: Ie644129a563244a6397036789c4c3ea83c4e9b09
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2020-01-02 23:21:01 +08:00

643 lines
17 KiB
C

/****************************************************************************
* examples/smps/smps_main.c
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Mateusz Szafoni <raiden00@railab.me>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdbool.h>
#include <errno.h>
#include <debug.h>
#include <sys/ioctl.h>
#include <sys/boardctl.h>
#include <nuttx/fs/fs.h>
#include <nuttx/power/smps.h>
#if defined(CONFIG_EXAMPLES_SMPS)
#ifndef CONFIG_DRIVERS_SMPS
# error "Smps example requires smps support"
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef CONFIG_LIBC_FLOATINGPOINT
# error "CONFIG_LIBC_FLOATINGPOINT must be set!"
#endif
#ifndef CONFIG_EXAMPLES_SMPS_TIME_DEFAULT
# define CONFIG_EXAMPLES_SMPS_TIME_DEFAULT 10
#endif
#ifndef CONFIG_EXAMPLES_SMPS_OUT_VOLTAGE_DEFAULT
# define CONFIG_EXAMPLES_SMPS_OUT_VOLTAGE_DEFAULT 0
#endif
#ifndef CONFIG_EXAMPLES_SMPS_OUT_CURRENT_DEFAULT
# define CONFIG_EXAMPLES_SMPS_OUT_CURRENT_DEFAULT 0
#endif
#ifndef CONFIG_EXAMPLES_SMPS_OUT_POWER_DEFAULT
# define CONFIG_EXAMPLES_SMPS_OUT_POWER_DEFAULT 0
#endif
#ifndef CONFIG_EXAMPLES_SMPS_OUT_VOLTAGE_LIMIT
# define CONFIG_EXAMPLES_SMPS_OUT_VOLTAGE_LIMIT 0
#endif
#ifndef CONFIG_EXAMPLES_SMPS_OUT_CURRENT_LIMIT
# define CONFIG_EXAMPLES_SMPS_OUT_CURRENT_LIMIT 0
#endif
#ifndef CONFIG_EXAMPLES_SMPS_OUT_POWER_LIMIT
# define CONFIG_EXAMPLES_SMPS_OUT_POWER_LIMIT 0
#endif
#ifndef CONFIG_EXAMPLES_SMPS_IN_VOLTAGE_LIMIT
# define CONFIG_EXAMPLES_SMPS_IN_VOLTAGE_LIMIT 0
#endif
#ifndef CONFIG_EXAMPLES_SMPS_IN_CURRENT_LIMIT
# define CONFIG_EXAMPLES_SMPS_IN_CURRENT_LIMIT 0
#endif
#ifndef CONFIG_EXAMPLES_SMPS_IN_POWER_LIMIT
# define CONFIG_EXAMPLES_SMPS_IN_POWER_LIMIT 0
#endif
/****************************************************************************
* Private Type Definition
****************************************************************************/
/* Application arguments */
struct args_s
{
int time; /* Run time limit in sec, -1 if forever */
float current; /* Output current for CC mode */
float voltage; /* Output voltage for CV mode */
float power; /* Output power for CP mode */
};
/****************************************************************************
* Private Function Protototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
struct args_s g_args;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: smps_help
****************************************************************************/
static void smps_help(FAR struct args_s *args)
{
printf("Usage: smps [OPTIONS]\n\n");
printf(" [-v voltage] output voltage in V\n");
printf(" valid values from 0.0 to output voltage limit\n");
printf(" [-c current] output current in A\n");
printf(" valid values from 0.0 to output current limit\n");
printf(" [-p power] output power in W\n");
printf(" valid values from 0.0 to output power limit\n");
printf(" [-t time] run time in seconds\n");
printf(" valid values greather than 0 and\n");
printf(" -1 for infinity [default]\n");
printf("\n");
}
/****************************************************************************
* Name: arg_string
****************************************************************************/
static int arg_string(FAR char **arg, FAR char **value)
{
FAR char *ptr = *arg;
if (ptr[2] == '\0')
{
*value = arg[1];
return 2;
}
else
{
*value = &ptr[2];
return 1;
}
}
/****************************************************************************
* Name: arg_decimal
****************************************************************************/
static int arg_decimal(FAR char **arg, FAR int *value)
{
FAR char *string;
int ret;
ret = arg_string(arg, &string);
*value = atoi(string);
return ret;
}
/****************************************************************************
* Name: arg_float
****************************************************************************/
static int arg_float(FAR char **arg, FAR float *value)
{
FAR char *string;
int ret;
ret = arg_string(arg, &string);
*value = atof(string);
return ret;
}
/****************************************************************************
* Name: parse_args
****************************************************************************/
static void parse_args(FAR struct args_s *args, int argc, FAR char **argv)
{
FAR char *ptr;
float f_value;
int i_value;
int index;
int nargs;
for (index = 1; index < argc;)
{
ptr = argv[index];
if (ptr[0] != '-')
{
printf("Invalid options format: %s\n", ptr);
exit(0);
}
switch (ptr[1])
{
/* Get voltage */
case 'v':
{
nargs = arg_float(&argv[index], &f_value);
index += nargs;
if (f_value <= 0.0 ||
(f_value * 1000 > CONFIG_EXAMPLES_SMPS_OUT_VOLTAGE_LIMIT))
{
printf("Invalid voltage %.2f\n", f_value);
exit(1);
}
args->voltage = f_value;
break;
}
/* Get current */
case 'i':
{
nargs = arg_float(&argv[index], &f_value);
index += nargs;
if (f_value <= 0.0 ||
(f_value * 1000 > CONFIG_EXAMPLES_SMPS_OUT_CURRENT_LIMIT))
{
printf("Invalid current %.2f\n", f_value);
exit(1);
}
args->current = f_value;
break;
}
/* Get power */
case 'p':
{
nargs = arg_float(&argv[index], &f_value);
index += nargs;
if (f_value <= 0.0 ||
(f_value * 1000 > CONFIG_EXAMPLES_SMPS_OUT_POWER_LIMIT))
{
printf("Invalid power %.2f\n", f_value);
exit(1);
}
args->power = f_value;
break;
}
/* Get time */
case 't':
{
nargs = arg_decimal(&argv[index], &i_value);
index += nargs;
if (i_value <= 0 && i_value != -1)
{
printf("Invalid time value %d s\n", i_value);
exit(1);
}
args->time = i_value;
break;
}
/* Print help message */
case 'h':
{
smps_help(args);
exit(0);
}
default:
{
printf("Unsupported option: %s\n", ptr);
smps_help(args);
exit(1);
}
}
}
}
/****************************************************************************
* Name: validate_args
****************************************************************************/
static int validate_args(FAR struct args_s *args)
{
int ret = OK;
if (args->current < 0 ||
args->current > (((float)CONFIG_EXAMPLES_SMPS_OUT_CURRENT_LIMIT)/1000.0))
{
printf("Not valid current value: %.2f\n", args->current);
goto errout;
}
if (args->voltage < 0 ||
args->voltage > (((float)CONFIG_EXAMPLES_SMPS_OUT_VOLTAGE_LIMIT)/1000.0))
{
printf("Not valid voltage value: %.2f\n", args->voltage);
goto errout;
}
if (args->power < 0 ||
args->power > (((float)CONFIG_EXAMPLES_SMPS_OUT_POWER_LIMIT)/1000.0))
{
printf("Not valid power value: %.2f\n", args->power);
goto errout;
}
errout:
return ret;
}
/****************************************************************************
* Name: feedback_print
****************************************************************************/
static void feedback_print(FAR struct smps_feedback_s *fb)
{
#ifdef CONFIG_SMPS_HAVE_INPUT_VOLTAGE
printf("v_out: %.3f\t", fb->v_out);
#endif
#ifdef CONFIG_SMPS_HAVE_OUTPUT_VOLTAGE
printf("v_in: %.3f\t", fb->v_in);
#endif
#ifdef CONFIG_SMPS_HAVE_OUTPUT_CURRENT
printf("i_out: %.3f\t", fb->i_out);
#endif
#ifdef CONFIG_SMPS_HAVE_INPUT_CURRENT
printf("i_in: %.3f\t", fb->i_in);
#endif
#ifdef CONFIG_SMPS_HAVE_OUTPUT_POWER
printf("p_in: %.3f\t", fb->p_in);
#endif
#ifdef CONFIG_SMPS_HAVE_INPUT_POWER
printf("p_out: %.3f\t", fb->p_out);
#endif
#ifdef CONFIG_SMPS_HAVE_EFFICIENCY
printf("eff: %.3f\t", fb->eff);
#endif
printf("\n");
}
static void print_info(struct smps_limits_s *limits, struct smps_params_s *params,
uint8_t *mode, struct args_s *args)
{
printf("-------------------------------------\n");
printf("Current SMPS settings:\n");
printf("\n");
#if CONFIG_EXAMPLES_SMPS_OUT_VOLTAGE_LIMIT > 0
printf(" Output voltage limit set to %.2f\n", limits->v_out);
#endif
#if CONFIG_EXAMPLES_SMPS_IN_VOLTAGE_LIMIT > 0
printf(" Input voltage limit set to %.2f\n", limits->v_in);
#endif
#if CONFIG_EXAMPLES_SMPS_OUT_CURRENT_LIMIT > 0
printf(" Output current limit set to %.2f\n", limits->i_out);
#endif
#if CONFIG_EXAMPLES_SMPS_IN_CURRENT_LIMIT > 0
printf(" Input current limit set to %.2f\n", limits->i_in);
#endif
#if CONFIG_EXAMPLES_SMPS_OUT_POWER_LIMIT > 0
printf(" Output power limit set to %.2f\n", limits->p_out);
#endif
#if CONFIG_EXAMPLES_SMPS_IN_POWER_LIMIT > 0
printf(" Input power limit set to %.2f\n", limits->p_in);
#endif
printf("\n");
printf(" Demo time: %d sec\n", args->time);
printf(" Mode set to %d\n", *mode);
if (params->v_out > 0)
{
printf(" Output voltage set to %.2f\n", params->v_out);
}
if (params->i_out > 0)
{
printf(" Output current set to %.2f\n", params->i_out);
}
if (params->p_out > 0)
{
printf(" Output power set to %.2f\n", params->p_out);
}
printf("-------------------------------------\n\n");
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: smps_main
****************************************************************************/
int main(int argc, char *argv[])
{
struct smps_limits_s smps_limits;
struct smps_params_s smps_params;
struct smps_state_s smps_state;
struct args_s *args = &g_args;
uint8_t smps_mode;
bool terminate;
int time = 0;
int ret = 0;
int fd = 0;
/* Initialize smps stuctures */
memset(&smps_limits, 0, sizeof(struct smps_limits_s));
memset(&smps_params, 0, sizeof(struct smps_params_s));
memset(args, 0, sizeof(struct args_s));
/* Initialize variables */
terminate = false;
/* Initialize SMPS limits */
#if CONFIG_EXAMPLES_SMPS_OUT_VOLTAGE_LIMIT > 0
smps_limits.v_out = (float)CONFIG_EXAMPLES_SMPS_OUT_VOLTAGE_LIMIT/1000.0;
#endif
#if CONFIG_EXAMPLES_SMPS_IN_VOLTAGE_LIMIT > 0
smps_limits.v_in = (float)CONFIG_EXAMPLES_SMPS_IN_VOLTAGE_LIMIT/1000.0;
#endif
#if CONFIG_EXAMPLES_SMPS_OUT_CURRENT_LIMIT > 0
smps_limits.i_out = (float)CONFIG_EXAMPLES_SMPS_OUT_CURRENT_LIMIT/1000.0;
#endif
#if CONFIG_EXAMPLES_SMPS_IN_CURRENT_LIMIT > 0
smps_limits.i_in = (float)CONFIG_EXAMPLES_SMPS_IN_CURRENT_LIMIT/1000.0;
#endif
#if CONFIG_EXAMPLES_SMPS_OUT_CURRENT_LIMIT > 0
smps_limits.p_out = (float)CONFIG_EXAMPLES_SMPS_OUT_POWER_LIMIT/1000.0;
#endif
#if CONFIG_EXAMPLES_SMPS_IN_CURRENT_LIMIT > 0
smps_limits.p_in = (float)CONFIG_EXAMPLES_SMPS_IN_POWER_LIMIT/1000.0;
#endif
/* Parse the command line */
parse_args(args, argc, argv);
/* Validate arguments */
ret = validate_args(args);
if (ret != OK)
{
printf("powerled_main: validate arguments failed!\n");
goto errout;
}
#ifndef CONFIG_NSH_ARCHINIT
/* Perform architecture-specific initialization (if configured) */
boardctl(BOARDIOC_INIT, 0);
#ifdef CONFIG_BOARDCTL_FINALINIT
/* Perform architecture-specific final-initialization (if configured) */
boardctl(BOARDIOC_FINALINIT, 0);
#endif
#endif
/* Set SMPS mode */
smps_mode = SMPS_OPMODE_CV;
/* Set SMPS params */
smps_params.v_out = (args->voltage > 0 ? args->voltage :
(float)CONFIG_EXAMPLES_SMPS_OUT_VOLTAGE_DEFAULT/1000.0);
smps_params.i_out = (args->current > 0 ? args->current :
(float)CONFIG_EXAMPLES_SMPS_OUT_CURRENT_DEFAULT/1000.0);
smps_params.p_out = (args->power > 0 ? args->power :
(float)CONFIG_EXAMPLES_SMPS_OUT_POWER_DEFAULT/1000.0);
args->time = (args->time == 0 ? CONFIG_EXAMPLES_SMPS_TIME_DEFAULT : args->time);
printf("\nStart smps_main application!\n\n");
/* Print demo info */
print_info(&smps_limits, &smps_params, &smps_mode, args);
/* Open the SMPS driver */
fd = open(CONFIG_EXAMPLES_SMPS_DEVPATH, 0);
if (fd <= 0)
{
printf("smps_main: open %s failed %d\n", CONFIG_EXAMPLES_SMPS_DEVPATH, errno);
goto errout;
}
/* Set SMPS limits */
ret = ioctl(fd, PWRIOC_SET_LIMITS, (unsigned long)&smps_limits);
if (ret != OK)
{
printf("IOCTL PWRIOC_LIMITS failed %d!\n", ret);
goto errout;
}
/* Set SMPS mode */
ret = ioctl(fd, PWRIOC_SET_MODE, (unsigned long)smps_mode);
if (ret != OK)
{
printf("IOCTL PWRIOC_MODE failed %d!\n", ret);
goto errout;
}
/* Set SMPS params */
ret = ioctl(fd, PWRIOC_SET_PARAMS, (unsigned long)&smps_params);
if (ret != OK)
{
printf("IOCTL PWRIOC_PARAMS failed %d!\n", ret);
goto errout;
}
/* Start SMPS driver */
ret = ioctl(fd, PWRIOC_START, (unsigned long)0);
if (ret != OK)
{
printf("IOCTL PWRIOC_START failed %d!\n", ret);
goto errout;
}
/* Main loop */
while(terminate != true)
{
/* Get current SMPS state */
ret = ioctl(fd, PWRIOC_GET_STATE, (unsigned long)&smps_state);
if (ret < 0)
{
printf("Failed to get state %d \n", ret);
}
/* Terminate if fault state */
if (smps_state.state > SMPS_STATE_RUN)
{
printf("Smps state = %d, fault = %d\n", smps_state.state,
smps_state.fault);
terminate = true;
}
/* Print feedback state */
if (time % 2 == 0)
{
feedback_print(&smps_state.fb);
}
/* Handle run time */
if (terminate != true)
{
/* Wait 1 sec */
sleep(1);
if (args->time != -1)
{
time += 1;
if (time >= args->time)
{
/* Exit loop */
terminate = true;
}
}
}
}
errout:
if (fd > 0)
{
printf("Stop smps driver\n");
/* Stop SMPS driver */
ret = ioctl(fd, PWRIOC_STOP, (unsigned long)0);
if (ret != OK)
{
printf("IOCTL PWRIOC_STOP failed %d!\n", ret);
}
/* Close file */
close(fd);
}
return 0;
}
#endif /* CONFIG_EXAMPLE_SMPS */