/**************************************************************************** * apps/examples/lp503x/lp503x_main.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "system/readline.h" #include /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ #define LP503X_HELP_TEXT(x) x /**************************************************************************** * Private Types ****************************************************************************/ typedef CODE int (*lp503x_func)(FAR char *pargs); struct lp503x_cmd_s { FAR const char *cmd; /* The command text */ FAR const char *arghelp; /* Text describing the args */ lp503x_func pfunc; /* Pointer to command handler */ FAR const char *help; /* The help text */ }; /**************************************************************************** * Private Function Prototypes ****************************************************************************/ static int lp503x_cmd_quit(FAR char *parg); static int lp503x_cmd_help(FAR char *parg); static int lp503x_cmd_set_rgbled(FAR char *parg); static int lp503x_cmd_setled(FAR char *parg); static int lp503x_cmd_setcolour(FAR char *parg); static int lp503x_cmd_pattern(FAR char *parg); static int lp503x_cmd_brightness(FAR char *parg); static int lp503x_cmd_mode(FAR char *parg); static int lp503x_cmd_disable(FAR char *parg); static int lp503x_cmd_set_bank_mode(FAR char *parg); static int lp503x_cmd_set_banka_colour(FAR char *parg); static int lp503x_cmd_set_bankb_colour(FAR char *parg); static int lp503x_cmd_set_bankc_colour(FAR char *parg); static int lp503x_cmd_set_bank_brightness(FAR char *parg); static int lp503x_cmd_set_individual_mode(FAR char *parg); /**************************************************************************** * Private Data ****************************************************************************/ int fd; static struct lp503x_cmd_s g_lp503x_cmds[] = { { "q", "", lp503x_cmd_quit, LP503X_HELP_TEXT("Exit lp503x") }, { "h", "", lp503x_cmd_help, LP503X_HELP_TEXT("Display help for commands") }, { "?", "", lp503x_cmd_help, LP503X_HELP_TEXT("Display help for commands") }, { "help", "", lp503x_cmd_help, LP503X_HELP_TEXT("Display help for commands") }, { "m", "", lp503x_cmd_mode, LP503X_HELP_TEXT("send default mode to the device") }, { "c", "hex", lp503x_cmd_setcolour, LP503X_HELP_TEXT("Hex RGB colour required") }, { "l", "led, 0..11", lp503x_cmd_set_rgbled, LP503X_HELP_TEXT("set RGB LED selected to current colour") }, { "n", "led, 0..35", lp503x_cmd_setled, LP503X_HELP_TEXT("set individual LED to current brightness X") }, { "p", "num of leds in pattern (1..12)", lp503x_cmd_pattern, LP503X_HELP_TEXT("play LED pattern") }, { "b", "brightness, 0-255", lp503x_cmd_brightness, LP503X_HELP_TEXT("set brightness of all leds") }, { "d", "disable=1", lp503x_cmd_disable, LP503X_HELP_TEXT("globally disable ALL leds") }, { "k", "led num", lp503x_cmd_set_bank_mode, LP503X_HELP_TEXT("enable bank mode for LED ") }, { "i", "led num 0..11", lp503x_cmd_set_individual_mode, LP503X_HELP_TEXT("enable individual mode for LED ") }, { "A", "", lp503x_cmd_set_banka_colour, LP503X_HELP_TEXT("set bankA colour") }, { "B", "", lp503x_cmd_set_bankb_colour, LP503X_HELP_TEXT("set bankB colour") }, { "C", "", lp503x_cmd_set_bankc_colour, LP503X_HELP_TEXT("set bankC colour") }, { "X", "0..255", lp503x_cmd_set_bank_brightness, LP503X_HELP_TEXT("Bank or individual LED brightness required") }, }; static const int g_lp503x_cmd_count = sizeof(g_lp503x_cmds) / sizeof(struct lp503x_cmd_s); FAR static struct lp503x_config_s *lp503x_config; FAR static struct ioctl_arg_s *lp503x_ioctl_args; int current_colour; int current_led_brightness; /**************************************************************************** * Private Functions ****************************************************************************/ /**************************************************************************** * Name:lp503x_cmd_mode * * send default (Kconfig) mode/config to the device ****************************************************************************/ static int lp503x_cmd_mode(FAR char *parg) { return ioctl(fd, PWMIOC_CONFIG, lp503x_config); } /**************************************************************************** * Name:lp503x_cmd_quit * * lp503x_cmd_quit() terminates the application ****************************************************************************/ static int lp503x_cmd_quit(FAR char *parg) { return OK; } /**************************************************************************** * Name:lp503x_cmd_disable * * Globally disable all LEDS ****************************************************************************/ static int lp503x_cmd_disable(FAR char *parg) { return ioctl(fd, PWMIOC_ENABLE, atoi(parg)) ; } /**************************************************************************** * Name:lp503x_setled * * sets the chosen led (0..35) to the current brightness (0..255) (T) ****************************************************************************/ static int lp503x_cmd_setled(FAR char *parg) { int ret; int lednum; lednum = atoi(parg); if (lednum > MAX_LEDS) { printf("ERROR: led number must be in range 0..35\n"); ret = -EINVAL; } else { lp503x_ioctl_args->lednum = lednum; lp503x_ioctl_args->param = current_led_brightness; ret = ioctl(fd, PWMIOC_SET_LED_COLOUR, lp503x_ioctl_args); } return ret; } /**************************************************************************** * Name:lp503x_setRGBled * * sets the chosen RGB led (0..11) to the current RGB colour ****************************************************************************/ static int lp503x_cmd_set_rgbled(FAR char *parg) { int ret; int lednum; lednum = atoi(parg); if (lednum > MAX_RGB_LEDS) { printf("ERROR: RGB led must be in range 0..11\n"); ret = -EINVAL; } else { lp503x_ioctl_args->lednum = lednum; lp503x_ioctl_args->param = current_colour; ret = ioctl(fd, PWMIOC_SET_RGB_COLOUR, lp503x_ioctl_args); } return ret; } /**************************************************************************** * Name:lp503x_cmd_set_bank_mode * * sets requested led to use "bank" mode ****************************************************************************/ static int lp503x_cmd_set_bank_mode(FAR char *parg) { int ret; int lednum; lednum = atoi(parg); if (lednum > MAX_RGB_LEDS) { printf("ERROR: RGB led must be in range 0..11\n"); ret = -EINVAL; } else { lp503x_ioctl_args->param = LP503X_LED_BANK_MODE_ENABLED; lp503x_ioctl_args->lednum = lednum; ret = ioctl(fd, PWMIOC_ENABLE_LED_BANK_MODE, lp503x_ioctl_args); } return ret; } /**************************************************************************** * Name:lp503x_cmd_set_individual_mode * * sets requested led to use "individual" mode (default) ****************************************************************************/ static int lp503x_cmd_set_individual_mode(FAR char *parg) { int ret; int lednum; lednum = atoi(parg); if (lednum > MAX_RGB_LEDS) { printf("ERROR: RGB led must be in range 0..11\n"); ret = -EINVAL; } else { lp503x_ioctl_args->param = LP503X_LED_BANK_MODE_DISABLED; lp503x_ioctl_args->lednum = lednum; ret = ioctl(fd, PWMIOC_ENABLE_LED_BANK_MODE, lp503x_ioctl_args); } return ret; } /**************************************************************************** * Name:lp503x_cmd_set_bank?_colour * * sets bank A/B/C to the current brightness (T) ****************************************************************************/ static int lp503x_cmd_set_banka_colour(FAR char *parg) { uint8_t requested_colour; requested_colour = atoi(parg); if ((requested_colour > MAX_BRIGHTNESS) || (requested_colour < 0)) { printf("ERR: Bank Colour (mix percent) must be in range 0..255\n"); return -EINVAL; } else { lp503x_ioctl_args->param = requested_colour; lp503x_ioctl_args->lednum = 'A'; return ioctl(fd, PWMIOC_SET_BANK_MIX_COLOUR, lp503x_ioctl_args); } } static int lp503x_cmd_set_bankb_colour(FAR char *parg) { uint8_t requested_colour; requested_colour = atoi(parg); if ((requested_colour > MAX_BRIGHTNESS) || (requested_colour < 0)) { printf("ERR: Bank Colour (mix percent) must be in range 0..255\n"); return -EINVAL; } else { lp503x_ioctl_args->param = requested_colour; lp503x_ioctl_args->lednum = 'B'; return ioctl(fd, PWMIOC_SET_BANK_MIX_COLOUR, lp503x_ioctl_args); } } static int lp503x_cmd_set_bankc_colour(FAR char *parg) { uint8_t requested_colour; requested_colour = atoi(parg); if ((requested_colour > MAX_BRIGHTNESS) || (requested_colour < 0)) { printf("ERR: Bank Colour (mix percent) must be in range 0..255\n"); return -EINVAL; } else { lp503x_ioctl_args->param = requested_colour; lp503x_ioctl_args->lednum = 'C'; return ioctl(fd, PWMIOC_SET_BANK_MIX_COLOUR, lp503x_ioctl_args); } } /**************************************************************************** * Name:lp503x_cmd_brightness * * sets all RGB led to the requested brightness ****************************************************************************/ static int lp503x_cmd_brightness(FAR char *parg) { int ret; int lednum; int requested_brightness; requested_brightness = ((int)strtol(parg, NULL, 0)) & 0xff; if ((requested_brightness > 255) || (requested_brightness < 0)) { printf("ERROR: brightness must be in range 0..255\n"); ret = -EINVAL; } else { lp503x_ioctl_args->param = requested_brightness; for (lednum = 0; lednum < 12; lednum++) { lp503x_ioctl_args->lednum = lednum; ret = ioctl(fd, PWMIOC_SET_RGB_BRIGHTNESS, lp503x_ioctl_args); } } return ret; } /**************************************************************************** * Name:lp503x_cmd_pattern * * run a pattern for "arg[0]" leds. * Repeats 5 times at different brightness levels ****************************************************************************/ static int lp503x_cmd_pattern(FAR char *parg) { int ret; int numleds; int i; int j; uint8_t k; int colour_lookup[12] = { 0x0000ff, 0x00ff00, 0xff0000, 0x00ffff, 0xff00ff, 0xffff33, 0xffffff, 0xffa500, 0xff00a5, 0x8080ff, 0x80ff80, 0xff8080 }; int pattern_brightness[5] = { 50, 100, 150, 200, 255 }; int curcolour; numleds = atoi(parg); if ((numleds > 12) || (numleds < 1)) { printf("Error: number of leds should be between 1 and 12\n"); return -EINVAL; } curcolour = 0; for (i = 0; i < 5; i++) { for (j = 0; j < numleds; j++) { lp503x_ioctl_args->lednum = j; lp503x_ioctl_args->param = pattern_brightness[i]; ret = ioctl(fd, PWMIOC_SET_RGB_BRIGHTNESS, lp503x_ioctl_args); curcolour++; if (curcolour >= numleds) { curcolour = 0; } lp503x_ioctl_args->param = colour_lookup[curcolour]; ret = ioctl(fd, PWMIOC_SET_RGB_COLOUR, lp503x_ioctl_args); } usleep(500000); curcolour++; } lp503x_ioctl_args->param = 0; for (k = 0; k < numleds; k++) { lp503x_ioctl_args->lednum = k; ret = ioctl(fd, PWMIOC_SET_RGB_COLOUR, lp503x_ioctl_args); } return ret; } /**************************************************************************** * Name:lp503x_cmd_set_bank_brightness * * sets the bank brightness to be used ****************************************************************************/ static int lp503x_cmd_set_bank_brightness(FAR char *parg) { int bank_brightness; if (parg != NULL || *parg != '\0') { bank_brightness = atoi(parg); if ((bank_brightness > MAX_BRIGHTNESS) || (bank_brightness < 0)) { printf("bank brightness range is 0..255\n"); bank_brightness = 0; return -EINVAL; } else { lp503x_ioctl_args->param = bank_brightness; current_led_brightness = bank_brightness; return ioctl(fd, PWMIOC_SET_BANK_BRIGHTNESS, lp503x_ioctl_args); } } return OK; } /**************************************************************************** * Name:lp503x_setcolour * * sets the current RGB colour to be used ****************************************************************************/ static int lp503x_cmd_setcolour(FAR char *parg) { int colour; if (parg == NULL || *parg != '\0') { printf("current colour is: 0x%06x\n", current_colour); } else { colour = (int)strtol(parg, NULL, 16); if (colour > MAX_RGB_COLOUR) { printf("colour range is 0...0xFFFFFF\n"); current_colour = 0; return -EINVAL; } else { current_colour = colour; printf("colour set to: 0x%06x\n", current_colour); } } return OK; } /**************************************************************************** * Name: lp503x_cmd_help * * lp503x_cmd_help() displays the application's help information on * supported commands and command syntax. ****************************************************************************/ static int lp503x_cmd_help(FAR char *parg) { int len; int maxlen = 0; int x; int c; /* Calculate length of longest cmd + arghelp */ for (x = 0; x < g_lp503x_cmd_count; x++) { len = strlen(g_lp503x_cmds[x].cmd) + strlen(g_lp503x_cmds[x].arghelp); if (len > maxlen) { maxlen = len; } } printf("lp503x commands\n================\n"); for (x = 0; x < g_lp503x_cmd_count; x++) { /* Print the command and it's arguments */ printf(" %s %s", g_lp503x_cmds[x].cmd, g_lp503x_cmds[x].arghelp); /* Calculate number of spaces to print before the help text */ len = maxlen - (strlen(g_lp503x_cmds[x].cmd) + strlen(g_lp503x_cmds[x].arghelp)); for (c = 0; c < len; c++) { printf(" "); } printf(" : %s\n", g_lp503x_cmds[x].help); } return OK; } /**************************************************************************** * lp503x_main ****************************************************************************/ int main(int argc, FAR char *argv[]) { bool running; char buffer[CONFIG_NSH_LINELEN]; int len; int x; char *cmd; char *arg; fd = open(CONFIG_EXAMPLES_LP503X_DEVPATH, O_CREAT); if (fd < 0) { fprintf(stderr, "ERROR: Failed to open %s: %d\n", CONFIG_EXAMPLES_LP503X_DEVPATH, errno); close(fd); return ENODEV; } running = true; while (running) { printf("lp503x> "); fflush(stdout); /* read a line from the terminal */ len = readline(buffer, sizeof(buffer), stdin, stdout); buffer[len] = '\0'; if (len > 0) { if (strncmp(buffer, "!", 1) != 0) { /* a command */ if (buffer[len - 1] == '\n') { buffer[len - 1] = '\0'; } /* Parse the command from the argument */ cmd = strtok_r(buffer, " \n", &arg); if (cmd == NULL) { continue; } /* Remove leading spaces from arg */ while (*arg == ' ') { arg++; } /* Find the command in our cmd array */ for (x = 0; x < g_lp503x_cmd_count; x++) { if (strcmp(cmd, g_lp503x_cmds[x].cmd) == 0) { /* Command found. Call it's handler if not NULL */ if (g_lp503x_cmds[x].pfunc != NULL) { g_lp503x_cmds[x].pfunc(arg); } /* Test if it is a quit command */ if (g_lp503x_cmds[x].pfunc == lp503x_cmd_quit) { running = FALSE; } break; } } } else { #ifdef CONFIG_SYSTEM_SYSTEM /* Transfer nuttx shell */ system(buffer + 1); #else printf("%s: unknown lp503x command\n", buffer); #endif } } } close(fd); return 0; }