kopia lustrzana https://github.com/Aircoookie/WLED
				
				
				
			
		
			
				
	
	
		
			124 wiersze
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			124 wiersze
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C++
		
	
	
#ifndef WLED_PIN_MANAGER_H
 | 
						|
#define WLED_PIN_MANAGER_H
 | 
						|
/*
 | 
						|
 * Registers pins so there is no attempt for two interfaces to use the same pin
 | 
						|
 */
 | 
						|
#include <Arduino.h>
 | 
						|
#include "const.h" // for USERMOD_* values
 | 
						|
 | 
						|
typedef struct PinManagerPinType {
 | 
						|
  int8_t pin;
 | 
						|
  bool   isOutput;
 | 
						|
} managed_pin_type;
 | 
						|
 | 
						|
/*
 | 
						|
 * Allows PinManager to "lock" an allocation to a specific
 | 
						|
 * owner, so someone else doesn't accidentally de-allocate
 | 
						|
 * a pin it hasn't allocated.  Also enhances debugging.
 | 
						|
 *
 | 
						|
 * RAM Cost:
 | 
						|
 *     17 bytes on ESP8266
 | 
						|
 *     40 bytes on ESP32
 | 
						|
 */
 | 
						|
enum struct PinOwner : uint8_t {
 | 
						|
  None          = 0,      // default == legacy == unspecified owner
 | 
						|
  // High bit is set for all built-in pin owners
 | 
						|
  Ethernet      = 0x81,
 | 
						|
  BusDigital    = 0x82,
 | 
						|
  BusOnOff      = 0x83,
 | 
						|
  BusPwm        = 0x84,   // 'BusP' == PWM output using BusPwm
 | 
						|
  Button        = 0x85,   // 'Butn' == button from configuration
 | 
						|
  IR            = 0x86,   // 'IR'   == IR receiver pin from configuration
 | 
						|
  Relay         = 0x87,   // 'Rly'  == Relay pin from configuration
 | 
						|
  SPI_RAM       = 0x88,   // 'SpiR' == SPI RAM
 | 
						|
  DebugOut      = 0x89,   // 'Dbg'  == debug output always IO1
 | 
						|
  DMX           = 0x8A,   // 'DMX'  == hard-coded to IO2
 | 
						|
  HW_I2C        = 0x8B,   // 'I2C'  == hardware I2C pins (4&5 on ESP8266, 21&22 on ESP32)
 | 
						|
  HW_SPI        = 0x8C,   // 'SPI'  == hardware (V)SPI pins (13,14&15 on ESP8266, 5,18&23 on ESP32)
 | 
						|
  // Use UserMod IDs from const.h here
 | 
						|
  UM_Unspecified       = USERMOD_ID_UNSPECIFIED,        // 0x01
 | 
						|
  UM_Example           = USERMOD_ID_EXAMPLE,            // 0x02 // Usermod "usermod_v2_example.h"
 | 
						|
  UM_Temperature       = USERMOD_ID_TEMPERATURE,        // 0x03 // Usermod "usermod_temperature.h"
 | 
						|
  // #define USERMOD_ID_FIXNETSERVICES                  // 0x04 // Usermod "usermod_Fix_unreachable_netservices.h" -- Does not allocate pins
 | 
						|
  UM_PIR               = USERMOD_ID_PIRSWITCH,          // 0x05 // Usermod "usermod_PIR_sensor_switch.h"
 | 
						|
  // #define USERMOD_ID_IMU                             // 0x06 // Usermod "usermod_mpu6050_imu.h" -- Uses "standard" HW_I2C pins
 | 
						|
  UM_FourLineDisplay   = USERMOD_ID_FOUR_LINE_DISP,     // 0x07 // Usermod "usermod_v2_four_line_display.h -- May use "standard" HW_I2C pins
 | 
						|
  UM_RotaryEncoderUI   = USERMOD_ID_ROTARY_ENC_UI,      // 0x08 // Usermod "usermod_v2_rotary_encoder_ui.h"
 | 
						|
  // #define USERMOD_ID_AUTO_SAVE                       // 0x09 // Usermod "usermod_v2_auto_save.h" -- Does not allocate pins
 | 
						|
  // #define USERMOD_ID_DHT                             // 0x0A // Usermod "usermod_dht.h" -- Statically allocates pins, not compatible with pinManager?
 | 
						|
  // #define USERMOD_ID_MODE_SORT                       // 0x0B // Usermod "usermod_v2_mode_sort.h" -- Does not allocate pins
 | 
						|
  // #define USERMOD_ID_VL53L0X                         // 0x0C // Usermod "usermod_vl53l0x_gestures.h" -- Uses "standard" HW_I2C pins
 | 
						|
  UM_MultiRelay        = USERMOD_ID_MULTI_RELAY,        // 0x0D // Usermod "usermod_multi_relay.h"
 | 
						|
  UM_AnimatedStaircase = USERMOD_ID_ANIMATED_STAIRCASE, // 0x0E // Usermod "Animated_Staircase.h"
 | 
						|
  UM_Battery           = USERMOD_ID_BATTERY,            //
 | 
						|
  // #define USERMOD_ID_RTC                             // 0x0F // Usermod "usermod_rtc.h" -- Uses "standard" HW_I2C pins
 | 
						|
  // #define USERMOD_ID_ELEKSTUBE_IPS                   // 0x10 // Usermod "usermod_elekstube_ips.h" -- Uses quite a few pins ... see Hardware.h and User_Setup.h
 | 
						|
  // #define USERMOD_ID_SN_PHOTORESISTOR                // 0x11 // Usermod "usermod_sn_photoresistor.h" -- Uses hard-coded pin (PHOTORESISTOR_PIN == A0), but could be easily updated to use pinManager
 | 
						|
  UM_BH1750            = USERMOD_ID_BH1750,             // 0x14 // Usermod "usermod_bme280.h -- Uses "standard" HW_I2C pins
 | 
						|
  UM_RGBRotaryEncoder  = USERMOD_RGB_ROTARY_ENCODER,    // 0x16 // Usermod "rgb-rotary-encoder.h"
 | 
						|
  UM_QuinLEDAnPenta    = USERMOD_ID_QUINLED_AN_PENTA,   // 0x17 // Usermod "quinled-an-penta.h"
 | 
						|
  UM_BME280            = USERMOD_ID_BME280,             // 0x1E // Usermod "usermod_bme280.h -- Uses "standard" HW_I2C pins
 | 
						|
  UM_Audioreactive     = USERMOD_ID_AUDIOREACTIVE,      // 0x20 // Usermod "audio_reactive.h"
 | 
						|
  UM_SdCard            = USERMOD_ID_SD_CARD,            // 0x25 // Usermod "usermod_sd_card.h"
 | 
						|
  UM_PWM_OUTPUTS       = USERMOD_ID_PWM_OUTPUTS         // 0x26 // Usermod "usermod_pwm_outputs.h"
 | 
						|
};
 | 
						|
static_assert(0u == static_cast<uint8_t>(PinOwner::None), "PinOwner::None must be zero, so default array initialization works as expected");
 | 
						|
 | 
						|
class PinManagerClass {
 | 
						|
  private:
 | 
						|
  #ifdef ESP8266
 | 
						|
  #define WLED_NUM_PINS 17
 | 
						|
  uint8_t pinAlloc[3] = {0x00, 0x00, 0x00}; //24bit, 1 bit per pin, we use first 17bits
 | 
						|
  PinOwner ownerTag[WLED_NUM_PINS] = { PinOwner::None };
 | 
						|
  #else
 | 
						|
  #define WLED_NUM_PINS 50
 | 
						|
  uint8_t pinAlloc[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // 56bit, 1 bit per pin, we use 50 bits on ESP32-S3
 | 
						|
  uint8_t ledcAlloc[2] = {0x00, 0x00}; //16 LEDC channels
 | 
						|
  PinOwner ownerTag[WLED_NUM_PINS] = { PinOwner::None }; // new MCU's have up to 50 GPIO
 | 
						|
  #endif
 | 
						|
  struct {
 | 
						|
    uint8_t i2cAllocCount : 4; // allow multiple allocation of I2C bus pins but keep track of allocations
 | 
						|
    uint8_t spiAllocCount : 4; // allow multiple allocation of SPI bus pins but keep track of allocations
 | 
						|
  };
 | 
						|
 | 
						|
  public:
 | 
						|
  PinManagerClass() : i2cAllocCount(0), spiAllocCount(0) {}
 | 
						|
  // De-allocates a single pin
 | 
						|
  bool deallocatePin(byte gpio, PinOwner tag);
 | 
						|
  // De-allocates multiple pins but only if all can be deallocated (PinOwner has to be specified)
 | 
						|
  bool deallocateMultiplePins(const uint8_t *pinArray, byte arrayElementCount, PinOwner tag);
 | 
						|
  bool deallocateMultiplePins(const managed_pin_type *pinArray, byte arrayElementCount, PinOwner tag);
 | 
						|
  // Allocates a single pin, with an owner tag.
 | 
						|
  // De-allocation requires the same owner tag (or override)
 | 
						|
  bool allocatePin(byte gpio, bool output, PinOwner tag);
 | 
						|
  // Allocates all the pins, or allocates none of the pins, with owner tag.
 | 
						|
  // Provided to simplify error condition handling in clients
 | 
						|
  // using more than one pin, such as I2C, SPI, rotary encoders,
 | 
						|
  // ethernet, etc..
 | 
						|
  bool allocateMultiplePins(const managed_pin_type * mptArray, byte arrayElementCount, PinOwner tag );
 | 
						|
 | 
						|
  #if !defined(ESP8266) // ESP8266 compiler doesn't understand deprecated attribute
 | 
						|
  [[deprecated("Replaced by three-parameter allocatePin(gpio, output, ownerTag), for improved debugging")]]
 | 
						|
  #endif
 | 
						|
  inline bool allocatePin(byte gpio, bool output = true) { return allocatePin(gpio, output, PinOwner::None); }
 | 
						|
  #if !defined(ESP8266) // ESP8266 compiler doesn't understand deprecated attribute
 | 
						|
  [[deprecated("Replaced by two-parameter deallocatePin(gpio, ownerTag), for improved debugging")]]
 | 
						|
  #endif
 | 
						|
  inline void deallocatePin(byte gpio) { deallocatePin(gpio, PinOwner::None); }
 | 
						|
 | 
						|
  // will return true for reserved pins
 | 
						|
  bool isPinAllocated(byte gpio, PinOwner tag = PinOwner::None);
 | 
						|
  // will return false for reserved pins
 | 
						|
  bool isPinOk(byte gpio, bool output = true);
 | 
						|
 | 
						|
  PinOwner getPinOwner(byte gpio);
 | 
						|
 | 
						|
  #ifdef ARDUINO_ARCH_ESP32
 | 
						|
  byte allocateLedc(byte channels);
 | 
						|
  void deallocateLedc(byte pos, byte channels);
 | 
						|
  #endif
 | 
						|
};
 | 
						|
 | 
						|
extern PinManagerClass pinManager;
 | 
						|
#endif
 |