Browse Source

Check used GPIOs via locks

fastled
Xose Pérez 7 years ago
parent
commit
3036676958
9 changed files with 97 additions and 15 deletions
  1. +6
    -2
      code/espurna/config/hardware.h
  2. +7
    -0
      code/espurna/config/prototypes.h
  3. +37
    -0
      code/espurna/gpio.ino
  4. +1
    -7
      code/espurna/sensors/BaseSensor.h
  5. +23
    -0
      code/espurna/sensors/DHTSensor.h
  6. +17
    -0
      code/espurna/sensors/DallasSensor.h
  7. +2
    -2
      code/espurna/sensors/ECH1560Sensor.h
  8. +2
    -2
      code/espurna/sensors/EventSensor.h
  9. +2
    -2
      code/espurna/sensors/HLW8012Sensor.h

+ 6
- 2
code/espurna/config/hardware.h View File

@ -219,8 +219,12 @@
#define LED1_PIN_INVERSE 1 #define LED1_PIN_INVERSE 1
// Jack is connected to GPIO14 (and with a small hack to GPIO4) // Jack is connected to GPIO14 (and with a small hack to GPIO4)
#define I2C_SDA_PIN 4
#define I2C_SCL_PIN 14
#define DALLAS_SUPPORT 1
#define DALLAS_PIN 14
#define DHT_SUPPORT 1
#define DHT_PIN 14
//#define I2C_SDA_PIN 4
//#define I2C_SCL_PIN 14
#elif defined(ITEAD_SONOFF_SV) #elif defined(ITEAD_SONOFF_SV)


+ 7
- 0
code/espurna/config/prototypes.h View File

@ -56,6 +56,13 @@ unsigned char i2cFindAndLock(size_t size, unsigned char * addresses);
bool i2cGetLock(unsigned char address); bool i2cGetLock(unsigned char address);
bool i2cReleaseLock(unsigned char address); bool i2cReleaseLock(unsigned char address);
// -----------------------------------------------------------------------------
// GPIO
// -----------------------------------------------------------------------------
bool gpioValid(unsigned char gpio);
bool gpioGetLock(unsigned char gpio);
bool gpioReleaseLock(unsigned char gpio);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Debug // Debug
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------


+ 37
- 0
code/espurna/gpio.ino View File

@ -0,0 +1,37 @@
/*
GPIO MODULE
Copyright (C) 2017 by Xose Pérez <xose dot perez at gmail dot com>
*/
bool _gpio_locked[16] = {false};
bool gpioValid(unsigned char gpio) {
if (0 <= gpio && gpio <= 5) return true;
if (12 <= gpio && gpio <= 15) return true;
return false;
}
bool gpioGetLock(unsigned char gpio) {
if (gpioValid(gpio)) {
if (!_gpio_locked[gpio]) {
_gpio_locked[gpio] = true;
DEBUG_MSG_P(PSTR("[GPIO] GPIO%d locked\n"), gpio);
return true;
}
}
DEBUG_MSG_P(PSTR("[GPIO] Failed getting lock for GPIO%d\n"), gpio);
return false;
}
bool gpioReleaseLock(unsigned char gpio) {
if (gpioValid(gpio)) {
_gpio_locked[gpio] = false;
DEBUG_MSG_P(PSTR("[GPIO] GPIO%d lock released\n"), gpio);
return true;
}
DEBUG_MSG_P(PSTR("[GPIO] Failed releasing lock for GPIO%d\n"), gpio);
return false;
}

+ 1
- 7
code/espurna/sensors/BaseSensor.h View File

@ -48,6 +48,7 @@ typedef enum magnitude_t {
#define SENSOR_ERROR_UNKNOWN_ID 4 // Sensor did not report a known ID #define SENSOR_ERROR_UNKNOWN_ID 4 // Sensor did not report a known ID
#define SENSOR_ERROR_CRC 5 // Sensor data corrupted #define SENSOR_ERROR_CRC 5 // Sensor data corrupted
#define SENSOR_ERROR_I2C 6 // Wrong or locked I2C address #define SENSOR_ERROR_I2C 6 // Wrong or locked I2C address
#define SENSOR_ERROR_GPIO_USED 7 // The GPIO is already in use
class BaseSensor { class BaseSensor {
@ -106,13 +107,6 @@ class BaseSensor {
protected: protected:
// Check if valid GPIO
bool _validGPIO(unsigned char gpio) {
if (0 <= gpio && gpio <= 5) return true;
if (12 <= gpio && gpio <= 15) return true;
return false;
}
unsigned char _sensor_id = 0x00; unsigned char _sensor_id = 0x00;
int _error = 0; int _error = 0;
bool _dirty = true; bool _dirty = true;


+ 23
- 0
code/espurna/sensors/DHTSensor.h View File

@ -30,6 +30,10 @@ class DHTSensor : public BaseSensor {
_sensor_id = SENSOR_DHTXX_ID; _sensor_id = SENSOR_DHTXX_ID;
} }
~DHTSensor() {
if (_previous != 0xFF) gpioReleaseLock(_previous);
}
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
void setGPIO(unsigned char gpio) { void setGPIO(unsigned char gpio) {
@ -54,6 +58,24 @@ class DHTSensor : public BaseSensor {
// Sensor API // Sensor API
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// Initialization method, must be idempotent
void begin() {
_count = 0;
// Manage GPIO lock
if (_previous != 0xFF) gpioReleaseLock(_previous);
_previous = 0xFF;
if (!gpioGetLock(_gpio)) {
_error = SENSOR_ERROR_GPIO_USED;
return;
}
_previous = _gpio;
_count = 2;
}
// Pre-read hook (usually to populate registers with up-to-date data) // Pre-read hook (usually to populate registers with up-to-date data)
void pre() { void pre() {
_read(); _read();
@ -194,6 +216,7 @@ class DHTSensor : public BaseSensor {
} }
unsigned char _gpio; unsigned char _gpio;
unsigned char _previous = 0xFF;
unsigned char _type; unsigned char _type;
unsigned long _last_ok = 0; unsigned long _last_ok = 0;


+ 17
- 0
code/espurna/sensors/DallasSensor.h View File

@ -39,6 +39,7 @@ class DallasSensor : public BaseSensor {
~DallasSensor() { ~DallasSensor() {
if (_wire) delete _wire; if (_wire) delete _wire;
if (_previous != 0xFF) gpioReleaseLock(_previous);
} }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@ -65,6 +66,14 @@ class DallasSensor : public BaseSensor {
if (!_dirty) return; if (!_dirty) return;
_dirty = false; _dirty = false;
// Manage GPIO lock
if (_previous != 0xFF) gpioReleaseLock(_previous);
_previous = 0xFF;
if (!gpioGetLock(_gpio)) {
_error = SENSOR_ERROR_GPIO_USED;
return;
}
// OneWire // OneWire
if (_wire) delete _wire; if (_wire) delete _wire;
_wire = new OneWire(_gpio); _wire = new OneWire(_gpio);
@ -78,6 +87,13 @@ class DallasSensor : public BaseSensor {
loadDevices(); loadDevices();
} }
// Check connection
if (_count == 0) {
gpioReleaseLock(_gpio);
} else {
_previous = _gpio;
}
} }
// Loop-like method, call it in your main loop // Loop-like method, call it in your main loop
@ -281,6 +297,7 @@ class DallasSensor : public BaseSensor {
std::vector<ds_device_t> _devices; std::vector<ds_device_t> _devices;
unsigned char _gpio; unsigned char _gpio;
unsigned char _previous = 0xFF;
OneWire * _wire = NULL; OneWire * _wire = NULL;
}; };

+ 2
- 2
code/espurna/sensors/ECH1560Sensor.h View File

@ -303,7 +303,7 @@ static void (*_ech1560_sensor_isr_list[10])() = {
}; };
void ECH1560Sensor::_attach(ECH1560Sensor * instance, unsigned char gpio, unsigned char mode) { void ECH1560Sensor::_attach(ECH1560Sensor * instance, unsigned char gpio, unsigned char mode) {
if (!_validGPIO(gpio)) return;
if (!gpioValid(gpio)) return;
_detach(gpio); _detach(gpio);
unsigned char index = gpio > 5 ? gpio-6 : gpio; unsigned char index = gpio > 5 ? gpio-6 : gpio;
_ech1560_sensor_instance[index] = instance; _ech1560_sensor_instance[index] = instance;
@ -314,7 +314,7 @@ void ECH1560Sensor::_attach(ECH1560Sensor * instance, unsigned char gpio, unsign
} }
void ECH1560Sensor::_detach(unsigned char gpio) { void ECH1560Sensor::_detach(unsigned char gpio) {
if (!_validGPIO(gpio)) return;
if (!gpioValid(gpio)) return;
unsigned char index = gpio > 5 ? gpio-6 : gpio; unsigned char index = gpio > 5 ? gpio-6 : gpio;
if (_ech1560_sensor_instance[index]) { if (_ech1560_sensor_instance[index]) {
detachInterrupt(gpio); detachInterrupt(gpio);


+ 2
- 2
code/espurna/sensors/EventSensor.h View File

@ -177,7 +177,7 @@ static void (*_event_sensor_isr_list[10])() = {
}; };
void EventSensor::_attach(EventSensor * instance, unsigned char gpio, unsigned char mode) { void EventSensor::_attach(EventSensor * instance, unsigned char gpio, unsigned char mode) {
if (!_validGPIO(gpio)) return;
if (!gpioValid(gpio)) return;
_detach(gpio); _detach(gpio);
unsigned char index = gpio > 5 ? gpio-6 : gpio; unsigned char index = gpio > 5 ? gpio-6 : gpio;
_event_sensor_instance[index] = instance; _event_sensor_instance[index] = instance;
@ -188,7 +188,7 @@ void EventSensor::_attach(EventSensor * instance, unsigned char gpio, unsigned c
} }
void EventSensor::_detach(unsigned char gpio) { void EventSensor::_detach(unsigned char gpio) {
if (!_validGPIO(gpio)) return;
if (!gpioValid(gpio)) return;
unsigned char index = gpio > 5 ? gpio-6 : gpio; unsigned char index = gpio > 5 ? gpio-6 : gpio;
if (_event_sensor_instance[index]) { if (_event_sensor_instance[index]) {
detachInterrupt(gpio); detachInterrupt(gpio);


+ 2
- 2
code/espurna/sensors/HLW8012Sensor.h View File

@ -287,7 +287,7 @@ static void (*_hlw8012_sensor_isr_list[10])() = {
}; };
void HLW8012Sensor::_attach(HLW8012Sensor * instance, unsigned char gpio, unsigned char mode) { void HLW8012Sensor::_attach(HLW8012Sensor * instance, unsigned char gpio, unsigned char mode) {
if (!_validGPIO(gpio)) return;
if (!gpioValid(gpio)) return;
_detach(gpio); _detach(gpio);
unsigned char index = gpio > 5 ? gpio-6 : gpio; unsigned char index = gpio > 5 ? gpio-6 : gpio;
_hlw8012_sensor_instance[index] = instance; _hlw8012_sensor_instance[index] = instance;
@ -298,7 +298,7 @@ void HLW8012Sensor::_attach(HLW8012Sensor * instance, unsigned char gpio, unsign
} }
void HLW8012Sensor::_detach(unsigned char gpio) { void HLW8012Sensor::_detach(unsigned char gpio) {
if (!_validGPIO(gpio)) return;
if (!gpioValid(gpio)) return;
unsigned char index = gpio > 5 ? gpio-6 : gpio; unsigned char index = gpio > 5 ? gpio-6 : gpio;
if (_hlw8012_sensor_instance[index]) { if (_hlw8012_sensor_instance[index]) {
detachInterrupt(gpio); detachInterrupt(gpio);


Loading…
Cancel
Save