diff --git a/ChangeLog b/ChangeLog index a56a37160e1..abe8b13bd78 100755 --- a/ChangeLog +++ b/ChangeLog @@ -11416,4 +11416,7 @@ * configs/board/src/xyz_cxxinitialize.c: Move CXX initialization logic out of the RTOS and into the application space, specifically to apps/platform/board, where it belongs (2016-01-29). + * drivers/modem/u-blox.c and include/nuttx/drivers/u-blox.h: Add an upper + half driver for the U-Blox Modem. From Vladimir Komendantskiy + (2018-01-30). diff --git a/drivers/Kconfig b/drivers/Kconfig index c836f5a8c49..41123641ebc 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -403,6 +403,16 @@ if MMCSD source drivers/mmcsd/Kconfig endif # MMCSD +menuconfig MODEM + bool "Modem Support" + default n + ---help--- + Enable modem support. + +if MODEM +source drivers/modem/Kconfig +endif # MODEM + menuconfig MTD bool "Memory Technology Device (MTD) Support" default n diff --git a/drivers/Makefile b/drivers/Makefile index c642b918774..025444990f9 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -59,6 +59,7 @@ include lcd$(DELIM)Make.defs include leds$(DELIM)Make.defs include loop$(DELIM)Make.defs include mmcsd$(DELIM)Make.defs +include modem$(DELIM)Make.defs include mtd$(DELIM)Make.defs include eeprom$(DELIM)Make.defs include net$(DELIM)Make.defs diff --git a/drivers/modem/Kconfig b/drivers/modem/Kconfig new file mode 100644 index 00000000000..bfc7568612e --- /dev/null +++ b/drivers/modem/Kconfig @@ -0,0 +1,20 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config MODEM_U_BLOX + bool "Enable u-blox modem driver" + default n + ---help--- + Compile the u-blox serial modem driver. The driver consists of + the upper half in the OS and the lower half with implementation + in the chosen board. + +config MODEM_U_BLOX_DEBUG + bool "Debug u-blox modem driver" + default n + depends on MODEM_U_BLOX + ---help--- + Allow the u-blox modem driver print debug information. + diff --git a/drivers/modem/Make.defs b/drivers/modem/Make.defs new file mode 100644 index 00000000000..6916f46fa2a --- /dev/null +++ b/drivers/modem/Make.defs @@ -0,0 +1,48 @@ +############################################################################ +# drivers/modem/Make.defs +# +# Copyright (C) 2016 Vladimir Komendantskiy. All rights reserved. +# Author: Vladimir Komendantskiy +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +ifeq ($(CONFIG_MODEM),y) + +ifeq ($(CONFIG_MODEM_U_BLOX),y) +CSRCS += u-blox.c +endif + +# Include modem driver build support + +DEPPATH += --dep-path modem +VPATH += :modem +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)modem} + +endif diff --git a/drivers/modem/u-blox.c b/drivers/modem/u-blox.c new file mode 100644 index 00000000000..05e4453ba96 --- /dev/null +++ b/drivers/modem/u-blox.c @@ -0,0 +1,338 @@ +/**************************************************************************** + * drivers/modem/u-blox.c + * + * Copyright (C) 2016 Vladimir Komendantskiy. All rights reserved. + * Author: Vladimir Komendantskiy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Debug ********************************************************************/ +/* Non-standard debug that may be enabled just for testing the modem driver */ + +#ifdef CONFIG_MODEM_U_BLOX_DEBUG +# define m_dbg dbg +# define m_vdbg vdbg +# define m_vlldbg lldbg +# define m_vllvdbg llvdbg +#else +# define m_dbg(x...) +# define m_vdbg(x...) +# define m_lldbg(x...) +# define m_llvdbg(x...) +#endif + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +/* The type of upper half driver state. */ + +struct ubxmdm_upper +{ + FAR char* path; /* Registration path */ + + /* The contained lower-half driver. */ + + FAR struct ubxmdm_lower* lower; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static ssize_t ubxmdm_read (FAR struct file* filep, + FAR char* buffer, + size_t buflen); +static ssize_t ubxmdm_write(FAR struct file* filep, + FAR const char* buffer, + size_t buflen); +static int ubxmdm_ioctl(FAR struct file* filep, + int cmd, + unsigned long arg); + +#ifndef CONFIG_DISABLE_POLL +static int ubxmdm_poll (FAR struct file* filep, + FAR struct pollfd* fds, + bool setup); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations ubxmdm_fops = +{ + 0, /* open */ + 0, /* close */ + ubxmdm_read, /* read */ + ubxmdm_write, /* write */ + 0, /* seek */ + ubxmdm_ioctl, /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + ubxmdm_poll, /* poll */ +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static ssize_t ubxmdm_read(FAR struct file* filep, + FAR char* buffer, + size_t len) +{ + return 0; /* Return EOF */ +} + +static ssize_t ubxmdm_write(FAR struct file* filep, + FAR const char* buffer, + size_t len) +{ + return len; /* Say that everything was written */ +} + +static int ubxmdm_ioctl(FAR struct file* filep, + int cmd, + unsigned long arg) +{ + FAR struct inode* inode = filep->f_inode; + FAR struct ubxmdm_upper* upper = inode->i_private; + FAR struct ubxmdm_lower* lower = upper->lower; + int ret; + FAR struct ubxmdm_status* status; + + m_vdbg("cmd: %d arg: %ld\n", cmd, arg); + DEBUGASSERT(upper && lower); + + switch (cmd) + { + /* cmd: UBXMDM_IOC_START + * Description: + * arg: Ignored + */ + + case MODEM_IOC_POWERON: + if (lower->ops->poweron) + { + ret = lower->ops->poweron(lower); + } + else + { + ret = -ENOSYS; + } + + break; + + /* cmd: UBXMDM_IOC_STOP + * Description: + * arg: Ignored + */ + + case MODEM_IOC_POWEROFF: + if (lower->ops->poweroff) + { + ret = lower->ops->poweroff(lower); + } + else + { + ret = -ENOSYS; + } + + break; + + /* cmd: UBXMDM_IOC_RESET + * Description: + * arg: Ignored + */ + + case MODEM_IOC_RESET: + if (lower->ops->reset) + { + ret = lower->ops->reset(lower); + } + else + { + ret = -ENOSYS; + } + + break; + + /* cmd: UBXMDM_IOC_GETSTATUS + * Description: + * arg: Writeable pointer to struct ubxmdm_status. + */ + + case MODEM_IOC_GETSTATUS: + if (lower->ops->getstatus) + { + status = (FAR struct ubxmdm_status*) ((uintptr_t) arg); + if (status) + { + ret = lower->ops->getstatus(lower, status); + } + else + { + ret = -EINVAL; + } + } + else + { + ret = -ENOSYS; + } + + break; + + /* Unrecognized IOCTL commands are forwarded to the lower-half IOCTL + * handler, if defined. + */ + + default: + m_vdbg("Forwarding unrecognized cmd: %d arg: %ld\n", cmd, arg); + + if (lower->ops->ioctl) + { + ret = lower->ops->ioctl(lower, cmd, arg); + } + else + { + ret = -ENOSYS; + } + + break; + } + + return ret; +} + +#ifndef CONFIG_DISABLE_POLL +static int ubxmdm_poll(FAR struct file* filep, + FAR struct pollfd* fds, + bool setup) +{ + if (setup) + { + fds->revents |= (fds->events & (POLLIN | POLLOUT)); + if (fds->revents != 0) + { + sem_post(fds->sem); + } + } + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +FAR void* ubxmdm_register(FAR const char *path, + FAR struct ubxmdm_lower *lower) +{ + FAR struct ubxmdm_upper *upper; + int ret; + + DEBUGASSERT(path && lower); + + upper = (FAR struct ubxmdm_upper*) + kmm_zalloc(sizeof(struct ubxmdm_upper)); + if (!upper) + { + m_dbg("Upper half allocation failed\n"); + goto errout; + } + + upper->lower = lower; + upper->path = strdup(path); + if (!upper->path) + { + m_dbg("Path allocation failed\n"); + goto errout_with_upper; + } + + ret = register_driver(path, &ubxmdm_fops, 0666, upper); + if (ret < 0) + { + m_dbg("register_driver failed: %d\n", ret); + goto errout_with_path; + } + + return (FAR void*) upper; + +errout_with_path: + kmm_free(upper->path); + +errout_with_upper: + kmm_free(upper); + +errout: + return NULL; +} + +void ubxmdm_unregister(FAR void *handle) +{ + FAR struct ubxmdm_upper *upper; + FAR struct ubxmdm_lower *lower; + + upper = (FAR struct ubxmdm_upper*) handle; + lower = upper->lower; + DEBUGASSERT(upper && lower); + + m_vdbg("Unregistering: %s\n", upper->path); + + DEBUGASSERT(lower->ops->poweroff); + (void) lower->ops->poweroff(lower); + + (void) unregister_driver(upper->path); + + kmm_free(upper->path); + kmm_free(upper); +} diff --git a/include/nuttx/fs/ioctl.h b/include/nuttx/fs/ioctl.h index 46fbdbf8abc..09893a63f8e 100644 --- a/include/nuttx/fs/ioctl.h +++ b/include/nuttx/fs/ioctl.h @@ -81,6 +81,7 @@ #define _ULEDBASE (0x1c00) /* User LED ioctl commands */ #define _ZCBASE (0x1d00) /* Zero Cross ioctl commands */ #define _LOOPBASE (0x1e00) /* Loop device commands */ +#define _MODEMBASE (0x1f00) /* Modem ioctl commands */ /* boardctl commands share the same number space */ @@ -367,6 +368,12 @@ #define _LOOPIOCVALID(c) (_IOC_TYPE(c)==_LOOPBASE) #define _LOOPIOC(nr) _IOC(_LOOPBASE,nr) +/* Modem driver ioctl definitions ********************************************/ +/* see nuttx/include/modem/*.h */ + +#define _MODEMIOCVALID(c) (_IOC_TYPE(c)==_MODEMBASE) +#define _MODEMIOC(nr) _IOC(_MODEMBASE,nr) + /* boardctl() command definitions *******************************************/ #define _BOARDIOCVALID(c) (_IOC_TYPE(c)==_BOARDBASE) diff --git a/include/nuttx/modem/u-blox.h b/include/nuttx/modem/u-blox.h new file mode 100644 index 00000000000..3b08ac422d7 --- /dev/null +++ b/include/nuttx/modem/u-blox.h @@ -0,0 +1,119 @@ +/**************************************************************************** + * include/nuttx/modem/u-blox.h + * + * Copyright (C) 2016 Vladimir Komendantskiy. All rights reserved. + * Author: Vladimir Komendantskiy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_MODEM_U_BLOX_H +#define __INCLUDE_NUTTX_MODEM_U_BLOX_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MODEM_IOC_POWERON _MODEMIOC(1) +#define MODEM_IOC_POWEROFF _MODEMIOC(2) +#define MODEM_IOC_RESET _MODEMIOC(3) +#define MODEM_IOC_GETSTATUS _MODEMIOC(4) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct ubxmdm_regval +{ + FAR char name[3]; + bool val; +}; + +struct ubxmdm_status +{ + bool on; + int register_values_size; + FAR struct ubxmdm_regval* register_values; +}; + +struct ubxmdm_lower; + +struct ubxmdm_ops +{ + CODE int (*poweron) (FAR struct ubxmdm_lower* lower); + CODE int (*poweroff) (FAR struct ubxmdm_lower* lower); + CODE int (*reset) (FAR struct ubxmdm_lower* lower); + CODE int (*getstatus)(FAR struct ubxmdm_lower* lower, + FAR struct ubxmdm_status* status); + CODE int (*ioctl) (FAR struct ubxmdm_lower* lower, + int cmd, + unsigned long arg); +}; + +struct ubxmdm_lower +{ + FAR const struct ubxmdm_ops *ops; +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * "Upper-Half" Timer Driver Interfaces + ****************************************************************************/ + +FAR void *ubxmdm_register(FAR const char *path, + FAR struct ubxmdm_lower *lower); + +void ubxmdm_unregister(FAR void *handle); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __INCLUDE_NUTTX_MODEM_U_BLOX_H */