diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig index 3cdb6909eb..2037b6d0ac 100644 --- a/drivers/sensors/Kconfig +++ b/drivers/sensors/Kconfig @@ -56,6 +56,11 @@ config SENSORS_FAKESENSOR 2.1234,3.23443,2.23456 ... +config SENSORS_GOLDFISH_GPS + bool "Goldfish GPS Support" + depends on SENSORS_GPS + default n + config SENSORS_APDS9960 bool "Avago APDS-9960 Gesture Sensor support" default n diff --git a/drivers/sensors/Make.defs b/drivers/sensors/Make.defs index d17b951a94..1514994768 100644 --- a/drivers/sensors/Make.defs +++ b/drivers/sensors/Make.defs @@ -44,6 +44,10 @@ ifeq ($(CONFIG_SENSORS_FAKESENSOR),y) CSRCS += fakesensor.c endif +ifeq ($(CONFIG_SENSORS_GOLDFISH_GPS),y) + CSRCS += goldfish_gps.c +endif + ifeq ($(CONFIG_SENSORS_HCSR04),y) CSRCS += hc_sr04.c endif diff --git a/drivers/sensors/goldfish_gps.c b/drivers/sensors/goldfish_gps.c new file mode 100644 index 0000000000..e8a66eee82 --- /dev/null +++ b/drivers/sensors/goldfish_gps.c @@ -0,0 +1,222 @@ +/**************************************************************************** + * drivers/sensors/goldfish_gps.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 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct goldfish_gps_s +{ + struct gps_lowerhalf_s gps; + struct file pipe; + volatile bool running; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int goldfish_gps_activate(FAR struct gps_lowerhalf_s *lower, + FAR struct file *filep, bool enabled); +static int goldfish_gps_thread(int argc, FAR char** argv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct gps_ops_s g_goldfish_gps_ops = +{ + .activate = goldfish_gps_activate, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static inline int goldfish_gps_write_pipe(FAR struct file *pipe, + FAR const void *buffer, + size_t size) +{ + FAR const char *p = (FAR const char *)buffer; + + while (size > 0) + { + int n = file_write(pipe, p, size); + if (n < 0) + { + return n; + } + + p += n; + size -= n; + } + + return 0; +} + +static inline int goldfish_gps_open_pipe(FAR struct file *filep, + FAR const char *ns, + FAR const char *pipe_name, + int flags) +{ + char buf[256]; + int buf_len; + int ret; + + ret = file_open(filep, "/dev/goldfish_pipe", flags); + if (ret < 0) + { + snerr("Could not open '%s': %s", + "/dev/goldfish_pipe", strerror(-ret)); + return ret; + } + + if (ns) + { + buf_len = snprintf(buf, sizeof(buf), "pipe:%s:%s", ns, pipe_name); + } + else + { + buf_len = snprintf(buf, sizeof(buf), "pipe:%s", pipe_name); + } + + ret = goldfish_gps_write_pipe(filep, buf, buf_len + 1); + if (ret < 0) + { + snerr("Could not connect to the '%s' service: %s", + buf, strerror(-ret)); + file_close(filep); + return ret; + } + + return OK; +} + +static int goldfish_gps_activate(FAR struct gps_lowerhalf_s *gps, + FAR struct file *filep, + bool enabled) +{ + FAR struct goldfish_gps_s *priv = + container_of(gps, struct goldfish_gps_s, gps); + priv->running = enabled; + + return OK; +} + +static int goldfish_gps_thread(int argc, FAR char** argv) +{ + FAR struct goldfish_gps_s *priv = (FAR struct goldfish_gps_s *) + ((uintptr_t)strtoul(argv[1], NULL, 0)); + ssize_t len; + char buf[256]; + + while (true) + { + len = file_read(&priv->pipe, buf, sizeof(buf)); + if (priv->running && len > 0) + { + priv->gps.push_data(priv->gps.priv, buf, len, true); + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: goldfish_gps_init + * + * Description: + * Goldfish GPS driver entrypoint. + * + * Input Parameters: + * devno - The user specifies which device of this type, from 0. + * batch_number- The maximum number of batch. + * + * Returned Value: + * Zero (OK) or positive on success; a negated errno value on failure. + * + ****************************************************************************/ + +int goldfish_gps_init(int devno, uint32_t batch_number) +{ + FAR struct goldfish_gps_s *gps; + FAR char *argv[2]; + char arg1[32]; + int ret; + + /* Alloc memory for sensor */ + + gps = kmm_zalloc(sizeof(struct goldfish_gps_s)); + if (!gps) + { + return -ENOMEM; + } + + ret = goldfish_gps_open_pipe(&gps->pipe, "qemud", "gps", O_RDWR); + if (ret < 0) + { + kmm_free(gps); + return ret; + } + + /* Create thread for sensor */ + + snprintf(arg1, 32, "%p", gps); + argv[0] = arg1; + argv[1] = NULL; + ret = kthread_create("goldfish_gps_thread", SCHED_PRIORITY_DEFAULT, + CONFIG_DEFAULT_TASK_STACKSIZE, + goldfish_gps_thread, argv); + if (ret < 0) + { + file_close(&gps->pipe); + kmm_free(gps); + return ret; + } + + /* Register sensor */ + + gps->gps.ops = &g_goldfish_gps_ops; + + return gps_register(&gps->gps, devno, batch_number); +} diff --git a/include/nuttx/sensors/goldfish_gps.h b/include/nuttx/sensors/goldfish_gps.h new file mode 100644 index 0000000000..3afd9a71bf --- /dev/null +++ b/include/nuttx/sensors/goldfish_gps.h @@ -0,0 +1,60 @@ +/**************************************************************************** + * include/nuttx/sensors/goldfish_gps.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_SENSORS_GOLDFISH_GPS_H +#define __INCLUDE_NUTTX_SENSORS_GOLDFISH_GPS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * Name: goldfish_gps_init + * + * Description: + * Goldfish GPS driver entrypoint. + * + * Input Parameters: + * devno - The user specifies which device of this type, from 0. + * batch_number- The maximum number of batch. + * + * Returned Value: + * Zero (OK) or positive on success; a negated errno value on failure. + * + ****************************************************************************/ + +int goldfish_gps_init(int devno, uint32_t batch_number); + +#ifdef __cplusplus +} +#endif + +#endif