/**************************************************************************** * examples/adc/powerled_main.c * * Copyright (C) 2017 Gregory Nutt. All rights reserved. * Author: Mateusz Szafoni * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #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 ****************************************************************************/ #ifdef CONFIG_NSH_BUILTIN_APPS 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"); } #endif /**************************************************************************** * Name: arg_string ****************************************************************************/ #ifdef CONFIG_NSH_BUILTIN_APPS 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; } } #endif /**************************************************************************** * Name: arg_decimal ****************************************************************************/ #ifdef CONFIG_NSH_BUILTIN_APPS 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; } #endif /**************************************************************************** * Name: arg_float ****************************************************************************/ #ifdef CONFIG_NSH_BUILTIN_APPS 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; } #endif /**************************************************************************** * Name: parse_args ****************************************************************************/ #ifdef CONFIG_NSH_BUILTIN_APPS 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); } } } } #endif /**************************************************************************** * Name: validate_args ****************************************************************************/ #ifdef CONFIG_NSH_BUILTIN_APPS 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; } #endif /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: powerled_main ****************************************************************************/ int powerled_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; /* 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 */ #ifdef CONFIG_NSH_BUILTIN_APPS parse_args(args, argc, argv); #endif /* Validate arguments */ #ifdef CONFIG_NSH_BUILTIN_APPS ret = validate_args(args); if (ret != OK) { printf("powerled_main: validate arguments failed!\n"); goto errout; } #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 %0.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 %0.2f\n", powerled_params.brightness); printf("Duty is %0.2f\n", powerled_params.duty); config = false; } printf("Frequency is %0.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 */