Skip to content

Commit

Permalink
Merge pull request #5959 from iNavFlight/dzikuvx-pcf8574-expander
Browse files Browse the repository at this point in the history
I/O Expander Board Support
  • Loading branch information
DzikuVx committed Jul 22, 2020
2 parents 612367d + 410db23 commit f83b54b
Show file tree
Hide file tree
Showing 14 changed files with 287 additions and 23 deletions.
9 changes: 9 additions & 0 deletions docs/Logic Conditions.md
Expand Up @@ -39,6 +39,14 @@ Logic conditions can be edited using INAV Configurator user interface, of via CL
| 11 | NOR | |
| 12 | NOT | |
| 13 | STICKY | `Operand A` is activation operator, `Operand B` is deactivation operator. After activation, operator will return `true` until Operand B is evaluated as `true`|
| 14 | ADD | Add `Operand A` to `Operand B` and returns the result |
| 15 | SUB | Substract `Operand B` from `Operand A` and returns the result |
| 16 | MUL | Multiply `Operand A` by `Operand B` and returns the result |
| 17 | DIV | Divide `Operand A` by `Operand B` and returns the result |
| 18 | GVAR SET | Store value from `Operand B` into the Global Variable addressed by `Operand B`. Bear in mind, that operand `Global Variable` means: Value stored in Global Variable of an index! To store in GVAR 1 use `Value 1` not `Global Variable 1` |
| 19 | GVAR INC | Increase the GVAR indexed by `Operand A` with value from `Operand B` |
| 20 | GVAR DEC | Decrease the GVAR indexed by `Operand A` with value from `Operand B` |
| 128 | IO PORT SET | Set I2C IO Expander pin `Operand A` to value of `Operand B`. `Operand A` accepts values `0-7` and `Operand B` accepts `0` and `1` |

### Operands

Expand All @@ -49,6 +57,7 @@ Logic conditions can be edited using INAV Configurator user interface, of via CL
| 2 | FLIGHT | `value` points to flight parameter table |
| 3 | FLIGHT_MODE | `value` points to flight modes table |
| 4 | LC | `value` points to other logic condition ID |
| 5 | GVAR | Value stored in Global Variable indexed by `value`. `GVAR 1` means: value in GVAR 1 |

#### FLIGHT

Expand Down
2 changes: 2 additions & 0 deletions make/source.mk
Expand Up @@ -53,6 +53,8 @@ MAIN_SRC = \
drivers/display_font_metadata.c \
drivers/exti.c \
drivers/io_pca9685.c \
drivers/io_pcf8574.c \
drivers/io_port_expander.c \
drivers/osd.c \
drivers/resource.c \
drivers/rx_nrf24l01.c \
Expand Down
1 change: 1 addition & 0 deletions src/main/build/debug.h
Expand Up @@ -76,5 +76,6 @@ typedef enum {
DEBUG_SPM_CELLS, // Smartport master FLVSS
DEBUG_SPM_VS600, // Smartport master VS600 VTX
DEBUG_SPM_VARIO, // Smartport master variometer
DEBUG_PCF8574,
DEBUG_COUNT
} debugType_e;
1 change: 1 addition & 0 deletions src/main/drivers/bus.h
Expand Up @@ -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 {
Expand Down
84 changes: 84 additions & 0 deletions src/main/drivers/io_pcf8574.c
@@ -0,0 +1,84 @@
/*
* 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 <stdbool.h>
#include <stdint.h>
#include "drivers/bus.h"
#include "drivers/io_pcf8574.h"
#include "drivers/time.h"
#include "build/debug.h"

#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;
}

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;
}
29 changes: 29 additions & 0 deletions 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);
67 changes: 67 additions & 0 deletions src/main/drivers/io_port_expander.c
@@ -0,0 +1,67 @@
/*
* 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 <stdbool.h>
#include "platform.h"
#include "drivers/io_port_expander.h"
#include "drivers/io_pcf8574.h"

#ifdef USE_I2C_IO_EXPANDER

static ioPortExpanderState_t ioPortExpanderState;

void ioPortExpanderInit(void)
{

ioPortExpanderState.active = pcf8574Init();

if (ioPortExpanderState.active) {
ioPortExpanderState.state = 0x00;
pcf8574Write(ioPortExpanderState.state); //Set all ports to OFF
}

}

void ioPortExpanderSet(uint8_t pin, uint8_t value)
{
if (pin > 7) {
return;
}

//Cast to 0/1
value = (bool) value;

ioPortExpanderState.state ^= (-value ^ ioPortExpanderState.state) & (1UL << pin);
ioPortExpanderState.shouldSync = true;
}

void ioPortExpanderSync(void)
{
if (ioPortExpanderState.active && ioPortExpanderState.shouldSync) {
pcf8574Write(ioPortExpanderState.state);
ioPortExpanderState.shouldSync = false;;
}
}

#endif
37 changes: 37 additions & 0 deletions src/main/drivers/io_port_expander.h
@@ -0,0 +1,37 @@
/*
* 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

#include "stdint.h"

typedef struct ioPortExpanderState_s {
uint8_t active;
uint8_t state;
uint8_t shouldSync;
} ioPortExpanderState_t;

void ioPortExpanderInit(void);
void ioPortExpanderSync(void);
void ioPortExpanderSet(uint8_t pin, uint8_t value);
5 changes: 5 additions & 0 deletions src/main/fc/fc_init.c
Expand Up @@ -83,6 +83,7 @@
#include "msc/emfat_file.h"
#endif
#include "drivers/sdcard/sdcard.h"
#include "drivers/io_port_expander.h"

#include "fc/cli.h"
#include "fc/config.h"
Expand Down Expand Up @@ -682,6 +683,10 @@ void init(void)
}
#endif

#ifdef USE_I2C_IO_EXPANDER
ioPortExpanderInit();
#endif

// Considering that the persistent reset reason is only used during init
persistentObjectWrite(PERSISTENT_OBJECT_RESET_REASON, RESET_NONE);

Expand Down
2 changes: 1 addition & 1 deletion src/main/fc/settings.yaml
Expand Up @@ -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", "SPM_CELLS", "SPM_VS600", "SPM_VARIO"]
"IRLOCK", "CD", "KALMAN", "SPM_CELLS", "SPM_VS600", "SPM_VARIO", "PCF8574"]
- name: async_mode
values: ["NONE", "GYRO", "ALL"]
- name: aux_operator
Expand Down
11 changes: 10 additions & 1 deletion src/main/programming/logic_condition.c
Expand Up @@ -41,6 +41,7 @@
#include "sensors/pitotmeter.h"
#include "flight/imu.h"
#include "flight/pid.h"
#include "drivers/io_port_expander.h"

#include "navigation/navigation.h"
#include "navigation/navigation_private.h"
Expand Down Expand Up @@ -180,7 +181,12 @@ static int logicConditionCompute(
return operandA;
}
break;

#ifdef USE_I2C_IO_EXPANDER
case LOGIC_CONDITION_PORT_SET:
ioPortExpanderSet((uint8_t)operandA, (uint8_t)operandB);
return operandB;
break;
#endif
default:
return false;
break;
Expand Down Expand Up @@ -456,6 +462,9 @@ void logicConditionUpdateTask(timeUs_t currentTimeUs) {
for (uint8_t i = 0; i < MAX_LOGIC_CONDITIONS; i++) {
logicConditionProcess(i);
}
#ifdef USE_I2C_IO_EXPANDER
ioPortExpanderSync();
#endif
}

void logicConditionReset(void) {
Expand Down
43 changes: 22 additions & 21 deletions src/main/programming/logic_condition.h
Expand Up @@ -29,27 +29,28 @@
#define MAX_LOGIC_CONDITIONS 16

typedef enum {
LOGIC_CONDITION_TRUE = 0, // 0
LOGIC_CONDITION_EQUAL, // 1
LOGIC_CONDITION_GREATER_THAN, // 2
LOGIC_CONDITION_LOWER_THAN, // 3
LOGIC_CONDITION_LOW, // 4
LOGIC_CONDITION_MID, // 5
LOGIC_CONDITION_HIGH, // 6
LOGIC_CONDITION_AND, // 7
LOGIC_CONDITION_OR, // 8
LOGIC_CONDITION_XOR, // 9
LOGIC_CONDITION_NAND, // 10
LOGIC_CONDITION_NOR, // 11
LOGIC_CONDITION_NOT, // 12
LOGIC_CONDITION_STICKY, // 13
LOGIC_CONDITION_ADD, // 14
LOGIC_CONDITION_SUB, // 15
LOGIC_CONDITION_MUL, // 16
LOGIC_CONDITION_DIV, // 17
LOGIC_CONDITION_GVAR_SET, // 18
LOGIC_CONDITION_GVAR_INC, // 19
LOGIC_CONDITION_GVAR_DEC, // 20
LOGIC_CONDITION_TRUE = 0,
LOGIC_CONDITION_EQUAL = 1,
LOGIC_CONDITION_GREATER_THAN = 2,
LOGIC_CONDITION_LOWER_THAN = 3,
LOGIC_CONDITION_LOW = 4,
LOGIC_CONDITION_MID = 5,
LOGIC_CONDITION_HIGH = 6,
LOGIC_CONDITION_AND = 7,
LOGIC_CONDITION_OR = 8,
LOGIC_CONDITION_XOR = 9,
LOGIC_CONDITION_NAND = 10,
LOGIC_CONDITION_NOR = 11,
LOGIC_CONDITION_NOT = 12,
LOGIC_CONDITION_STICKY = 13,
LOGIC_CONDITION_ADD = 14,
LOGIC_CONDITION_SUB = 15,
LOGIC_CONDITION_MUL = 16,
LOGIC_CONDITION_DIV = 17,
LOGIC_CONDITION_GVAR_SET = 18,
LOGIC_CONDITION_GVAR_INC = 19,
LOGIC_CONDITION_GVAR_DEC = 20,
LOGIC_CONDITION_PORT_SET = 128,
LOGIC_CONDITION_LAST
} logicOperation_e;

Expand Down
2 changes: 2 additions & 0 deletions src/main/target/common.h
Expand Up @@ -121,6 +121,8 @@
#define USE_D_BOOST
#define USE_ANTIGRAVITY

#define USE_I2C_IO_EXPANDER

#else // FLASH_SIZE < 256
#define LOG_LEVEL_MAXIMUM LOG_LEVEL_ERROR
#endif
Expand Down

0 comments on commit f83b54b

Please sign in to comment.