nuttx-apps/examples/powerled/powerled_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

786 lines
21 KiB
C

/****************************************************************************
* examples/adc/powerled_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 <nuttx/fs/fs.h>
#include <nuttx/power/powerled.h>
#if defined(CONFIG_EXAMPLES_POWERLED)
#ifndef CONFIG_DRIVERS_POWERLED
# error "Powerled example requires powerled support"
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef CONFIG_EXAMPLES_POWERLED_CURRENT_LIMIT
# error "LED current limit must be set!"
#endif
#ifndef CONFIG_LIBC_FLOATINGPOINT
# error "CONFIG_LIBC_FLOATINGPOINT must be set!"
#endif
#define DEMO_CONT_BRIGHTNESS_MAX 100.0
#define DEMO_CONT_BRIGHTNESS_MIN 0.0
#define DEMO_CONT_BRIGHTNESS_STEP 10.0
#define DEMO_FLASH_FREQUENCY_STEP 0.5
#define DEMO_FLASH_FREQUENCY_MIN 1.0
#define DEMO_FLASH_FREQUENCY_MAX 5.0
#define DEMO_FLASH_DUTY_SET 50.0
#define DEMO_FLASH_BRIGHTNESS_SET 100.0
/****************************************************************************
* Private Type Definition
****************************************************************************/
/* Example modes */
enum powerled_main_mode_e
{
POWERLED_MAIN_DEMO = 0,
POWERLED_MAIN_CONT,
POWERLED_MAIN_FLASH
};
/* Application arguments */
struct args_s
{
uint8_t mode;
int time;
float duty;
float brightness;
float frequency;
};
/****************************************************************************
* Private Function Protototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
struct args_s g_args;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: powerled_help
****************************************************************************/
static void powerled_help(FAR struct args_s *args)
{
printf("Usage: powerled [OPTIONS]\n\n");
printf(" [-m mode] select mode\n");
printf(" 0 - demo mode [deafult]\n");
printf(" 1 - continuous mode\n");
printf(" 2 - flash mode\n");
printf(" [-d duty] selects duty cycle for flash mode in %%\n");
printf(" valid values from 0.0 to 100.0\n");
printf(" [-b brightness] selects LED brightness in %%\n");
printf(" valid values from 0.0 to 100.0\n");
printf(" [-f frequency] selects frequency for flash mode in Hz\n");
printf(" valid values greater than 0.0\n");
printf(" [-t time] selects time for continuous and flash mode in s\n");
printf(" valid values greater 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;
int index;
int nargs;
int i_value;
float f_value;
for (index = 1; index < argc;)
{
ptr = argv[index];
if (ptr[0] != '-')
{
printf("Invalid options format: %s\n", ptr);
exit(0);
}
switch (ptr[1])
{
/* Get operation mode */
case 'm':
{
nargs = arg_decimal(&argv[index], &i_value);
index += nargs;
if ((i_value != POWERLED_MAIN_DEMO) &&
(i_value != POWERLED_MAIN_CONT) &&
(i_value != POWERLED_MAIN_FLASH))
{
printf("Unsupported mode %d\n", i_value);
exit(1);
}
args->mode = i_value;
break;
}
/* Get duty cycle */
case 'd':
{
nargs = arg_float(&argv[index], &f_value);
index += nargs;
if (f_value <= 0.0 || f_value > 100.0)
{
printf("Invalid duty value %.2f%%\n", f_value);
exit(1);
}
args->duty = f_value;
break;
}
/* Get LED brightness */
case 'b':
{
nargs = arg_float(&argv[index], &f_value);
index += nargs;
if (f_value <= 0.0 || f_value > 100.0)
{
printf("Invalid brightness value %.2f%%\n", f_value);
exit(1);
}
args->brightness = f_value;
break;
}
/* Get flashing frequency */
case 'f':
{
nargs = arg_float(&argv[index], &f_value);
index += nargs;
if (f_value <= 0.0)
{
printf("Invalid frequency value %.2f Hz\n", f_value);
exit(1);
}
args->frequency = f_value;
break;
}
/* Get work time */
case 't':
{
nargs = arg_decimal(&argv[index], &i_value);
index += nargs;
if (i_value <= 0)
{
printf("Invalid time value %d s\n", i_value);
exit(1);
}
args->time = i_value;
break;
}
/* Print help message */
case 'h':
{
powerled_help(args);
exit(0);
}
default:
{
printf("Unsupported option: %s\n", ptr);
powerled_help(args);
exit(1);
}
}
}
}
/****************************************************************************
* Name: validate_args
****************************************************************************/
static int validate_args(FAR struct args_s *args)
{
int ret = OK;
/* Validate parameters for demo mode */
if (args->mode == POWERLED_MAIN_DEMO)
{
printf("Powerled demo selected!\n");
/* Demo mode does not use time parameter */
args->time = -1;
}
/* Validate parameters for continuous mode */
if (args->mode == POWERLED_MAIN_CONT)
{
printf("Powerled continuous mode selected!\n");
printf(" brightnes: %.2f\n", args->brightness);
printf(" time: %d\n", args->time);
/* Needs brightness */
if (args->brightness <= 0.0)
{
printf("Continuous mode needs brightness parameter!\n");
ret = -EINVAL;
goto errout;
}
}
/* Validate parameters for flash mode */
if (args->mode == POWERLED_MAIN_FLASH)
{
printf("Powerled flash mode selected!\n");
printf(" brightness: %.2f\n", args->brightness);
printf(" frequency: %.2f\n", args->frequency);
printf(" duty: %.2f\n", args->duty);
printf(" time: %d\n", args->time);
/* Needs brightness */
if (args->brightness <= 0.0)
{
printf("Flash mode needs brightness parameter!\n");
ret = -EINVAL;
goto errout;
}
/* Needs frequency */
if (args->frequency <= 0.0)
{
printf("Flash mode needs frequency parameter!\n");
ret = -EINVAL;
goto errout;
}
/* Needs duty */
if (args->duty <= 0.0)
{
printf("Flash mode needs duty parameter!\n");
ret = -EINVAL;
goto errout;
}
}
errout:
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: powerled_main
****************************************************************************/
int main(int argc, char *argv[])
{
struct powerled_limits_s powerled_limits;
struct powerled_params_s powerled_params;
struct powerled_state_s powerled_state;
struct args_s *args = &g_args;
uint8_t powerled_mode;
uint8_t demo;
bool terminate;
bool config;
int ret;
int fd = -1;
/* Initialize variables */
g_args.mode = POWERLED_MAIN_DEMO;
g_args.time = -1;
g_args.duty = 0.0;
g_args.brightness = 0.0;
g_args.frequency = 0.0;
demo = POWERLED_OPMODE_CONTINUOUS;
terminate = false;
config = true;
/* Initialize powerled stuctures */
memset(&powerled_limits, 0, sizeof(struct powerled_limits_s));
memset(&powerled_params, 0, sizeof(struct powerled_params_s));
/* 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 LED current limit */
powerled_limits.current = (((float)CONFIG_EXAMPLES_POWERLED_CURRENT_LIMIT)/1000.0);
printf("\nStart powerled_main application!\n");
/* Open the Powerled driver */
fd = open(CONFIG_EXAMPLES_POWERLED_DEVPATH, 0);
if (fd <= 0)
{
printf("powerled_main: open %s failed %d\n", CONFIG_EXAMPLES_POWERLED_DEVPATH, errno);
goto errout;
}
/* Set LED current limit */
printf("Set max current: %.3f A\n", powerled_limits.current);
ret = ioctl(fd, PWRIOC_SET_LIMITS, (unsigned long)&powerled_limits);
if (ret < 0)
{
printf("failed to set limits %d. Force exit!\n", ret);
goto errout;
}
/* Main loop */
while (terminate != true)
{
switch (args->mode)
{
case POWERLED_MAIN_DEMO:
{
/* Continuous mode demo */
if (demo == POWERLED_OPMODE_CONTINUOUS)
{
if (config == true)
{
printf("\nConfigure continuous mode demo\n");
powerled_mode = POWERLED_OPMODE_CONTINUOUS;
/* Set Powerled continuous mode */
ret = ioctl(fd, PWRIOC_SET_MODE, (unsigned long)powerled_mode);
if (ret < 0)
{
printf("failed to set powerled mode %d \n", ret);
}
config = false;
}
printf("Brightness is %.2f\n", powerled_params.brightness);
/* Set Powerled parameters */
ret = ioctl(fd, PWRIOC_SET_PARAMS, (unsigned long)&powerled_params);
if (ret < 0)
{
printf("failed to set params %d \n", ret);
}
/* Start Powerled */
ret = ioctl(fd, PWRIOC_START, (unsigned long)0);
if (ret != OK)
{
printf("IOCTL PWRIOC_START failed %d!\n", ret);
}
/* Increase brightness */
powerled_params.brightness += DEMO_CONT_BRIGHTNESS_STEP;
/* Change mode if max brightness */
if (powerled_params.brightness > DEMO_CONT_BRIGHTNESS_MAX)
{
demo = POWERLED_OPMODE_FLASH;
config = true;
}
/* Next step after 1 second */
sleep(1);
}
if (demo == POWERLED_OPMODE_FLASH)
{
/* Flash mode demo */
if (config == true)
{
printf("\nConfigure flash mode demo\n");
powerled_params.brightness = DEMO_FLASH_BRIGHTNESS_SET;
powerled_params.duty = DEMO_FLASH_DUTY_SET;
powerled_params.frequency = DEMO_FLASH_FREQUENCY_MIN;
powerled_mode = POWERLED_OPMODE_FLASH;
/* Set Powerled flash mode */
ret = ioctl(fd, PWRIOC_SET_MODE, (unsigned long)powerled_mode);
if (ret < 0)
{
printf("failed to set powerled mode %d \n", ret);
}
printf("Brightness is %.2f\n", powerled_params.brightness);
printf("Duty is %.2f\n", powerled_params.duty);
config = false;
}
printf("Frequency is %.2f\n", powerled_params.frequency);
/* Set Powerled parameters */
ret = ioctl(fd, PWRIOC_SET_PARAMS, (unsigned long)&powerled_params);
if (ret < 0)
{
printf("failed to set params %d \n", ret);
}
/* Start Powerled */
ret = ioctl(fd, PWRIOC_START, (unsigned long)0);
if (ret != OK)
{
printf("IOCTL PWRIOC_START failed %d!\n", ret);
}
/* Increase flash frequency */
powerled_params.frequency += DEMO_FLASH_FREQUENCY_STEP;
/* Terinate demo if max frequency */
if (powerled_params.frequency > DEMO_FLASH_FREQUENCY_MAX)
{
terminate = true;
config = false;
}
/* Next step after 1 second */
sleep(2);
}
break;
}
case POWERLED_MAIN_CONT:
{
/* Configure only once */
if (config == true)
{
printf("\nStart Continuous mode!\n");
powerled_mode = POWERLED_OPMODE_CONTINUOUS;
/* Set Powerled continuous mode */
ret = ioctl(fd, PWRIOC_SET_MODE, (unsigned long)powerled_mode);
if (ret < 0)
{
printf("failed to set powerled mode %d \n", ret);
}
powerled_params.brightness = args->brightness;
powerled_params.duty = 0;
powerled_params.frequency = 0;
/* Set Powerled parameters */
ret = ioctl(fd, PWRIOC_SET_PARAMS, (unsigned long)&powerled_params);
if (ret < 0)
{
printf("failed to set params %d \n", ret);
}
/* Start Powerled */
ret = ioctl(fd, PWRIOC_START, (unsigned long)0);
if (ret != OK)
{
printf("IOCTL PWRIOC_START failed %d!\n", ret);
}
config = false;
}
break;
}
case POWERLED_MAIN_FLASH:
{
/* Configure only once */
if (config == true)
{
printf("\nStart Flash mode!\n");
powerled_mode = POWERLED_OPMODE_FLASH;
/* Set Powerled flash mode */
ret = ioctl(fd, PWRIOC_SET_MODE, (unsigned long)powerled_mode);
if (ret < 0)
{
printf("failed to set powerled mode %d \n", ret);
}
powerled_params.brightness = args->brightness;
powerled_params.duty = args->duty;
powerled_params.frequency = args->frequency;
/* Set Powerled parameters */
ret = ioctl(fd, PWRIOC_SET_PARAMS, (unsigned long)&powerled_params);
if (ret < 0)
{
printf("failed to set params %d \n", ret);
}
/* Start Powerled */
ret = ioctl(fd, PWRIOC_START, (unsigned long)0);
if (ret < 0)
{
printf("IOCTL PWRIOC_START failed %d!\n", ret);
}
config = false;
}
break;
}
default:
{
printf("Unsupported powerled mode %d!\n", args->mode);
goto errout;
}
}
/* Get driver state */
ret = ioctl(fd, PWRIOC_GET_STATE, (unsigned long)&powerled_state);
if (ret < 0)
{
printf("Failed to get state %d \n", ret);
}
/* Terminate if fault state */
if (powerled_state.state > POWERLED_STATE_RUN)
{
printf("Powerled state = %d, fault = %d\n", powerled_state.state,
powerled_state.fault);
terminate = true;
}
if (args->time != -1 && terminate != true)
{
printf("wait %d s ...\n", args->time);
/* Wait */
sleep(args->time);
/* Exit loop */
terminate = true;
}
}
errout:
fflush(stdout);
fflush(stderr);
if (fd > 0)
{
printf("Stop powerled driver\n");
/* Stop powerled 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_POWERLED */