diff --git a/audioutils/morsey/.gitignore b/audioutils/morsey/.gitignore new file mode 100644 index 00000000000..26b43c94641 --- /dev/null +++ b/audioutils/morsey/.gitignore @@ -0,0 +1 @@ +morsey diff --git a/audioutils/morsey/Kconfig b/audioutils/morsey/Kconfig new file mode 100644 index 00000000000..4f8b2f98dd2 --- /dev/null +++ b/audioutils/morsey/Kconfig @@ -0,0 +1,6 @@ +config AUDIOUTILS_MORSEY + bool "Morse code playing library" + default n + ---help--- + Simple library for parsing ASCII text into playable Morse code. Not + necessarily restricted to audio. diff --git a/audioutils/morsey/Make.defs b/audioutils/morsey/Make.defs new file mode 100644 index 00000000000..9fab9a304d6 --- /dev/null +++ b/audioutils/morsey/Make.defs @@ -0,0 +1,25 @@ +############################################################################ +# apps/audioutils/morsey/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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_AUDIOUTILS_MORSEY),) +CONFIGURED_APPS += $(APPDIR)/audioutils/morsey +endif diff --git a/audioutils/morsey/Makefile b/audioutils/morsey/Makefile new file mode 100644 index 00000000000..599ae5700c7 --- /dev/null +++ b/audioutils/morsey/Makefile @@ -0,0 +1,50 @@ +############################################################################ +# apps/audioutils/morsey/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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 + +CSRCS = $(MORSEY_DIR)/morsey.c + +MORSEY_DIR = morsey +MORSEY_VERSION = v1.0.0 +MORSEY_MORSEY_H_SHA256 = 55f45e7b9a4d810f928ffe3ee9bea4cc318e28b1f49abf9512aee2638bd1dbfa +MORSEY_MORSEY_C_SHA256 = f946c9845a90a4c1a459490906ae071d0ac5b41326b7a5ce971efb97792ef56a + +$(MORSEY_DIR): + $(Q) echo "Cloning Morsey repo..." + $(Q) git clone --depth=1 --branch=$(MORSEY_VERSION) https://github.com/linguini1/morsey.git + $(Q) touch $(MORSEY_DIR) + $(Q) echo "Checking Morsey hashes..." + $(Q) $(APPDIR)/tools/check-hash.sh sha256 $(MORSEY_MORSEY_H_SHA256) $@/morsey.h + $(Q) $(APPDIR)/tools/check-hash.sh sha256 $(MORSEY_MORSEY_C_SHA256) $@/morsey.c + +create_includes: $(MORSEY_DIR)/morsey.h + $(Q) cp $< $(APPDIR)/include/audioutils + +context:: $(MORSEY_DIR) + $(Q) $(MAKE) create_includes + +distclean:: + $(call DELFILE, $(APPDIR)/include/audioutils/morsey.h) + $(call DELDIR, morsey) + +include $(APPDIR)/Application.mk diff --git a/examples/txmorse/CMakeLists.txt b/examples/txmorse/CMakeLists.txt new file mode 100644 index 00000000000..4694557629d --- /dev/null +++ b/examples/txmorse/CMakeLists.txt @@ -0,0 +1,33 @@ +# ############################################################################## +# apps/examples/txmorse/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# +# ############################################################################## + +if(CONFIG_EXAMPLES_TXMORSE) + nuttx_add_application( + NAME + ${CONFIG_EXAMPLES_TXMORSE_PROGNAME} + SRCS + txmorse_main.c + STACKSIZE + ${CONFIG_EXAMPLES_TXMORSE_STACKSIZE} + PRIORITY + ${CONFIG_EXAMPLES_TXMORSE_PRIORITY}) +endif() diff --git a/examples/txmorse/Kconfig b/examples/txmorse/Kconfig new file mode 100644 index 00000000000..3754a9ffe06 --- /dev/null +++ b/examples/txmorse/Kconfig @@ -0,0 +1,30 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_TXMORSE + tristate "txmorse (Morse code transmitter)" + default n + depends on AUDIOUTILS_MORSEY + ---help--- + Enable the Morse code transmission example. + +if EXAMPLES_TXMORSE + +config EXAMPLES_TXMORSE_PROGNAME + string "Program name" + default "txmorse" + ---help--- + This is the name of the program that will be used when the NSH ELF + program is installed. + +config EXAMPLES_TXMORSE_PRIORITY + int "txmorse task priority" + default 100 + +config EXAMPLES_TXMORSE_STACKSIZE + int "txmorse stack size" + default DEFAULT_TASK_STACKSIZE + +endif diff --git a/examples/txmorse/Make.defs b/examples/txmorse/Make.defs new file mode 100644 index 00000000000..0c52d4fb885 --- /dev/null +++ b/examples/txmorse/Make.defs @@ -0,0 +1,25 @@ +############################################################################ +# apps/examples/txmorse/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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_TXMORSE),) +CONFIGURED_APPS += $(APPDIR)/examples/txmorse +endif diff --git a/examples/txmorse/Makefile b/examples/txmorse/Makefile new file mode 100644 index 00000000000..8d9bcefff71 --- /dev/null +++ b/examples/txmorse/Makefile @@ -0,0 +1,34 @@ +############################################################################ +# apps/examples/txmorse/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# 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 + +# Application info + +PROGNAME = $(CONFIG_EXAMPLES_TXMORSE_PROGNAME) +PRIORITY = $(CONFIG_EXAMPLES_TXMORSE_PRIORITY) +STACKSIZE = $(CONFIG_EXAMPLES_TXMORSE_STACKSIZE) +MODULE = $(CONFIG_EXAMPLES_TXMORSE) + +MAINSRC = txmorse_main.c + +include $(APPDIR)/Application.mk diff --git a/examples/txmorse/txmorse_main.c b/examples/txmorse/txmorse_main.c new file mode 100644 index 00000000000..cc2a3f95748 --- /dev/null +++ b/examples/txmorse/txmorse_main.c @@ -0,0 +1,294 @@ +/**************************************************************************** + * apps/examples/txmorse/txmorse_main.c + * + * SPDX-License-Identifer: Apache-2.0 + * + * 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 + +#ifdef CONFIG_DEV_GPIO +#include +#endif + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Default millisecond duration of dot (2.5WPM) */ + +#define DEFAULT_DURATION (240) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: transmit_console + * + * Description: + * Transmit Morse code as printed characters to the console. + ****************************************************************************/ + +static void transmit_console(int on, unsigned duration_ms, void *arg) +{ + unsigned ms_per_unit = *((unsigned *)arg); + + if (on) + { + /* We are printing a dot or a dash */ + + if (duration_ms == ms_per_unit * MORSEY_UNITS_DOT) + { + putchar('.'); + } + else if (duration_ms == ms_per_unit * MORSEY_UNITS_DASH) + { + putchar('-'); + } + } + else + { + /* We are indicating separation */ + + if (duration_ms == ms_per_unit * MORSEY_UNITS_INTERELEM) + { + return; /* Inter-element gap, do nothing */ + } + else if (duration_ms == ms_per_unit * MORSEY_UNITS_INTERLET) + { + putchar(' '); /* Inter-letter gap, print a space */ + } + else if (duration_ms == ms_per_unit * MORSEY_UNITS_INTERWORD) + { + putchar('/'); /* Inter-word gap, print / delimiter */ + } + } +} + +/**************************************************************************** + * Name: cleanup_console + * + * Description: + * Default cleanup function; does nothing. + * + * Input Parameters: + * arg - User argument. + * + ****************************************************************************/ + +static void cleanup_console(void *arg) +{ + UNUSED(arg); + putchar('\n'); /* Newline character after message is done */ +} + +#ifdef CONFIG_DEV_GPIO + +/**************************************************************************** + * Name: transmit_gpio + * + * Description: + * Transmit Morse over a GPIO pin. + * + * Input Parameters: + * arg - Pointer to file descriptor of GPIO device + * + ****************************************************************************/ + +static void transmit_gpio(int on, unsigned duration_ms, void *arg) +{ + int err; + int fd = *((int *)arg); + + if (on) + { + err = ioctl(fd, GPIOC_WRITE, 1); + if (err < 0) + { + fprintf(stderr, "Failed to turn on GPIO: %d\n", errno); + return; + } + } + + usleep(duration_ms * 1000); + + err = ioctl(fd, GPIOC_WRITE, 0); + if (err < 0) + { + fprintf(stderr, "Failed to turn off GPIO: %d\n", errno); + } +} + +/**************************************************************************** + * Name: cleanup_gpio + * + * Description: + * Clean up a GPIO Morse sink. + * + * Input Parameters: + * arg - User argument (pointer to file descriptor) + * + ****************************************************************************/ + +static void cleanup_gpio(void *arg) +{ + int fd = *((int *)arg); + close(fd); +} + +#endif /* CONFIG_DEV_GPIO */ + +/**************************************************************************** + * Name: print_usage + * + * Description: + * Prints out the usage information for the program. + * + * Input Parameters: + * sink - The stream to output the usage information + * + ****************************************************************************/ + +static void print_usage(FILE *sink) +{ + fprintf(sink, "USAGE: " CONFIG_EXAMPLES_TXMORSE_PROGNAME + " [-d dot_duration_ms] \"my text\" [path/to/device]\n"); + fprintf(sink, + "Ex: " CONFIG_EXAMPLES_TXMORSE_PROGNAME " \"sos\" /dev/gpio1\n"); + fprintf(sink, "Default dot duration is 240 ms\n"); + fprintf(sink, "Default device is output to console\n"); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(int argc, char **argv) +{ + int err; + int c; + int fd; + struct morsey_state_s state; + + transmit_f txfunc = transmit_console; /* Default transmit */ + void (*cleanupfunc)(void *) = cleanup_console; /* Default cleanup */ + void *arg = NULL; + + unsigned duration = DEFAULT_DURATION; + char *devpath = NULL; + char *message = NULL; + + arg = &duration; /* Default argument */ + + /* Parse command line arguments */ + + while ((c = getopt(argc, argv, ":hd:")) != -1) + { + switch (c) + { + case 'h': + print_usage(stdout); + return EXIT_SUCCESS; + case 'd': + duration = strtoul(optarg, NULL, 10); + break; + case '?': + fprintf(stderr, "Unknown option -%c\n", optopt); + print_usage(stderr); + return EXIT_FAILURE; + } + } + + /* Get text to encode */ + + if (argc <= optind) + { + fprintf(stderr, "Missing text to encode!\n"); + return EXIT_FAILURE; + } + + message = argv[optind++]; + + /* Check for optional device path */ + + if (argc > optind) + { + devpath = argv[optind++]; + } + + /* Choose transmit function based on device path */ + + if (devpath == NULL) + { + txfunc = transmit_console; + cleanupfunc = cleanup_console; + arg = &duration; + } +#ifdef CONFIG_DEV_GPIO + else if (strstr(devpath, "gpio")) + { + txfunc = transmit_gpio; + cleanupfunc = cleanup_gpio; + fd = open(devpath, O_WRONLY); + if (fd < 0) + { + fprintf(stderr, "Couldn't open '%s': %d\n", devpath, errno); + return EXIT_FAILURE; + } + + arg = &fd; + } +#endif + else + { + fprintf(stderr, "Unrecognized device '%s', defaulting to console.\n", + devpath); + } + + /* Set up library to play */ + + morsey_init(&state, duration, 0); + + /* Transmit the text as Morse code */ + + err = morsey_transmit(message, strlen(message), &state, txfunc, arg); + if (err == 0) + { + cleanupfunc(arg); + return 0; + } + + fprintf(stderr, "Error transmitting: %d\n", err); + cleanupfunc(arg); + return err; +} diff --git a/include/.gitignore b/include/.gitignore index 1c2896091a8..b237d4f3c02 100644 --- a/include/.gitignore +++ b/include/.gitignore @@ -1,3 +1,4 @@ /netutils/cJSON.h /netutils/cJSON_Utils.h /audioutils/rtttl.h +/audioutils/morsey.h