diff --git a/examples/README.md b/examples/README.md index 789f3ed47..b8557abc1 100644 --- a/examples/README.md +++ b/examples/README.md @@ -209,6 +209,10 @@ Attempts to keep the system busy by passing data through a pipe in loop back mode. This may be useful if you are trying run down other problems that you think might only occur when the system is very busy. +## `cordic` + +A simple test of the CORDIC character driver. + ## `dac` Write to DAC This is a tool for writing values to DAC device. diff --git a/examples/cordic/Kconfig b/examples/cordic/Kconfig new file mode 100644 index 000000000..5ad75f4b4 --- /dev/null +++ b/examples/cordic/Kconfig @@ -0,0 +1,35 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_CORDIC + tristate "CORDIC example" + default n + ---help--- + Enable the CORDIC example + +if EXAMPLES_CORDIC + +config EXAMPLES_CORDIC_DEVPATH + string "CORDIC Device Path" + default "/dev/cordic0" + ---help--- + The device path + +config EXAMPLES_CORDIC_PROGNAME + string "Program name" + default "cordic" + ---help--- + This is the name of the program that will be used when the NSH ELF + program is installed. + +config EXAMPLES_CORDIC_PRIORITY + int "CORDIC task priority" + default 100 + +config EXAMPLES_CORDIC_STACKSIZE + int "CORDIC stack size" + default DEFAULT_TASK_STACKSIZE + +endif diff --git a/examples/cordic/Make.defs b/examples/cordic/Make.defs new file mode 100644 index 000000000..7494f87ec --- /dev/null +++ b/examples/cordic/Make.defs @@ -0,0 +1,23 @@ +############################################################################ +# apps/examples/cordic/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_CORDIC),) +CONFIGURED_APPS += $(APPDIR)/examples/cordic +endif diff --git a/examples/cordic/Makefile b/examples/cordic/Makefile new file mode 100644 index 000000000..c58d75a75 --- /dev/null +++ b/examples/cordic/Makefile @@ -0,0 +1,34 @@ +############################################################################ +# apps/examples/cordic/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. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# CORDIC built-in application info + +PROGNAME = $(CONFIG_EXAMPLES_CORDIC_PROGNAME) +PRIORITY = $(CONFIG_EXAMPLES_CORDIC_PRIORITY) +STACKSIZE = $(CONFIG_EXAMPLES_CORDIC_STACKSIZE) +MODULE = $(CONFIG_EXAMPLES_CORDIC) + +# CORDIC Example + +MAINSRC = cordic_main.c + +include $(APPDIR)/Application.mk diff --git a/examples/cordic/cordic_main.c b/examples/cordic/cordic_main.c new file mode 100644 index 000000000..fe128a7d5 --- /dev/null +++ b/examples/cordic/cordic_main.c @@ -0,0 +1,257 @@ +/**************************************************************************** + * apps/examples/cordic/cordic_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 +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_MATH_CORDIC_USE_Q31 +# error Not supported +#endif + +#ifndef CONFIG_LIBC_FLOATINGPOINT +# error CONFIG_LIBC_FLOATINGPOINT must be enabled +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * cordic_main + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + struct cordic_calc_s io; + int fd = 0; + int ret = OK; + float arg1f = 0.0f; + float arg2f = 0.0f; + float res1f = 0.0f; + float res2f = 0.0f; + b16_t arg1b16 = 0; + b16_t arg2b16 = 0; + b16_t res1b16 = 0; + b16_t res2b16 = 0; + + /* Reset data */ + + memset(&io, 0, sizeof(struct cordic_calc_s)); + + /* Open the CORDIC device */ + + fd = open(CONFIG_EXAMPLES_CORDIC_DEVPATH, O_RDWR); + if (fd < 0) + { + printf("ERROR: open %s failed: %d\n", + CONFIG_EXAMPLES_CORDIC_DEVPATH, errno); + goto errout; + } + + /* Get cosine */ + + arg1f = 0.05f; + arg2f = 1.0f; + io.func = CORDIC_CALC_FUNC_COS; + io.res2_incl = false; + io.arg1 = ftoq31(arg1f); + io.arg2 = ftoq31(arg2f); + + ret = ioctl(fd, MATHIOC_CORDIC_CALC, (unsigned long)((uintptr_t)&io)); + if (ret < 0) + { + printf("ERROR: MATHIOC_CORDIC_CALC failed, errno=%d\n", errno); + } + + res1f = q31tof(io.res1); + res2f = q31tof(io.res2); + + printf("[float] func=%" PRIu8 " res2_inc=%d " + "arg1f=%0.5f arg2=%0.5f res1=%0.5f res2=%0.5f\n", + io.func, io.res2_incl, arg1f, arg2f, res1f, res2f); + + /* Get cosine and sine from single call */ + + arg1f = -0.5f; + arg2f = 1.0f; + io.func = CORDIC_CALC_FUNC_COS; + io.res2_incl = true; + io.arg1 = ftoq31(arg1f); + io.arg2 = ftoq31(arg2f); + + ret = ioctl(fd, MATHIOC_CORDIC_CALC, (unsigned long)((uintptr_t)&io)); + if (ret < 0) + { + printf("ERROR: MATHIOC_CORDIC_CALC failed, errno=%d\n", errno); + } + + res1f = q31tof(io.res1); + res2f = q31tof(io.res2); + + printf("[float] func=%" PRIu8 " res2_inc=%d " + "arg1f=%0.5f arg2=%0.5f res1f=%0.5f res2f=%0.5f\n", + io.func, io.res2_incl, arg1f, arg2f, res1f, res2f); + + /* Get cosine and sine from single call */ + + arg1f = -0.1f; + arg2f = 1.0f; + io.func = CORDIC_CALC_FUNC_COS; + io.res2_incl = true; + io.arg1 = ftoq31(arg1f); + io.arg2 = ftoq31(arg2f); + + ret = ioctl(fd, MATHIOC_CORDIC_CALC, (unsigned long)((uintptr_t)&io)); + if (ret < 0) + { + printf("ERROR: MATHIOC_CORDIC_CALC failed, errno=%d\n", errno); + } + + res1f = q31tof(io.res1); + res2f = q31tof(io.res2); + + printf("[float] func=%" PRIu8 " res2_inc=%d " + "arg1f=%0.5f arg2=%0.5f res1=%0.5f res2=%0.5f\n", + io.func, io.res2_incl, arg1f, arg2f, res1f, res2f); + + /* Get cosine and sine from single call */ + + arg1f = 0.8f; + arg2f = 1.0f; + io.func = CORDIC_CALC_FUNC_COS; + io.res2_incl = true; + io.arg1 = ftoq31(arg1f); + io.arg2 = ftoq31(arg2f); + + ret = ioctl(fd, MATHIOC_CORDIC_CALC, (unsigned long)((uintptr_t)&io)); + if (ret < 0) + { + printf("ERROR: MATHIOC_CORDIC_CALC failed, errno=%d\n", errno); + } + + res1f = q31tof(io.res1); + res2f = q31tof(io.res2); + + printf("[float] func=%" PRIu8 " res2_inc=%d " + "arg1f=%0.5f arg2=%0.5f res1=%0.5f res2=%0.5f\n", + io.func, io.res2_incl, arg1f, arg2f, res1f, res2f); + + /* Get phase and modulus from single call */ + + arg1f = -0.5f; + arg2f = -0.5f; + io.func = CORDIC_CALC_FUNC_PHASE; + io.res2_incl = true; + io.arg1 = ftoq31(arg1f); + io.arg2 = ftoq31(arg2f); + + ret = ioctl(fd, MATHIOC_CORDIC_CALC, (unsigned long)((uintptr_t)&io)); + if (ret < 0) + { + printf("ERROR: MATHIOC_CORDIC_CALC failed, errno=%d\n", errno); + } + + res1f = q31tof(io.res1); + res2f = q31tof(io.res2); + + printf("[float] func=%" PRIu8 " res2_inc=%d " + "arg1f=%0.5f arg2=%0.5f res1f=%0.5f res2f=%0.5f\n", + io.func, io.res2_incl, arg1f, arg2f, res1f, res2f); + + /* Get cosine and sine from single call (fixed16) */ + + arg1b16 = ftob16(-0.5f); + arg2b16 = ftob16(1.0f); + io.func = CORDIC_CALC_FUNC_COS; + io.res2_incl = true; + io.arg1 = b16toq31(arg1b16); + io.arg2 = b16toq31(arg2b16); + + ret = ioctl(fd, MATHIOC_CORDIC_CALC, (unsigned long)((uintptr_t)&io)); + if (ret < 0) + { + printf("ERROR: MATHIOC_CORDIC_CALC failed, errno=%d\n", errno); + } + + res1b16 = q31tob16(io.res1); + res2b16 = q31tob16(io.res2); + + printf("[fixed16] func=%" PRIu8 " res2_inc=%d " + "arg1f=%0.5f arg2=%0.5f res1=%0.5f res2=%0.5f\n", + io.func, io.res2_incl, b16tof(arg1b16), b16tof(arg2b16), + b16tof(res1b16), b16tof(res2b16)); + + /* Get phase and modulus from single call (fixed16) */ + + arg1b16 = ftob16(-0.5f); + arg2b16 = ftob16(-0.5f); + io.func = CORDIC_CALC_FUNC_PHASE; + io.res2_incl = true; + io.arg1 = b16toq31(arg1b16); + io.arg2 = b16toq31(arg2b16); + + ret = ioctl(fd, MATHIOC_CORDIC_CALC, (unsigned long)((uintptr_t)&io)); + if (ret < 0) + { + printf("ERROR: MATHIOC_CORDIC_CALC failed, errno=%d\n", errno); + } + + res1b16 = q31tob16(io.res1); + res2b16 = q31tob16(io.res2); + + printf("[fxied16] func=%" PRIu8 " res2_inc=%d " + "arg1f=%0.5f arg2=%0.5f res1=%0.5f res2=%0.5f\n", + io.func, io.res2_incl, b16tof(arg1b16), b16tof(arg2b16), + b16tof(res1b16), b16tof(res2b16)); + +errout: + + /* Close CORDIC device */ + + if (fd > 0) + { + close(fd); + } + + return 0; +}