From 9d1a70af861969214a30572b3747115e93879269 Mon Sep 17 00:00:00 2001 From: TimJTi <56726697+TimJTi@users.noreply.github.com> Date: Wed, 21 Dec 2022 16:10:57 +0000 Subject: [PATCH] Add example app for LP503x LED driver Update examples/lp503x/lp503x_main.c Move struct lp503x_cmd_s to private types section Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Update examples/lp503x/lp503x_main.c Co-Authored-By: Petro Karashchenko --- examples/lp503x/Kconfig | 33 ++ examples/lp503x/Make.defs | 23 ++ examples/lp503x/Makefile | 34 ++ examples/lp503x/lp503x_main.c | 716 ++++++++++++++++++++++++++++++++++ 4 files changed, 806 insertions(+) create mode 100755 examples/lp503x/Kconfig create mode 100755 examples/lp503x/Make.defs create mode 100755 examples/lp503x/Makefile create mode 100755 examples/lp503x/lp503x_main.c diff --git a/examples/lp503x/Kconfig b/examples/lp503x/Kconfig new file mode 100755 index 000000000..ea609c97e --- /dev/null +++ b/examples/lp503x/Kconfig @@ -0,0 +1,33 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_LP503X + tristate "LP503X PWM LED example" + default n + ---help--- + Enable the LP503X example + +if EXAMPLES_LP503X + +config EXAMPLES_LP503X_PROGNAME + string "Program name" + default "lp503x" + ---help--- + This is the name of the program that will be used when the NSH ELF + program is installed. + +config EXAMPLES_LP503X_DEVPATH + string "LP503X device path" + default "/dev/leddrv0" + +config EXAMPLES_LP503X_PRIORITY + int "lp503x task priority" + default 100 + +config EXAMPLES_LP503X_STACKSIZE + int "lp503x stack size" + default DEFAULT_TASK_STACKSIZE + +endif diff --git a/examples/lp503x/Make.defs b/examples/lp503x/Make.defs new file mode 100755 index 000000000..f89e60f5e --- /dev/null +++ b/examples/lp503x/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# apps/examples/lp503x/Make.defs +# +# 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. +# +############################################################################ + +ifneq ($(CONFIG_EXAMPLES_LP503X),) +CONFIGURED_APPS += $(APPDIR)/examples/lp503x +endif diff --git a/examples/lp503x/Makefile b/examples/lp503x/Makefile new file mode 100755 index 000000000..fc5eb8f2c --- /dev/null +++ b/examples/lp503x/Makefile @@ -0,0 +1,34 @@ +############################################################################ +# apps/examples/lp5036/Makefile +# +# 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. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# LP503x built-in application info + +PROGNAME = $(CONFIG_EXAMPLES_LP503X_PROGNAME) +PRIORITY = $(CONFIG_EXAMPLES_LP503X_PRIORITY) +STACKSIZE = $(CONFIG_EXAMPLES_LP503X_STACKSIZE) +MODULE = $(CONFIG_EXAMPLES_LP503X) + +# LP503x Test + +MAINSRC = lp503x_main.c + +include $(APPDIR)/Application.mk diff --git a/examples/lp503x/lp503x_main.c b/examples/lp503x/lp503x_main.c new file mode 100755 index 000000000..9ad3ea332 --- /dev/null +++ b/examples/lp503x/lp503x_main.c @@ -0,0 +1,716 @@ +/**************************************************************************** + * 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 "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; +}