diff --git a/platforms/nuttx/src/px4/common/CMakeLists.txt b/platforms/nuttx/src/px4/common/CMakeLists.txt index 385bf7dd35..313b8150b6 100644 --- a/platforms/nuttx/src/px4/common/CMakeLists.txt +++ b/platforms/nuttx/src/px4/common/CMakeLists.txt @@ -62,3 +62,5 @@ else() add_library(px4_layer ${PX4_SOURCE_DIR}/platforms/common/empty.c) endif() add_dependencies(px4_layer prebuild_targets) + +add_subdirectory(gpio) diff --git a/platforms/nuttx/src/px4/common/gpio/CMakeLists.txt b/platforms/nuttx/src/px4/common/gpio/CMakeLists.txt new file mode 100644 index 0000000000..208cc5c828 --- /dev/null +++ b/platforms/nuttx/src/px4/common/gpio/CMakeLists.txt @@ -0,0 +1,35 @@ +############################################################################ +# +# Copyright (c) 2020 PX4 Development Team. All rights reserved. +# +# 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 PX4 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. +# +############################################################################ + + +add_subdirectory(mcp23009) diff --git a/platforms/nuttx/src/px4/common/gpio/mcp23009/CMakeLists.txt b/platforms/nuttx/src/px4/common/gpio/mcp23009/CMakeLists.txt new file mode 100644 index 0000000000..5660edfac1 --- /dev/null +++ b/platforms/nuttx/src/px4/common/gpio/mcp23009/CMakeLists.txt @@ -0,0 +1,35 @@ +############################################################################ +# +# Copyright (c) 2020 PX4 Development Team. All rights reserved. +# +# 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 PX4 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. +# +############################################################################ +px4_add_library(platform_gpio_mcp23009 + mcp23009.cpp + ) diff --git a/platforms/nuttx/src/px4/common/gpio/mcp23009/mcp23009.cpp b/platforms/nuttx/src/px4/common/gpio/mcp23009/mcp23009.cpp new file mode 100644 index 0000000000..ede9c2c172 --- /dev/null +++ b/platforms/nuttx/src/px4/common/gpio/mcp23009/mcp23009.cpp @@ -0,0 +1,212 @@ +/**************************************************************************** + * + * Copyright (c) 2020 PX4 Development Team. All rights reserved. + * + * 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 PX4 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. + * + ****************************************************************************/ + +#include +#include +#include "mcp23009_registers.hpp" + +using namespace Microchip_MCP23009; + +const struct gpio_operations_s MCP23009::gpio_ops = { +go_read : MCP23009::go_read, +go_write : MCP23009::go_write, +go_attach : nullptr, +go_enable : nullptr, +go_setpintype : MCP23009::go_setpintype, +}; + +MCP23009::MCP23009(int bus, int address, int first_minor, int bus_frequency) : + I2C(DRV_GPIO_DEVTYPE_MCP23009, "MCP23009", bus, address, bus_frequency), + _first_minor(first_minor) +{ +} + +MCP23009::~MCP23009() +{ + /* set all as input & unregister */ + for (int i = 0; i < num_gpios; ++i) { + go_setpintype(i, GPIO_INPUT_PIN); + gpio_pin_unregister(&_gpio[i].gpio, _first_minor + i); + } +} + +int MCP23009::go_read(struct gpio_dev_s *dev, bool *value) +{ + mcp23009_gpio_dev_s *gpio = (struct mcp23009_gpio_dev_s *)dev; + return gpio->obj->go_read(gpio->id, value); +} + +int MCP23009::go_write(struct gpio_dev_s *dev, bool value) +{ + mcp23009_gpio_dev_s *gpio = (struct mcp23009_gpio_dev_s *)dev; + return gpio->obj->go_write(gpio->id, value); +} + +int MCP23009::go_setpintype(struct gpio_dev_s *dev, enum gpio_pintype_e pintype) +{ + mcp23009_gpio_dev_s *gpio = (struct mcp23009_gpio_dev_s *)dev; + return gpio->obj->go_setpintype(gpio->id, pintype); +} + + +int MCP23009::read_reg(Register address, uint8_t &data) +{ + return transfer((uint8_t *)&address, 1, &data, 1); +} + +int MCP23009::write_reg(Register address, uint8_t value) +{ + uint8_t data[2] = {(uint8_t)address, value}; + return transfer(data, sizeof(data), nullptr, 0); +} + +int MCP23009::init(uint8_t direction, uint8_t intital, uint8_t pull_up) +{ + /* do I2C init (and probe) first */ + int ret = I2C::init(); + + if (ret != PX4_OK) { + return ret; + } + + /* Use this state as the out puts */ + + ret = write_reg(Register::OLAT, intital); + ret |= write_reg(Register::IODIR, direction); + ret |= write_reg(Register::GPPU, pull_up); + + if (ret != PX4_OK) { + return ret; + } + + /* register the pins */ + for (int i = 0; i < num_gpios; ++i) { + _gpio[i].gpio.gp_pintype = GPIO_INPUT_PIN; + _gpio[i].gpio.gp_ops = &gpio_ops; + _gpio[i].id = i; + _gpio[i].obj = this; + ret = gpio_pin_register(&_gpio[i].gpio, _first_minor + i); + + if (ret != PX4_OK) { + return ret; + } + } + + return ret; +} + +int MCP23009::probe() +{ + // no whoami, try to read IOCON + uint8_t data; + return read_reg(Register::IOCON, data); +} + +int MCP23009::go_read(int id, bool *value) +{ + + uint8_t data; + int ret = read_reg(Register::GPIO, data); + + if (ret != 0) { + return ret; + } + + *value = data & (1 << id); + return 0; +} + +int MCP23009::go_write(int id, bool value) +{ + uint8_t data; + int ret = read_reg(Register::GPIO, data); + + if (ret != 0) { + return ret; + } + + if (value) { + data |= (1 << id); + + } else { + data &= ~(1 << id); + } + + return write_reg(Register::GPIO, data); +} + +int MCP23009::go_setpintype(int id, enum gpio_pintype_e pintype) +{ + uint8_t direction; + int ret = read_reg(Register::IODIR, direction); + + if (ret != 0) { + return ret; + } + + uint8_t pullup; + ret = read_reg(Register::GPPU, pullup); + + if (ret != 0) { + return ret; + } + + switch (pintype) { + case GPIO_INPUT_PIN: + direction |= (1 << id); + pullup &= ~(1 << id); + break; + + case GPIO_INPUT_PIN_PULLUP: + direction |= (1 << id); + pullup |= (1 << id); + break; + + case GPIO_OUTPUT_PIN: + direction &= ~(1 << id); + break; + + default: + return -EINVAL; + } + + _gpio[id].gpio.gp_pintype = pintype; + + ret = write_reg(Register::GPPU, pullup); + + if (ret != 0) { + return ret; + } + + return write_reg(Register::IODIR, direction); +} diff --git a/platforms/nuttx/src/px4/common/gpio/mcp23009/mcp23009_registers.hpp b/platforms/nuttx/src/px4/common/gpio/mcp23009/mcp23009_registers.hpp new file mode 100644 index 0000000000..1e99a0ea03 --- /dev/null +++ b/platforms/nuttx/src/px4/common/gpio/mcp23009/mcp23009_registers.hpp @@ -0,0 +1,68 @@ +/**************************************************************************** + * + * Copyright (c) 2020 PX4 Development Team. All rights reserved. + * + * 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 PX4 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. + * + ****************************************************************************/ + +#pragma once + +#include + +// TODO: move to a central header +static constexpr uint8_t Bit0 = (1 << 0); +static constexpr uint8_t Bit1 = (1 << 1); +static constexpr uint8_t Bit2 = (1 << 2); +static constexpr uint8_t Bit3 = (1 << 3); +static constexpr uint8_t Bit4 = (1 << 4); +static constexpr uint8_t Bit5 = (1 << 5); +static constexpr uint8_t Bit6 = (1 << 6); +static constexpr uint8_t Bit7 = (1 << 7); + +namespace Microchip_MCP23009 +{ + +enum class +Register : uint8_t { + + IODIR = 0x00, + IPOL = 0x01, + GPINTEN = 0x02, + DEFVAL = 0x03, + INTCON = 0x04, + IOCON = 0x05, + GPPU = 0x06, + INTF = 0x07, + INTCAP = 0x08, + GPIO = 0x09, + OLAT = 0x0a + +}; + +} // namespace Microchip_MCP23009 diff --git a/platforms/nuttx/src/px4/common/include/px4_platform/gpio/mcp23009.hpp b/platforms/nuttx/src/px4/common/include/px4_platform/gpio/mcp23009.hpp new file mode 100644 index 0000000000..3a12aaaca7 --- /dev/null +++ b/platforms/nuttx/src/px4/common/include/px4_platform/gpio/mcp23009.hpp @@ -0,0 +1,81 @@ +/**************************************************************************** + * + * Copyright (c) 2020 PX4 Development Team. All rights reserved. + * + * 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 PX4 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. + * + ****************************************************************************/ + +#pragma once + +#include + +#include + +using namespace time_literals; + +namespace Microchip_MCP23009 +{ +enum class Register : uint8_t; +} + +class MCP23009 : public device::I2C +{ +public: + MCP23009(int bus, int address, int first_minor = 0, int bus_frequency = 400000); + virtual ~MCP23009(); + + int init(uint8_t direction, uint8_t intital = 0, uint8_t pull_up = 0); + +protected: + int probe() override; + +private: + static constexpr int num_gpios = 8; + static const gpio_operations_s gpio_ops; + + struct mcp23009_gpio_dev_s { + struct gpio_dev_s gpio; + uint8_t id; + MCP23009 *obj; + }; + + static int go_read(struct gpio_dev_s *dev, bool *value); + static int go_write(struct gpio_dev_s *dev, bool value); + static int go_setpintype(struct gpio_dev_s *dev, enum gpio_pintype_e pintype); + + int go_read(int id, bool *value); + int go_write(int id, bool value); + int go_setpintype(int id, enum gpio_pintype_e pintype); + + int read_reg(Microchip_MCP23009::Register address, uint8_t &data); + int write_reg(Microchip_MCP23009::Register address, uint8_t data); + + const int _first_minor; + mcp23009_gpio_dev_s _gpio[num_gpios] {}; +}; diff --git a/src/drivers/drv_sensor.h b/src/drivers/drv_sensor.h index c32a1d12bc..2dfbd2ef65 100644 --- a/src/drivers/drv_sensor.h +++ b/src/drivers/drv_sensor.h @@ -163,6 +163,8 @@ #define DRV_ADC_DEVTYPE_ADS1115 0x90 #define DRV_DIST_DEVTYPE_VL53L1X 0x91 +#define DRV_GPIO_DEVTYPE_MCP23009 0x99 + #define DRV_DEVTYPE_UNUSED 0xff #endif /* _DRV_SENSOR_H */