From d85693cd98678cbf09c3d9ddb8df575e852ad9e7 Mon Sep 17 00:00:00 2001 From: "Pawel Spychalski (DzikuVx)" Date: Mon, 20 Jul 2020 18:05:38 +0200 Subject: [PATCH] PCF8574 Basic Driver --- make/source.mk | 1 + src/main/build/debug.h | 1 + src/main/drivers/bus.h | 1 + src/main/drivers/io_pcf8574.c | 90 +++++++++++++++++++++++++++++++ src/main/drivers/io_pcf8574.h | 29 ++++++++++ src/main/fc/fc_init.c | 6 +++ src/main/fc/settings.yaml | 2 +- src/main/target/common.h | 3 ++ src/main/target/common_hardware.c | 17 ++++++ 9 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 src/main/drivers/io_pcf8574.c create mode 100644 src/main/drivers/io_pcf8574.h diff --git a/make/source.mk b/make/source.mk index e1b9aa1284..d1b0b3e065 100644 --- a/make/source.mk +++ b/make/source.mk @@ -45,6 +45,7 @@ COMMON_SRC = \ drivers/exti.c \ drivers/io.c \ drivers/io_pca9685.c \ + drivers/io_pcf8574.c \ drivers/irlock.c \ drivers/light_led.c \ drivers/osd.c \ diff --git a/src/main/build/debug.h b/src/main/build/debug.h index a5a5e90ea6..3ae2e3109c 100644 --- a/src/main/build/debug.h +++ b/src/main/build/debug.h @@ -73,5 +73,6 @@ typedef enum { DEBUG_IRLOCK, DEBUG_CD, DEBUG_KALMAN, + DEBUG_PCF8574, DEBUG_COUNT } debugType_e; diff --git a/src/main/drivers/bus.h b/src/main/drivers/bus.h index d5a877f7d6..6e7dc2f48b 100755 --- a/src/main/drivers/bus.h +++ b/src/main/drivers/bus.h @@ -145,6 +145,7 @@ typedef enum { DEVHW_UG2864, // I2C OLED display DEVHW_SDCARD, // Generic SD-Card DEVHW_IRLOCK, // IR-Lock visual positioning hardware + DEVHW_PCF8574, // 8-bit I/O expander } devHardwareType_e; typedef enum { diff --git a/src/main/drivers/io_pcf8574.c b/src/main/drivers/io_pcf8574.c new file mode 100644 index 0000000000..dded542209 --- /dev/null +++ b/src/main/drivers/io_pcf8574.c @@ -0,0 +1,90 @@ +/* + * This file is part of INAV. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 3, as described below: + * + * This file is free software: you may copy, redistribute and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#include +#include +#include "drivers/bus.h" +#include "drivers/io_pcf8574.h" +#include "drivers/time.h" +#include "build/debug.h" + +#ifdef USE_PCF8574 + +#define PCF8574_WRITE_ADDRESS 0x40 +#define PCF8574_READ_ADDRESS 0x41 + +static busDevice_t *busDev; + +static bool deviceDetect(busDevice_t *busDev) +{ + for (int retry = 0; retry < 5; retry++) + { + uint8_t sig; + + delay(150); + + bool ack = busRead(busDev, 0x00, &sig); + if (ack) + { + return true; + } + }; + + return false; +} + +bool pcf8574Init(void) +{ + busDev = busDeviceInit(BUSTYPE_I2C, DEVHW_PCF8574, 0, 0); + if (busDev == NULL) + { + DEBUG_SET(DEBUG_PCF8574, 0, 1); + return false; + } + + if (!deviceDetect(busDev)) + { + DEBUG_SET(DEBUG_PCF8574, 0, 2); + busDeviceDeInit(busDev); + return false; + } + + pcf8574Write(0x00); //Set all ports to OFF + delay(25); + return true; +} + +void pcf8574Write(uint8_t data) +{ + busWrite(busDev, PCF8574_WRITE_ADDRESS, data); +} + +uint8_t pcf8574Read(void) +{ + uint8_t data; + busRead(busDev, PCF8574_READ_ADDRESS, &data); + return data; +} + +#endif \ No newline at end of file diff --git a/src/main/drivers/io_pcf8574.h b/src/main/drivers/io_pcf8574.h new file mode 100644 index 0000000000..dc87f69449 --- /dev/null +++ b/src/main/drivers/io_pcf8574.h @@ -0,0 +1,29 @@ +/* + * This file is part of INAV. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU General Public License Version 3, as described below: + * + * This file is free software: you may copy, redistribute and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ + +#pragma once + +bool pcf8574Init(void); +void pcf8574Write(uint8_t data); +uint8_t pcf8574Read(void); \ No newline at end of file diff --git a/src/main/fc/fc_init.c b/src/main/fc/fc_init.c index 1ee4dd016d..dbc91f4681 100644 --- a/src/main/fc/fc_init.c +++ b/src/main/fc/fc_init.c @@ -83,6 +83,7 @@ #include "msc/emfat_file.h" #endif #include "drivers/sdcard/sdcard.h" +#include "drivers/io_pcf8574.h" #include "fc/cli.h" #include "fc/config.h" @@ -674,6 +675,11 @@ void init(void) } #endif +#ifdef USE_PCF8574 + bool pcfActive = pcf8574Init(); + DEBUG_SET(DEBUG_PCF8574, 1, pcfActive); +#endif + // Considering that the persistent reset reason is only used during init persistentObjectWrite(PERSISTENT_OBJECT_RESET_REASON, RESET_NONE); diff --git a/src/main/fc/settings.yaml b/src/main/fc/settings.yaml index 5ab9066e3d..9493f03915 100644 --- a/src/main/fc/settings.yaml +++ b/src/main/fc/settings.yaml @@ -84,7 +84,7 @@ tables: "FLOW", "SBUS", "FPORT", "ALWAYS", "SAG_COMP_VOLTAGE", "VIBE", "CRUISE", "REM_FLIGHT_TIME", "SMARTAUDIO", "ACC", "ITERM_RELAX", "ERPM", "RPM_FILTER", "RPM_FREQ", "NAV_YAW", "DYNAMIC_FILTER", "DYNAMIC_FILTER_FREQUENCY", - "IRLOCK", "CD", "KALMAN"] + "IRLOCK", "CD", "KALMAN", "PCF8574"] - name: async_mode values: ["NONE", "GYRO", "ALL"] - name: aux_operator diff --git a/src/main/target/common.h b/src/main/target/common.h index a6ff91b038..95bd52a71e 100755 --- a/src/main/target/common.h +++ b/src/main/target/common.h @@ -121,6 +121,9 @@ #define USE_D_BOOST #define USE_ANTIGRAVITY +#define USE_I2C_IO_EXPANDER +#define USE_PCF8574 + #else // FLASH_SIZE < 256 #define LOG_LEVEL_MAXIMUM LOG_LEVEL_ERROR #endif diff --git a/src/main/target/common_hardware.c b/src/main/target/common_hardware.c index b372e9c8f7..0818d11973 100755 --- a/src/main/target/common_hardware.c +++ b/src/main/target/common_hardware.c @@ -353,4 +353,21 @@ BUSDEV_REGISTER_I2C(busdev_irlock, DEVHW_IRLOCK, IRLOCK_I2C_BUS, 0x54, NONE, DEVFLAGS_USE_RAW_REGISTERS); #endif +#if defined(USE_I2C) && defined(USE_PCF8574) + + #if !defined(PCF8574_I2C_BUS) && defined(EXTERNAL_I2C_BUS) + #define PCF8574_I2C_BUS EXTERNAL_I2C_BUS + #endif + + #if !defined(PCF8574_I2C_BUS) && defined(DEFAULT_I2C_BUS) + #define PCF8574_I2C_BUS DEFAULT_I2C_BUS + #endif + + #if !defined(PCF8574_I2C_BUS) + #define PCF8574_I2C_BUS BUS_I2C1 + #endif + + BUSDEV_REGISTER_I2C(busdev_pcf8574, DEVHW_PCF8574, PCF8574_I2C_BUS, 0x20, NONE, DEVFLAGS_NONE, 0); +#endif + #endif // USE_TARGET_HARDWARE_DESCRIPTORS