mirror of
https://github.com/SpacehuhnTech/esp8266_deauther.git
synced 2025-12-12 15:50:47 -08:00
Included necessary libraries locally
This commit is contained in:
@@ -11,29 +11,29 @@
|
||||
// ===== adjustable ===== //
|
||||
#if defined(SSD1306_I2C)
|
||||
#include <Wire.h>
|
||||
#include <SSD1306Wire.h>
|
||||
#include "src/esp8266-oled-ssd1306-4.1.0/SSD1306Wire.h"
|
||||
#elif defined(SSD1306_SPI)
|
||||
#include <SPI.h>
|
||||
#include <SSD1306Spi.h>
|
||||
#include "src/esp8266-oled-ssd1306-4.1.0/SSD1306Spi.h"
|
||||
#elif defined(SH1106_I2C)
|
||||
#include <Wire.h>
|
||||
#include <SH1106Wire.h>
|
||||
#include "src/esp8266-oled-ssd1306-4.1.0/SH1106Wire.h"
|
||||
#elif defined(SH1106_SPI)
|
||||
#include <SPI.h>
|
||||
#include <SH1106Spi.h>
|
||||
#include "src/esp8266-oled-ssd1306-4.1.0/SH1106Spi.h"
|
||||
#endif /* if defined(SSD1306_I2C) */
|
||||
|
||||
#ifdef RTC_DS3231
|
||||
#include <DS3231.h>
|
||||
#endif
|
||||
#include "src/DS3231-1.0.3/DS3231.h"
|
||||
#endif // ifdef RTC_DS3231
|
||||
|
||||
#include <SimpleButton.h>
|
||||
#include "src/SimpleButton/SimpleButton.h"
|
||||
|
||||
using namespace simplebutton;
|
||||
|
||||
|
||||
extern Names names;
|
||||
extern SSIDs ssids;
|
||||
extern Names names;
|
||||
extern SSIDs ssids;
|
||||
extern Accesspoints accesspoints;
|
||||
extern Stations stations;
|
||||
extern Scan scan;
|
||||
@@ -59,9 +59,9 @@ struct MenuNode {
|
||||
};
|
||||
|
||||
struct Menu {
|
||||
SimpleList<MenuNode>*list;
|
||||
Menu * parentMenu;
|
||||
uint8_t selected;
|
||||
SimpleList<MenuNode>* list;
|
||||
Menu * parentMenu;
|
||||
uint8_t selected;
|
||||
std::function<void()> build; // function that is executed when button is clicked
|
||||
};
|
||||
|
||||
@@ -69,8 +69,8 @@ class DisplayUI {
|
||||
public:
|
||||
enum DISPLAY_MODE { OFF = 0, BUTTON_TEST = 1, MENU = 2, LOADSCAN = 3, PACKETMONITOR = 4, INTRO = 5, CLOCK = 6 };
|
||||
|
||||
uint8_t mode = DISPLAY_MODE::MENU;
|
||||
bool highlightLED = false;
|
||||
uint8_t mode = DISPLAY_MODE::MENU;
|
||||
bool highlightLED = false;
|
||||
|
||||
Button* up = NULL;
|
||||
Button* down = NULL;
|
||||
@@ -88,10 +88,10 @@ class DisplayUI {
|
||||
SH1106Spi display = SH1106Spi(SPI_RES, SPI_DC, SPI_CS);
|
||||
#endif /* if defined(SSD1306_I2C) */
|
||||
|
||||
const uint8_t maxLen = 18;
|
||||
const uint8_t lineHeight = 12;
|
||||
const uint8_t buttonDelay = 250;
|
||||
const uint8_t drawInterval = 100; // 100ms = 10 FPS
|
||||
const uint8_t maxLen = 18;
|
||||
const uint8_t lineHeight = 12;
|
||||
const uint8_t buttonDelay = 250;
|
||||
const uint8_t drawInterval = 100; // 100ms = 10 FPS
|
||||
const uint16_t scrollSpeed = 500; // time interval in ms
|
||||
const uint16_t screenIntroTime = 2500;
|
||||
const uint16_t screenWidth = 128;
|
||||
@@ -191,7 +191,7 @@ class DisplayUI {
|
||||
|
||||
#ifdef RTC_DS3231
|
||||
DS3231 clock;
|
||||
#endif
|
||||
#endif // ifdef RTC_DS3231
|
||||
};
|
||||
|
||||
// ===== FONT ===== //
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
extern "C" {
|
||||
#include "user_interface.h"
|
||||
}
|
||||
#include "ArduinoJson.h"
|
||||
#include "src/ArduinoJson-v5.13.5/ArduinoJson.h"
|
||||
#include "language.h"
|
||||
#include "SimpleList.h"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
extern "C" {
|
||||
#include "user_interface.h"
|
||||
}
|
||||
#include "ArduinoJson.h"
|
||||
#include "src/ArduinoJson-v5.13.5/ArduinoJson.h"
|
||||
#include "language.h"
|
||||
#include "SimpleList.h"
|
||||
#include "Accesspoints.h"
|
||||
|
||||
@@ -14,7 +14,7 @@ extern "C" {
|
||||
|
||||
#include "EEPROMHelper.h"
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include "src/ArduinoJson-v5.13.5/ArduinoJson.h"
|
||||
#if ARDUINOJSON_VERSION_MAJOR != 5
|
||||
// The software was build using ArduinoJson v5.x
|
||||
// version 6 is still in beta at the time of writing
|
||||
@@ -37,8 +37,8 @@ extern "C" {
|
||||
#include "led.h"
|
||||
|
||||
// Run-Time Variables //
|
||||
Names names;
|
||||
SSIDs ssids;
|
||||
Names names;
|
||||
SSIDs ssids;
|
||||
Accesspoints accesspoints;
|
||||
Stations stations;
|
||||
Scan scan;
|
||||
@@ -63,9 +63,9 @@ void setup() {
|
||||
|
||||
// start SPIFFS
|
||||
prnt(SETUP_MOUNT_SPIFFS);
|
||||
//bool spiffsError = !LittleFS.begin();
|
||||
// bool spiffsError = !LittleFS.begin();
|
||||
LittleFS.begin();
|
||||
prntln(/*spiffsError ? SETUP_ERROR : */SETUP_OK);
|
||||
prntln(/*spiffsError ? SETUP_ERROR : */ SETUP_OK);
|
||||
|
||||
// Start EEPROM
|
||||
EEPROMHelper::begin(EEPROM_SIZE);
|
||||
@@ -83,7 +83,7 @@ void setup() {
|
||||
#endif // ifdef FORMAT_EEPROM
|
||||
|
||||
// Format SPIFFS when in boot-loop
|
||||
if (/*spiffsError || */!EEPROMHelper::checkBootNum(BOOT_COUNTER_ADDR)) {
|
||||
if (/*spiffsError || */ !EEPROMHelper::checkBootNum(BOOT_COUNTER_ADDR)) {
|
||||
prnt(SETUP_FORMAT_SPIFFS);
|
||||
LittleFS.format();
|
||||
prntln(SETUP_OK);
|
||||
@@ -118,7 +118,7 @@ void setup() {
|
||||
}
|
||||
|
||||
// copy web files to SPIFFS
|
||||
//copyWebFiles(false);
|
||||
// copyWebFiles(false);
|
||||
|
||||
// load everything else
|
||||
names.load();
|
||||
@@ -156,8 +156,8 @@ void setup() {
|
||||
void loop() {
|
||||
currentTime = millis();
|
||||
|
||||
led::update(); // update LED color
|
||||
wifi::update(); // manage access point
|
||||
led::update(); // update LED color
|
||||
wifi::update(); // manage access point
|
||||
attack.update(); // run attacks
|
||||
displayUI.update();
|
||||
cli.update(); // read and run serial input
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
extern "C" {
|
||||
#include "user_interface.h"
|
||||
}
|
||||
#include "ArduinoJson.h"
|
||||
#include "src/ArduinoJson-v5.13.5/ArduinoJson.h"
|
||||
|
||||
/*
|
||||
Here is a collection of useful functions and variables.
|
||||
@@ -196,6 +196,7 @@ bool eqls(const char* str, const char* keywordPtr) {
|
||||
if (strlen(str) > 255) return false; // when string too long
|
||||
|
||||
char keyword[strlen_P(keywordPtr) + 1];
|
||||
|
||||
strcpy_P(keyword, keywordPtr);
|
||||
|
||||
uint8_t lenStr = strlen(str);
|
||||
@@ -324,6 +325,7 @@ void setOutputPower(float dBm) {
|
||||
}
|
||||
|
||||
uint8_t val = (dBm * 4.0f);
|
||||
|
||||
system_phy_set_max_tpw(val);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,37 +3,37 @@
|
||||
This software is licensed under the MIT License. See the license file for details.
|
||||
Source: github.com/spacehuhn/esp8266_deauther
|
||||
*/
|
||||
|
||||
|
||||
#include "led.h"
|
||||
|
||||
#include "A_config.h" // Config for LEDs
|
||||
#include <Arduino.h> // digitalWrite, analogWrite, pinMode
|
||||
#include <Arduino.h> // digitalWrite, analogWrite, pinMode
|
||||
#include "language.h" // Strings used in printColor and tempDisable
|
||||
#include "settings.h" // used in update()
|
||||
#include "Attack.h" // used in update()
|
||||
#include "Scan.h" // used in update()
|
||||
#include "Attack.h" // used in update()
|
||||
#include "Scan.h" // used in update()
|
||||
|
||||
// Inlcude libraries for Neopixel or LED_MY92xx if used
|
||||
#if defined(LED_NEOPIXEL)
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
#include "src/Adafruit_NeoPixel-1.7.0/Adafruit_NeoPixel.h"
|
||||
#elif defined(LED_MY92)
|
||||
#include <my92xx.h>
|
||||
#include "src/my92xx-3.0.3/my92xx.h"
|
||||
#endif // if defined(LED_NEOPIXEL)
|
||||
|
||||
extern Attack attack;
|
||||
extern Scan scan;
|
||||
extern Attack attack;
|
||||
extern Scan scan;
|
||||
|
||||
namespace led {
|
||||
// ===== PRIVATE ===== //
|
||||
LED_MODE mode = OFF;
|
||||
|
||||
#if defined(LED_NEOPIXEL_RGB)
|
||||
Adafruit_NeoPixel strip {LED_NEOPIXEL_NUM, LED_NEOPIXEL_PIN, NEO_RGB + NEO_KHZ400};
|
||||
Adafruit_NeoPixel strip { LED_NEOPIXEL_NUM, LED_NEOPIXEL_PIN, NEO_RGB + NEO_KHZ400 };
|
||||
#elif defined(LED_NEOPIXEL_GRB)
|
||||
Adafruit_NeoPixel strip {LED_NEOPIXEL_NUM, LED_NEOPIXEL_PIN, NEO_GRB + NEO_KHZ400};
|
||||
Adafruit_NeoPixel strip { LED_NEOPIXEL_NUM, LED_NEOPIXEL_PIN, NEO_GRB + NEO_KHZ400 };
|
||||
#elif defined(LED_MY92)
|
||||
my92xx myled {LED_MY92_MODEL, LED_MY92_NUM, LED_MY92_DATA, LED_MY92_CLK, MY92XX_COMMAND_DEFAULT};
|
||||
#endif
|
||||
my92xx myled { LED_MY92_MODEL, LED_MY92_NUM, LED_MY92_DATA, LED_MY92_CLK, MY92XX_COMMAND_DEFAULT };
|
||||
#endif // if defined(LED_NEOPIXEL_RGB)
|
||||
|
||||
|
||||
void setColor(uint8_t r, uint8_t g, uint8_t b) {
|
||||
@@ -83,20 +83,20 @@ namespace led {
|
||||
analogWriteRange(0xff);
|
||||
|
||||
#if defined(LED_DIGITAL) || defined(LED_RGB)
|
||||
if (LED_PIN_R < 255) pinMode(LED_PIN_R, OUTPUT);
|
||||
if (LED_PIN_G < 255) pinMode(LED_PIN_G, OUTPUT);
|
||||
if (LED_PIN_B < 255) pinMode(LED_PIN_B, OUTPUT);
|
||||
if (LED_PIN_R < 255) pinMode(LED_PIN_R, OUTPUT);
|
||||
if (LED_PIN_G < 255) pinMode(LED_PIN_G, OUTPUT);
|
||||
if (LED_PIN_B < 255) pinMode(LED_PIN_B, OUTPUT);
|
||||
#elif defined(LED_NEOPIXEL)
|
||||
strip.begin();
|
||||
strip.setBrightness(LED_MODE_BRIGHTNESS);
|
||||
strip.show();
|
||||
strip.begin();
|
||||
strip.setBrightness(LED_MODE_BRIGHTNESS);
|
||||
strip.show();
|
||||
#elif defined(LED_MY9291)
|
||||
myled.setChannel(LED_MY92_CH_R, 0);
|
||||
myled.setChannel(LED_MY92_CH_G, 0);
|
||||
myled.setChannel(LED_MY92_CH_B, 0);
|
||||
myled.setChannel(LED_MY92_CH_BRIGHTNESS, LED_MODE_BRIGHTNESS);
|
||||
myled.setState(true);
|
||||
myled.update();
|
||||
myled.setChannel(LED_MY92_CH_R, 0);
|
||||
myled.setChannel(LED_MY92_CH_G, 0);
|
||||
myled.setChannel(LED_MY92_CH_B, 0);
|
||||
myled.setChannel(LED_MY92_CH_BRIGHTNESS, LED_MODE_BRIGHTNESS);
|
||||
myled.setState(true);
|
||||
myled.update();
|
||||
#endif // if defined(LED_DIGITAL) || defined(LED_RGB)
|
||||
}
|
||||
|
||||
|
||||
2601
esp8266_deauther/src/Adafruit_NeoPixel-1.7.0/Adafruit_NeoPixel.cpp
Normal file
2601
esp8266_deauther/src/Adafruit_NeoPixel-1.7.0/Adafruit_NeoPixel.cpp
Normal file
File diff suppressed because it is too large
Load Diff
366
esp8266_deauther/src/Adafruit_NeoPixel-1.7.0/Adafruit_NeoPixel.h
Normal file
366
esp8266_deauther/src/Adafruit_NeoPixel-1.7.0/Adafruit_NeoPixel.h
Normal file
@@ -0,0 +1,366 @@
|
||||
/*!
|
||||
* @file Adafruit_NeoPixel.h
|
||||
*
|
||||
* This is part of Adafruit's NeoPixel library for the Arduino platform,
|
||||
* allowing a broad range of microcontroller boards (most AVR boards,
|
||||
* many ARM devices, ESP8266 and ESP32, among others) to control Adafruit
|
||||
* NeoPixels, FLORA RGB Smart Pixels and compatible devices -- WS2811,
|
||||
* WS2812, WS2812B, SK6812, etc.
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing products
|
||||
* from Adafruit!
|
||||
*
|
||||
* Written by Phil "Paint Your Dragon" Burgess for Adafruit Industries,
|
||||
* with contributions by PJRC, Michael Miller and other members of the
|
||||
* open source community.
|
||||
*
|
||||
* This file is part of the Adafruit_NeoPixel library.
|
||||
*
|
||||
* Adafruit_NeoPixel is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Adafruit_NeoPixel 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with NeoPixel. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ADAFRUIT_NEOPIXEL_H
|
||||
#define ADAFRUIT_NEOPIXEL_H
|
||||
|
||||
#ifdef ARDUINO
|
||||
#if (ARDUINO >= 100)
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#include <pins_arduino.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_LPC1768
|
||||
#include <Arduino.h>
|
||||
#endif
|
||||
|
||||
// The order of primary colors in the NeoPixel data stream can vary among
|
||||
// device types, manufacturers and even different revisions of the same
|
||||
// item. The third parameter to the Adafruit_NeoPixel constructor encodes
|
||||
// the per-pixel byte offsets of the red, green and blue primaries (plus
|
||||
// white, if present) in the data stream -- the following #defines provide
|
||||
// an easier-to-use named version for each permutation. e.g. NEO_GRB
|
||||
// indicates a NeoPixel-compatible device expecting three bytes per pixel,
|
||||
// with the first byte transmitted containing the green value, second
|
||||
// containing red and third containing blue. The in-memory representation
|
||||
// of a chain of NeoPixels is the same as the data-stream order; no
|
||||
// re-ordering of bytes is required when issuing data to the chain.
|
||||
// Most of these values won't exist in real-world devices, but it's done
|
||||
// this way so we're ready for it (also, if using the WS2811 driver IC,
|
||||
// one might have their pixels set up in any weird permutation).
|
||||
|
||||
// Bits 5,4 of this value are the offset (0-3) from the first byte of a
|
||||
// pixel to the location of the red color byte. Bits 3,2 are the green
|
||||
// offset and 1,0 are the blue offset. If it is an RGBW-type device
|
||||
// (supporting a white primary in addition to R,G,B), bits 7,6 are the
|
||||
// offset to the white byte...otherwise, bits 7,6 are set to the same value
|
||||
// as 5,4 (red) to indicate an RGB (not RGBW) device.
|
||||
// i.e. binary representation:
|
||||
// 0bWWRRGGBB for RGBW devices
|
||||
// 0bRRRRGGBB for RGB
|
||||
|
||||
// RGB NeoPixel permutations; white and red offsets are always same
|
||||
// Offset: W R G B
|
||||
#define NEO_RGB ((0<<6) | (0<<4) | (1<<2) | (2)) ///< Transmit as R,G,B
|
||||
#define NEO_RBG ((0<<6) | (0<<4) | (2<<2) | (1)) ///< Transmit as R,B,G
|
||||
#define NEO_GRB ((1<<6) | (1<<4) | (0<<2) | (2)) ///< Transmit as G,R,B
|
||||
#define NEO_GBR ((2<<6) | (2<<4) | (0<<2) | (1)) ///< Transmit as G,B,R
|
||||
#define NEO_BRG ((1<<6) | (1<<4) | (2<<2) | (0)) ///< Transmit as B,R,G
|
||||
#define NEO_BGR ((2<<6) | (2<<4) | (1<<2) | (0)) ///< Transmit as B,G,R
|
||||
|
||||
// RGBW NeoPixel permutations; all 4 offsets are distinct
|
||||
// Offset: W R G B
|
||||
#define NEO_WRGB ((0<<6) | (1<<4) | (2<<2) | (3)) ///< Transmit as W,R,G,B
|
||||
#define NEO_WRBG ((0<<6) | (1<<4) | (3<<2) | (2)) ///< Transmit as W,R,B,G
|
||||
#define NEO_WGRB ((0<<6) | (2<<4) | (1<<2) | (3)) ///< Transmit as W,G,R,B
|
||||
#define NEO_WGBR ((0<<6) | (3<<4) | (1<<2) | (2)) ///< Transmit as W,G,B,R
|
||||
#define NEO_WBRG ((0<<6) | (2<<4) | (3<<2) | (1)) ///< Transmit as W,B,R,G
|
||||
#define NEO_WBGR ((0<<6) | (3<<4) | (2<<2) | (1)) ///< Transmit as W,B,G,R
|
||||
|
||||
#define NEO_RWGB ((1<<6) | (0<<4) | (2<<2) | (3)) ///< Transmit as R,W,G,B
|
||||
#define NEO_RWBG ((1<<6) | (0<<4) | (3<<2) | (2)) ///< Transmit as R,W,B,G
|
||||
#define NEO_RGWB ((2<<6) | (0<<4) | (1<<2) | (3)) ///< Transmit as R,G,W,B
|
||||
#define NEO_RGBW ((3<<6) | (0<<4) | (1<<2) | (2)) ///< Transmit as R,G,B,W
|
||||
#define NEO_RBWG ((2<<6) | (0<<4) | (3<<2) | (1)) ///< Transmit as R,B,W,G
|
||||
#define NEO_RBGW ((3<<6) | (0<<4) | (2<<2) | (1)) ///< Transmit as R,B,G,W
|
||||
|
||||
#define NEO_GWRB ((1<<6) | (2<<4) | (0<<2) | (3)) ///< Transmit as G,W,R,B
|
||||
#define NEO_GWBR ((1<<6) | (3<<4) | (0<<2) | (2)) ///< Transmit as G,W,B,R
|
||||
#define NEO_GRWB ((2<<6) | (1<<4) | (0<<2) | (3)) ///< Transmit as G,R,W,B
|
||||
#define NEO_GRBW ((3<<6) | (1<<4) | (0<<2) | (2)) ///< Transmit as G,R,B,W
|
||||
#define NEO_GBWR ((2<<6) | (3<<4) | (0<<2) | (1)) ///< Transmit as G,B,W,R
|
||||
#define NEO_GBRW ((3<<6) | (2<<4) | (0<<2) | (1)) ///< Transmit as G,B,R,W
|
||||
|
||||
#define NEO_BWRG ((1<<6) | (2<<4) | (3<<2) | (0)) ///< Transmit as B,W,R,G
|
||||
#define NEO_BWGR ((1<<6) | (3<<4) | (2<<2) | (0)) ///< Transmit as B,W,G,R
|
||||
#define NEO_BRWG ((2<<6) | (1<<4) | (3<<2) | (0)) ///< Transmit as B,R,W,G
|
||||
#define NEO_BRGW ((3<<6) | (1<<4) | (2<<2) | (0)) ///< Transmit as B,R,G,W
|
||||
#define NEO_BGWR ((2<<6) | (3<<4) | (1<<2) | (0)) ///< Transmit as B,G,W,R
|
||||
#define NEO_BGRW ((3<<6) | (2<<4) | (1<<2) | (0)) ///< Transmit as B,G,R,W
|
||||
|
||||
// Add NEO_KHZ400 to the color order value to indicate a 400 KHz device.
|
||||
// All but the earliest v1 NeoPixels expect an 800 KHz data stream, this is
|
||||
// the default if unspecified. Because flash space is very limited on ATtiny
|
||||
// devices (e.g. Trinket, Gemma), v1 NeoPixels aren't handled by default on
|
||||
// those chips, though it can be enabled by removing the ifndef/endif below,
|
||||
// but code will be bigger. Conversely, can disable the NEO_KHZ400 line on
|
||||
// other MCUs to remove v1 support and save a little space.
|
||||
|
||||
#define NEO_KHZ800 0x0000 ///< 800 KHz data transmission
|
||||
#ifndef __AVR_ATtiny85__
|
||||
#define NEO_KHZ400 0x0100 ///< 400 KHz data transmission
|
||||
#endif
|
||||
|
||||
// If 400 KHz support is enabled, the third parameter to the constructor
|
||||
// requires a 16-bit value (in order to select 400 vs 800 KHz speed).
|
||||
// If only 800 KHz is enabled (as is default on ATtiny), an 8-bit value
|
||||
// is sufficient to encode pixel color order, saving some space.
|
||||
|
||||
#ifdef NEO_KHZ400
|
||||
typedef uint16_t neoPixelType; ///< 3rd arg to Adafruit_NeoPixel constructor
|
||||
#else
|
||||
typedef uint8_t neoPixelType; ///< 3rd arg to Adafruit_NeoPixel constructor
|
||||
#endif
|
||||
|
||||
// These two tables are declared outside the Adafruit_NeoPixel class
|
||||
// because some boards may require oldschool compilers that don't
|
||||
// handle the C++11 constexpr keyword.
|
||||
|
||||
/* A PROGMEM (flash mem) table containing 8-bit unsigned sine wave (0-255).
|
||||
Copy & paste this snippet into a Python REPL to regenerate:
|
||||
import math
|
||||
for x in range(256):
|
||||
print("{:3},".format(int((math.sin(x/128.0*math.pi)+1.0)*127.5+0.5))),
|
||||
if x&15 == 15: print
|
||||
*/
|
||||
static const uint8_t PROGMEM _NeoPixelSineTable[256] = {
|
||||
128,131,134,137,140,143,146,149,152,155,158,162,165,167,170,173,
|
||||
176,179,182,185,188,190,193,196,198,201,203,206,208,211,213,215,
|
||||
218,220,222,224,226,228,230,232,234,235,237,238,240,241,243,244,
|
||||
245,246,248,249,250,250,251,252,253,253,254,254,254,255,255,255,
|
||||
255,255,255,255,254,254,254,253,253,252,251,250,250,249,248,246,
|
||||
245,244,243,241,240,238,237,235,234,232,230,228,226,224,222,220,
|
||||
218,215,213,211,208,206,203,201,198,196,193,190,188,185,182,179,
|
||||
176,173,170,167,165,162,158,155,152,149,146,143,140,137,134,131,
|
||||
128,124,121,118,115,112,109,106,103,100, 97, 93, 90, 88, 85, 82,
|
||||
79, 76, 73, 70, 67, 65, 62, 59, 57, 54, 52, 49, 47, 44, 42, 40,
|
||||
37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11,
|
||||
10, 9, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9,
|
||||
10, 11, 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35,
|
||||
37, 40, 42, 44, 47, 49, 52, 54, 57, 59, 62, 65, 67, 70, 73, 76,
|
||||
79, 82, 85, 88, 90, 93, 97,100,103,106,109,112,115,118,121,124};
|
||||
|
||||
/* Similar to above, but for an 8-bit gamma-correction table.
|
||||
Copy & paste this snippet into a Python REPL to regenerate:
|
||||
import math
|
||||
gamma=2.6
|
||||
for x in range(256):
|
||||
print("{:3},".format(int(math.pow((x)/255.0,gamma)*255.0+0.5))),
|
||||
if x&15 == 15: print
|
||||
*/
|
||||
static const uint8_t PROGMEM _NeoPixelGammaTable[256] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
|
||||
3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7,
|
||||
7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12,
|
||||
13, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20,
|
||||
20, 21, 21, 22, 22, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29,
|
||||
30, 31, 31, 32, 33, 34, 34, 35, 36, 37, 38, 38, 39, 40, 41, 42,
|
||||
42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
|
||||
58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70, 71, 72, 73, 75,
|
||||
76, 77, 78, 80, 81, 82, 84, 85, 86, 88, 89, 90, 92, 93, 94, 96,
|
||||
97, 99,100,102,103,105,106,108,109,111,112,114,115,117,119,120,
|
||||
122,124,125,127,129,130,132,134,136,137,139,141,143,145,146,148,
|
||||
150,152,154,156,158,160,162,164,166,168,170,172,174,176,178,180,
|
||||
182,184,186,188,191,193,195,197,199,202,204,206,209,211,213,215,
|
||||
218,220,223,225,227,230,232,235,237,240,242,245,247,250,252,255};
|
||||
|
||||
/*!
|
||||
@brief Class that stores state and functions for interacting with
|
||||
Adafruit NeoPixels and compatible devices.
|
||||
*/
|
||||
class Adafruit_NeoPixel {
|
||||
|
||||
public:
|
||||
|
||||
// Constructor: number of LEDs, pin number, LED type
|
||||
Adafruit_NeoPixel(uint16_t n, uint16_t pin=6,
|
||||
neoPixelType type=NEO_GRB + NEO_KHZ800);
|
||||
Adafruit_NeoPixel(void);
|
||||
~Adafruit_NeoPixel();
|
||||
|
||||
void begin(void);
|
||||
void show(void);
|
||||
void setPin(uint16_t p);
|
||||
void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
|
||||
void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b,
|
||||
uint8_t w);
|
||||
void setPixelColor(uint16_t n, uint32_t c);
|
||||
void fill(uint32_t c=0, uint16_t first=0, uint16_t count=0);
|
||||
void setBrightness(uint8_t);
|
||||
void clear(void);
|
||||
void updateLength(uint16_t n);
|
||||
void updateType(neoPixelType t);
|
||||
/*!
|
||||
@brief Check whether a call to show() will start sending data
|
||||
immediately or will 'block' for a required interval. NeoPixels
|
||||
require a short quiet time (about 300 microseconds) after the
|
||||
last bit is received before the data 'latches' and new data can
|
||||
start being received. Usually one's sketch is implicitly using
|
||||
this time to generate a new frame of animation...but if it
|
||||
finishes very quickly, this function could be used to see if
|
||||
there's some idle time available for some low-priority
|
||||
concurrent task.
|
||||
@return 1 or true if show() will start sending immediately, 0 or false
|
||||
if show() would block (meaning some idle time is available).
|
||||
*/
|
||||
bool canShow(void) {
|
||||
if (endTime > micros()) {
|
||||
endTime = micros();
|
||||
}
|
||||
return (micros() - endTime) >= 300L;
|
||||
}
|
||||
/*!
|
||||
@brief Get a pointer directly to the NeoPixel data buffer in RAM.
|
||||
Pixel data is stored in a device-native format (a la the NEO_*
|
||||
constants) and is not translated here. Applications that access
|
||||
this buffer will need to be aware of the specific data format
|
||||
and handle colors appropriately.
|
||||
@return Pointer to NeoPixel buffer (uint8_t* array).
|
||||
@note This is for high-performance applications where calling
|
||||
setPixelColor() on every single pixel would be too slow (e.g.
|
||||
POV or light-painting projects). There is no bounds checking
|
||||
on the array, creating tremendous potential for mayhem if one
|
||||
writes past the ends of the buffer. Great power, great
|
||||
responsibility and all that.
|
||||
*/
|
||||
uint8_t *getPixels(void) const { return pixels; };
|
||||
uint8_t getBrightness(void) const;
|
||||
/*!
|
||||
@brief Retrieve the pin number used for NeoPixel data output.
|
||||
@return Arduino pin number (-1 if not set).
|
||||
*/
|
||||
int16_t getPin(void) const { return pin; };
|
||||
/*!
|
||||
@brief Return the number of pixels in an Adafruit_NeoPixel strip object.
|
||||
@return Pixel count (0 if not set).
|
||||
*/
|
||||
uint16_t numPixels(void) const { return numLEDs; }
|
||||
uint32_t getPixelColor(uint16_t n) const;
|
||||
/*!
|
||||
@brief An 8-bit integer sine wave function, not directly compatible
|
||||
with standard trigonometric units like radians or degrees.
|
||||
@param x Input angle, 0-255; 256 would loop back to zero, completing
|
||||
the circle (equivalent to 360 degrees or 2 pi radians).
|
||||
One can therefore use an unsigned 8-bit variable and simply
|
||||
add or subtract, allowing it to overflow/underflow and it
|
||||
still does the expected contiguous thing.
|
||||
@return Sine result, 0 to 255, or -128 to +127 if type-converted to
|
||||
a signed int8_t, but you'll most likely want unsigned as this
|
||||
output is often used for pixel brightness in animation effects.
|
||||
*/
|
||||
static uint8_t sine8(uint8_t x) {
|
||||
return pgm_read_byte(&_NeoPixelSineTable[x]); // 0-255 in, 0-255 out
|
||||
}
|
||||
/*!
|
||||
@brief An 8-bit gamma-correction function for basic pixel brightness
|
||||
adjustment. Makes color transitions appear more perceptially
|
||||
correct.
|
||||
@param x Input brightness, 0 (minimum or off/black) to 255 (maximum).
|
||||
@return Gamma-adjusted brightness, can then be passed to one of the
|
||||
setPixelColor() functions. This uses a fixed gamma correction
|
||||
exponent of 2.6, which seems reasonably okay for average
|
||||
NeoPixels in average tasks. If you need finer control you'll
|
||||
need to provide your own gamma-correction function instead.
|
||||
*/
|
||||
static uint8_t gamma8(uint8_t x) {
|
||||
return pgm_read_byte(&_NeoPixelGammaTable[x]); // 0-255 in, 0-255 out
|
||||
}
|
||||
/*!
|
||||
@brief Convert separate red, green and blue values into a single
|
||||
"packed" 32-bit RGB color.
|
||||
@param r Red brightness, 0 to 255.
|
||||
@param g Green brightness, 0 to 255.
|
||||
@param b Blue brightness, 0 to 255.
|
||||
@return 32-bit packed RGB value, which can then be assigned to a
|
||||
variable for later use or passed to the setPixelColor()
|
||||
function. Packed RGB format is predictable, regardless of
|
||||
LED strand color order.
|
||||
*/
|
||||
static uint32_t Color(uint8_t r, uint8_t g, uint8_t b) {
|
||||
return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
|
||||
}
|
||||
/*!
|
||||
@brief Convert separate red, green, blue and white values into a
|
||||
single "packed" 32-bit WRGB color.
|
||||
@param r Red brightness, 0 to 255.
|
||||
@param g Green brightness, 0 to 255.
|
||||
@param b Blue brightness, 0 to 255.
|
||||
@param w White brightness, 0 to 255.
|
||||
@return 32-bit packed WRGB value, which can then be assigned to a
|
||||
variable for later use or passed to the setPixelColor()
|
||||
function. Packed WRGB format is predictable, regardless of
|
||||
LED strand color order.
|
||||
*/
|
||||
static uint32_t Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
||||
return ((uint32_t)w << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
|
||||
}
|
||||
static uint32_t ColorHSV(uint16_t hue, uint8_t sat=255, uint8_t val=255);
|
||||
/*!
|
||||
@brief A gamma-correction function for 32-bit packed RGB or WRGB
|
||||
colors. Makes color transitions appear more perceptially
|
||||
correct.
|
||||
@param x 32-bit packed RGB or WRGB color.
|
||||
@return Gamma-adjusted packed color, can then be passed in one of the
|
||||
setPixelColor() functions. Like gamma8(), this uses a fixed
|
||||
gamma correction exponent of 2.6, which seems reasonably okay
|
||||
for average NeoPixels in average tasks. If you need finer
|
||||
control you'll need to provide your own gamma-correction
|
||||
function instead.
|
||||
*/
|
||||
static uint32_t gamma32(uint32_t x);
|
||||
|
||||
protected:
|
||||
|
||||
#ifdef NEO_KHZ400 // If 400 KHz NeoPixel support enabled...
|
||||
bool is800KHz; ///< true if 800 KHz pixels
|
||||
#endif
|
||||
bool begun; ///< true if begin() previously called
|
||||
uint16_t numLEDs; ///< Number of RGB LEDs in strip
|
||||
uint16_t numBytes; ///< Size of 'pixels' buffer below
|
||||
int16_t pin; ///< Output pin number (-1 if not yet set)
|
||||
uint8_t brightness; ///< Strip brightness 0-255 (stored as +1)
|
||||
uint8_t *pixels; ///< Holds LED color values (3 or 4 bytes each)
|
||||
uint8_t rOffset; ///< Red index within each 3- or 4-byte pixel
|
||||
uint8_t gOffset; ///< Index of green byte
|
||||
uint8_t bOffset; ///< Index of blue byte
|
||||
uint8_t wOffset; ///< Index of white (==rOffset if no white)
|
||||
uint32_t endTime; ///< Latch timing reference
|
||||
#ifdef __AVR__
|
||||
volatile uint8_t *port; ///< Output PORT register
|
||||
uint8_t pinMask; ///< Output PORT bitmask
|
||||
#endif
|
||||
#if defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_ARDUINO_CORE_STM32)
|
||||
GPIO_TypeDef *gpioPort; ///< Output GPIO PORT
|
||||
uint32_t gpioPin; ///< Output GPIO PIN
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // ADAFRUIT_NEOPIXEL_H
|
||||
165
esp8266_deauther/src/Adafruit_NeoPixel-1.7.0/COPYING
Normal file
165
esp8266_deauther/src/Adafruit_NeoPixel-1.7.0/COPYING
Normal file
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
86
esp8266_deauther/src/Adafruit_NeoPixel-1.7.0/esp8266.c
Normal file
86
esp8266_deauther/src/Adafruit_NeoPixel-1.7.0/esp8266.c
Normal file
@@ -0,0 +1,86 @@
|
||||
// This is a mash-up of the Due show() code + insights from Michael Miller's
|
||||
// ESP8266 work for the NeoPixelBus library: github.com/Makuna/NeoPixelBus
|
||||
// Needs to be a separate .c file to enforce ICACHE_RAM_ATTR execution.
|
||||
|
||||
#if defined(ESP8266)
|
||||
|
||||
#include <Arduino.h>
|
||||
#ifdef ESP8266
|
||||
#include <eagle_soc.h>
|
||||
#endif
|
||||
|
||||
static uint32_t _getCycleCount(void) __attribute__((always_inline));
|
||||
static inline uint32_t _getCycleCount(void) {
|
||||
uint32_t ccount;
|
||||
__asm__ __volatile__("rsr %0,ccount":"=a" (ccount));
|
||||
return ccount;
|
||||
}
|
||||
|
||||
#ifdef ESP8266
|
||||
void ICACHE_RAM_ATTR espShow(
|
||||
uint8_t pin, uint8_t *pixels, uint32_t numBytes, boolean is800KHz) {
|
||||
#else
|
||||
void espShow(
|
||||
uint8_t pin, uint8_t *pixels, uint32_t numBytes, boolean is800KHz) {
|
||||
#endif
|
||||
|
||||
#define CYCLES_800_T0H (F_CPU / 2500000) // 0.4us
|
||||
#define CYCLES_800_T1H (F_CPU / 1250000) // 0.8us
|
||||
#define CYCLES_800 (F_CPU / 800000) // 1.25us per bit
|
||||
#define CYCLES_400_T0H (F_CPU / 2000000) // 0.5uS
|
||||
#define CYCLES_400_T1H (F_CPU / 833333) // 1.2us
|
||||
#define CYCLES_400 (F_CPU / 400000) // 2.5us per bit
|
||||
|
||||
uint8_t *p, *end, pix, mask;
|
||||
uint32_t t, time0, time1, period, c, startTime;
|
||||
|
||||
#ifdef ESP8266
|
||||
uint32_t pinMask;
|
||||
pinMask = _BV(pin);
|
||||
#endif
|
||||
|
||||
p = pixels;
|
||||
end = p + numBytes;
|
||||
pix = *p++;
|
||||
mask = 0x80;
|
||||
startTime = 0;
|
||||
|
||||
#ifdef NEO_KHZ400
|
||||
if(is800KHz) {
|
||||
#endif
|
||||
time0 = CYCLES_800_T0H;
|
||||
time1 = CYCLES_800_T1H;
|
||||
period = CYCLES_800;
|
||||
#ifdef NEO_KHZ400
|
||||
} else { // 400 KHz bitstream
|
||||
time0 = CYCLES_400_T0H;
|
||||
time1 = CYCLES_400_T1H;
|
||||
period = CYCLES_400;
|
||||
}
|
||||
#endif
|
||||
|
||||
for(t = time0;; t = time0) {
|
||||
if(pix & mask) t = time1; // Bit high duration
|
||||
while(((c = _getCycleCount()) - startTime) < period); // Wait for bit start
|
||||
#ifdef ESP8266
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pinMask); // Set high
|
||||
#else
|
||||
gpio_set_level(pin, HIGH);
|
||||
#endif
|
||||
startTime = c; // Save start time
|
||||
while(((c = _getCycleCount()) - startTime) < t); // Wait high duration
|
||||
#ifdef ESP8266
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinMask); // Set low
|
||||
#else
|
||||
gpio_set_level(pin, LOW);
|
||||
#endif
|
||||
if(!(mask >>= 1)) { // Next bit/byte
|
||||
if(p >= end) break;
|
||||
pix = *p++;
|
||||
mask = 0x80;
|
||||
}
|
||||
}
|
||||
while((_getCycleCount() - startTime) < period); // Wait for last bit
|
||||
}
|
||||
|
||||
#endif // ESP8266
|
||||
3429
esp8266_deauther/src/ArduinoJson-v5.13.5/ArduinoJson.h
Normal file
3429
esp8266_deauther/src/ArduinoJson-v5.13.5/ArduinoJson.h
Normal file
File diff suppressed because it is too large
Load Diff
738
esp8266_deauther/src/DS3231-1.0.3/DS3231.cpp
Normal file
738
esp8266_deauther/src/DS3231-1.0.3/DS3231.cpp
Normal file
@@ -0,0 +1,738 @@
|
||||
/*
|
||||
DS3231.cpp: DS3231 Real-Time Clock library
|
||||
Eric Ayars
|
||||
4/1/11
|
||||
|
||||
Spliced in DateTime all-at-once reading (to avoid rollover) and unix time
|
||||
from Jean-Claude Wippler and Limor Fried
|
||||
Andy Wickert
|
||||
5/15/11
|
||||
|
||||
Fixed problem with SD processors(no function call) by replacing all occurences of the term PM, which
|
||||
is defined as a macro on SAMD controllers by PM_time.
|
||||
Simon Gassner
|
||||
11/28/2017
|
||||
|
||||
|
||||
Released into the public domain.
|
||||
*/
|
||||
|
||||
#include "DS3231.h"
|
||||
|
||||
// These included for the DateTime class inclusion; will try to find a way to
|
||||
// not need them in the future...
|
||||
#if defined(__AVR__)
|
||||
#include <avr/pgmspace.h>
|
||||
#elif defined(ESP8266)
|
||||
#include <pgmspace.h>
|
||||
#endif // if defined(__AVR__)
|
||||
// Changed the following to work on 1.0
|
||||
// #include "WProgram.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
|
||||
#define CLOCK_ADDRESS 0x68
|
||||
|
||||
#define SECONDS_FROM_1970_TO_2000 946684800
|
||||
|
||||
|
||||
// Constructor
|
||||
DS3231::DS3231() {
|
||||
// nothing to do for this constructor.
|
||||
}
|
||||
|
||||
// Utilities from JeeLabs/Ladyada
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// utility code, some of this could be exposed in the DateTime API if needed
|
||||
|
||||
// DS3231 is smart enough to know this, but keeping it for now so I don't have
|
||||
// to rewrite their code. -ADW
|
||||
static const uint8_t daysInMonth[] PROGMEM = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
// number of days since 2000/01/01, valid for 2001..2099
|
||||
static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d) {
|
||||
if (y >= 2000)
|
||||
y -= 2000;
|
||||
uint16_t days = d;
|
||||
|
||||
for (uint8_t i = 1; i < m; ++i) days += pgm_read_byte(daysInMonth + i - 1);
|
||||
if ((m > 2) && (y % 4 == 0))
|
||||
++days;
|
||||
return days + 365 * y + (y + 3) / 4 - 1;
|
||||
}
|
||||
|
||||
static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s) {
|
||||
return ((days * 24L + h) * 60 + m) * 60 + s;
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
Public Functions
|
||||
*****************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* TO GET ALL DATE/TIME INFORMATION AT ONCE AND AVOID THE CHANCE OF ROLLOVER
|
||||
* DateTime implementation spliced in here from Jean-Claude Wippler's (JeeLabs)
|
||||
* RTClib, as modified by Limor Fried (Ladyada); source code at:
|
||||
* https://github.com/adafruit/RTClib
|
||||
******************************************************************************/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// DateTime implementation - ignores time zones and DST changes
|
||||
// NOTE: also ignores leap seconds, see http://en.wikipedia.org/wiki/Leap_second
|
||||
|
||||
DateTime::DateTime(uint32_t t) {
|
||||
t -= SECONDS_FROM_1970_TO_2000; // bring to 2000 timestamp from 1970
|
||||
|
||||
ss = t % 60;
|
||||
t /= 60;
|
||||
mm = t % 60;
|
||||
t /= 60;
|
||||
hh = t % 24;
|
||||
uint16_t days = t / 24;
|
||||
uint8_t leap;
|
||||
|
||||
for (yOff = 0;; ++yOff) {
|
||||
leap = yOff % 4 == 0;
|
||||
if (days < 365 + leap)
|
||||
break;
|
||||
days -= 365 + leap;
|
||||
}
|
||||
|
||||
for (m = 1;; ++m) {
|
||||
uint8_t daysPerMonth = pgm_read_byte(daysInMonth + m - 1);
|
||||
if (leap && (m == 2))
|
||||
++daysPerMonth;
|
||||
if (days < daysPerMonth)
|
||||
break;
|
||||
days -= daysPerMonth;
|
||||
}
|
||||
d = days + 1;
|
||||
}
|
||||
|
||||
DateTime::DateTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec) {
|
||||
if (year >= 2000)
|
||||
year -= 2000;
|
||||
yOff = year;
|
||||
m = month;
|
||||
d = day;
|
||||
hh = hour;
|
||||
mm = min;
|
||||
ss = sec;
|
||||
}
|
||||
|
||||
static uint8_t conv2d(const char* p) {
|
||||
uint8_t v = 0;
|
||||
|
||||
if (('0' <= *p) && (*p <= '9'))
|
||||
v = *p - '0';
|
||||
return 10 * v + *++p - '0';
|
||||
}
|
||||
|
||||
// UNIX time: IS CORRECT ONLY WHEN SET TO UTC!!!
|
||||
uint32_t DateTime::unixtime(void) const {
|
||||
uint32_t t;
|
||||
uint16_t days = date2days(yOff, m, d);
|
||||
|
||||
t = time2long(days, hh, mm, ss);
|
||||
t += SECONDS_FROM_1970_TO_2000; // seconds from 1970 to 2000
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// Slightly modified from JeeLabs / Ladyada
|
||||
// Get all date/time at once to avoid rollover (e.g., minute/second don't match)
|
||||
static uint8_t bcd2bin(uint8_t val) {
|
||||
return val - 6 * (val >> 4);
|
||||
}
|
||||
|
||||
static uint8_t bin2bcd(uint8_t val) {
|
||||
return val + 6 * (val / 10);
|
||||
}
|
||||
|
||||
DateTime RTClib::now() {
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0); // This is the first register address (Seconds)
|
||||
// We'll read from here on for 7 bytes: secs reg, minutes reg, hours, days, months and years.
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(CLOCK_ADDRESS, 7);
|
||||
uint8_t ss = bcd2bin(Wire.read() & 0x7F);
|
||||
uint8_t mm = bcd2bin(Wire.read());
|
||||
uint8_t hh = bcd2bin(Wire.read());
|
||||
|
||||
Wire.read();
|
||||
uint8_t d = bcd2bin(Wire.read());
|
||||
uint8_t m = bcd2bin(Wire.read());
|
||||
uint16_t y = bcd2bin(Wire.read()) + 2000;
|
||||
|
||||
return DateTime(y, m, d, hh, mm, ss);
|
||||
}
|
||||
|
||||
///// ERIC'S ORIGINAL CODE FOLLOWS /////
|
||||
|
||||
byte DS3231::getSecond() {
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x00);
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(CLOCK_ADDRESS, 1);
|
||||
return bcdToDec(Wire.read());
|
||||
}
|
||||
|
||||
byte DS3231::getMinute() {
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x01);
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(CLOCK_ADDRESS, 1);
|
||||
return bcdToDec(Wire.read());
|
||||
}
|
||||
|
||||
byte DS3231::getHour(bool& h12, bool& PM_time) {
|
||||
byte temp_buffer;
|
||||
byte hour;
|
||||
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x02);
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(CLOCK_ADDRESS, 1);
|
||||
temp_buffer = Wire.read();
|
||||
h12 = temp_buffer & 0b01000000;
|
||||
if (h12) {
|
||||
PM_time = temp_buffer & 0b00100000;
|
||||
hour = bcdToDec(temp_buffer & 0b00011111);
|
||||
} else {
|
||||
hour = bcdToDec(temp_buffer & 0b00111111);
|
||||
}
|
||||
return hour;
|
||||
}
|
||||
|
||||
byte DS3231::getDoW() {
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x03);
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(CLOCK_ADDRESS, 1);
|
||||
return bcdToDec(Wire.read());
|
||||
}
|
||||
|
||||
byte DS3231::getDate() {
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x04);
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(CLOCK_ADDRESS, 1);
|
||||
return bcdToDec(Wire.read());
|
||||
}
|
||||
|
||||
byte DS3231::getMonth(bool& Century) {
|
||||
byte temp_buffer;
|
||||
byte hour;
|
||||
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x05);
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(CLOCK_ADDRESS, 1);
|
||||
temp_buffer = Wire.read();
|
||||
Century = temp_buffer & 0b10000000;
|
||||
return bcdToDec(temp_buffer & 0b01111111);
|
||||
}
|
||||
|
||||
byte DS3231::getYear() {
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x06);
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(CLOCK_ADDRESS, 1);
|
||||
return bcdToDec(Wire.read());
|
||||
}
|
||||
|
||||
void DS3231::setSecond(byte Second) {
|
||||
// Sets the seconds
|
||||
// This function also resets the Oscillator Stop Flag, which is set
|
||||
// whenever power is interrupted.
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x00);
|
||||
Wire.write(decToBcd(Second));
|
||||
Wire.endTransmission();
|
||||
// Clear OSF flag
|
||||
byte temp_buffer = readControlByte(1);
|
||||
|
||||
writeControlByte((temp_buffer & 0b01111111), 1);
|
||||
}
|
||||
|
||||
void DS3231::setMinute(byte Minute) {
|
||||
// Sets the minutes
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x01);
|
||||
Wire.write(decToBcd(Minute));
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
void DS3231::setHour(byte Hour) {
|
||||
// Sets the hour, without changing 12/24h mode.
|
||||
// The hour must be in 24h format.
|
||||
|
||||
bool h12;
|
||||
|
||||
// Start by figuring out what the 12/24 mode is
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x02);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(CLOCK_ADDRESS, 1);
|
||||
h12 = (Wire.read() & 0b01000000);
|
||||
// if h12 is true, it's 12h mode; false is 24h.
|
||||
|
||||
if (h12) {
|
||||
// 12 hour
|
||||
if (Hour > 12) {
|
||||
Hour = decToBcd(Hour-12) | 0b01100000;
|
||||
} else {
|
||||
Hour = decToBcd(Hour) & 0b11011111;
|
||||
}
|
||||
} else {
|
||||
// 24 hour
|
||||
Hour = decToBcd(Hour) & 0b10111111;
|
||||
}
|
||||
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x02);
|
||||
Wire.write(Hour);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
void DS3231::setDoW(byte DoW) {
|
||||
// Sets the Day of Week
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x03);
|
||||
Wire.write(decToBcd(DoW));
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
void DS3231::setDate(byte Date) {
|
||||
// Sets the Date
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x04);
|
||||
Wire.write(decToBcd(Date));
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
void DS3231::setMonth(byte Month) {
|
||||
// Sets the month
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x05);
|
||||
Wire.write(decToBcd(Month));
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
void DS3231::setYear(byte Year) {
|
||||
// Sets the year
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x06);
|
||||
Wire.write(decToBcd(Year));
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
void DS3231::setClockMode(bool h12) {
|
||||
// sets the mode to 12-hour (true) or 24-hour (false).
|
||||
// One thing that bothers me about how I've written this is that
|
||||
// if the read and right happen at the right hourly millisecnd,
|
||||
// the clock will be set back an hour. Not sure how to do it better,
|
||||
// though, and as long as one doesn't set the mode frequently it's
|
||||
// a very minimal risk.
|
||||
// It's zero risk if you call this BEFORE setting the hour, since
|
||||
// the setHour() function doesn't change this mode.
|
||||
|
||||
byte temp_buffer;
|
||||
|
||||
// Start by reading byte 0x02.
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x02);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(CLOCK_ADDRESS, 1);
|
||||
temp_buffer = Wire.read();
|
||||
|
||||
// Set the flag to the requested value:
|
||||
if (h12) {
|
||||
temp_buffer = temp_buffer | 0b01000000;
|
||||
} else {
|
||||
temp_buffer = temp_buffer & 0b10111111;
|
||||
}
|
||||
|
||||
// Write the byte
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x02);
|
||||
Wire.write(temp_buffer);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
float DS3231::getTemperature() {
|
||||
// Checks the internal thermometer on the DS3231 and returns the
|
||||
// temperature as a floating-point value.
|
||||
|
||||
// Updated / modified a tiny bit from "Coding Badly" and "Tri-Again"
|
||||
// http://forum.arduino.cc/index.php/topic,22301.0.html
|
||||
|
||||
byte tMSB, tLSB;
|
||||
float temp3231;
|
||||
|
||||
// temp registers (11h-12h) get updated automatically every 64s
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x11);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(CLOCK_ADDRESS, 2);
|
||||
|
||||
// Should I do more "if available" checks here?
|
||||
if (Wire.available()) {
|
||||
tMSB = Wire.read(); // 2's complement int portion
|
||||
tLSB = Wire.read(); // fraction portion
|
||||
|
||||
temp3231 = ((((short)tMSB << 8) | (short)tLSB) >> 6) / 4.0;
|
||||
}
|
||||
else {
|
||||
temp3231 = -9999; // Some obvious error value
|
||||
}
|
||||
|
||||
return temp3231;
|
||||
}
|
||||
|
||||
void DS3231::getA1Time(byte& A1Day, byte& A1Hour, byte& A1Minute, byte& A1Second, byte& AlarmBits, bool& A1Dy, bool& A1h12, bool& A1PM) {
|
||||
byte temp_buffer;
|
||||
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x07);
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(CLOCK_ADDRESS, 4);
|
||||
|
||||
temp_buffer = Wire.read(); // Get A1M1 and A1 Seconds
|
||||
A1Second = bcdToDec(temp_buffer & 0b01111111);
|
||||
// put A1M1 bit in position 0 of DS3231_AlarmBits.
|
||||
AlarmBits = AlarmBits | (temp_buffer & 0b10000000)>>7;
|
||||
|
||||
temp_buffer = Wire.read(); // Get A1M2 and A1 minutes
|
||||
A1Minute = bcdToDec(temp_buffer & 0b01111111);
|
||||
// put A1M2 bit in position 1 of DS3231_AlarmBits.
|
||||
AlarmBits = AlarmBits | (temp_buffer & 0b10000000)>>6;
|
||||
|
||||
temp_buffer = Wire.read(); // Get A1M3 and A1 Hour
|
||||
// put A1M3 bit in position 2 of DS3231_AlarmBits.
|
||||
AlarmBits = AlarmBits | (temp_buffer & 0b10000000)>>5;
|
||||
// determine A1 12/24 mode
|
||||
A1h12 = temp_buffer & 0b01000000;
|
||||
if (A1h12) {
|
||||
A1PM = temp_buffer & 0b00100000; // determine am/pm
|
||||
A1Hour = bcdToDec(temp_buffer & 0b00011111); // 12-hour
|
||||
} else {
|
||||
A1Hour = bcdToDec(temp_buffer & 0b00111111); // 24-hour
|
||||
}
|
||||
|
||||
temp_buffer = Wire.read(); // Get A1M4 and A1 Day/Date
|
||||
// put A1M3 bit in position 3 of DS3231_AlarmBits.
|
||||
AlarmBits = AlarmBits | (temp_buffer & 0b10000000)>>4;
|
||||
// determine A1 day or date flag
|
||||
A1Dy = (temp_buffer & 0b01000000)>>6;
|
||||
if (A1Dy) {
|
||||
// alarm is by day of week, not date.
|
||||
A1Day = bcdToDec(temp_buffer & 0b00001111);
|
||||
} else {
|
||||
// alarm is by date, not day of week.
|
||||
A1Day = bcdToDec(temp_buffer & 0b00111111);
|
||||
}
|
||||
}
|
||||
|
||||
void DS3231::getA2Time(byte& A2Day, byte& A2Hour, byte& A2Minute, byte& AlarmBits, bool& A2Dy, bool& A2h12, bool& A2PM) {
|
||||
byte temp_buffer;
|
||||
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x0b);
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(CLOCK_ADDRESS, 3);
|
||||
temp_buffer = Wire.read(); // Get A2M2 and A2 Minutes
|
||||
A2Minute = bcdToDec(temp_buffer & 0b01111111);
|
||||
// put A2M2 bit in position 4 of DS3231_AlarmBits.
|
||||
AlarmBits = AlarmBits | (temp_buffer & 0b10000000)>>3;
|
||||
|
||||
temp_buffer = Wire.read(); // Get A2M3 and A2 Hour
|
||||
// put A2M3 bit in position 5 of DS3231_AlarmBits.
|
||||
AlarmBits = AlarmBits | (temp_buffer & 0b10000000)>>2;
|
||||
// determine A2 12/24 mode
|
||||
A2h12 = temp_buffer & 0b01000000;
|
||||
if (A2h12) {
|
||||
A2PM = temp_buffer & 0b00100000; // determine am/pm
|
||||
A2Hour = bcdToDec(temp_buffer & 0b00011111); // 12-hour
|
||||
} else {
|
||||
A2Hour = bcdToDec(temp_buffer & 0b00111111); // 24-hour
|
||||
}
|
||||
|
||||
temp_buffer = Wire.read(); // Get A2M4 and A1 Day/Date
|
||||
// put A2M4 bit in position 6 of DS3231_AlarmBits.
|
||||
AlarmBits = AlarmBits | (temp_buffer & 0b10000000)>>1;
|
||||
// determine A2 day or date flag
|
||||
A2Dy = (temp_buffer & 0b01000000)>>6;
|
||||
if (A2Dy) {
|
||||
// alarm is by day of week, not date.
|
||||
A2Day = bcdToDec(temp_buffer & 0b00001111);
|
||||
} else {
|
||||
// alarm is by date, not day of week.
|
||||
A2Day = bcdToDec(temp_buffer & 0b00111111);
|
||||
}
|
||||
}
|
||||
|
||||
void DS3231::setA1Time(byte A1Day, byte A1Hour, byte A1Minute, byte A1Second, byte AlarmBits, bool A1Dy, bool A1h12, bool A1PM) {
|
||||
// Sets the alarm-1 date and time on the DS3231, using A1* information
|
||||
byte temp_buffer;
|
||||
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x07); // A1 starts at 07h
|
||||
// Send A1 second and A1M1
|
||||
Wire.write(decToBcd(A1Second) | ((AlarmBits & 0b00000001) << 7));
|
||||
// Send A1 Minute and A1M2
|
||||
Wire.write(decToBcd(A1Minute) | ((AlarmBits & 0b00000010) << 6));
|
||||
// Figure out A1 hour
|
||||
if (A1h12) {
|
||||
// Start by converting existing time to h12 if it was given in 24h.
|
||||
if (A1Hour > 12) {
|
||||
// well, then, this obviously isn't a h12 time, is it?
|
||||
A1Hour = A1Hour - 12;
|
||||
A1PM = true;
|
||||
}
|
||||
if (A1PM) {
|
||||
// Afternoon
|
||||
// Convert the hour to BCD and add appropriate flags.
|
||||
temp_buffer = decToBcd(A1Hour) | 0b01100000;
|
||||
} else {
|
||||
// Morning
|
||||
// Convert the hour to BCD and add appropriate flags.
|
||||
temp_buffer = decToBcd(A1Hour) | 0b01000000;
|
||||
}
|
||||
} else {
|
||||
// Now for 24h
|
||||
temp_buffer = decToBcd(A1Hour);
|
||||
}
|
||||
temp_buffer = temp_buffer | ((AlarmBits & 0b00000100)<<5);
|
||||
// A1 hour is figured out, send it
|
||||
Wire.write(temp_buffer);
|
||||
// Figure out A1 day/date and A1M4
|
||||
temp_buffer = ((AlarmBits & 0b00001000)<<4) | decToBcd(A1Day);
|
||||
if (A1Dy) {
|
||||
// Set A1 Day/Date flag (Otherwise it's zero)
|
||||
temp_buffer = temp_buffer | 0b01000000;
|
||||
}
|
||||
Wire.write(temp_buffer);
|
||||
// All done!
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
void DS3231::setA2Time(byte A2Day, byte A2Hour, byte A2Minute, byte AlarmBits, bool A2Dy, bool A2h12, bool A2PM) {
|
||||
// Sets the alarm-2 date and time on the DS3231, using A2* information
|
||||
byte temp_buffer;
|
||||
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
Wire.write(0x0b); // A1 starts at 0bh
|
||||
// Send A2 Minute and A2M2
|
||||
Wire.write(decToBcd(A2Minute) | ((AlarmBits & 0b00010000) << 3));
|
||||
// Figure out A2 hour
|
||||
if (A2h12) {
|
||||
// Start by converting existing time to h12 if it was given in 24h.
|
||||
if (A2Hour > 12) {
|
||||
// well, then, this obviously isn't a h12 time, is it?
|
||||
A2Hour = A2Hour - 12;
|
||||
A2PM = true;
|
||||
}
|
||||
if (A2PM) {
|
||||
// Afternoon
|
||||
// Convert the hour to BCD and add appropriate flags.
|
||||
temp_buffer = decToBcd(A2Hour) | 0b01100000;
|
||||
} else {
|
||||
// Morning
|
||||
// Convert the hour to BCD and add appropriate flags.
|
||||
temp_buffer = decToBcd(A2Hour) | 0b01000000;
|
||||
}
|
||||
} else {
|
||||
// Now for 24h
|
||||
temp_buffer = decToBcd(A2Hour);
|
||||
}
|
||||
// add in A2M3 bit
|
||||
temp_buffer = temp_buffer | ((AlarmBits & 0b00100000)<<2);
|
||||
// A2 hour is figured out, send it
|
||||
Wire.write(temp_buffer);
|
||||
// Figure out A2 day/date and A2M4
|
||||
temp_buffer = ((AlarmBits & 0b01000000)<<1) | decToBcd(A2Day);
|
||||
if (A2Dy) {
|
||||
// Set A2 Day/Date flag (Otherwise it's zero)
|
||||
temp_buffer = temp_buffer | 0b01000000;
|
||||
}
|
||||
Wire.write(temp_buffer);
|
||||
// All done!
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
void DS3231::turnOnAlarm(byte Alarm) {
|
||||
// turns on alarm number "Alarm". Defaults to 2 if Alarm is not 1.
|
||||
byte temp_buffer = readControlByte(0);
|
||||
|
||||
// modify control byte
|
||||
if (Alarm == 1) {
|
||||
temp_buffer = temp_buffer | 0b00000101;
|
||||
} else {
|
||||
temp_buffer = temp_buffer | 0b00000110;
|
||||
}
|
||||
writeControlByte(temp_buffer, 0);
|
||||
}
|
||||
|
||||
void DS3231::turnOffAlarm(byte Alarm) {
|
||||
// turns off alarm number "Alarm". Defaults to 2 if Alarm is not 1.
|
||||
// Leaves interrupt pin alone.
|
||||
byte temp_buffer = readControlByte(0);
|
||||
|
||||
// modify control byte
|
||||
if (Alarm == 1) {
|
||||
temp_buffer = temp_buffer & 0b11111110;
|
||||
} else {
|
||||
temp_buffer = temp_buffer & 0b11111101;
|
||||
}
|
||||
writeControlByte(temp_buffer, 0);
|
||||
}
|
||||
|
||||
bool DS3231::checkAlarmEnabled(byte Alarm) {
|
||||
// Checks whether the given alarm is enabled.
|
||||
byte result = 0x0;
|
||||
byte temp_buffer = readControlByte(0);
|
||||
|
||||
if (Alarm == 1) {
|
||||
result = temp_buffer & 0b00000001;
|
||||
} else {
|
||||
result = temp_buffer & 0b00000010;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DS3231::checkIfAlarm(byte Alarm) {
|
||||
// Checks whether alarm 1 or alarm 2 flag is on, returns T/F accordingly.
|
||||
// Turns flag off, also.
|
||||
// defaults to checking alarm 2, unless Alarm == 1.
|
||||
byte result;
|
||||
byte temp_buffer = readControlByte(1);
|
||||
|
||||
if (Alarm == 1) {
|
||||
// Did alarm 1 go off?
|
||||
result = temp_buffer & 0b00000001;
|
||||
// clear flag
|
||||
temp_buffer = temp_buffer & 0b11111110;
|
||||
} else {
|
||||
// Did alarm 2 go off?
|
||||
result = temp_buffer & 0b00000010;
|
||||
// clear flag
|
||||
temp_buffer = temp_buffer & 0b11111101;
|
||||
}
|
||||
writeControlByte(temp_buffer, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
void DS3231::enableOscillator(bool TF, bool battery, byte frequency) {
|
||||
// turns oscillator on or off. True is on, false is off.
|
||||
// if battery is true, turns on even for battery-only operation,
|
||||
// otherwise turns off if Vcc is off.
|
||||
// frequency must be 0, 1, 2, or 3.
|
||||
// 0 = 1 Hz
|
||||
// 1 = 1.024 kHz
|
||||
// 2 = 4.096 kHz
|
||||
// 3 = 8.192 kHz (Default if frequency byte is out of range)
|
||||
if (frequency > 3) frequency = 3;
|
||||
// read control byte in, but zero out current state of RS2 and RS1.
|
||||
byte temp_buffer = readControlByte(0) & 0b11100111;
|
||||
|
||||
if (battery) {
|
||||
// turn on BBSQW flag
|
||||
temp_buffer = temp_buffer | 0b01000000;
|
||||
} else {
|
||||
// turn off BBSQW flag
|
||||
temp_buffer = temp_buffer & 0b10111111;
|
||||
}
|
||||
if (TF) {
|
||||
// set ~EOSC to 0 and INTCN to zero.
|
||||
temp_buffer = temp_buffer & 0b01111011;
|
||||
} else {
|
||||
// set ~EOSC to 1, leave INTCN as is.
|
||||
temp_buffer = temp_buffer | 0b10000000;
|
||||
}
|
||||
// shift frequency into bits 3 and 4 and set.
|
||||
frequency = frequency << 3;
|
||||
temp_buffer = temp_buffer | frequency;
|
||||
// And write the control bits
|
||||
writeControlByte(temp_buffer, 0);
|
||||
}
|
||||
|
||||
void DS3231::enable32kHz(bool TF) {
|
||||
// turn 32kHz pin on or off
|
||||
byte temp_buffer = readControlByte(1);
|
||||
|
||||
if (TF) {
|
||||
// turn on 32kHz pin
|
||||
temp_buffer = temp_buffer | 0b00001000;
|
||||
} else {
|
||||
// turn off 32kHz pin
|
||||
temp_buffer = temp_buffer & 0b11110111;
|
||||
}
|
||||
writeControlByte(temp_buffer, 1);
|
||||
}
|
||||
|
||||
bool DS3231::oscillatorCheck() {
|
||||
// Returns false if the oscillator has been off for some reason.
|
||||
// If this is the case, the time is probably not correct.
|
||||
byte temp_buffer = readControlByte(1);
|
||||
bool result = true;
|
||||
|
||||
if (temp_buffer & 0b10000000) {
|
||||
// Oscillator Stop Flag (OSF) is set, so return false.
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*****************************************
|
||||
Private Functions
|
||||
*****************************************/
|
||||
byte DS3231::decToBcd(byte val) {
|
||||
// Convert normal decimal numbers to binary coded decimal
|
||||
return (val/10*16) + (val%10);
|
||||
}
|
||||
|
||||
byte DS3231::bcdToDec(byte val) {
|
||||
// Convert binary coded decimal to normal decimal numbers
|
||||
return (val/16*10) + (val%16);
|
||||
}
|
||||
|
||||
byte DS3231::readControlByte(bool which) {
|
||||
// Read selected control byte
|
||||
// first byte (0) is 0x0e, second (1) is 0x0f
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
if (which) {
|
||||
// second control byte
|
||||
Wire.write(0x0f);
|
||||
} else {
|
||||
// first control byte
|
||||
Wire.write(0x0e);
|
||||
}
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(CLOCK_ADDRESS, 1);
|
||||
return Wire.read();
|
||||
}
|
||||
|
||||
void DS3231::writeControlByte(byte control, bool which) {
|
||||
// Write the selected control byte.
|
||||
// which=false -> 0x0e, true->0x0f.
|
||||
Wire.beginTransmission(CLOCK_ADDRESS);
|
||||
if (which) {
|
||||
Wire.write(0x0f);
|
||||
} else {
|
||||
Wire.write(0x0e);
|
||||
}
|
||||
Wire.write(control);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
183
esp8266_deauther/src/DS3231-1.0.3/DS3231.h
Normal file
183
esp8266_deauther/src/DS3231-1.0.3/DS3231.h
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* DS3231.h
|
||||
*
|
||||
* Arduino Library for the DS3231 Real-Time Clock chip
|
||||
*
|
||||
* (c) Eric Ayars
|
||||
* 4/1/11
|
||||
* released into the public domain. If you use this, please let me know
|
||||
* (just out of pure curiosity!) by sending me an email:
|
||||
* eric@ayars.org
|
||||
*
|
||||
*/
|
||||
|
||||
// Modified by Andy Wickert 5/15/11: Spliced in stuff from RTClib
|
||||
// Modified by Simon Gassner 11/28/2017: Changed Term "PM" to "PM_time" for compability with SAMD Processors
|
||||
#ifndef DS3231_h
|
||||
#define DS3231_h
|
||||
|
||||
// Changed the following to work on 1.0
|
||||
//#include "WProgram.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <Wire.h>
|
||||
|
||||
// DateTime (get everything at once) from JeeLabs / Adafruit
|
||||
// Simple general-purpose date/time class (no TZ / DST / leap second handling!)
|
||||
class DateTime {
|
||||
public:
|
||||
DateTime (uint32_t t =0);
|
||||
DateTime (uint16_t year, uint8_t month, uint8_t day,
|
||||
uint8_t hour =0, uint8_t min =0, uint8_t sec =0);
|
||||
DateTime (const char* date, const char* time);
|
||||
uint16_t year() const { return 2000 + yOff; }
|
||||
uint8_t month() const { return m; }
|
||||
uint8_t day() const { return d; }
|
||||
uint8_t hour() const { return hh; }
|
||||
uint8_t minute() const { return mm; }
|
||||
uint8_t second() const { return ss; }
|
||||
uint8_t dayOfTheWeek() const;
|
||||
|
||||
// 32-bit times as seconds since 1/1/2000
|
||||
long secondstime() const;
|
||||
// 32-bit times as seconds since 1/1/1970
|
||||
// THE ABOVE COMMENT IS CORRECT FOR LOCAL TIME; TO USE THIS COMMAND TO
|
||||
// OBTAIN TRUE UNIX TIME SINCE EPOCH, YOU MUST CALL THIS COMMAND AFTER
|
||||
// SETTING YOUR CLOCK TO UTC
|
||||
uint32_t unixtime(void) const;
|
||||
|
||||
protected:
|
||||
uint8_t yOff, m, d, hh, mm, ss;
|
||||
};
|
||||
|
||||
class RTClib {
|
||||
public:
|
||||
// Get date and time snapshot
|
||||
static DateTime now();
|
||||
};
|
||||
|
||||
// Eric's original code is everything below this line
|
||||
class DS3231 {
|
||||
public:
|
||||
|
||||
//Constructor
|
||||
DS3231();
|
||||
|
||||
// Time-retrieval functions
|
||||
|
||||
// the get*() functions retrieve current values of the registers.
|
||||
byte getSecond();
|
||||
byte getMinute();
|
||||
byte getHour(bool& h12, bool& PM_time);
|
||||
// In addition to returning the hour register, this function
|
||||
// returns the values of the 12/24-hour flag and the AM/PM flag.
|
||||
byte getDoW();
|
||||
byte getDate();
|
||||
byte getMonth(bool& Century);
|
||||
// Also sets the flag indicating century roll-over.
|
||||
byte getYear();
|
||||
// Last 2 digits only
|
||||
|
||||
// Time-setting functions
|
||||
// Note that none of these check for sensibility: You can set the
|
||||
// date to July 42nd and strange things will probably result.
|
||||
|
||||
void setSecond(byte Second);
|
||||
// In addition to setting the seconds, this clears the
|
||||
// "Oscillator Stop Flag".
|
||||
void setMinute(byte Minute);
|
||||
// Sets the minute
|
||||
void setHour(byte Hour);
|
||||
// Sets the hour
|
||||
void setDoW(byte DoW);
|
||||
// Sets the Day of the Week (1-7);
|
||||
void setDate(byte Date);
|
||||
// Sets the Date of the Month
|
||||
void setMonth(byte Month);
|
||||
// Sets the Month of the year
|
||||
void setYear(byte Year);
|
||||
// Last two digits of the year
|
||||
void setClockMode(bool h12);
|
||||
// Set 12/24h mode. True is 12-h, false is 24-hour.
|
||||
|
||||
// Temperature function
|
||||
|
||||
float getTemperature();
|
||||
|
||||
// Alarm functions
|
||||
|
||||
void getA1Time(byte& A1Day, byte& A1Hour, byte& A1Minute, byte& A1Second, byte& AlarmBits, bool& A1Dy, bool& A1h12, bool& A1PM);
|
||||
/* Retrieves everything you could want to know about alarm
|
||||
* one.
|
||||
* A1Dy true makes the alarm go on A1Day = Day of Week,
|
||||
* A1Dy false makes the alarm go on A1Day = Date of month.
|
||||
*
|
||||
* byte AlarmBits sets the behavior of the alarms:
|
||||
* Dy A1M4 A1M3 A1M2 A1M1 Rate
|
||||
* X 1 1 1 1 Once per second
|
||||
* X 1 1 1 0 Alarm when seconds match
|
||||
* X 1 1 0 0 Alarm when min, sec match
|
||||
* X 1 0 0 0 Alarm when hour, min, sec match
|
||||
* 0 0 0 0 0 Alarm when date, h, m, s match
|
||||
* 1 0 0 0 0 Alarm when DoW, h, m, s match
|
||||
*
|
||||
* Dy A2M4 A2M3 A2M2 Rate
|
||||
* X 1 1 1 Once per minute (at seconds = 00)
|
||||
* X 1 1 0 Alarm when minutes match
|
||||
* X 1 0 0 Alarm when hours and minutes match
|
||||
* 0 0 0 0 Alarm when date, hour, min match
|
||||
* 1 0 0 0 Alarm when DoW, hour, min match
|
||||
*/
|
||||
void getA2Time(byte& A2Day, byte& A2Hour, byte& A2Minute, byte& AlarmBits, bool& A2Dy, bool& A2h12, bool& A2PM);
|
||||
// Same as getA1Time();, but A2 only goes on seconds == 00.
|
||||
void setA1Time(byte A1Day, byte A1Hour, byte A1Minute, byte A1Second, byte AlarmBits, bool A1Dy, bool A1h12, bool A1PM);
|
||||
// Set the details for Alarm 1
|
||||
void setA2Time(byte A2Day, byte A2Hour, byte A2Minute, byte AlarmBits, bool A2Dy, bool A2h12, bool A2PM);
|
||||
// Set the details for Alarm 2
|
||||
void turnOnAlarm(byte Alarm);
|
||||
// Enables alarm 1 or 2 and the external interrupt pin.
|
||||
// If Alarm != 1, it assumes Alarm == 2.
|
||||
void turnOffAlarm(byte Alarm);
|
||||
// Disables alarm 1 or 2 (default is 2 if Alarm != 1);
|
||||
// and leaves the interrupt pin alone.
|
||||
bool checkAlarmEnabled(byte Alarm);
|
||||
// Returns T/F to indicate whether the requested alarm is
|
||||
// enabled. Defaults to 2 if Alarm != 1.
|
||||
bool checkIfAlarm(byte Alarm);
|
||||
// Checks whether the indicated alarm (1 or 2, 2 default);
|
||||
// has been activated.
|
||||
|
||||
// Oscillator functions
|
||||
|
||||
void enableOscillator(bool TF, bool battery, byte frequency);
|
||||
// turns oscillator on or off. True is on, false is off.
|
||||
// if battery is true, turns on even for battery-only operation,
|
||||
// otherwise turns off if Vcc is off.
|
||||
// frequency must be 0, 1, 2, or 3.
|
||||
// 0 = 1 Hz
|
||||
// 1 = 1.024 kHz
|
||||
// 2 = 4.096 kHz
|
||||
// 3 = 8.192 kHz (Default if frequency byte is out of range);
|
||||
void enable32kHz(bool TF);
|
||||
// Turns the 32kHz output pin on (true); or off (false).
|
||||
bool oscillatorCheck();;
|
||||
// Checks the status of the OSF (Oscillator Stop Flag);.
|
||||
// If this returns false, then the clock is probably not
|
||||
// giving you the correct time.
|
||||
// The OSF is cleared by function setSecond();.
|
||||
|
||||
private:
|
||||
|
||||
byte decToBcd(byte val);
|
||||
// Convert normal decimal numbers to binary coded decimal
|
||||
byte bcdToDec(byte val);
|
||||
// Convert binary coded decimal to normal decimal numbers
|
||||
byte readControlByte(bool which);
|
||||
// Read selected control byte: (0); reads 0x0e, (1) reads 0x0f
|
||||
void writeControlByte(byte control, bool which);
|
||||
// Write the selected control byte.
|
||||
// which == false -> 0x0e, true->0x0f.
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
24
esp8266_deauther/src/DS3231-1.0.3/LICENSE
Normal file
24
esp8266_deauther/src/DS3231-1.0.3/LICENSE
Normal file
@@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
139
esp8266_deauther/src/SimpleButton/Buttons/AnalogStick.cpp
Normal file
139
esp8266_deauther/src/SimpleButton/Buttons/AnalogStick.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
#include "AnalogStick.h"
|
||||
|
||||
namespace simplebutton {
|
||||
AnalogStick::AnalogStick() {
|
||||
setup(255, 255, 255);
|
||||
}
|
||||
|
||||
AnalogStick::AnalogStick(uint8_t xPin, uint8_t yPin, uint8_t buttonPin) {
|
||||
setup(xPin, yPin, buttonPin);
|
||||
}
|
||||
|
||||
AnalogStick::~AnalogStick() {
|
||||
if (this->up) delete this->up;
|
||||
if (this->down) delete this->down;
|
||||
if (this->left) delete this->left;
|
||||
if (this->right) delete this->right;
|
||||
}
|
||||
|
||||
void AnalogStick::setup(uint8_t xPin, uint8_t yPin, uint8_t buttonPin) {
|
||||
this->xPin = xPin;
|
||||
this->yPin = yPin;
|
||||
this->buttonPin = buttonPin;
|
||||
|
||||
if (xPin < 255) pinMode(xPin, INPUT);
|
||||
if (yPin < 255) pinMode(yPin, INPUT);
|
||||
if (buttonPin < 255) pinMode(buttonPin, INPUT);
|
||||
|
||||
this->button = new ButtonPullup(buttonPin);
|
||||
this->up = new ButtonAnalog(yPin);
|
||||
this->down = new ButtonAnalog(yPin);
|
||||
this->left = new ButtonAnalog(xPin);
|
||||
this->right = new ButtonAnalog(xPin);
|
||||
|
||||
setLogic(1024);
|
||||
}
|
||||
|
||||
void AnalogStick::update() {
|
||||
button->update();
|
||||
up->update();
|
||||
down->update();
|
||||
left->update();
|
||||
right->update();
|
||||
|
||||
this->xValue = left->getState();
|
||||
this->yValue = up->getState();
|
||||
}
|
||||
|
||||
void AnalogStick::update(uint8_t xValue, uint8_t yValue, bool buttonPress) {
|
||||
this->xValue = xValue;
|
||||
this->yValue = yValue;
|
||||
|
||||
button->update(buttonPress);
|
||||
up->update(yValue);
|
||||
down->update(yValue);
|
||||
left->update(xValue);
|
||||
right->update(xValue);
|
||||
}
|
||||
|
||||
uint8_t AnalogStick::getX() {
|
||||
return xValue;
|
||||
}
|
||||
|
||||
uint8_t AnalogStick::getY() {
|
||||
return yValue;
|
||||
}
|
||||
|
||||
void AnalogStick::setButtons(ButtonAnalog* up, ButtonAnalog* down, ButtonAnalog* left, ButtonAnalog* right,
|
||||
Button* button) {
|
||||
if (this->up) delete this->up;
|
||||
if (this->down) delete this->down;
|
||||
if (this->left) delete this->left;
|
||||
if (this->right) delete this->right;
|
||||
|
||||
this->up = up ? up : new ButtonAnalog();
|
||||
this->down = down ? down : new ButtonAnalog();
|
||||
this->left = left ? left : new ButtonAnalog();
|
||||
this->right = right ? right : new ButtonAnalog();
|
||||
|
||||
this->button = button ? button : new Button();
|
||||
|
||||
setLogic(this->logic, this->tolerance);
|
||||
}
|
||||
|
||||
void AnalogStick::setLogic(uint16_t logic) {
|
||||
setLogic(logic, tolerance);
|
||||
}
|
||||
|
||||
void AnalogStick::setLogic(uint16_t logic, uint8_t tolerance) {
|
||||
this->logic = logic;
|
||||
this->tolerance = tolerance;
|
||||
|
||||
uint16_t difference = (double)logic * ((double)tolerance / double(100));
|
||||
|
||||
up->setBounds(0, difference);
|
||||
down->setBounds(logic - difference, logic);
|
||||
left->setBounds(0, difference);
|
||||
right->setBounds(logic - difference, logic);
|
||||
}
|
||||
|
||||
void AnalogStick::setUpdateInterval(uint32_t updateInterval) {
|
||||
button->setUpdateInterval(updateInterval);
|
||||
up->setUpdateInterval(updateInterval);
|
||||
down->setUpdateInterval(updateInterval);
|
||||
left->setUpdateInterval(updateInterval);
|
||||
right->setUpdateInterval(updateInterval);
|
||||
}
|
||||
|
||||
void AnalogStick::setDefaultMinPushTime(uint32_t defaultMinPushTime) {
|
||||
button->setDefaultMinPushTime(defaultMinPushTime);
|
||||
up->setDefaultMinPushTime(defaultMinPushTime);
|
||||
down->setDefaultMinPushTime(defaultMinPushTime);
|
||||
left->setDefaultMinPushTime(defaultMinPushTime);
|
||||
right->setDefaultMinPushTime(defaultMinPushTime);
|
||||
}
|
||||
|
||||
void AnalogStick::setDefaultMinReleaseTime(uint32_t defaultMinReleaseTime) {
|
||||
button->setDefaultMinReleaseTime(defaultMinReleaseTime);
|
||||
up->setDefaultMinReleaseTime(defaultMinReleaseTime);
|
||||
down->setDefaultMinReleaseTime(defaultMinReleaseTime);
|
||||
left->setDefaultMinReleaseTime(defaultMinReleaseTime);
|
||||
right->setDefaultMinReleaseTime(defaultMinReleaseTime);
|
||||
}
|
||||
|
||||
void AnalogStick::setDefaultTimeSpan(uint32_t defaultTimeSpan) {
|
||||
button->setDefaultTimeSpan(defaultTimeSpan);
|
||||
up->setDefaultTimeSpan(defaultTimeSpan);
|
||||
down->setDefaultTimeSpan(defaultTimeSpan);
|
||||
left->setDefaultTimeSpan(defaultTimeSpan);
|
||||
right->setDefaultTimeSpan(defaultTimeSpan);
|
||||
}
|
||||
|
||||
void AnalogStick::setDefaultHoldTime(uint32_t defaultHoldInterval) {
|
||||
button->setDefaultHoldTime(defaultHoldInterval);
|
||||
up->setDefaultHoldTime(defaultHoldInterval);
|
||||
down->setDefaultHoldTime(defaultHoldInterval);
|
||||
left->setDefaultHoldTime(defaultHoldInterval);
|
||||
right->setDefaultHoldTime(defaultHoldInterval);
|
||||
}
|
||||
}
|
||||
53
esp8266_deauther/src/SimpleButton/Buttons/AnalogStick.h
Normal file
53
esp8266_deauther/src/SimpleButton/Buttons/AnalogStick.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef SimpleButton_AnalogStick_h
|
||||
#define SimpleButton_AnalogStick_h
|
||||
|
||||
#include "ButtonPullup.h"
|
||||
#include "ButtonAnalog.h"
|
||||
|
||||
namespace simplebutton {
|
||||
class AnalogStick {
|
||||
public:
|
||||
Button* button = NULL;
|
||||
ButtonAnalog* up = NULL;
|
||||
ButtonAnalog* down = NULL;
|
||||
ButtonAnalog* left = NULL;
|
||||
ButtonAnalog* right = NULL;
|
||||
|
||||
AnalogStick();
|
||||
AnalogStick(uint8_t xPin, uint8_t yPin, uint8_t buttonPin);
|
||||
|
||||
~AnalogStick();
|
||||
|
||||
void setup(uint8_t xPin, uint8_t yPin, uint8_t buttonPin);
|
||||
|
||||
void update();
|
||||
void update(uint8_t xValue, uint8_t yValue, bool buttonPress);
|
||||
|
||||
uint8_t getX();
|
||||
uint8_t getY();
|
||||
|
||||
void setButtons(ButtonAnalog* up, ButtonAnalog* down, ButtonAnalog* left, ButtonAnalog* right,
|
||||
Button* button);
|
||||
void setLogic(uint16_t logic);
|
||||
void setLogic(uint16_t logic, uint8_t tolerance);
|
||||
|
||||
void setUpdateInterval(uint32_t updateInterval);
|
||||
void setDefaultMinPushTime(uint32_t defaultMinPushTime);
|
||||
void setDefaultMinReleaseTime(uint32_t defaultMinReleaseTime);
|
||||
void setDefaultTimeSpan(uint32_t defaultTimeSpan);
|
||||
void setDefaultHoldTime(uint32_t defaultHoldInterval);
|
||||
|
||||
private:
|
||||
uint16_t logic = 1024;
|
||||
uint8_t tolerance = 25; // percentage
|
||||
|
||||
uint8_t xValue = 0;
|
||||
uint8_t yValue = 0;
|
||||
|
||||
uint8_t xPin = 0;
|
||||
uint8_t yPin = 0;
|
||||
uint8_t buttonPin = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ifndef SimpleButton_AnalogStick_h
|
||||
319
esp8266_deauther/src/SimpleButton/Buttons/Button.cpp
Normal file
319
esp8266_deauther/src/SimpleButton/Buttons/Button.cpp
Normal file
@@ -0,0 +1,319 @@
|
||||
#include "../SimpleButton.h"
|
||||
|
||||
namespace simplebutton {
|
||||
Button::Button() {
|
||||
setup(255, false);
|
||||
}
|
||||
|
||||
Button::Button(uint8_t pin) {
|
||||
setup(pin, false);
|
||||
}
|
||||
|
||||
Button::Button(uint8_t pin, bool inverted) {
|
||||
setup(pin, inverted);
|
||||
}
|
||||
|
||||
Button::~Button() {}
|
||||
|
||||
void Button::setup(uint8_t pin, bool inverted) {
|
||||
this->button_pin = pin;
|
||||
this->button_inverted = inverted;
|
||||
enable();
|
||||
}
|
||||
|
||||
void Button::enable() {
|
||||
button_enabled = true;
|
||||
|
||||
if ((button_pin < 255) && !button_setup) {
|
||||
pinMode(button_pin, INPUT);
|
||||
button_setup = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Button::disable() {
|
||||
button_enabled = false;
|
||||
}
|
||||
|
||||
void Button::reset() {
|
||||
pushedFlag = false;
|
||||
releasedFlag = false;
|
||||
holdFlag = false;
|
||||
}
|
||||
|
||||
void Button::push() {
|
||||
if (!state) {
|
||||
state = true;
|
||||
|
||||
prevPushTime = pushTime;
|
||||
prevReleaseTime = releaseTime;
|
||||
pushedFlag = true;
|
||||
|
||||
pushTime = millis();
|
||||
holdTime = millis();
|
||||
holdFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Button::release() {
|
||||
if (state) {
|
||||
state = false;
|
||||
releasedFlag = true;
|
||||
releaseTime = millis();
|
||||
}
|
||||
}
|
||||
|
||||
void Button::click() {
|
||||
click(defaultMinPushTime);
|
||||
}
|
||||
|
||||
void Button::click(uint32_t time) {
|
||||
push();
|
||||
pushTime = millis() - time - defaultMinReleaseTime;
|
||||
release();
|
||||
releaseTime = millis() - defaultMinReleaseTime;
|
||||
|
||||
updateEvents();
|
||||
}
|
||||
|
||||
int Button::read() {
|
||||
bool currentState = false;
|
||||
|
||||
if (button_enabled && button_setup) {
|
||||
currentState = digitalRead(button_pin);
|
||||
|
||||
if (button_inverted) currentState = !currentState;
|
||||
}
|
||||
|
||||
return (int)currentState;
|
||||
}
|
||||
|
||||
void Button::update() {
|
||||
if (millis() - updateTime >= updateInterval) {
|
||||
updateEvents();
|
||||
if (button_enabled && button_setup) update(read());
|
||||
}
|
||||
}
|
||||
|
||||
void Button::update(int state) {
|
||||
// update time
|
||||
updateTime = millis();
|
||||
|
||||
// check events
|
||||
updateEvents();
|
||||
|
||||
// update state
|
||||
if (state > 0) push();
|
||||
else release();
|
||||
}
|
||||
|
||||
void Button::updateEvents() {
|
||||
Event* e = this->events;
|
||||
|
||||
while (e != NULL) {
|
||||
switch (e->getMode()) {
|
||||
case e->MODE::PUSHED:
|
||||
if (this->pushed()) e->run();
|
||||
break;
|
||||
|
||||
case e->MODE::RELEASED:
|
||||
if (this->released()) e->run();
|
||||
break;
|
||||
|
||||
case e->MODE::CLICKED:
|
||||
if (this->clicked(e->getMinPushTime(), e->getMinReleaseTime())) e->run();
|
||||
break;
|
||||
|
||||
case e->MODE::DOUBLECLICKED:
|
||||
if (this->doubleClicked(e->getMinPushTime(), e->getMinReleaseTime(), e->getTimeSpan())) e->run();
|
||||
break;
|
||||
|
||||
case e->MODE::HOLDING:
|
||||
if (this->holding(e->getInterval())) e->run();
|
||||
break;
|
||||
}
|
||||
e = e->next;
|
||||
}
|
||||
}
|
||||
|
||||
bool Button::isInverted() {
|
||||
return button_inverted;
|
||||
}
|
||||
|
||||
bool Button::isEnabled() {
|
||||
return button_enabled;
|
||||
}
|
||||
|
||||
bool Button::isSetup() {
|
||||
return button_setup;
|
||||
}
|
||||
|
||||
bool Button::getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
int Button::getClicks() {
|
||||
return (int)clicks;
|
||||
}
|
||||
|
||||
int Button::getPushTime() {
|
||||
return (int)(millis() - pushTime);
|
||||
}
|
||||
|
||||
bool Button::pushed() {
|
||||
if (pushedFlag) {
|
||||
pushedFlag = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Button::released() {
|
||||
if (releasedFlag && (pushTime < releaseTime)) {
|
||||
releasedFlag = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Button::clicked() {
|
||||
return clicked(defaultMinPushTime);
|
||||
}
|
||||
|
||||
bool Button::clicked(uint32_t minPushTime) {
|
||||
return clicked(minPushTime, defaultMinReleaseTime);
|
||||
}
|
||||
|
||||
bool Button::clicked(uint32_t minPushTime, uint32_t minReleaseTime) {
|
||||
bool notHolding = !holdFlag;
|
||||
bool minTime = millis() - pushTime >= minPushTime;
|
||||
bool releaseTimeout = millis() - releaseTime >= minReleaseTime;
|
||||
|
||||
if (notHolding && minTime && releaseTimeout) {
|
||||
if (released()) {
|
||||
clicks++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Button::doubleClicked() {
|
||||
return doubleClicked(defaultMinPushTime);
|
||||
}
|
||||
|
||||
bool Button::doubleClicked(uint32_t minPushTime) {
|
||||
return doubleClicked(minPushTime, defaultTimeSpan);
|
||||
}
|
||||
|
||||
bool Button::doubleClicked(uint32_t minPushTime, uint32_t timeSpan) {
|
||||
return doubleClicked(minPushTime, defaultMinReleaseTime, timeSpan);
|
||||
}
|
||||
|
||||
bool Button::doubleClicked(uint32_t minPushTime, uint32_t minReleaseTime, uint32_t timeSpan) {
|
||||
bool wasPrevClicked = prevReleaseTime - prevPushTime >= minPushTime;
|
||||
bool inTimeSpan = millis() - prevPushTime <= timeSpan;
|
||||
bool releaseTimeout = millis() - prevReleaseTime >= minReleaseTime;
|
||||
|
||||
if (wasPrevClicked && inTimeSpan && releaseTimeout) {
|
||||
if (clicked(minPushTime)) {
|
||||
pushTime = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Button::holding() {
|
||||
return holding(defaultHoldInterval);
|
||||
}
|
||||
|
||||
bool Button::holding(uint32_t interval) {
|
||||
if (getState() && (millis() - holdTime >= interval)) {
|
||||
holdTime = millis();
|
||||
holdFlag = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Button::setUpdateInterval(uint32_t updateInterval) {
|
||||
this->updateInterval = updateInterval;
|
||||
}
|
||||
|
||||
void Button::setDefaultMinPushTime(uint32_t defaultMinPushTime) {
|
||||
this->defaultMinPushTime = defaultMinPushTime;
|
||||
}
|
||||
|
||||
void Button::setDefaultMinReleaseTime(uint32_t defaultMinReleaseTime) {
|
||||
this->defaultMinReleaseTime = defaultMinReleaseTime;
|
||||
}
|
||||
|
||||
void Button::setDefaultTimeSpan(uint32_t defaultTimeSpan) {
|
||||
this->defaultTimeSpan = defaultTimeSpan;
|
||||
}
|
||||
|
||||
void Button::setDefaultHoldTime(uint32_t defaultHoldInterval) {
|
||||
this->defaultHoldInterval = defaultHoldInterval;
|
||||
}
|
||||
|
||||
void Button::setOnPushed(ButtonEventFunction) {
|
||||
this->addEvent(new PushEvent(fnct));
|
||||
}
|
||||
|
||||
void Button::setOnReleased(ButtonEventFunction) {
|
||||
this->addEvent(new ReleaseEvent(fnct));
|
||||
}
|
||||
|
||||
void Button::setOnClicked(ButtonEventFunction) {
|
||||
setOnClicked(fnct, defaultMinPushTime, defaultMinReleaseTime);
|
||||
}
|
||||
|
||||
void Button::setOnClicked(ButtonEventFunction, uint32_t minPushTime) {
|
||||
setOnClicked(fnct, minPushTime, defaultMinReleaseTime);
|
||||
}
|
||||
|
||||
void Button::setOnClicked(ButtonEventFunction, uint32_t minPushTime, uint32_t minReleaseTime) {
|
||||
this->addEvent(new ClickEvent(fnct, minPushTime, minReleaseTime));
|
||||
}
|
||||
|
||||
void Button::setOnDoubleClicked(ButtonEventFunction) {
|
||||
setOnDoubleClicked(fnct, defaultMinPushTime, defaultMinReleaseTime, defaultTimeSpan);
|
||||
}
|
||||
|
||||
void Button::setOnDoubleClicked(ButtonEventFunction, uint32_t minPushTime) {
|
||||
setOnDoubleClicked(fnct, minPushTime, defaultMinReleaseTime, defaultTimeSpan);
|
||||
}
|
||||
|
||||
void Button::setOnDoubleClicked(ButtonEventFunction, uint32_t minPushTime, uint32_t timeSpan) {
|
||||
setOnDoubleClicked(fnct, minPushTime, defaultMinReleaseTime, timeSpan);
|
||||
}
|
||||
|
||||
void Button::setOnDoubleClicked(ButtonEventFunction, uint32_t minPushTime, uint32_t minReleaseTime, uint32_t timeSpan) {
|
||||
this->addEvent(new DoubleclickEvent(fnct, minPushTime, minReleaseTime, timeSpan));
|
||||
}
|
||||
|
||||
void Button::setOnHolding(ButtonEventFunction) {
|
||||
setOnHolding(fnct, defaultHoldInterval);
|
||||
}
|
||||
|
||||
void Button::setOnHolding(ButtonEventFunction, uint32_t interval) {
|
||||
this->addEvent(new HoldEvent(fnct, interval));
|
||||
}
|
||||
|
||||
void Button::clearEvents() {
|
||||
delete events;
|
||||
events = NULL;
|
||||
}
|
||||
|
||||
void Button::addEvent(Event* e) {
|
||||
if (events == NULL) events = e;
|
||||
else {
|
||||
Event* tmp = events;
|
||||
|
||||
while (tmp->next != NULL) tmp = tmp->next;
|
||||
tmp->next = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
111
esp8266_deauther/src/SimpleButton/Buttons/Button.h
Normal file
111
esp8266_deauther/src/SimpleButton/Buttons/Button.h
Normal file
@@ -0,0 +1,111 @@
|
||||
#ifndef SimpleButton_Button_h
|
||||
#define SimpleButton_Button_h
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "../Events/Event.h"
|
||||
#include "../Events/PushEvent.h"
|
||||
#include "../Events/ReleaseEvent.h"
|
||||
#include "../Events/ClickEvent.h"
|
||||
#include "../Events/DoubleclickEvent.h"
|
||||
#include "../Events/HoldEvent.h"
|
||||
|
||||
namespace simplebutton {
|
||||
class Button {
|
||||
public:
|
||||
Button();
|
||||
Button(uint8_t pin);
|
||||
Button(uint8_t pin, bool inverted);
|
||||
|
||||
virtual ~Button();
|
||||
|
||||
void setup(uint8_t pin, bool inverted);
|
||||
|
||||
virtual void enable();
|
||||
virtual void disable();
|
||||
virtual void reset();
|
||||
|
||||
virtual void push();
|
||||
virtual void release();
|
||||
|
||||
virtual void click();
|
||||
virtual void click(uint32_t time);
|
||||
|
||||
virtual int read();
|
||||
virtual void update();
|
||||
virtual void update(int state);
|
||||
virtual void updateEvents();
|
||||
|
||||
virtual bool isInverted();
|
||||
virtual bool isEnabled();
|
||||
virtual bool isSetup();
|
||||
|
||||
virtual bool getState();
|
||||
virtual int getClicks();
|
||||
virtual int getPushTime();
|
||||
|
||||
virtual bool pushed();
|
||||
virtual bool released();
|
||||
virtual bool clicked();
|
||||
virtual bool clicked(uint32_t minPushTime);
|
||||
virtual bool clicked(uint32_t minPushTime, uint32_t minReleaseTime);
|
||||
virtual bool doubleClicked();
|
||||
virtual bool doubleClicked(uint32_t minPushTime);
|
||||
virtual bool doubleClicked(uint32_t minPushTime, uint32_t timeSpan);
|
||||
virtual bool doubleClicked(uint32_t minPushTime, uint32_t minReleaseTime, uint32_t timeSpan);
|
||||
virtual bool holding();
|
||||
virtual bool holding(uint32_t interval);
|
||||
|
||||
virtual void setUpdateInterval(uint32_t updateInterval);
|
||||
virtual void setDefaultMinPushTime(uint32_t defaultMinPushTime);
|
||||
virtual void setDefaultMinReleaseTime(uint32_t defaultMinReleaseTime);
|
||||
virtual void setDefaultTimeSpan(uint32_t defaultTimeSpan);
|
||||
virtual void setDefaultHoldTime(uint32_t defaultHoldInterval);
|
||||
|
||||
virtual void setOnPushed(ButtonEventFunction);
|
||||
virtual void setOnReleased(ButtonEventFunction);
|
||||
virtual void setOnClicked(ButtonEventFunction);
|
||||
virtual void setOnClicked(ButtonEventFunction, uint32_t minPushTime);
|
||||
virtual void setOnClicked(ButtonEventFunction, uint32_t minPushTime, uint32_t minReleaseTime);
|
||||
virtual void setOnDoubleClicked(ButtonEventFunction);
|
||||
virtual void setOnDoubleClicked(ButtonEventFunction, uint32_t minPushTime);
|
||||
virtual void setOnDoubleClicked(ButtonEventFunction, uint32_t minPushTime, uint32_t timeSpan);
|
||||
virtual void setOnDoubleClicked(
|
||||
ButtonEventFunction, uint32_t minPushTime, uint32_t minReleaseTime, uint32_t timeSpan);
|
||||
virtual void setOnHolding(ButtonEventFunction);
|
||||
virtual void setOnHolding(ButtonEventFunction, uint32_t interval);
|
||||
|
||||
virtual void clearEvents();
|
||||
|
||||
protected:
|
||||
Event* events = NULL;
|
||||
|
||||
bool button_inverted = false;
|
||||
bool button_setup = false;
|
||||
bool button_enabled = false;
|
||||
bool state = false;
|
||||
bool pushedFlag = false;
|
||||
bool releasedFlag = false;
|
||||
bool holdFlag = false;
|
||||
|
||||
uint8_t button_pin = 255;
|
||||
|
||||
uint16_t clicks = 0;
|
||||
|
||||
uint32_t pushTime = 0;
|
||||
uint32_t releaseTime = 0;
|
||||
uint32_t prevPushTime = 0;
|
||||
uint32_t prevReleaseTime = 0;
|
||||
uint32_t holdTime = 0;
|
||||
uint32_t updateTime = 0;
|
||||
|
||||
uint32_t updateInterval = 5;
|
||||
uint32_t defaultMinPushTime = 40;
|
||||
uint32_t defaultMinReleaseTime = 40;
|
||||
uint32_t defaultTimeSpan = 500;
|
||||
uint32_t defaultHoldInterval = 500;
|
||||
|
||||
void addEvent(Event* e);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ifndef SimpleButton_Button_h
|
||||
77
esp8266_deauther/src/SimpleButton/Buttons/ButtonAnalog.cpp
Normal file
77
esp8266_deauther/src/SimpleButton/Buttons/ButtonAnalog.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "ButtonAnalog.h"
|
||||
|
||||
namespace simplebutton {
|
||||
ButtonAnalog::ButtonAnalog() {
|
||||
setup(255, 0, 1024);
|
||||
}
|
||||
|
||||
ButtonAnalog::ButtonAnalog(uint8_t pin) {
|
||||
setup(pin, 0, 1024);
|
||||
}
|
||||
|
||||
ButtonAnalog::ButtonAnalog(uint16_t minValue, uint16_t maxValue) {
|
||||
setup(255, minValue, maxValue);
|
||||
}
|
||||
|
||||
ButtonAnalog::ButtonAnalog(uint8_t pin, uint16_t minValue, uint16_t maxValue) {
|
||||
setup(pin, minValue, maxValue);
|
||||
}
|
||||
|
||||
ButtonAnalog::~ButtonAnalog() {}
|
||||
|
||||
void ButtonAnalog::setup(uint8_t pin, uint16_t minValue, uint16_t maxValue) {
|
||||
this->button_pin = pin;
|
||||
this->minValue = minValue;
|
||||
this->maxValue = maxValue;
|
||||
enable();
|
||||
}
|
||||
|
||||
int ButtonAnalog::read() {
|
||||
int currentState = 0;
|
||||
|
||||
if (button_enabled && button_setup) {
|
||||
currentState = analogRead(button_pin);
|
||||
}
|
||||
|
||||
return currentState;
|
||||
}
|
||||
|
||||
void ButtonAnalog::update() {
|
||||
if (millis() - updateTime >= updateInterval) {
|
||||
Button::updateEvents();
|
||||
if (button_enabled && button_setup) update(read());
|
||||
}
|
||||
}
|
||||
|
||||
void ButtonAnalog::update(int state) {
|
||||
uint16_t newState = state;
|
||||
|
||||
updateTime = millis();
|
||||
|
||||
value = newState;
|
||||
|
||||
if ((newState >= minValue) && (newState <= maxValue)) push();
|
||||
else release();
|
||||
}
|
||||
|
||||
void ButtonAnalog::setMin(uint16_t minValue) {
|
||||
this->minValue = minValue;
|
||||
}
|
||||
|
||||
void ButtonAnalog::setMax(uint16_t maxValue) {
|
||||
this->maxValue = maxValue;
|
||||
}
|
||||
|
||||
void ButtonAnalog::setBounds(uint16_t minValue, uint16_t maxValue) {
|
||||
setMin(minValue);
|
||||
setMax(maxValue);
|
||||
}
|
||||
|
||||
void ButtonAnalog::setValue(int value) {
|
||||
this->value = (uint16_t)value;
|
||||
}
|
||||
|
||||
uint16_t ButtonAnalog::getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
37
esp8266_deauther/src/SimpleButton/Buttons/ButtonAnalog.h
Normal file
37
esp8266_deauther/src/SimpleButton/Buttons/ButtonAnalog.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef SimpleButton_ButtonAnalog_h
|
||||
#define SimpleButton_ButtonAnalog_h
|
||||
|
||||
#include "Button.h"
|
||||
|
||||
|
||||
namespace simplebutton {
|
||||
class ButtonAnalog : public Button {
|
||||
public:
|
||||
ButtonAnalog();
|
||||
ButtonAnalog(uint8_t pin);
|
||||
ButtonAnalog(uint16_t minValue, uint16_t maxValue);
|
||||
ButtonAnalog(uint8_t pin, uint16_t minValue, uint16_t maxValue);
|
||||
|
||||
~ButtonAnalog();
|
||||
|
||||
void setup(uint8_t pin, uint16_t minValue, uint16_t maxValue);
|
||||
|
||||
int read();
|
||||
|
||||
void update();
|
||||
void update(int state);
|
||||
|
||||
void setMin(uint16_t minValue);
|
||||
void setMax(uint16_t maxValue);
|
||||
void setBounds(uint16_t minValue, uint16_t maxValue);
|
||||
|
||||
uint16_t getValue();
|
||||
void setValue(int value);
|
||||
|
||||
private:
|
||||
uint16_t minValue = 0;
|
||||
uint16_t maxValue = 1024;
|
||||
uint16_t value = 0;
|
||||
};
|
||||
}
|
||||
#endif // ifndef SimpleButton_ButtonAnalog_h
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "ButtonGPIOExpander.h"
|
||||
|
||||
namespace simplebutton {
|
||||
ButtonGPIOExpander::ButtonGPIOExpander() {
|
||||
setup(NULL, 255, false);
|
||||
}
|
||||
|
||||
ButtonGPIOExpander::ButtonGPIOExpander(GPIOExpander* pcf, uint8_t pin) {
|
||||
setup(pcf, pin, false);
|
||||
}
|
||||
|
||||
ButtonGPIOExpander::ButtonGPIOExpander(GPIOExpander* pcf, uint8_t pin, bool inverted) {
|
||||
setup(pcf, pin, inverted);
|
||||
}
|
||||
|
||||
ButtonGPIOExpander::~ButtonGPIOExpander() {}
|
||||
|
||||
void ButtonGPIOExpander::setup(GPIOExpander* pcf, uint8_t pin, bool inverted) {
|
||||
this->pcf = pcf;
|
||||
this->button_pin = pin;
|
||||
this->button_inverted = inverted;
|
||||
enable();
|
||||
}
|
||||
|
||||
void ButtonGPIOExpander::enable() {
|
||||
button_enabled = true;
|
||||
|
||||
if (pcf) {
|
||||
pcf->write(button_pin, 0);
|
||||
if (pcf->connected()) button_setup = true;
|
||||
}
|
||||
}
|
||||
|
||||
int ButtonGPIOExpander::read() {
|
||||
bool currentState = false;
|
||||
|
||||
if (button_enabled && button_setup) {
|
||||
currentState = pcf->read(button_pin) > 0;
|
||||
|
||||
if (button_inverted) currentState = !currentState;
|
||||
}
|
||||
|
||||
return (int)currentState;
|
||||
}
|
||||
|
||||
void ButtonGPIOExpander::update() {
|
||||
if (button_enabled && button_setup) {
|
||||
update(read());
|
||||
}
|
||||
}
|
||||
|
||||
void ButtonGPIOExpander::update(int state) {
|
||||
Button::update(state);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef SimpleButton_ButtonGPIOExpander_h
|
||||
#define SimpleButton_ButtonGPIOExpander_h
|
||||
|
||||
#include "Button.h"
|
||||
#include "../libs/GPIOExpander.h"
|
||||
#include "../libs/PCF8574.h"
|
||||
#include "../libs/PCF8575.h"
|
||||
#include "../libs/MCP23017.h"
|
||||
|
||||
namespace simplebutton {
|
||||
class ButtonGPIOExpander : public Button {
|
||||
public:
|
||||
ButtonGPIOExpander();
|
||||
ButtonGPIOExpander(GPIOExpander* pcf, uint8_t pin);
|
||||
ButtonGPIOExpander(GPIOExpander* pcf, uint8_t pin, bool inverted);
|
||||
|
||||
virtual ~ButtonGPIOExpander();
|
||||
|
||||
void setup(GPIOExpander* pcf, uint8_t pin, bool inverted);
|
||||
|
||||
virtual void enable();
|
||||
|
||||
virtual int read();
|
||||
virtual void update();
|
||||
virtual void update(int state);
|
||||
|
||||
protected:
|
||||
GPIOExpander* pcf = NULL;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ifndef SimpleButton_ButtonGPIOExpander_h
|
||||
28
esp8266_deauther/src/SimpleButton/Buttons/ButtonPullup.cpp
Normal file
28
esp8266_deauther/src/SimpleButton/Buttons/ButtonPullup.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "ButtonPullup.h"
|
||||
|
||||
namespace simplebutton {
|
||||
ButtonPullup::ButtonPullup() {
|
||||
setup(255);
|
||||
}
|
||||
|
||||
ButtonPullup::ButtonPullup(uint8_t pin) {
|
||||
setup(pin);
|
||||
}
|
||||
|
||||
ButtonPullup::~ButtonPullup() {}
|
||||
|
||||
void ButtonPullup::setup(uint8_t pin) {
|
||||
this->button_pin = pin;
|
||||
this->button_inverted = true;
|
||||
enable();
|
||||
}
|
||||
|
||||
void ButtonPullup::enable() {
|
||||
button_enabled = true;
|
||||
|
||||
if ((button_pin < 255) && !button_setup) {
|
||||
pinMode(button_pin, INPUT_PULLUP);
|
||||
button_setup = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
20
esp8266_deauther/src/SimpleButton/Buttons/ButtonPullup.h
Normal file
20
esp8266_deauther/src/SimpleButton/Buttons/ButtonPullup.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef SimpleButton_ButtonPullup_h
|
||||
#define SimpleButton_ButtonPullup_h
|
||||
|
||||
#include "Button.h"
|
||||
|
||||
namespace simplebutton {
|
||||
class ButtonPullup : public Button {
|
||||
public:
|
||||
ButtonPullup();
|
||||
ButtonPullup(uint8_t pin);
|
||||
|
||||
~ButtonPullup();
|
||||
|
||||
void setup(uint8_t pin);
|
||||
|
||||
void enable();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ifndef SimpleButton_ButtonPullup_h
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "ButtonPullupGPIOExpander.h"
|
||||
|
||||
namespace simplebutton {
|
||||
ButtonPullupGPIOExpander::ButtonPullupGPIOExpander() {
|
||||
setup(NULL, 255);
|
||||
}
|
||||
|
||||
ButtonPullupGPIOExpander::ButtonPullupGPIOExpander(GPIOExpander* pcf, uint8_t pin) {
|
||||
setup(pcf, pin);
|
||||
}
|
||||
|
||||
ButtonPullupGPIOExpander::~ButtonPullupGPIOExpander() {}
|
||||
|
||||
void ButtonPullupGPIOExpander::setup(GPIOExpander* pcf, uint8_t pin) {
|
||||
this->pcf = pcf;
|
||||
this->button_pin = pin;
|
||||
this->button_inverted = true;
|
||||
enable();
|
||||
}
|
||||
|
||||
void ButtonPullupGPIOExpander::enable() {
|
||||
button_enabled = true;
|
||||
|
||||
if (pcf) {
|
||||
pcf->write(button_pin, 1);
|
||||
if (pcf->connected()) button_setup = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef SimpleButton_ButtonPullupGPIOExpander_h
|
||||
#define SimpleButton_ButtonPullupGPIOExpander_h
|
||||
|
||||
#include "ButtonGPIOExpander.h"
|
||||
|
||||
namespace simplebutton {
|
||||
class ButtonPullupGPIOExpander : public ButtonGPIOExpander {
|
||||
public:
|
||||
ButtonPullupGPIOExpander();
|
||||
ButtonPullupGPIOExpander(GPIOExpander* pcf, uint8_t pin);
|
||||
|
||||
~ButtonPullupGPIOExpander();
|
||||
|
||||
void setup(GPIOExpander* pcf, uint8_t pin);
|
||||
|
||||
void enable();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ifndef SimpleButton_ButtonPullupGPIOExpander_h
|
||||
400
esp8266_deauther/src/SimpleButton/Buttons/PS2Gamepad.cpp
Normal file
400
esp8266_deauther/src/SimpleButton/Buttons/PS2Gamepad.cpp
Normal file
@@ -0,0 +1,400 @@
|
||||
#include "PS2Gamepad.h"
|
||||
|
||||
namespace simplebutton {
|
||||
#include "PS2Gamepad.h"
|
||||
|
||||
PS2Gamepad::PS2Gamepad() {}
|
||||
|
||||
PS2Gamepad::PS2Gamepad(uint8_t clockPin, uint8_t cmdPin, uint8_t attPin, uint8_t dataPin, bool analog) {
|
||||
setup(clockPin, cmdPin, attPin, dataPin, analog);
|
||||
}
|
||||
|
||||
PS2Gamepad::~PS2Gamepad() {
|
||||
if (up) delete up;
|
||||
if (down) delete down;
|
||||
if (left) delete left;
|
||||
if (right) delete right;
|
||||
|
||||
if (l1) delete l1;
|
||||
if (l2) delete l2;
|
||||
if (r1) delete r1;
|
||||
if (r2) delete r2;
|
||||
|
||||
if (square) delete square;
|
||||
if (triangle) delete triangle;
|
||||
if (cross) delete cross;
|
||||
if (circle) delete circle;
|
||||
|
||||
if (select) delete select;
|
||||
if (start) delete start;
|
||||
|
||||
if (analogLeft) delete analogLeft;
|
||||
if (analogRight) delete analogRight;
|
||||
}
|
||||
|
||||
void PS2Gamepad::setup(uint8_t clockPin, uint8_t cmdPin, uint8_t attPin, uint8_t dataPin, bool analog) {
|
||||
// pin setup
|
||||
this->clockPin = clockPin;
|
||||
this->cmdPin = cmdPin;
|
||||
this->attPin = attPin;
|
||||
this->dataPin = dataPin;
|
||||
this->rumbleEnabled = analog;
|
||||
this->pressureEnabled = analog;
|
||||
|
||||
pinMode(clockPin, OUTPUT);
|
||||
pinMode(attPin, OUTPUT);
|
||||
pinMode(cmdPin, OUTPUT);
|
||||
|
||||
pinMode(dataPin, INPUT_PULLUP);
|
||||
|
||||
digitalWrite(cmdPin, HIGH);
|
||||
digitalWrite(clockPin, HIGH);
|
||||
|
||||
// button setup
|
||||
if (!up) up = new ButtonAnalog(1, 255);
|
||||
if (!down) down = new ButtonAnalog(1, 255);
|
||||
if (!left) left = new ButtonAnalog(1, 255);
|
||||
if (!right) right = new ButtonAnalog(1, 255);
|
||||
|
||||
if (!l1) l1 = new ButtonAnalog(1, 255);
|
||||
if (!l2) l2 = new ButtonAnalog(1, 255);
|
||||
if (!r1) r1 = new ButtonAnalog(1, 255);
|
||||
if (!r2) r2 = new ButtonAnalog(1, 255);
|
||||
|
||||
if (!square) square = new ButtonAnalog(1, 255);
|
||||
if (!triangle) triangle = new ButtonAnalog(1, 255);
|
||||
if (!cross) cross = new ButtonAnalog(1, 255);
|
||||
if (!circle) circle = new ButtonAnalog(1, 255);
|
||||
|
||||
if (!select) select = new Button();
|
||||
if (!start) start = new Button();
|
||||
|
||||
if (!analogLeft) {
|
||||
analogLeft = new AnalogStick();
|
||||
analogLeft->setLogic(256);
|
||||
}
|
||||
if (!analogRight) {
|
||||
analogRight = new AnalogStick();
|
||||
analogRight->setLogic(256);
|
||||
}
|
||||
|
||||
// connection setup
|
||||
poll();
|
||||
delay(10);
|
||||
poll();
|
||||
delay(10);
|
||||
poll();
|
||||
|
||||
/*
|
||||
if ((gamepadData[1] != 0x41) && (gamepadData[1] != 0x73) && (gamepadData[1] != 0x79)) {
|
||||
errorCode = 1;
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
int tries = 0;
|
||||
bool success = false;
|
||||
|
||||
do {
|
||||
sendEnter();
|
||||
|
||||
delayMicroseconds(5);
|
||||
|
||||
digitalWrite(cmdPin, HIGH);
|
||||
digitalWrite(clockPin, HIGH);
|
||||
digitalWrite(attPin, LOW); // enable joystick
|
||||
|
||||
delayMicroseconds(5);
|
||||
|
||||
sendRead();
|
||||
|
||||
digitalWrite(attPin, HIGH); // disable joystick
|
||||
|
||||
sendMode();
|
||||
if (rumbleEnabled) sendRumble();
|
||||
if (pressureEnabled) sendBytesLarge();
|
||||
sendExit();
|
||||
|
||||
poll();
|
||||
|
||||
if ((gamepadData[1] == 0x79) || (gamepadData[1] == 0x73)) {
|
||||
success = true;
|
||||
} else {
|
||||
tries++;
|
||||
}
|
||||
} while (tries < 10 && !success);
|
||||
|
||||
if (!success) {
|
||||
errorCode = 2;
|
||||
} else {
|
||||
is_connected = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PS2Gamepad::update() {
|
||||
if (is_connected && (millis() - lastPoll > updateInterval)) {
|
||||
poll();
|
||||
|
||||
up->update(getDigitalValue(4));
|
||||
down->update(getDigitalValue(6));
|
||||
left->update(getDigitalValue(7));
|
||||
right->update(getDigitalValue(5));
|
||||
|
||||
l1->update(getDigitalValue(10));
|
||||
l2->update(getDigitalValue(8));
|
||||
r1->update(getDigitalValue(11));
|
||||
r2->update(getDigitalValue(9));
|
||||
|
||||
square->update(getDigitalValue(15));
|
||||
triangle->update(getDigitalValue(12));
|
||||
cross->update(getDigitalValue(14));
|
||||
circle->update(getDigitalValue(13));
|
||||
|
||||
select->update(getDigitalValue(0));
|
||||
start->update(getDigitalValue(3));
|
||||
|
||||
analogLeft->update(getAnalogValue(7), getAnalogValue(8), getDigitalValue(1));
|
||||
analogRight->update(getAnalogValue(5), getAnalogValue(6), getDigitalValue(2));
|
||||
|
||||
if (pressureEnabled) {
|
||||
up->setValue(getDigitalValue(4) | getAnalogValue(11));
|
||||
down->setValue(getDigitalValue(6) | getAnalogValue(12));
|
||||
left->setValue(getDigitalValue(7) | getAnalogValue(10));
|
||||
right->setValue(getDigitalValue(5) | getAnalogValue(9));
|
||||
|
||||
l1->setValue(getDigitalValue(10) | getAnalogValue(17));
|
||||
l2->setValue(getDigitalValue(8) | getAnalogValue(19));
|
||||
r1->setValue(getDigitalValue(11) | getAnalogValue(18));
|
||||
r2->setValue(getDigitalValue(9) | getAnalogValue(20));
|
||||
|
||||
square->setValue(getDigitalValue(15) | getAnalogValue(16));
|
||||
triangle->setValue(getDigitalValue(12) | getAnalogValue(13));
|
||||
cross->setValue(getDigitalValue(14) | getAnalogValue(15));
|
||||
circle->setValue(getDigitalValue(13) | getAnalogValue(14));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String PS2Gamepad::getError() {
|
||||
String msg;
|
||||
|
||||
switch (errorCode) {
|
||||
case 0:
|
||||
msg += String("OK");
|
||||
break;
|
||||
|
||||
case 1:
|
||||
msg += String("Mode not matched or not found [");
|
||||
msg += String(gamepadData[1], HEX);
|
||||
msg += String("]");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
msg += String("Not accepting commands [");
|
||||
msg += String(gamepadData[1], HEX);
|
||||
msg += String("]");
|
||||
break;
|
||||
}
|
||||
|
||||
errorCode = 0;
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
bool PS2Gamepad::connected() {
|
||||
return is_connected;
|
||||
}
|
||||
|
||||
void PS2Gamepad::setUpdateInterval(uint32_t updateInterval) {
|
||||
this->updateInterval = updateInterval;
|
||||
}
|
||||
|
||||
void PS2Gamepad::setMotors(uint8_t motorA, uint8_t motorB) {
|
||||
if (!rumbleEnabled) {
|
||||
rumbleEnabled = true;
|
||||
pressureEnabled = true;
|
||||
reconfig();
|
||||
}
|
||||
poll(motorA, motorB);
|
||||
}
|
||||
|
||||
void PS2Gamepad::reconfig() {
|
||||
sendEnter();
|
||||
sendMode();
|
||||
if (rumbleEnabled) sendRumble();
|
||||
if (pressureEnabled) sendBytesLarge();
|
||||
sendExit();
|
||||
}
|
||||
|
||||
void PS2Gamepad::poll() {
|
||||
if (millis() - lastPoll > 1500) reconfig();
|
||||
lastPoll = millis();
|
||||
|
||||
uint8_t dwordA[9] = { 0x01, 0x42, 0x00, motorA, motorB, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t dwordB[12] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
int tries = 0;
|
||||
bool success = false;
|
||||
|
||||
do {
|
||||
digitalWrite(cmdPin, HIGH);
|
||||
digitalWrite(clockPin, HIGH);
|
||||
digitalWrite(attPin, LOW); // low enable joystick
|
||||
|
||||
delayMicroseconds(5);
|
||||
|
||||
// send command to ask for data
|
||||
for (int i = 0; i < 9; i++) {
|
||||
gamepadData[i] = shift(dwordA[i]);
|
||||
}
|
||||
|
||||
// if controller is in full data return mode, get the rest of data
|
||||
if (gamepadData[1] == 0x79) {
|
||||
for (int i = 0; i < 12; i++) {
|
||||
gamepadData[i + 9] = shift(dwordB[i]);
|
||||
}
|
||||
}
|
||||
|
||||
digitalWrite(attPin, HIGH); // disable joystick
|
||||
|
||||
// Check to see if we received valid data or not.
|
||||
// We should be in analog mode for our data to be valid (analog == 0x7_)
|
||||
if ((gamepadData[1] & 0xf0) == 0x70) {
|
||||
success = true;
|
||||
} else {
|
||||
// If we got to here, we are not in analog mode, try to recover...
|
||||
reconfig();
|
||||
tries++;
|
||||
}
|
||||
} while (tries < 10 && !success);
|
||||
|
||||
prevButtonData = buttonData;
|
||||
|
||||
buttonData = ((uint16_t)gamepadData[4] << 8) | gamepadData[3];
|
||||
}
|
||||
|
||||
void PS2Gamepad::poll(uint8_t motorA, uint8_t motorB) {
|
||||
this->motorA = motorA;
|
||||
this->motorB = motorB;
|
||||
poll();
|
||||
}
|
||||
|
||||
bool PS2Gamepad::getDigitalValue(uint8_t button) {
|
||||
if (/*button >= 0 && */ button <= 15) return (~buttonData >> button) & 1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
uint8_t PS2Gamepad::getAnalogValue(uint8_t button) {
|
||||
return gamepadData[button];
|
||||
}
|
||||
|
||||
uint8_t PS2Gamepad::shift(uint8_t data) {
|
||||
uint8_t tmp = 0;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (data & (1 << i)) digitalWrite(cmdPin, HIGH);
|
||||
else digitalWrite(cmdPin, LOW);
|
||||
|
||||
digitalWrite(clockPin, LOW);
|
||||
delayMicroseconds(5);
|
||||
|
||||
if (digitalRead(dataPin)) bitSet(tmp, i);
|
||||
|
||||
digitalWrite(clockPin, HIGH);
|
||||
delayMicroseconds(5);
|
||||
}
|
||||
|
||||
digitalWrite(cmdPin, HIGH);
|
||||
delayMicroseconds(5);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void PS2Gamepad::sendEnter() {
|
||||
digitalWrite(attPin, LOW);
|
||||
|
||||
shift(0x01);
|
||||
shift(0x43);
|
||||
shift(0x00);
|
||||
shift(0x01);
|
||||
shift(0x00);
|
||||
|
||||
digitalWrite(attPin, HIGH);
|
||||
}
|
||||
|
||||
void PS2Gamepad::sendMode() {
|
||||
digitalWrite(attPin, LOW);
|
||||
|
||||
shift(0x01);
|
||||
shift(0x44);
|
||||
shift(0x00);
|
||||
shift(0x01);
|
||||
shift(0x03);
|
||||
shift(0x00);
|
||||
shift(0x00);
|
||||
shift(0x00);
|
||||
shift(0x00);
|
||||
|
||||
digitalWrite(attPin, HIGH);
|
||||
}
|
||||
|
||||
void PS2Gamepad::sendRumble() {
|
||||
digitalWrite(attPin, LOW);
|
||||
|
||||
shift(0x01);
|
||||
shift(0x4D);
|
||||
shift(0x00);
|
||||
shift(0x00);
|
||||
shift(0x01);
|
||||
|
||||
digitalWrite(attPin, HIGH);
|
||||
}
|
||||
|
||||
void PS2Gamepad::sendBytesLarge() {
|
||||
digitalWrite(attPin, LOW);
|
||||
|
||||
shift(0x01);
|
||||
shift(0x4F);
|
||||
shift(0x00);
|
||||
shift(0xFF);
|
||||
shift(0xFF);
|
||||
shift(0x03);
|
||||
shift(0x00);
|
||||
shift(0x00);
|
||||
shift(0x00);
|
||||
|
||||
digitalWrite(attPin, HIGH);
|
||||
}
|
||||
|
||||
void PS2Gamepad::sendExit() {
|
||||
digitalWrite(attPin, LOW);
|
||||
|
||||
shift(0x01);
|
||||
shift(0x43);
|
||||
shift(0x00);
|
||||
shift(0x00);
|
||||
shift(0x5A);
|
||||
shift(0x5A);
|
||||
shift(0x5A);
|
||||
shift(0x5A);
|
||||
shift(0x5A);
|
||||
|
||||
digitalWrite(attPin, HIGH);
|
||||
}
|
||||
|
||||
void PS2Gamepad::sendRead() {
|
||||
digitalWrite(attPin, LOW);
|
||||
|
||||
shift(0x01);
|
||||
shift(0x45);
|
||||
shift(0x00);
|
||||
controllerType = shift(0x5A);
|
||||
shift(0x5A);
|
||||
shift(0x5A);
|
||||
shift(0x5A);
|
||||
shift(0x5A);
|
||||
shift(0x5A);
|
||||
|
||||
digitalWrite(attPin, HIGH);
|
||||
}
|
||||
}
|
||||
93
esp8266_deauther/src/SimpleButton/Buttons/PS2Gamepad.h
Normal file
93
esp8266_deauther/src/SimpleButton/Buttons/PS2Gamepad.h
Normal file
@@ -0,0 +1,93 @@
|
||||
#ifndef SimpleButton_PS2Gamepad_h
|
||||
#define SimpleButton_PS2Gamepad_h
|
||||
|
||||
#include "Button.h"
|
||||
#include "AnalogStick.h"
|
||||
|
||||
namespace simplebutton {
|
||||
class PS2Gamepad {
|
||||
public:
|
||||
ButtonAnalog* up = NULL;
|
||||
ButtonAnalog* down = NULL;
|
||||
ButtonAnalog* left = NULL;
|
||||
ButtonAnalog* right = NULL;
|
||||
|
||||
ButtonAnalog* l1 = NULL;
|
||||
ButtonAnalog* l2 = NULL;
|
||||
ButtonAnalog* r1 = NULL;
|
||||
ButtonAnalog* r2 = NULL;
|
||||
|
||||
ButtonAnalog* square = NULL;
|
||||
ButtonAnalog* triangle = NULL;
|
||||
ButtonAnalog* cross = NULL;
|
||||
ButtonAnalog* circle = NULL;
|
||||
|
||||
Button* select = NULL;
|
||||
Button* start = NULL;
|
||||
|
||||
AnalogStick* analogLeft = NULL;
|
||||
AnalogStick* analogRight = NULL;
|
||||
|
||||
PS2Gamepad();
|
||||
PS2Gamepad(uint8_t clockPin, uint8_t cmdPin, uint8_t attPin, uint8_t dataPin, bool analog = true);
|
||||
~PS2Gamepad();
|
||||
|
||||
void setup(uint8_t clockPin, uint8_t cmdPin, uint8_t attPin, uint8_t dataPin, bool analog = true);
|
||||
void reconfig();
|
||||
|
||||
void update();
|
||||
|
||||
String getError();
|
||||
|
||||
bool connected();
|
||||
|
||||
void setUpdateInterval(uint32_t updateInterval);
|
||||
void setMotors(uint8_t motorA, uint8_t motorB);
|
||||
|
||||
private:
|
||||
void poll();
|
||||
void poll(uint8_t motorA, uint8_t motorB);
|
||||
|
||||
bool getDigitalValue(uint8_t button);
|
||||
uint8_t getAnalogValue(uint8_t button);
|
||||
|
||||
// config
|
||||
uint8_t motorA = 0x00; // 0 = OFF, 1 = ONN
|
||||
uint8_t motorB = 0x00; // usually 0-39 = OFF, 40 - 255 = ON
|
||||
|
||||
bool rumbleEnabled = false;
|
||||
bool pressureEnabled = false;
|
||||
|
||||
uint32_t updateInterval = 25;
|
||||
|
||||
// class variables
|
||||
bool is_connected = false;
|
||||
|
||||
uint8_t errorCode = 0;
|
||||
uint8_t controllerType = 0;
|
||||
uint8_t gamepadData[21];
|
||||
|
||||
uint16_t buttonData = 0;
|
||||
uint16_t prevButtonData = 0;
|
||||
|
||||
uint32_t lastPoll = 0;
|
||||
|
||||
uint8_t clockPin = 0;
|
||||
uint8_t cmdPin = 0;
|
||||
uint8_t attPin = 0;
|
||||
uint8_t dataPin = 0;
|
||||
|
||||
// in/output
|
||||
uint8_t shift(uint8_t data);
|
||||
|
||||
// commands
|
||||
void sendEnter();
|
||||
void sendMode();
|
||||
void sendRumble();
|
||||
void sendBytesLarge();
|
||||
void sendExit();
|
||||
void sendRead();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ifndef SimpleButton_PS2Gamepad_h
|
||||
172
esp8266_deauther/src/SimpleButton/Buttons/RotaryEncoder.cpp
Normal file
172
esp8266_deauther/src/SimpleButton/Buttons/RotaryEncoder.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
#include "RotaryEncoder.h"
|
||||
|
||||
namespace simplebutton {
|
||||
RotaryEncoder::RotaryEncoder() {
|
||||
setButtons(NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
RotaryEncoder::RotaryEncoder(uint8_t channelA, uint8_t channelB, uint8_t button) {
|
||||
setup(channelA, channelB, button);
|
||||
}
|
||||
|
||||
RotaryEncoder::RotaryEncoder(GPIOExpander* pcf, uint8_t channelA, uint8_t channelB, uint8_t button) {
|
||||
setup(pcf, channelA, channelB, button);
|
||||
}
|
||||
|
||||
RotaryEncoder::RotaryEncoder(Button* clockwise, Button* anticlockwise, Button* button) {
|
||||
setup(clockwise, anticlockwise, button);
|
||||
}
|
||||
|
||||
RotaryEncoder::~RotaryEncoder() {
|
||||
if (this->clockwise) delete this->clockwise;
|
||||
if (this->anticlockwise) delete this->anticlockwise;
|
||||
if (this->button) delete this->button;
|
||||
}
|
||||
|
||||
void RotaryEncoder::setup(uint8_t channelA, uint8_t channelB, uint8_t button) {
|
||||
this->clockwise = new ButtonPullup(channelA);
|
||||
this->anticlockwise = new ButtonPullup(channelB);
|
||||
this->button = new ButtonPullup(button);
|
||||
|
||||
prevA = clockwise->read();
|
||||
prevB = anticlockwise->read();
|
||||
}
|
||||
|
||||
void RotaryEncoder::setup(GPIOExpander* pcf, uint8_t channelA, uint8_t channelB, uint8_t button) {
|
||||
this->clockwise = new ButtonPullupGPIOExpander(pcf, channelA);
|
||||
this->anticlockwise = new ButtonPullupGPIOExpander(pcf, channelB);
|
||||
this->button = new ButtonPullupGPIOExpander(pcf, button);
|
||||
|
||||
prevA = clockwise->read();
|
||||
prevB = anticlockwise->read();
|
||||
}
|
||||
|
||||
void RotaryEncoder::setup(Button* clockwise, Button* anticlockwise, Button* button) {
|
||||
setButtons(clockwise, anticlockwise, button);
|
||||
|
||||
prevA = clockwise->read();
|
||||
prevB = anticlockwise->read();
|
||||
}
|
||||
|
||||
void RotaryEncoder::update() {
|
||||
update(clockwise->read(), anticlockwise->read(), button->read());
|
||||
}
|
||||
|
||||
void RotaryEncoder::update(bool stateA, bool stateB, bool buttonState) {
|
||||
button->update(buttonState);
|
||||
|
||||
if (curState == State::STILL) {
|
||||
if ((stateA != prevA) && (stateB == prevB)) {
|
||||
prevA = stateA;
|
||||
curState = State::ANTICLOCKWISE;
|
||||
} else if ((stateA == prevA) && (stateB != prevB)) {
|
||||
prevB = stateB;
|
||||
curState = State::CLOCKWISE;
|
||||
}
|
||||
} else if ((curState != State::STILL) && (stateA == stateB)) {
|
||||
prevA = stateA;
|
||||
prevB = stateB;
|
||||
|
||||
if (curState == prevState) steps++;
|
||||
else steps = 1;
|
||||
|
||||
if (steps >= button_steps) {
|
||||
if (curState == State::CLOCKWISE) {
|
||||
if (!inverted) goClockwise();
|
||||
else goAnticlockwise();
|
||||
} else if (curState == State::ANTICLOCKWISE) {
|
||||
if (!inverted) goAnticlockwise();
|
||||
else goClockwise();
|
||||
}
|
||||
|
||||
steps = 0;
|
||||
}
|
||||
|
||||
prevState = curState;
|
||||
curState = State::STILL;
|
||||
}
|
||||
}
|
||||
|
||||
void RotaryEncoder::reset() {
|
||||
button->reset();
|
||||
clockwise->reset();
|
||||
anticlockwise->reset();
|
||||
|
||||
curState = State::STILL;
|
||||
prevState = State::STILL;
|
||||
|
||||
steps = 0;
|
||||
}
|
||||
|
||||
int32_t RotaryEncoder::getPos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
void RotaryEncoder::setButtons(Button* clockwise, Button* anticlockwise, Button* button) {
|
||||
if (this->clockwise) delete this->clockwise;
|
||||
if (this->anticlockwise) delete this->anticlockwise;
|
||||
if (this->button) delete this->button;
|
||||
|
||||
this->clockwise = clockwise ? clockwise : new Button();
|
||||
this->anticlockwise = anticlockwise ? anticlockwise : new Button();
|
||||
this->button = button ? button : new Button();
|
||||
}
|
||||
|
||||
void RotaryEncoder::setPos(int32_t pos) {
|
||||
this->pos = pos;
|
||||
}
|
||||
|
||||
void RotaryEncoder::setMin(int32_t value) {
|
||||
this->min = value;
|
||||
}
|
||||
|
||||
void RotaryEncoder::setMax(int32_t value) {
|
||||
this->max = value;
|
||||
}
|
||||
|
||||
void RotaryEncoder::setEncoding(uint8_t steps) {
|
||||
if ((steps == 1) || (steps == 2) || (steps == 4)) this->button_steps = steps;
|
||||
}
|
||||
|
||||
void RotaryEncoder::enableLoop(bool loop) {
|
||||
this->loop = loop;
|
||||
}
|
||||
|
||||
void RotaryEncoder::setInverted(bool inverted) {
|
||||
this->inverted = inverted;
|
||||
}
|
||||
|
||||
void RotaryEncoder::goClockwise() {
|
||||
clockwise->click();
|
||||
anticlockwise->reset();
|
||||
if (pos < max) pos++;
|
||||
else if (loop) pos = min;
|
||||
}
|
||||
|
||||
void RotaryEncoder::goAnticlockwise() {
|
||||
anticlockwise->click();
|
||||
clockwise->reset();
|
||||
if (pos > min) pos--;
|
||||
else if (loop) pos = max;
|
||||
}
|
||||
|
||||
bool RotaryEncoder::clicked() {
|
||||
return button->clicked();
|
||||
}
|
||||
|
||||
bool RotaryEncoder::incremented() {
|
||||
return clockwise->clicked();
|
||||
}
|
||||
|
||||
bool RotaryEncoder::decremented() {
|
||||
return anticlockwise->clicked();
|
||||
}
|
||||
|
||||
bool RotaryEncoder::minVal() {
|
||||
return pos == min;
|
||||
}
|
||||
|
||||
bool RotaryEncoder::maxVal() {
|
||||
return pos == max;
|
||||
}
|
||||
}
|
||||
71
esp8266_deauther/src/SimpleButton/Buttons/RotaryEncoder.h
Normal file
71
esp8266_deauther/src/SimpleButton/Buttons/RotaryEncoder.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#ifndef SimpleButton_RotaryEncoder_h
|
||||
#define SimpleButton_RotaryEncoder_h
|
||||
|
||||
#include "Button.h"
|
||||
#include "ButtonPullup.h"
|
||||
#include "ButtonGPIOExpander.h"
|
||||
#include "ButtonPullupGPIOExpander.h"
|
||||
|
||||
namespace simplebutton {
|
||||
class RotaryEncoder {
|
||||
public:
|
||||
Button* button = NULL;
|
||||
Button* clockwise = NULL;
|
||||
Button* anticlockwise = NULL;
|
||||
|
||||
RotaryEncoder();
|
||||
RotaryEncoder(uint8_t channelA, uint8_t channelB, uint8_t button);
|
||||
RotaryEncoder(GPIOExpander* pcf, uint8_t channelA, uint8_t channelB, uint8_t button);
|
||||
RotaryEncoder(Button* clockwise, Button* anticlockwise, Button* button);
|
||||
|
||||
~RotaryEncoder();
|
||||
|
||||
void setup(uint8_t channelA, uint8_t channelB, uint8_t button);
|
||||
void setup(GPIOExpander* pcf, uint8_t channelA, uint8_t channelB, uint8_t button);
|
||||
void setup(Button* clockwise, Button* anticlockwise, Button* button);
|
||||
|
||||
void update();
|
||||
void update(bool stateA, bool stateB, bool buttonState);
|
||||
|
||||
void reset();
|
||||
|
||||
int32_t getPos();
|
||||
|
||||
void setButtons(Button* clockwise, Button* anticlockwise, Button* button);
|
||||
void setPos(int32_t pos);
|
||||
void enableLoop(bool loop);
|
||||
void setEncoding(uint8_t steps);
|
||||
void setMin(int32_t value);
|
||||
void setMax(int32_t value);
|
||||
void setInverted(bool inverted);
|
||||
|
||||
bool clicked();
|
||||
bool incremented();
|
||||
bool decremented();
|
||||
bool minVal();
|
||||
bool maxVal();
|
||||
|
||||
private:
|
||||
int32_t pos = 0;
|
||||
|
||||
bool prevA = false;
|
||||
bool prevB = false;
|
||||
|
||||
enum State { STILL = 0, CLOCKWISE = 1, ANTICLOCKWISE = 2 };
|
||||
State curState = State::STILL;
|
||||
State prevState = State::STILL;
|
||||
|
||||
uint8_t button_steps = 1; // how many steps per turn (encoding)
|
||||
uint8_t steps = 0; // tmp counter
|
||||
|
||||
int32_t min = -128;
|
||||
int32_t max = 127;
|
||||
bool loop = false;
|
||||
bool inverted = false;
|
||||
|
||||
void goClockwise();
|
||||
void goAnticlockwise();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ifndef SimpleButton_RotaryEncoder_h
|
||||
276
esp8266_deauther/src/SimpleButton/Buttons/RotaryEncoderI2C.cpp
Normal file
276
esp8266_deauther/src/SimpleButton/Buttons/RotaryEncoderI2C.cpp
Normal file
@@ -0,0 +1,276 @@
|
||||
#include "RotaryEncoderI2C.h"
|
||||
namespace simplebutton {
|
||||
RotaryEncoderI2C::RotaryEncoderI2C() {
|
||||
setup(0x30);
|
||||
}
|
||||
|
||||
RotaryEncoderI2C::RotaryEncoderI2C(uint8_t i2cAddress) {
|
||||
setup(i2cAddress);
|
||||
}
|
||||
|
||||
RotaryEncoderI2C::RotaryEncoderI2C(uint8_t i2cAddress, TwoWire* wire) {
|
||||
setup(i2cAddress, wire);
|
||||
}
|
||||
|
||||
RotaryEncoderI2C::~RotaryEncoderI2C() {}
|
||||
|
||||
void RotaryEncoderI2C::setup(uint8_t i2cAddress) {
|
||||
setup(i2cAddress, &Wire);
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::setup(uint8_t i2cAddress, TwoWire* wire) {
|
||||
this->i2cAddress = i2cAddress;
|
||||
this->wire = wire;
|
||||
|
||||
this->clockwise = new Button();
|
||||
this->anticlockwise = new Button();
|
||||
this->button = new Button();
|
||||
|
||||
setMin(-128);
|
||||
setMax(127);
|
||||
|
||||
begin();
|
||||
}
|
||||
|
||||
bool RotaryEncoderI2C::interrupt() {
|
||||
if (interruptEnable) return digitalRead(interruptPin) == LOW;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::enableInterrupt(uint8_t pin, bool pullup) {
|
||||
interruptPin = pin;
|
||||
interruptEnable = true;
|
||||
interruptPullup = pullup;
|
||||
pinMode(pin, INPUT);
|
||||
}
|
||||
|
||||
bool RotaryEncoderI2C::update() {
|
||||
if (interrupt()) {
|
||||
readStatus();
|
||||
|
||||
if (clicked()) button->click();
|
||||
|
||||
if (incremented()) clockwise->click();
|
||||
|
||||
if (decremented()) anticlockwise->click();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::begin() {
|
||||
uint8_t config = 0x00;
|
||||
|
||||
if (interruptEnable) config = config | 0x01;
|
||||
if (ledEnabled) config = config | 0x02;
|
||||
if (loop) config = config | 0x04;
|
||||
if (inverted) config = config | 0x08;
|
||||
if (!interruptPullup) config = config | 0x10;
|
||||
if (encoding) config = config | 0x20;
|
||||
|
||||
setConfig(config);
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::reset() {
|
||||
button->reset();
|
||||
clockwise->reset();
|
||||
anticlockwise->reset();
|
||||
|
||||
setConfig(0x80);
|
||||
update();
|
||||
}
|
||||
|
||||
bool RotaryEncoderI2C::connected() {
|
||||
return error == 0;
|
||||
}
|
||||
|
||||
String RotaryEncoderI2C::getError() {
|
||||
String msg;
|
||||
|
||||
switch (error) {
|
||||
case 0:
|
||||
msg += "OK";
|
||||
break;
|
||||
|
||||
case 1:
|
||||
msg += String(F("Data too long to fit in transmit buffer"));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
msg += String(F("Received NACK on transmit of address"));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
msg += String(F("Received NACK on transmit of data"));
|
||||
|
||||
case 4:
|
||||
msg += String(F("Unknown transmission error"));
|
||||
break;
|
||||
|
||||
case 5:
|
||||
msg += String(F("I2C error"));
|
||||
break;
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::setConfig(uint8_t config) {
|
||||
write(0x00, config);
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::enableLed(bool led) {
|
||||
ledEnabled = led;
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::enableLoop(bool loop) {
|
||||
this->loop = loop;
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::setEncoding(uint8_t encoding) {
|
||||
if (encoding == 1) this->encoding = false;
|
||||
else if (encoding == 2) this->encoding = true;
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::setInverted(bool inverted) {
|
||||
this->inverted = inverted;
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::setPos(int32_t value) {
|
||||
write(0x02, value);
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::setMin(int32_t value) {
|
||||
write(0x0A, value);
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::setMax(int32_t value) {
|
||||
write(0x06, value);
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::setLed(uint8_t valueA, uint8_t valueB) {
|
||||
setLedA(valueA);
|
||||
setLedB(valueB);
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::setLedA(uint8_t value) {
|
||||
if (ledEnabled) write(0x0E, value);
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::setLedB(uint8_t value) {
|
||||
if (ledEnabled) write(0x0F, value);
|
||||
}
|
||||
|
||||
int32_t RotaryEncoderI2C::getPos() {
|
||||
return read32(0x02);
|
||||
}
|
||||
|
||||
uint8_t RotaryEncoderI2C::readStatus() {
|
||||
status = read(0x01);
|
||||
return status;
|
||||
}
|
||||
|
||||
uint8_t RotaryEncoderI2C::readLedA() {
|
||||
return read(0x0E);
|
||||
}
|
||||
|
||||
uint8_t RotaryEncoderI2C::readLedB() {
|
||||
return read(0x0F);
|
||||
}
|
||||
|
||||
int32_t RotaryEncoderI2C::readMax() {
|
||||
return read32(0x06);
|
||||
}
|
||||
|
||||
int32_t RotaryEncoderI2C::readMin() {
|
||||
return read32(0x0A);
|
||||
}
|
||||
|
||||
bool RotaryEncoderI2C::clicked() {
|
||||
return status & 0x01;
|
||||
}
|
||||
|
||||
bool RotaryEncoderI2C::incremented() {
|
||||
return status & 0x02;
|
||||
}
|
||||
|
||||
bool RotaryEncoderI2C::decremented() {
|
||||
return status & 0x04;
|
||||
}
|
||||
|
||||
bool RotaryEncoderI2C::minVal() {
|
||||
return status & 0x10;
|
||||
}
|
||||
|
||||
bool RotaryEncoderI2C::maxVal() {
|
||||
return status & 0x08;
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::write(uint8_t address, uint8_t value) {
|
||||
wire->beginTransmission(i2cAddress);
|
||||
|
||||
wire->write(address);
|
||||
wire->write(value);
|
||||
|
||||
error = wire->endTransmission();
|
||||
}
|
||||
|
||||
void RotaryEncoderI2C::write(uint8_t address, int32_t value) {
|
||||
wire->beginTransmission(i2cAddress);
|
||||
|
||||
wire->write(address);
|
||||
wire->write(((uint32_t)value >> 24) & 0xFF);
|
||||
wire->write(((uint32_t)value >> 16) & 0xFF);
|
||||
wire->write(((uint32_t)value >> 8) & 0xFF);
|
||||
wire->write((uint32_t)value & 0xFF);
|
||||
|
||||
error = wire->endTransmission();
|
||||
}
|
||||
|
||||
uint8_t RotaryEncoderI2C::read(uint8_t address) {
|
||||
uint8_t data = 0xFF;
|
||||
|
||||
// ask for some sweet data
|
||||
|
||||
wire->beginTransmission(i2cAddress);
|
||||
wire->write(address);
|
||||
error = wire->endTransmission();
|
||||
|
||||
// read out the sweet data
|
||||
wire->requestFrom(i2cAddress, (uint8_t)1);
|
||||
|
||||
if (wire->available() == 1) {
|
||||
data = wire->read();
|
||||
} else {
|
||||
error = ROTARY_ENCODER_I2C_ERROR;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
int32_t RotaryEncoderI2C::read32(uint8_t address) {
|
||||
uint32_t data = 0xFFFFFFFF;
|
||||
|
||||
// ask for some sweet data
|
||||
wire->beginTransmission(i2cAddress);
|
||||
wire->write(address);
|
||||
error = wire->endTransmission();
|
||||
|
||||
// read out the sweet data
|
||||
wire->requestFrom(i2cAddress, (uint8_t)4);
|
||||
|
||||
if (wire->available() == 4) {
|
||||
data = wire->read();
|
||||
data = (data << 8) | wire->read();
|
||||
data = (data << 8) | wire->read();
|
||||
data = (data << 8) | wire->read();
|
||||
} else {
|
||||
error = ROTARY_ENCODER_I2C_ERROR;
|
||||
}
|
||||
|
||||
return (int32_t)data;
|
||||
}
|
||||
}
|
||||
92
esp8266_deauther/src/SimpleButton/Buttons/RotaryEncoderI2C.h
Normal file
92
esp8266_deauther/src/SimpleButton/Buttons/RotaryEncoderI2C.h
Normal file
@@ -0,0 +1,92 @@
|
||||
#ifndef SimpleButton_RotaryEncoderI2C_h
|
||||
#define SimpleButton_RotaryEncoderI2C_h
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <Wire.h>
|
||||
|
||||
#define ROTARY_ENCODER_I2C_ERROR 5
|
||||
|
||||
#include "Button.h"
|
||||
|
||||
namespace simplebutton {
|
||||
class RotaryEncoderI2C {
|
||||
public:
|
||||
Button* clockwise = NULL;
|
||||
Button* anticlockwise = NULL;
|
||||
Button* button = NULL;
|
||||
|
||||
RotaryEncoderI2C();
|
||||
RotaryEncoderI2C(uint8_t i2cAddress);
|
||||
RotaryEncoderI2C(uint8_t i2cAddressdress, TwoWire* wire);
|
||||
|
||||
~RotaryEncoderI2C();
|
||||
|
||||
void setup(uint8_t i2cAddress);
|
||||
void setup(uint8_t i2cAddress, TwoWire* wire);
|
||||
|
||||
bool update();
|
||||
|
||||
void begin();
|
||||
void reset();
|
||||
|
||||
bool connected();
|
||||
String getError();
|
||||
|
||||
void setConfig(uint8_t config);
|
||||
|
||||
void enableInterrupt(uint8_t pin, bool pullup);
|
||||
void enableLed(bool led);
|
||||
void enableLoop(bool loop);
|
||||
void setEncoding(uint8_t encoding);
|
||||
void setInverted(bool inverted);
|
||||
|
||||
bool interrupt();
|
||||
|
||||
void setPos(int32_t value);
|
||||
void setMin(int32_t value);
|
||||
void setMax(int32_t value);
|
||||
void setLed(uint8_t valueA, uint8_t valueB);
|
||||
void setLedA(uint8_t value);
|
||||
void setLedB(uint8_t value);
|
||||
|
||||
int32_t getPos();
|
||||
|
||||
uint8_t readStatus();
|
||||
uint8_t readLedA();
|
||||
uint8_t readLedB();
|
||||
int32_t readMax();
|
||||
int32_t readMin();
|
||||
|
||||
bool clicked();
|
||||
bool incremented();
|
||||
bool decremented();
|
||||
bool minVal();
|
||||
bool maxVal();
|
||||
|
||||
private:
|
||||
// temp variables
|
||||
uint8_t status = 0x00;
|
||||
uint8_t error = 0;
|
||||
|
||||
// i2c stuff
|
||||
uint8_t i2cAddress = 0x00;
|
||||
TwoWire* wire = NULL;
|
||||
|
||||
// config
|
||||
uint8_t interruptPin = 0;
|
||||
bool interruptEnable = false; // INTE
|
||||
bool interruptPullup = true;
|
||||
bool ledEnabled = false; // LEDE
|
||||
bool encoding = false; // x1 = false, x2 = true
|
||||
bool loop = false; // WRAPE
|
||||
bool inverted = false; // DIRE
|
||||
|
||||
// internal functions
|
||||
void write(uint8_t address, uint8_t value);
|
||||
void write(uint8_t address, int32_t value);
|
||||
|
||||
uint8_t read(uint8_t address);
|
||||
int32_t read32(uint8_t address);
|
||||
};
|
||||
}
|
||||
#endif // ifndef SimpleButton_RotaryEncoderI2C_h
|
||||
63
esp8266_deauther/src/SimpleButton/Buttons/Switch.cpp
Normal file
63
esp8266_deauther/src/SimpleButton/Buttons/Switch.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "Switch.h"
|
||||
|
||||
namespace simplebutton {
|
||||
Switch::Switch() {
|
||||
button = new Button();
|
||||
}
|
||||
|
||||
Switch::Switch(uint8_t pin) {
|
||||
setup(pin);
|
||||
}
|
||||
|
||||
Switch::Switch(GPIOExpander* pcf, uint8_t pin) {
|
||||
setup(pcf, pin);
|
||||
}
|
||||
|
||||
Switch::Switch(Button* button) {
|
||||
setup(button);
|
||||
}
|
||||
|
||||
Switch::~Switch() {
|
||||
if (this->button) delete this->button;
|
||||
}
|
||||
|
||||
void Switch::setup(uint8_t pin) {
|
||||
button = new Button(pin);
|
||||
tmpState = button->read();
|
||||
}
|
||||
|
||||
void Switch::setup(GPIOExpander* pcf, uint8_t pin) {
|
||||
button = new ButtonGPIOExpander(pcf, pin);
|
||||
tmpState = button->read();
|
||||
}
|
||||
|
||||
void Switch::setup(Button* button) {
|
||||
setButton(button);
|
||||
tmpState = button->read();
|
||||
}
|
||||
|
||||
void Switch::update() {
|
||||
update(button->read());
|
||||
}
|
||||
|
||||
void Switch::update(bool state) {
|
||||
bool prevState = tmpState;
|
||||
|
||||
tmpState = state > 0;
|
||||
|
||||
if (prevState != tmpState) button->click();
|
||||
}
|
||||
|
||||
void Switch::setButton(Button* button) {
|
||||
if (this->button) delete this->button;
|
||||
this->button = button ? button : new Button();
|
||||
}
|
||||
|
||||
bool Switch::getState() {
|
||||
return tmpState;
|
||||
}
|
||||
|
||||
bool Switch::clicked() {
|
||||
return button->clicked();
|
||||
}
|
||||
}
|
||||
36
esp8266_deauther/src/SimpleButton/Buttons/Switch.h
Normal file
36
esp8266_deauther/src/SimpleButton/Buttons/Switch.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef SimpleButton_Switch_h
|
||||
#define SimpleButton_Switch_h
|
||||
|
||||
#include "Button.h"
|
||||
#include "ButtonGPIOExpander.h"
|
||||
|
||||
namespace simplebutton {
|
||||
class Switch {
|
||||
public:
|
||||
Button* button = NULL;
|
||||
|
||||
Switch();
|
||||
Switch(uint8_t pin);
|
||||
Switch(GPIOExpander* pcf, uint8_t pin);
|
||||
Switch(Button* button);
|
||||
|
||||
~Switch();
|
||||
|
||||
void setup(uint8_t pin);
|
||||
void setup(GPIOExpander* pcf, uint8_t pin);
|
||||
void setup(Button* button);
|
||||
|
||||
void update();
|
||||
void update(bool state);
|
||||
|
||||
void setButton(Button* button);
|
||||
|
||||
bool getState();
|
||||
bool clicked();
|
||||
|
||||
private:
|
||||
bool tmpState = false;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ifndef SimpleButton_Switch_h
|
||||
28
esp8266_deauther/src/SimpleButton/Events/ClickEvent.cpp
Normal file
28
esp8266_deauther/src/SimpleButton/Events/ClickEvent.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "ClickEvent.h"
|
||||
|
||||
namespace simplebutton {
|
||||
ClickEvent::ClickEvent(ButtonEventFunction, uint32_t minPushTime, uint32_t minReleaseTime) {
|
||||
this->fnct = fnct;
|
||||
this->minPushTime = minPushTime;
|
||||
this->minReleaseTime = minReleaseTime;
|
||||
}
|
||||
|
||||
ClickEvent::~ClickEvent() {
|
||||
if (next) {
|
||||
delete next;
|
||||
next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ClickEvent::getMode() {
|
||||
return MODE::CLICKED;
|
||||
}
|
||||
|
||||
uint32_t ClickEvent::getMinPushTime() {
|
||||
return minPushTime;
|
||||
}
|
||||
|
||||
uint32_t ClickEvent::getMinReleaseTime() {
|
||||
return minReleaseTime;
|
||||
}
|
||||
}
|
||||
22
esp8266_deauther/src/SimpleButton/Events/ClickEvent.h
Normal file
22
esp8266_deauther/src/SimpleButton/Events/ClickEvent.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef SimpleButton_ClickEvent_h
|
||||
#define SimpleButton_ClickEvent_h
|
||||
|
||||
#include "Event.h"
|
||||
|
||||
namespace simplebutton {
|
||||
class ClickEvent : public Event {
|
||||
public:
|
||||
ClickEvent(ButtonEventFunction, uint32_t minPushTime, uint32_t minReleaseTime);
|
||||
~ClickEvent();
|
||||
|
||||
uint8_t getMode();
|
||||
uint32_t getMinPushTime();
|
||||
uint32_t getMinReleaseTime();
|
||||
|
||||
private:
|
||||
uint32_t minPushTime = 0;
|
||||
uint32_t minReleaseTime = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ifndef SimpleButton_ClickEvent_h
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "DoubleclickEvent.h"
|
||||
|
||||
namespace simplebutton {
|
||||
DoubleclickEvent::DoubleclickEvent(ButtonEventFunction, uint32_t minPushTime, uint32_t minReleaseTime,
|
||||
uint32_t timeSpan) {
|
||||
this->fnct = fnct;
|
||||
this->minPushTime = minPushTime;
|
||||
this->minReleaseTime = minReleaseTime;
|
||||
this->timeSpan = timeSpan;
|
||||
}
|
||||
|
||||
DoubleclickEvent::~DoubleclickEvent() {
|
||||
if (next) {
|
||||
delete next;
|
||||
next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t DoubleclickEvent::getMode() {
|
||||
return MODE::DOUBLECLICKED;
|
||||
}
|
||||
|
||||
uint32_t DoubleclickEvent::getMinPushTime() {
|
||||
return minPushTime;
|
||||
}
|
||||
|
||||
uint32_t DoubleclickEvent::getMinReleaseTime() {
|
||||
return minReleaseTime;
|
||||
}
|
||||
|
||||
uint32_t DoubleclickEvent::getTimeSpan() {
|
||||
return timeSpan;
|
||||
}
|
||||
}
|
||||
24
esp8266_deauther/src/SimpleButton/Events/DoubleclickEvent.h
Normal file
24
esp8266_deauther/src/SimpleButton/Events/DoubleclickEvent.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef SimpleButton_DoubleclickEvent_h
|
||||
#define SimpleButton_DoubleclickEvent_h
|
||||
|
||||
#include "Event.h"
|
||||
|
||||
namespace simplebutton {
|
||||
class DoubleclickEvent : public Event {
|
||||
public:
|
||||
DoubleclickEvent(ButtonEventFunction, uint32_t minPushTime, uint32_t minReleaseTime, uint32_t timeSpan);
|
||||
~DoubleclickEvent();
|
||||
|
||||
uint8_t getMode();
|
||||
uint32_t getMinPushTime();
|
||||
uint32_t getMinReleaseTime();
|
||||
uint32_t getTimeSpan();
|
||||
|
||||
private:
|
||||
uint32_t minPushTime = 0;
|
||||
uint32_t minReleaseTime = 0;
|
||||
uint32_t timeSpan = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ifndef SimpleButton_DoubleclickEvent_h
|
||||
34
esp8266_deauther/src/SimpleButton/Events/Event.cpp
Normal file
34
esp8266_deauther/src/SimpleButton/Events/Event.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include "Event.h"
|
||||
|
||||
namespace simplebutton {
|
||||
Event::~Event() {
|
||||
if (next) {
|
||||
delete next;
|
||||
next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Event::run() {
|
||||
if (fnct) fnct();
|
||||
}
|
||||
|
||||
uint8_t Event::getMode() {
|
||||
return MODE::NONE;
|
||||
}
|
||||
|
||||
uint32_t Event::getMinPushTime() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t Event::getMinReleaseTime() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t Event::getTimeSpan() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t Event::getInterval() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
30
esp8266_deauther/src/SimpleButton/Events/Event.h
Normal file
30
esp8266_deauther/src/SimpleButton/Events/Event.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef SimpleButton_Event_h
|
||||
#define SimpleButton_Event_h
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <functional>
|
||||
|
||||
#define ButtonEventFunction std::function<void()>fnct
|
||||
|
||||
namespace simplebutton {
|
||||
class Event {
|
||||
public:
|
||||
Event* next = NULL;
|
||||
enum MODE { NONE = 0, PUSHED = 1, RELEASED = 2, CLICKED = 3, DOUBLECLICKED = 4, HOLDING = 5 };
|
||||
|
||||
virtual ~Event();
|
||||
|
||||
virtual void run();
|
||||
|
||||
virtual uint8_t getMode();
|
||||
virtual uint32_t getMinPushTime();
|
||||
virtual uint32_t getMinReleaseTime();
|
||||
virtual uint32_t getTimeSpan();
|
||||
virtual uint32_t getInterval();
|
||||
|
||||
protected:
|
||||
ButtonEventFunction = NULL;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ifndef Event_h
|
||||
23
esp8266_deauther/src/SimpleButton/Events/HoldEvent.cpp
Normal file
23
esp8266_deauther/src/SimpleButton/Events/HoldEvent.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "HoldEvent.h"
|
||||
|
||||
namespace simplebutton {
|
||||
HoldEvent::HoldEvent(ButtonEventFunction, uint32_t interval) {
|
||||
this->fnct = fnct;
|
||||
this->interval = interval;
|
||||
}
|
||||
|
||||
HoldEvent::~HoldEvent() {
|
||||
if (next) {
|
||||
delete next;
|
||||
next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t HoldEvent::getMode() {
|
||||
return MODE::HOLDING;
|
||||
}
|
||||
|
||||
uint32_t HoldEvent::getInterval() {
|
||||
return interval;
|
||||
}
|
||||
}
|
||||
19
esp8266_deauther/src/SimpleButton/Events/HoldEvent.h
Normal file
19
esp8266_deauther/src/SimpleButton/Events/HoldEvent.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef SimpleButton_HoldEvent_h
|
||||
#define SimpleButton_HoldEvent_h
|
||||
|
||||
#include "Event.h"
|
||||
namespace simplebutton {
|
||||
class HoldEvent : public Event {
|
||||
public:
|
||||
HoldEvent(ButtonEventFunction, uint32_t interval);
|
||||
~HoldEvent();
|
||||
|
||||
uint8_t getMode();
|
||||
uint32_t getInterval();
|
||||
|
||||
private:
|
||||
uint32_t interval = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ifndef SimpleButton_HoldEvent_h
|
||||
18
esp8266_deauther/src/SimpleButton/Events/PushEvent.cpp
Normal file
18
esp8266_deauther/src/SimpleButton/Events/PushEvent.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "PushEvent.h"
|
||||
|
||||
namespace simplebutton {
|
||||
PushEvent::PushEvent(ButtonEventFunction) {
|
||||
this->fnct = fnct;
|
||||
}
|
||||
|
||||
PushEvent::~PushEvent() {
|
||||
if (next) {
|
||||
delete next;
|
||||
next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t PushEvent::getMode() {
|
||||
return MODE::PUSHED;
|
||||
}
|
||||
}
|
||||
16
esp8266_deauther/src/SimpleButton/Events/PushEvent.h
Normal file
16
esp8266_deauther/src/SimpleButton/Events/PushEvent.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef SimpleButton_PushEvent_h
|
||||
#define SimpleButton_PushEvent_h
|
||||
|
||||
#include "Event.h"
|
||||
|
||||
namespace simplebutton {
|
||||
class PushEvent : public Event {
|
||||
public:
|
||||
PushEvent(ButtonEventFunction);
|
||||
~PushEvent();
|
||||
|
||||
uint8_t getMode();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ifndef SimpleButton_PushEvent_h
|
||||
18
esp8266_deauther/src/SimpleButton/Events/ReleaseEvent.cpp
Normal file
18
esp8266_deauther/src/SimpleButton/Events/ReleaseEvent.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "ReleaseEvent.h"
|
||||
|
||||
namespace simplebutton {
|
||||
ReleaseEvent::ReleaseEvent(ButtonEventFunction) {
|
||||
this->fnct = fnct;
|
||||
}
|
||||
|
||||
ReleaseEvent::~ReleaseEvent() {
|
||||
if (next) {
|
||||
delete next;
|
||||
next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ReleaseEvent::getMode() {
|
||||
return MODE::RELEASED;
|
||||
}
|
||||
}
|
||||
16
esp8266_deauther/src/SimpleButton/Events/ReleaseEvent.h
Normal file
16
esp8266_deauther/src/SimpleButton/Events/ReleaseEvent.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef SimpleButton_ReleaseEvent_h
|
||||
#define SimpleButton_ReleaseEvent_h
|
||||
|
||||
#include "Event.h"
|
||||
|
||||
namespace simplebutton {
|
||||
class ReleaseEvent : public Event {
|
||||
public:
|
||||
ReleaseEvent(ButtonEventFunction);
|
||||
~ReleaseEvent();
|
||||
|
||||
uint8_t getMode();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ifndef SimpleButton_ReleaseEvent_h
|
||||
21
esp8266_deauther/src/SimpleButton/LICENSE
Normal file
21
esp8266_deauther/src/SimpleButton/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Stefan Kremser
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
15
esp8266_deauther/src/SimpleButton/SimpleButton.h
Normal file
15
esp8266_deauther/src/SimpleButton/SimpleButton.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef SimpleButton_h
|
||||
#define SimpleButton_h
|
||||
|
||||
#include "Buttons/Button.h"
|
||||
#include "Buttons/ButtonGPIOExpander.h"
|
||||
#include "Buttons/ButtonPullup.h"
|
||||
#include "Buttons/ButtonPullupGPIOExpander.h"
|
||||
#include "Buttons/ButtonAnalog.h"
|
||||
#include "Buttons/Switch.h"
|
||||
#include "Buttons/RotaryEncoder.h"
|
||||
#include "Buttons/RotaryEncoderI2C.h"
|
||||
#include "Buttons/AnalogStick.h"
|
||||
#include "Buttons/PS2Gamepad.h"
|
||||
|
||||
#endif // ifndef SimpleButton_h
|
||||
54
esp8266_deauther/src/SimpleButton/libs/GPIOExpander.cpp
Normal file
54
esp8266_deauther/src/SimpleButton/libs/GPIOExpander.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "GPIOExpander.h"
|
||||
|
||||
namespace simplebutton {
|
||||
void GPIOExpander::setup(uint8_t address) {
|
||||
this->wire = &Wire;
|
||||
this->address = address;
|
||||
write(0);
|
||||
}
|
||||
|
||||
void GPIOExpander::setup(uint8_t address, TwoWire* wire) {
|
||||
this->wire = wire;
|
||||
this->address = address;
|
||||
write(0);
|
||||
}
|
||||
|
||||
bool GPIOExpander::connected() {
|
||||
return error == 0;
|
||||
}
|
||||
|
||||
String GPIOExpander::getError() {
|
||||
String msg;
|
||||
|
||||
switch (error) {
|
||||
case 0:
|
||||
msg += String(F("OK"));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
msg += String(F("Data too long to fit in transmit buffer"));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
msg += String(F("Received NACK on transmit of address"));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
msg += String(F("Received NACK on transmit of data"));
|
||||
|
||||
case 4:
|
||||
msg += String(F("Unknown transmission error"));
|
||||
break;
|
||||
|
||||
case 5:
|
||||
msg += String(F("Pin error"));
|
||||
break;
|
||||
|
||||
case 6:
|
||||
msg += String(F("I2C error"));
|
||||
break;
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
37
esp8266_deauther/src/SimpleButton/libs/GPIOExpander.h
Normal file
37
esp8266_deauther/src/SimpleButton/libs/GPIOExpander.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef SimpleButton_GPIOExpander_h
|
||||
#define SimpleButton_GPIOExpander_h
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <Wire.h>
|
||||
|
||||
#define PCF_PIN_ERROR 5
|
||||
#define PCF_I2C_ERROR 6
|
||||
|
||||
namespace simplebutton {
|
||||
class GPIOExpander {
|
||||
public:
|
||||
virtual ~GPIOExpander() = default;
|
||||
|
||||
virtual void setup(uint8_t address);
|
||||
virtual void setup(uint8_t address, TwoWire* wire);
|
||||
|
||||
virtual int read() = 0;
|
||||
virtual int read(uint8_t pin) = 0;
|
||||
|
||||
virtual void write(int value) = 0;
|
||||
virtual void write(uint8_t pin, bool value) = 0;
|
||||
|
||||
virtual void toggle() = 0;
|
||||
virtual void toggle(uint8_t pin) = 0;
|
||||
|
||||
virtual bool connected();
|
||||
virtual String getError();
|
||||
|
||||
protected:
|
||||
uint8_t error = 0;
|
||||
|
||||
TwoWire* wire;
|
||||
uint8_t address;
|
||||
};
|
||||
}
|
||||
#endif // ifndef SimpleButton_GPIOExpander_h
|
||||
173
esp8266_deauther/src/SimpleButton/libs/MCP23017.cpp
Normal file
173
esp8266_deauther/src/SimpleButton/libs/MCP23017.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
#include "MCP23017.h"
|
||||
namespace simplebutton {
|
||||
MCP23017::MCP23017(uint8_t address) {
|
||||
setup(address);
|
||||
}
|
||||
|
||||
MCP23017::MCP23017(uint8_t address, TwoWire* wire) {
|
||||
setup(address, wire);
|
||||
}
|
||||
|
||||
MCP23017::~MCP23017() {}
|
||||
|
||||
void MCP23017::setup(uint8_t address) {
|
||||
setup(address, &Wire);
|
||||
}
|
||||
|
||||
void MCP23017::setup(uint8_t address, TwoWire* wire) {
|
||||
this->address = address;
|
||||
this->wire = wire;
|
||||
|
||||
setIO();
|
||||
setPullups();
|
||||
}
|
||||
|
||||
int MCP23017::read() {
|
||||
this->pinData = readRegister16(0x12); // 0x12 = GPIOA
|
||||
|
||||
return this->pinData;
|
||||
}
|
||||
|
||||
int MCP23017::read(uint8_t pin) {
|
||||
if (pin >= 16) {
|
||||
error = PCF_PIN_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// make sure the pin is set to be an input
|
||||
if (getPinMode(pin) == OUTPUT) {
|
||||
bool pullup = getPinState(pin);
|
||||
setPinMode(pin, pullup ? INPUT_PULLUP : INPUT);
|
||||
}
|
||||
|
||||
return (read() >> pin) & 0x1;
|
||||
}
|
||||
|
||||
void MCP23017::write(int value) {
|
||||
// make sure all pins are set as outputs
|
||||
for (int i = 0; i < 16; i++) {
|
||||
bool output = (value >> i) & 0x1;
|
||||
if (output && (getPinMode(i) != OUTPUT)) setPinMode(i, OUTPUT);
|
||||
}
|
||||
|
||||
this->pinData = value;
|
||||
|
||||
writeRegister(0x12, value); // 0x12 = GPIOA
|
||||
}
|
||||
|
||||
void MCP23017::write(uint8_t pin, bool value) {
|
||||
if (pin >= 16) {
|
||||
error = PCF_PIN_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (getPinState(pin) != value) toggle(pin);
|
||||
}
|
||||
|
||||
void MCP23017::toggle() {
|
||||
pinData = ~pinData;
|
||||
write(pinData);
|
||||
}
|
||||
|
||||
void MCP23017::toggle(uint8_t pin) {
|
||||
if (pin >= 16) {
|
||||
error = PCF_PIN_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
pinData ^= 1 << pin;
|
||||
write(pinData);
|
||||
}
|
||||
|
||||
void MCP23017::setIO() {
|
||||
writeRegister(0x00, this->pinModes); // 0x00 = IODIRA register
|
||||
}
|
||||
|
||||
void MCP23017::setPullups() {
|
||||
writeRegister(0x0C, this->pinPullups); // 0x0C = GPPUA register
|
||||
}
|
||||
|
||||
void MCP23017::setPinMode(uint8_t pin, uint8_t mode) {
|
||||
if (pin >= 16) {
|
||||
error = PCF_PIN_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (getPinMode(pin) == mode) return;
|
||||
|
||||
bool input = (mode == INPUT || mode == INPUT_PULLUP);
|
||||
bool pullup = (mode == INPUT_PULLUP);
|
||||
|
||||
bitWrite(pinModes, pin, input);
|
||||
bitWrite(pinPullups, pin, pullup);
|
||||
|
||||
setIO();
|
||||
setPullups();
|
||||
}
|
||||
|
||||
uint8_t MCP23017::getPinMode(uint8_t pin) {
|
||||
if (pin >= 16) {
|
||||
error = PCF_PIN_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool input = (this->pinModes >> pin) & 0x1;
|
||||
bool pullup = (this->pinPullups >> pin) & 0x1;
|
||||
|
||||
if (!input) return OUTPUT;
|
||||
|
||||
if (pullup) return INPUT_PULLUP;
|
||||
|
||||
return INPUT;
|
||||
}
|
||||
|
||||
bool MCP23017::getPinState(uint8_t pin) {
|
||||
if (pin >= 16) {
|
||||
error = PCF_PIN_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
return (pinData >> pin) & 0x1;
|
||||
}
|
||||
|
||||
uint8_t MCP23017::readRegister8(uint8_t address) {
|
||||
wire->beginTransmission(this->address);
|
||||
wire->write(address);
|
||||
error = wire->endTransmission();
|
||||
|
||||
wire->requestFrom(this->address, (uint8_t)1);
|
||||
|
||||
if (wire->available() == 1) {
|
||||
return wire->read();
|
||||
} else {
|
||||
error = PCF_I2C_ERROR;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t MCP23017::readRegister16(uint8_t address) {
|
||||
wire->beginTransmission(this->address);
|
||||
wire->write(address);
|
||||
error = wire->endTransmission();
|
||||
|
||||
wire->requestFrom(this->address, (uint8_t)2);
|
||||
|
||||
if (wire->available() == 2) {
|
||||
uint16_t dataA = wire->read();
|
||||
uint16_t dataB = wire->read();
|
||||
|
||||
return (dataB << 8) | dataA;
|
||||
} else {
|
||||
error = PCF_I2C_ERROR;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MCP23017::writeRegister(uint8_t address, uint16_t value) {
|
||||
wire->beginTransmission(this->address);
|
||||
wire->write(address);
|
||||
wire->write(value & 0xFF);
|
||||
wire->write(value >> 8);
|
||||
error = wire->endTransmission();
|
||||
}
|
||||
}
|
||||
46
esp8266_deauther/src/SimpleButton/libs/MCP23017.h
Normal file
46
esp8266_deauther/src/SimpleButton/libs/MCP23017.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef SimpleButton_MCP23017_h
|
||||
#define SimpleButton_MCP23017_h
|
||||
|
||||
#include "GPIOExpander.h"
|
||||
|
||||
namespace simplebutton {
|
||||
class MCP23017 : public GPIOExpander {
|
||||
public:
|
||||
MCP23017(uint8_t address);
|
||||
MCP23017(uint8_t address, TwoWire* wire);
|
||||
|
||||
~MCP23017();
|
||||
|
||||
void setup(uint8_t address);
|
||||
void setup(uint8_t address, TwoWire* wire);
|
||||
|
||||
int read();
|
||||
int read(uint8_t pin);
|
||||
|
||||
void write(int value);
|
||||
void write(uint8_t pin, bool value);
|
||||
|
||||
void toggle();
|
||||
void toggle(uint8_t pin);
|
||||
|
||||
private:
|
||||
uint16_t pinData = 0x0000;
|
||||
uint16_t pinModes = 0x0000;
|
||||
uint16_t pinPullups = 0x0000;
|
||||
|
||||
void setIO();
|
||||
void setPullups();
|
||||
|
||||
void setPinMode(uint8_t pin, uint8_t mode);
|
||||
uint8_t getPinMode(uint8_t pin);
|
||||
|
||||
bool getPinState(uint8_t pin);
|
||||
|
||||
uint8_t readRegister8(uint8_t address);
|
||||
uint16_t readRegister16(uint8_t address);
|
||||
|
||||
void writeRegister(uint8_t address, uint16_t value);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ifndef SimpleButton_MCP23017_h
|
||||
76
esp8266_deauther/src/SimpleButton/libs/PCF8574.cpp
Normal file
76
esp8266_deauther/src/SimpleButton/libs/PCF8574.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#include "PCF8574.h"
|
||||
|
||||
namespace simplebutton {
|
||||
PCF8574::PCF8574(uint8_t address) {
|
||||
setup(address);
|
||||
}
|
||||
|
||||
PCF8574::PCF8574(uint8_t address, TwoWire* wire) {
|
||||
setup(address, wire);
|
||||
}
|
||||
|
||||
PCF8574::~PCF8574() {}
|
||||
|
||||
int PCF8574::read() {
|
||||
wire->requestFrom(address, (uint8_t)1);
|
||||
|
||||
data = 0;
|
||||
|
||||
if (wire->available() >= 1) {
|
||||
data = wire->read();
|
||||
} else {
|
||||
error = PCF_I2C_ERROR;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
int PCF8574::read(uint8_t pin) {
|
||||
if (pin < 8) {
|
||||
data = read();
|
||||
return (data & (1 << pin)) > 0;
|
||||
} else {
|
||||
error = PCF_PIN_ERROR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void PCF8574::write(int value) {
|
||||
wire->beginTransmission(address);
|
||||
|
||||
pinModeMask &= 0xff00;
|
||||
pinModeMask |= value;
|
||||
data = pinModeMask;
|
||||
|
||||
wire->write(data);
|
||||
|
||||
error = wire->endTransmission();
|
||||
}
|
||||
|
||||
void PCF8574::write(uint8_t pin, bool value) {
|
||||
if (pin >= 8) {
|
||||
error = PCF_PIN_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value) pinModeMask |= value << pin;
|
||||
else pinModeMask &= ~(1 << pin);
|
||||
|
||||
write(pinModeMask);
|
||||
}
|
||||
|
||||
void PCF8574::toggle() {
|
||||
pinModeMask = ~pinModeMask;
|
||||
write(pinModeMask);
|
||||
}
|
||||
|
||||
void PCF8574::toggle(uint8_t pin) {
|
||||
if (pin < 8) {
|
||||
pinModeMask ^= 1 << pin;
|
||||
|
||||
write(pinModeMask);
|
||||
} else {
|
||||
error = PCF_PIN_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
28
esp8266_deauther/src/SimpleButton/libs/PCF8574.h
Normal file
28
esp8266_deauther/src/SimpleButton/libs/PCF8574.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef SimpleButton_PCF8574_h
|
||||
#define SimpleButton_PCF8574_h
|
||||
|
||||
#include "GPIOExpander.h"
|
||||
|
||||
namespace simplebutton {
|
||||
class PCF8574 : public GPIOExpander {
|
||||
public:
|
||||
PCF8574(uint8_t address);
|
||||
PCF8574(uint8_t address, TwoWire* wire);
|
||||
~PCF8574();
|
||||
|
||||
int read();
|
||||
int read(uint8_t pin);
|
||||
|
||||
void write(int value);
|
||||
void write(uint8_t pin, bool value);
|
||||
|
||||
void toggle();
|
||||
void toggle(uint8_t pin);
|
||||
|
||||
private:
|
||||
uint8_t data;
|
||||
uint8_t pinModeMask;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ifndef SimpleButton_PCF8574_h
|
||||
62
esp8266_deauther/src/SimpleButton/libs/PCF8575.cpp
Normal file
62
esp8266_deauther/src/SimpleButton/libs/PCF8575.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include "PCF8575.h"
|
||||
|
||||
namespace simplebutton {
|
||||
PCF8575::PCF8575(uint8_t address) {
|
||||
setup(address);
|
||||
}
|
||||
|
||||
PCF8575::PCF8575(uint8_t address, TwoWire* wire) {
|
||||
setup(address, wire);
|
||||
}
|
||||
|
||||
PCF8575::~PCF8575() {}
|
||||
|
||||
int PCF8575::read() {
|
||||
wire->requestFrom(address, (uint8_t)2);
|
||||
|
||||
data = 0;
|
||||
|
||||
if (wire->available() >= 2) {
|
||||
data = wire->read();
|
||||
data |= wire->read() << 8;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
int PCF8575::read(uint8_t pin) {
|
||||
data = read();
|
||||
|
||||
return (data & (1 << pin)) > 0;
|
||||
}
|
||||
|
||||
void PCF8575::write(int value) {
|
||||
wire->beginTransmission(address);
|
||||
|
||||
pinModeMask = value;
|
||||
data = pinModeMask;
|
||||
|
||||
wire->write((uint8_t)data);
|
||||
wire->write((uint8_t)(data >> 8));
|
||||
|
||||
wire->endTransmission();
|
||||
}
|
||||
|
||||
void PCF8575::write(uint8_t pin, bool value) {
|
||||
if (value) pinModeMask |= value << pin;
|
||||
else pinModeMask &= ~(1 << pin);
|
||||
|
||||
write(pinModeMask);
|
||||
}
|
||||
|
||||
void PCF8575::toggle() {
|
||||
pinModeMask = ~pinModeMask;
|
||||
write(pinModeMask);
|
||||
}
|
||||
|
||||
void PCF8575::toggle(uint8_t pin) {
|
||||
pinModeMask ^= 1 << pin;
|
||||
|
||||
write(pinModeMask);
|
||||
}
|
||||
}
|
||||
28
esp8266_deauther/src/SimpleButton/libs/PCF8575.h
Normal file
28
esp8266_deauther/src/SimpleButton/libs/PCF8575.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef SimpleButton_PCF8575_h
|
||||
#define SimpleButton_PCF8575_h
|
||||
|
||||
#include "GPIOExpander.h"
|
||||
|
||||
namespace simplebutton {
|
||||
class PCF8575 : public GPIOExpander {
|
||||
public:
|
||||
PCF8575(uint8_t address);
|
||||
PCF8575(uint8_t address, TwoWire* wire);
|
||||
|
||||
~PCF8575();
|
||||
|
||||
int read();
|
||||
int read(uint8_t pin);
|
||||
|
||||
void write(int value);
|
||||
void write(uint8_t pin, bool value);
|
||||
|
||||
void toggle();
|
||||
void toggle(uint8_t pin);
|
||||
|
||||
private:
|
||||
uint16_t data;
|
||||
uint16_t pinModeMask;
|
||||
};
|
||||
}
|
||||
#endif // ifndef SimpleButton_PCF8575_h
|
||||
1022
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/OLEDDisplay.cpp
Normal file
1022
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/OLEDDisplay.cpp
Normal file
File diff suppressed because it is too large
Load Diff
373
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/OLEDDisplay.h
Normal file
373
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/OLEDDisplay.h
Normal file
@@ -0,0 +1,373 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
* Copyright (c) 2018 by Fabrice Weinberg
|
||||
* Copyright (c) 2019 by Helmut Tschemernjak - www.radioshuttle.de
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
* Please support us by buying our products (and not the clones) from
|
||||
* https://thingpulse.com
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OLEDDISPLAY_h
|
||||
#define OLEDDISPLAY_h
|
||||
|
||||
#ifdef ARDUINO
|
||||
#include <Arduino.h>
|
||||
#elif __MBED__
|
||||
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
|
||||
|
||||
#include <mbed.h>
|
||||
#define delay(x) wait_ms(x)
|
||||
#define yield() void()
|
||||
|
||||
/*
|
||||
* This is a little Arduino String emulation to keep the OLEDDisplay
|
||||
* library code in common between Arduino and mbed-os
|
||||
*/
|
||||
class String {
|
||||
public:
|
||||
String(const char *s) { _str = s; };
|
||||
int length() { return strlen(_str); };
|
||||
const char *c_str() { return _str; };
|
||||
void toCharArray(char *buf, unsigned int bufsize, unsigned int index = 0) const {
|
||||
memcpy(buf, _str + index, std::min(bufsize, strlen(_str)));
|
||||
};
|
||||
private:
|
||||
const char *_str;
|
||||
};
|
||||
|
||||
#else
|
||||
#error "Unkown operating system"
|
||||
#endif
|
||||
|
||||
#include "OLEDDisplayFonts.h"
|
||||
|
||||
//#define DEBUG_OLEDDISPLAY(...) Serial.printf( __VA_ARGS__ )
|
||||
//#define DEBUG_OLEDDISPLAY(...) dprintf("%s", __VA_ARGS__ )
|
||||
|
||||
#ifndef DEBUG_OLEDDISPLAY
|
||||
#define DEBUG_OLEDDISPLAY(...)
|
||||
#endif
|
||||
|
||||
// Use DOUBLE BUFFERING by default
|
||||
#ifndef OLEDDISPLAY_REDUCE_MEMORY
|
||||
#define OLEDDISPLAY_DOUBLE_BUFFER
|
||||
#endif
|
||||
|
||||
// Header Values
|
||||
#define JUMPTABLE_BYTES 4
|
||||
|
||||
#define JUMPTABLE_LSB 1
|
||||
#define JUMPTABLE_SIZE 2
|
||||
#define JUMPTABLE_WIDTH 3
|
||||
#define JUMPTABLE_START 4
|
||||
|
||||
#define WIDTH_POS 0
|
||||
#define HEIGHT_POS 1
|
||||
#define FIRST_CHAR_POS 2
|
||||
#define CHAR_NUM_POS 3
|
||||
|
||||
|
||||
// Display commands
|
||||
#define CHARGEPUMP 0x8D
|
||||
#define COLUMNADDR 0x21
|
||||
#define COMSCANDEC 0xC8
|
||||
#define COMSCANINC 0xC0
|
||||
#define DISPLAYALLON 0xA5
|
||||
#define DISPLAYALLON_RESUME 0xA4
|
||||
#define DISPLAYOFF 0xAE
|
||||
#define DISPLAYON 0xAF
|
||||
#define EXTERNALVCC 0x1
|
||||
#define INVERTDISPLAY 0xA7
|
||||
#define MEMORYMODE 0x20
|
||||
#define NORMALDISPLAY 0xA6
|
||||
#define PAGEADDR 0x22
|
||||
#define SEGREMAP 0xA0
|
||||
#define SETCOMPINS 0xDA
|
||||
#define SETCONTRAST 0x81
|
||||
#define SETDISPLAYCLOCKDIV 0xD5
|
||||
#define SETDISPLAYOFFSET 0xD3
|
||||
#define SETHIGHCOLUMN 0x10
|
||||
#define SETLOWCOLUMN 0x00
|
||||
#define SETMULTIPLEX 0xA8
|
||||
#define SETPRECHARGE 0xD9
|
||||
#define SETSEGMENTREMAP 0xA1
|
||||
#define SETSTARTLINE 0x40
|
||||
#define SETVCOMDETECT 0xDB
|
||||
#define SWITCHCAPVCC 0x2
|
||||
|
||||
#ifndef _swap_int16_t
|
||||
#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; }
|
||||
#endif
|
||||
|
||||
enum OLEDDISPLAY_COLOR {
|
||||
BLACK = 0,
|
||||
WHITE = 1,
|
||||
INVERSE = 2
|
||||
};
|
||||
|
||||
enum OLEDDISPLAY_TEXT_ALIGNMENT {
|
||||
TEXT_ALIGN_LEFT = 0,
|
||||
TEXT_ALIGN_RIGHT = 1,
|
||||
TEXT_ALIGN_CENTER = 2,
|
||||
TEXT_ALIGN_CENTER_BOTH = 3
|
||||
};
|
||||
|
||||
|
||||
enum OLEDDISPLAY_GEOMETRY {
|
||||
GEOMETRY_128_64 = 0,
|
||||
GEOMETRY_128_32,
|
||||
GEOMETRY_RAWMODE,
|
||||
};
|
||||
|
||||
typedef char (*FontTableLookupFunction)(const uint8_t ch);
|
||||
char DefaultFontTableLookup(const uint8_t ch);
|
||||
|
||||
|
||||
#ifdef ARDUINO
|
||||
class OLEDDisplay : public Print {
|
||||
#elif __MBED__
|
||||
class OLEDDisplay : public Stream {
|
||||
#else
|
||||
#error "Unkown operating system"
|
||||
#endif
|
||||
|
||||
public:
|
||||
OLEDDisplay();
|
||||
virtual ~OLEDDisplay();
|
||||
|
||||
uint16_t width(void) const { return displayWidth; };
|
||||
uint16_t height(void) const { return displayHeight; };
|
||||
|
||||
// Use this to resume after a deep sleep without resetting the display (what init() would do).
|
||||
// Returns true if connection to the display was established and the buffer allocated, false otherwise.
|
||||
bool allocateBuffer();
|
||||
|
||||
// Allocates the buffer and initializes the driver & display. Resets the display!
|
||||
// Returns false if buffer allocation failed, true otherwise.
|
||||
bool init();
|
||||
|
||||
// Free the memory used by the display
|
||||
void end();
|
||||
|
||||
// Cycle through the initialization
|
||||
void resetDisplay(void);
|
||||
|
||||
/* Drawing functions */
|
||||
// Sets the color of all pixel operations
|
||||
void setColor(OLEDDISPLAY_COLOR color);
|
||||
|
||||
// Returns the current color.
|
||||
OLEDDISPLAY_COLOR getColor();
|
||||
|
||||
// Draw a pixel at given position
|
||||
void setPixel(int16_t x, int16_t y);
|
||||
|
||||
// Draw a pixel at given position and color
|
||||
void setPixelColor(int16_t x, int16_t y, OLEDDISPLAY_COLOR color);
|
||||
|
||||
// Clear a pixel at given position FIXME: INVERSE is untested with this function
|
||||
void clearPixel(int16_t x, int16_t y);
|
||||
|
||||
// Draw a line from position 0 to position 1
|
||||
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1);
|
||||
|
||||
// Draw the border of a rectangle at the given location
|
||||
void drawRect(int16_t x, int16_t y, int16_t width, int16_t height);
|
||||
|
||||
// Fill the rectangle
|
||||
void fillRect(int16_t x, int16_t y, int16_t width, int16_t height);
|
||||
|
||||
// Draw the border of a circle
|
||||
void drawCircle(int16_t x, int16_t y, int16_t radius);
|
||||
|
||||
// Draw all Quadrants specified in the quads bit mask
|
||||
void drawCircleQuads(int16_t x0, int16_t y0, int16_t radius, uint8_t quads);
|
||||
|
||||
// Fill circle
|
||||
void fillCircle(int16_t x, int16_t y, int16_t radius);
|
||||
|
||||
// Draw a line horizontally
|
||||
void drawHorizontalLine(int16_t x, int16_t y, int16_t length);
|
||||
|
||||
// Draw a line vertically
|
||||
void drawVerticalLine(int16_t x, int16_t y, int16_t length);
|
||||
|
||||
// Draws a rounded progress bar with the outer dimensions given by width and height. Progress is
|
||||
// a unsigned byte value between 0 and 100
|
||||
void drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress);
|
||||
|
||||
// Draw a bitmap in the internal image format
|
||||
void drawFastImage(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *image);
|
||||
|
||||
// Draw a XBM
|
||||
void drawXbm(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *xbm);
|
||||
|
||||
// Draw icon 16x16 xbm format
|
||||
void drawIco16x16(int16_t x, int16_t y, const char *ico, bool inverse = false);
|
||||
|
||||
/* Text functions */
|
||||
|
||||
// Draws a string at the given location
|
||||
void drawString(int16_t x, int16_t y, String text);
|
||||
|
||||
// Draws a String with a maximum width at the given location.
|
||||
// If the given String is wider than the specified width
|
||||
// The text will be wrapped to the next line at a space or dash
|
||||
void drawStringMaxWidth(int16_t x, int16_t y, uint16_t maxLineWidth, String text);
|
||||
|
||||
// Returns the width of the const char* with the current
|
||||
// font settings
|
||||
uint16_t getStringWidth(const char* text, uint16_t length);
|
||||
|
||||
// Convencience method for the const char version
|
||||
uint16_t getStringWidth(String text);
|
||||
|
||||
// Specifies relative to which anchor point
|
||||
// the text is rendered. Available constants:
|
||||
// TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER_BOTH
|
||||
void setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment);
|
||||
|
||||
// Sets the current font. Available default fonts
|
||||
// ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24
|
||||
void setFont(const uint8_t *fontData);
|
||||
|
||||
// Set the function that will convert utf-8 to font table index
|
||||
void setFontTableLookupFunction(FontTableLookupFunction function);
|
||||
|
||||
/* Display functions */
|
||||
|
||||
// Turn the display on
|
||||
void displayOn(void);
|
||||
|
||||
// Turn the display offs
|
||||
void displayOff(void);
|
||||
|
||||
// Inverted display mode
|
||||
void invertDisplay(void);
|
||||
|
||||
// Normal display mode
|
||||
void normalDisplay(void);
|
||||
|
||||
// Set display contrast
|
||||
// really low brightness & contrast: contrast = 10, precharge = 5, comdetect = 0
|
||||
// normal brightness & contrast: contrast = 100
|
||||
void setContrast(uint8_t contrast, uint8_t precharge = 241, uint8_t comdetect = 64);
|
||||
|
||||
// Convenience method to access
|
||||
void setBrightness(uint8_t);
|
||||
|
||||
// Reset display rotation or mirroring
|
||||
void resetOrientation();
|
||||
|
||||
// Turn the display upside down
|
||||
void flipScreenVertically();
|
||||
|
||||
// Mirror the display (to be used in a mirror or as a projector)
|
||||
void mirrorScreen();
|
||||
|
||||
// Write the buffer to the display memory
|
||||
virtual void display(void) = 0;
|
||||
|
||||
// Clear the local pixel buffer
|
||||
void clear(void);
|
||||
|
||||
// Log buffer implementation
|
||||
|
||||
// This will define the lines and characters you can
|
||||
// print to the screen. When you exeed the buffer size (lines * chars)
|
||||
// the output may be truncated due to the size constraint.
|
||||
bool setLogBuffer(uint16_t lines, uint16_t chars);
|
||||
|
||||
// Draw the log buffer at position (x, y)
|
||||
void drawLogBuffer(uint16_t x, uint16_t y);
|
||||
|
||||
// Get screen geometry
|
||||
uint16_t getWidth(void);
|
||||
uint16_t getHeight(void);
|
||||
|
||||
// Implement needed function to be compatible with Print class
|
||||
size_t write(uint8_t c);
|
||||
size_t write(const char* s);
|
||||
|
||||
// Implement needed function to be compatible with Stream class
|
||||
#ifdef __MBED__
|
||||
int _putc(int c);
|
||||
int _getc() { return -1; };
|
||||
#endif
|
||||
|
||||
|
||||
uint8_t *buffer;
|
||||
|
||||
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
|
||||
uint8_t *buffer_back;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
OLEDDISPLAY_GEOMETRY geometry;
|
||||
|
||||
uint16_t displayWidth;
|
||||
uint16_t displayHeight;
|
||||
uint16_t displayBufferSize;
|
||||
|
||||
// Set the correct height, width and buffer for the geometry
|
||||
void setGeometry(OLEDDISPLAY_GEOMETRY g, uint16_t width = 0, uint16_t height = 0);
|
||||
|
||||
OLEDDISPLAY_TEXT_ALIGNMENT textAlignment;
|
||||
OLEDDISPLAY_COLOR color;
|
||||
|
||||
const uint8_t *fontData;
|
||||
|
||||
// State values for logBuffer
|
||||
uint16_t logBufferSize;
|
||||
uint16_t logBufferFilled;
|
||||
uint16_t logBufferLine;
|
||||
uint16_t logBufferMaxLines;
|
||||
char *logBuffer;
|
||||
|
||||
|
||||
// the header size of the buffer used, e.g. for the SPI command header
|
||||
virtual int getBufferOffset(void) = 0;
|
||||
|
||||
// Send a command to the display (low level function)
|
||||
virtual void sendCommand(uint8_t com) {(void)com;};
|
||||
|
||||
// Connect to the display
|
||||
virtual bool connect() { return false; };
|
||||
|
||||
// Send all the init commands
|
||||
void sendInitCommands();
|
||||
|
||||
// converts utf8 characters to extended ascii
|
||||
char* utf8ascii(String s);
|
||||
|
||||
void inline drawInternal(int16_t xMove, int16_t yMove, int16_t width, int16_t height, const uint8_t *data, uint16_t offset, uint16_t bytesInData) __attribute__((always_inline));
|
||||
|
||||
void drawStringInternal(int16_t xMove, int16_t yMove, char* text, uint16_t textLength, uint16_t textWidth);
|
||||
|
||||
FontTableLookupFunction fontTableLookupFunction;
|
||||
};
|
||||
|
||||
#endif
|
||||
1278
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/OLEDDisplayFonts.h
Normal file
1278
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/OLEDDisplayFonts.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,469 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
* Copyright (c) 2018 by Fabrice Weinberg
|
||||
* Copyright (c) 2019 by Helmut Tschemernjak - www.radioshuttle.de
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
* Please support us by buying our products (and not the clones) from
|
||||
* https://thingpulse.com
|
||||
*
|
||||
*/
|
||||
|
||||
#include "OLEDDisplayUi.h"
|
||||
|
||||
void LoadingDrawDefault(OLEDDisplay *display, LoadingStage* stage, uint8_t progress) {
|
||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display->setFont(ArialMT_Plain_10);
|
||||
display->drawString(64, 18, stage->process);
|
||||
display->drawProgressBar(4, 32, 120, 8, progress);
|
||||
};
|
||||
|
||||
|
||||
OLEDDisplayUi::OLEDDisplayUi(OLEDDisplay *display) {
|
||||
this->display = display;
|
||||
|
||||
indicatorPosition = BOTTOM;
|
||||
indicatorDirection = LEFT_RIGHT;
|
||||
activeSymbol = ANIMATION_activeSymbol;
|
||||
inactiveSymbol = ANIMATION_inactiveSymbol;
|
||||
frameAnimationDirection = SLIDE_RIGHT;
|
||||
lastTransitionDirection = 1;
|
||||
ticksPerFrame = 151; // ~ 5000ms at 30 FPS
|
||||
ticksPerTransition = 15; // ~ 500ms at 30 FPS
|
||||
frameCount = 0;
|
||||
nextFrameNumber = -1;
|
||||
overlayCount = 0;
|
||||
indicatorDrawState = 1;
|
||||
loadingDrawFunction = LoadingDrawDefault;
|
||||
updateInterval = 33;
|
||||
state.lastUpdate = 0;
|
||||
state.ticksSinceLastStateSwitch = 0;
|
||||
state.frameState = FIXED;
|
||||
state.currentFrame = 0;
|
||||
state.frameTransitionDirection = 1;
|
||||
state.isIndicatorDrawen = true;
|
||||
state.manuelControll = false;
|
||||
state.userData = NULL;
|
||||
shouldDrawIndicators = true;
|
||||
autoTransition = true;
|
||||
}
|
||||
|
||||
void OLEDDisplayUi::init() {
|
||||
this->display->init();
|
||||
}
|
||||
|
||||
void OLEDDisplayUi::setTargetFPS(uint8_t fps){
|
||||
float oldInterval = this->updateInterval;
|
||||
this->updateInterval = ((float) 1.0 / (float) fps) * 1000;
|
||||
|
||||
// Calculate new ticksPerFrame
|
||||
float changeRatio = oldInterval / (float) this->updateInterval;
|
||||
this->ticksPerFrame *= changeRatio;
|
||||
this->ticksPerTransition *= changeRatio;
|
||||
}
|
||||
|
||||
// -/------ Automatic controll ------\-
|
||||
|
||||
void OLEDDisplayUi::enableAutoTransition(){
|
||||
this->autoTransition = true;
|
||||
}
|
||||
void OLEDDisplayUi::disableAutoTransition(){
|
||||
this->autoTransition = false;
|
||||
}
|
||||
void OLEDDisplayUi::setAutoTransitionForwards(){
|
||||
this->state.frameTransitionDirection = 1;
|
||||
this->lastTransitionDirection = 1;
|
||||
}
|
||||
void OLEDDisplayUi::setAutoTransitionBackwards(){
|
||||
this->state.frameTransitionDirection = -1;
|
||||
this->lastTransitionDirection = -1;
|
||||
}
|
||||
void OLEDDisplayUi::setTimePerFrame(uint16_t time){
|
||||
this->ticksPerFrame = (uint16_t) ( (float) time / (float) updateInterval);
|
||||
}
|
||||
void OLEDDisplayUi::setTimePerTransition(uint16_t time){
|
||||
this->ticksPerTransition = (uint16_t) ( (float) time / (float) updateInterval);
|
||||
}
|
||||
|
||||
// -/------ Customize indicator position and style -------\-
|
||||
void OLEDDisplayUi::enableIndicator(){
|
||||
this->state.isIndicatorDrawen = true;
|
||||
}
|
||||
|
||||
void OLEDDisplayUi::disableIndicator(){
|
||||
this->state.isIndicatorDrawen = false;
|
||||
}
|
||||
|
||||
void OLEDDisplayUi::enableAllIndicators(){
|
||||
this->shouldDrawIndicators = true;
|
||||
}
|
||||
|
||||
void OLEDDisplayUi::disableAllIndicators(){
|
||||
this->shouldDrawIndicators = false;
|
||||
}
|
||||
|
||||
void OLEDDisplayUi::setIndicatorPosition(IndicatorPosition pos) {
|
||||
this->indicatorPosition = pos;
|
||||
}
|
||||
void OLEDDisplayUi::setIndicatorDirection(IndicatorDirection dir) {
|
||||
this->indicatorDirection = dir;
|
||||
}
|
||||
void OLEDDisplayUi::setActiveSymbol(const uint8_t* symbol) {
|
||||
this->activeSymbol = symbol;
|
||||
}
|
||||
void OLEDDisplayUi::setInactiveSymbol(const uint8_t* symbol) {
|
||||
this->inactiveSymbol = symbol;
|
||||
}
|
||||
|
||||
|
||||
// -/----- Frame settings -----\-
|
||||
void OLEDDisplayUi::setFrameAnimation(AnimationDirection dir) {
|
||||
this->frameAnimationDirection = dir;
|
||||
}
|
||||
void OLEDDisplayUi::setFrames(FrameCallback* frameFunctions, uint8_t frameCount) {
|
||||
this->frameFunctions = frameFunctions;
|
||||
this->frameCount = frameCount;
|
||||
this->resetState();
|
||||
}
|
||||
|
||||
// -/----- Overlays ------\-
|
||||
void OLEDDisplayUi::setOverlays(OverlayCallback* overlayFunctions, uint8_t overlayCount){
|
||||
this->overlayFunctions = overlayFunctions;
|
||||
this->overlayCount = overlayCount;
|
||||
}
|
||||
|
||||
// -/----- Loading Process -----\-
|
||||
|
||||
void OLEDDisplayUi::setLoadingDrawFunction(LoadingDrawFunction loadingDrawFunction) {
|
||||
this->loadingDrawFunction = loadingDrawFunction;
|
||||
}
|
||||
|
||||
void OLEDDisplayUi::runLoadingProcess(LoadingStage* stages, uint8_t stagesCount) {
|
||||
uint8_t progress = 0;
|
||||
uint8_t increment = 100 / stagesCount;
|
||||
|
||||
for (uint8_t i = 0; i < stagesCount; i++) {
|
||||
display->clear();
|
||||
this->loadingDrawFunction(this->display, &stages[i], progress);
|
||||
display->display();
|
||||
|
||||
stages[i].callback();
|
||||
|
||||
progress += increment;
|
||||
yield();
|
||||
}
|
||||
|
||||
display->clear();
|
||||
this->loadingDrawFunction(this->display, &stages[stagesCount-1], progress);
|
||||
display->display();
|
||||
|
||||
delay(150);
|
||||
}
|
||||
|
||||
// -/----- Manuel control -----\-
|
||||
void OLEDDisplayUi::nextFrame() {
|
||||
if (this->state.frameState != IN_TRANSITION) {
|
||||
this->state.manuelControll = true;
|
||||
this->state.frameState = IN_TRANSITION;
|
||||
this->state.ticksSinceLastStateSwitch = 0;
|
||||
this->lastTransitionDirection = this->state.frameTransitionDirection;
|
||||
this->state.frameTransitionDirection = 1;
|
||||
}
|
||||
}
|
||||
void OLEDDisplayUi::previousFrame() {
|
||||
if (this->state.frameState != IN_TRANSITION) {
|
||||
this->state.manuelControll = true;
|
||||
this->state.frameState = IN_TRANSITION;
|
||||
this->state.ticksSinceLastStateSwitch = 0;
|
||||
this->lastTransitionDirection = this->state.frameTransitionDirection;
|
||||
this->state.frameTransitionDirection = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void OLEDDisplayUi::switchToFrame(uint8_t frame) {
|
||||
if (frame >= this->frameCount) return;
|
||||
this->state.ticksSinceLastStateSwitch = 0;
|
||||
if (frame == this->state.currentFrame) return;
|
||||
this->state.frameState = FIXED;
|
||||
this->state.currentFrame = frame;
|
||||
this->state.isIndicatorDrawen = true;
|
||||
}
|
||||
|
||||
void OLEDDisplayUi::transitionToFrame(uint8_t frame) {
|
||||
if (frame >= this->frameCount) return;
|
||||
this->state.ticksSinceLastStateSwitch = 0;
|
||||
if (frame == this->state.currentFrame) return;
|
||||
this->nextFrameNumber = frame;
|
||||
this->lastTransitionDirection = this->state.frameTransitionDirection;
|
||||
this->state.manuelControll = true;
|
||||
this->state.frameState = IN_TRANSITION;
|
||||
this->state.frameTransitionDirection = frame < this->state.currentFrame ? -1 : 1;
|
||||
}
|
||||
|
||||
|
||||
// -/----- State information -----\-
|
||||
OLEDDisplayUiState* OLEDDisplayUi::getUiState(){
|
||||
return &this->state;
|
||||
}
|
||||
|
||||
int16_t OLEDDisplayUi::update(){
|
||||
#ifdef ARDUINO
|
||||
unsigned long frameStart = millis();
|
||||
#elif __MBED__
|
||||
Timer t;
|
||||
t.start();
|
||||
unsigned long frameStart = t.read_ms();
|
||||
#else
|
||||
#error "Unkown operating system"
|
||||
#endif
|
||||
int16_t timeBudget = this->updateInterval - (frameStart - this->state.lastUpdate);
|
||||
if ( timeBudget <= 0) {
|
||||
// Implement frame skipping to ensure time budget is keept
|
||||
if (this->autoTransition && this->state.lastUpdate != 0) this->state.ticksSinceLastStateSwitch += ceil((double)-timeBudget / (double)this->updateInterval);
|
||||
|
||||
this->state.lastUpdate = frameStart;
|
||||
this->tick();
|
||||
}
|
||||
#ifdef ARDUINO
|
||||
return this->updateInterval - (millis() - frameStart);
|
||||
#elif __MBED__
|
||||
return this->updateInterval - (t.read_ms() - frameStart);
|
||||
#else
|
||||
#error "Unkown operating system"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void OLEDDisplayUi::tick() {
|
||||
this->state.ticksSinceLastStateSwitch++;
|
||||
|
||||
switch (this->state.frameState) {
|
||||
case IN_TRANSITION:
|
||||
if (this->state.ticksSinceLastStateSwitch >= this->ticksPerTransition){
|
||||
this->state.frameState = FIXED;
|
||||
this->state.currentFrame = getNextFrameNumber();
|
||||
this->state.ticksSinceLastStateSwitch = 0;
|
||||
this->nextFrameNumber = -1;
|
||||
}
|
||||
break;
|
||||
case FIXED:
|
||||
// Revert manuelControll
|
||||
if (this->state.manuelControll) {
|
||||
this->state.frameTransitionDirection = this->lastTransitionDirection;
|
||||
this->state.manuelControll = false;
|
||||
}
|
||||
if (this->state.ticksSinceLastStateSwitch >= this->ticksPerFrame){
|
||||
if (this->autoTransition){
|
||||
this->state.frameState = IN_TRANSITION;
|
||||
}
|
||||
this->state.ticksSinceLastStateSwitch = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
this->display->clear();
|
||||
this->drawFrame();
|
||||
if (shouldDrawIndicators) {
|
||||
this->drawIndicator();
|
||||
}
|
||||
this->drawOverlays();
|
||||
this->display->display();
|
||||
}
|
||||
|
||||
void OLEDDisplayUi::resetState() {
|
||||
this->state.lastUpdate = 0;
|
||||
this->state.ticksSinceLastStateSwitch = 0;
|
||||
this->state.frameState = FIXED;
|
||||
this->state.currentFrame = 0;
|
||||
this->state.isIndicatorDrawen = true;
|
||||
}
|
||||
|
||||
void OLEDDisplayUi::drawFrame(){
|
||||
switch (this->state.frameState){
|
||||
case IN_TRANSITION: {
|
||||
float progress = (float) this->state.ticksSinceLastStateSwitch / (float) this->ticksPerTransition;
|
||||
int16_t x = 0, y = 0, x1 = 0, y1 = 0;
|
||||
switch(this->frameAnimationDirection){
|
||||
case SLIDE_LEFT:
|
||||
x = -this->display->width() * progress;
|
||||
y = 0;
|
||||
x1 = x + this->display->width();
|
||||
y1 = 0;
|
||||
break;
|
||||
case SLIDE_RIGHT:
|
||||
x = this->display->width() * progress;
|
||||
y = 0;
|
||||
x1 = x - this->display->width();
|
||||
y1 = 0;
|
||||
break;
|
||||
case SLIDE_UP:
|
||||
x = 0;
|
||||
y = -this->display->height() * progress;
|
||||
x1 = 0;
|
||||
y1 = y + this->display->height();
|
||||
break;
|
||||
case SLIDE_DOWN:
|
||||
default:
|
||||
x = 0;
|
||||
y = this->display->height() * progress;
|
||||
x1 = 0;
|
||||
y1 = y - this->display->height();
|
||||
break;
|
||||
}
|
||||
|
||||
// Invert animation if direction is reversed.
|
||||
int8_t dir = this->state.frameTransitionDirection >= 0 ? 1 : -1;
|
||||
x *= dir; y *= dir; x1 *= dir; y1 *= dir;
|
||||
|
||||
bool drawenCurrentFrame;
|
||||
|
||||
|
||||
// Prope each frameFunction for the indicator Drawen state
|
||||
this->enableIndicator();
|
||||
(this->frameFunctions[this->state.currentFrame])(this->display, &this->state, x, y);
|
||||
drawenCurrentFrame = this->state.isIndicatorDrawen;
|
||||
|
||||
this->enableIndicator();
|
||||
(this->frameFunctions[this->getNextFrameNumber()])(this->display, &this->state, x1, y1);
|
||||
|
||||
// Build up the indicatorDrawState
|
||||
if (drawenCurrentFrame && !this->state.isIndicatorDrawen) {
|
||||
// Drawen now but not next
|
||||
this->indicatorDrawState = 2;
|
||||
} else if (!drawenCurrentFrame && this->state.isIndicatorDrawen) {
|
||||
// Not drawen now but next
|
||||
this->indicatorDrawState = 1;
|
||||
} else if (!drawenCurrentFrame && !this->state.isIndicatorDrawen) {
|
||||
// Not drawen in both frames
|
||||
this->indicatorDrawState = 3;
|
||||
}
|
||||
|
||||
// If the indicator isn't draw in the current frame
|
||||
// reflect it in state.isIndicatorDrawen
|
||||
if (!drawenCurrentFrame) this->state.isIndicatorDrawen = false;
|
||||
|
||||
break;
|
||||
}
|
||||
case FIXED:
|
||||
// Always assume that the indicator is drawn!
|
||||
// And set indicatorDrawState to "not known yet"
|
||||
this->indicatorDrawState = 0;
|
||||
this->enableIndicator();
|
||||
(this->frameFunctions[this->state.currentFrame])(this->display, &this->state, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OLEDDisplayUi::drawIndicator() {
|
||||
|
||||
// Only draw if the indicator is invisible
|
||||
// for both frames or
|
||||
// the indiactor is shown and we are IN_TRANSITION
|
||||
if (this->indicatorDrawState == 3 || (!this->state.isIndicatorDrawen && this->state.frameState != IN_TRANSITION)) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t posOfHighlightFrame = 0;
|
||||
float indicatorFadeProgress = 0;
|
||||
|
||||
// if the indicator needs to be slided in we want to
|
||||
// highlight the next frame in the transition
|
||||
uint8_t frameToHighlight = this->indicatorDrawState == 1 ? this->getNextFrameNumber() : this->state.currentFrame;
|
||||
|
||||
// Calculate the frame that needs to be highlighted
|
||||
// based on the Direction the indiactor is drawn
|
||||
switch (this->indicatorDirection){
|
||||
case LEFT_RIGHT:
|
||||
posOfHighlightFrame = frameToHighlight;
|
||||
break;
|
||||
case RIGHT_LEFT:
|
||||
default:
|
||||
posOfHighlightFrame = this->frameCount - frameToHighlight;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (this->indicatorDrawState) {
|
||||
case 1: // Indicator was not drawn in this frame but will be in next
|
||||
// Slide IN
|
||||
indicatorFadeProgress = 1 - ((float) this->state.ticksSinceLastStateSwitch / (float) this->ticksPerTransition);
|
||||
break;
|
||||
case 2: // Indicator was drawn in this frame but not in next
|
||||
// Slide OUT
|
||||
indicatorFadeProgress = ((float) this->state.ticksSinceLastStateSwitch / (float) this->ticksPerTransition);
|
||||
break;
|
||||
}
|
||||
|
||||
//Space between indicators - reduce for small screen sizes
|
||||
uint16_t indicatorSpacing = 12;
|
||||
if (this->display->getHeight() < 64 && (this->indicatorPosition == RIGHT || this->indicatorPosition == LEFT)) {
|
||||
indicatorSpacing = 6;
|
||||
}
|
||||
|
||||
uint16_t frameStartPos = (indicatorSpacing * frameCount / 2);
|
||||
const uint8_t *image;
|
||||
|
||||
uint16_t x = 0,y = 0;
|
||||
|
||||
|
||||
for (uint8_t i = 0; i < this->frameCount; i++) {
|
||||
|
||||
switch (this->indicatorPosition){
|
||||
case TOP:
|
||||
y = 0 - (8 * indicatorFadeProgress);
|
||||
x = (this->display->width() / 2) - frameStartPos + 12 * i;
|
||||
break;
|
||||
case BOTTOM:
|
||||
y = (this->display->height() - 8) + (8 * indicatorFadeProgress);
|
||||
x = (this->display->width() / 2) - frameStartPos + 12 * i;
|
||||
break;
|
||||
case RIGHT:
|
||||
x = (this->display->width() - 8) + (8 * indicatorFadeProgress);
|
||||
y = (this->display->height() / 2) - frameStartPos + 2 + 12 * i;
|
||||
break;
|
||||
case LEFT:
|
||||
default:
|
||||
x = 0 - (8 * indicatorFadeProgress);
|
||||
y = (this->display->height() / 2) - frameStartPos + 2 + indicatorSpacing * i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (posOfHighlightFrame == i) {
|
||||
image = this->activeSymbol;
|
||||
} else {
|
||||
image = this->inactiveSymbol;
|
||||
}
|
||||
|
||||
this->display->drawFastImage(x, y, 8, 8, image);
|
||||
}
|
||||
}
|
||||
|
||||
void OLEDDisplayUi::drawOverlays() {
|
||||
for (uint8_t i=0;i<this->overlayCount;i++){
|
||||
(this->overlayFunctions[i])(this->display, &this->state);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t OLEDDisplayUi::getNextFrameNumber(){
|
||||
if (this->nextFrameNumber != -1) return this->nextFrameNumber;
|
||||
return (this->state.currentFrame + this->frameCount + this->state.frameTransitionDirection) % this->frameCount;
|
||||
}
|
||||
312
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/OLEDDisplayUi.h
Normal file
312
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/OLEDDisplayUi.h
Normal file
@@ -0,0 +1,312 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
* Copyright (c) 2018 by Fabrice Weinberg
|
||||
* Copyright (c) 2019 by Helmut Tschemernjak - www.radioshuttle.de
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
* Please support us by buying our products (and not the clones) from
|
||||
* https://thingpulse.com
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OLEDDISPLAYUI_h
|
||||
#define OLEDDISPLAYUI_h
|
||||
|
||||
#ifdef ARDUINO
|
||||
#include <Arduino.h>
|
||||
#elif __MBED__
|
||||
#include <mbed.h>
|
||||
#else
|
||||
#error "Unkown operating system"
|
||||
#endif
|
||||
|
||||
#include "OLEDDisplay.h"
|
||||
|
||||
//#define DEBUG_OLEDDISPLAYUI(...) Serial.printf( __VA_ARGS__ )
|
||||
|
||||
#ifndef DEBUG_OLEDDISPLAYUI
|
||||
#define DEBUG_OLEDDISPLAYUI(...)
|
||||
#endif
|
||||
|
||||
enum AnimationDirection {
|
||||
SLIDE_UP,
|
||||
SLIDE_DOWN,
|
||||
SLIDE_LEFT,
|
||||
SLIDE_RIGHT
|
||||
};
|
||||
|
||||
enum IndicatorPosition {
|
||||
TOP,
|
||||
RIGHT,
|
||||
BOTTOM,
|
||||
LEFT
|
||||
};
|
||||
|
||||
enum IndicatorDirection {
|
||||
LEFT_RIGHT,
|
||||
RIGHT_LEFT
|
||||
};
|
||||
|
||||
enum FrameState {
|
||||
IN_TRANSITION,
|
||||
FIXED
|
||||
};
|
||||
|
||||
|
||||
const uint8_t ANIMATION_activeSymbol[] PROGMEM = {
|
||||
0x00, 0x18, 0x3c, 0x7e, 0x7e, 0x3c, 0x18, 0x00
|
||||
};
|
||||
|
||||
const uint8_t ANIMATION_inactiveSymbol[] PROGMEM = {
|
||||
0x00, 0x0, 0x0, 0x18, 0x18, 0x0, 0x0, 0x00
|
||||
};
|
||||
|
||||
|
||||
// Structure of the UiState
|
||||
struct OLEDDisplayUiState {
|
||||
uint64_t lastUpdate;
|
||||
uint16_t ticksSinceLastStateSwitch;
|
||||
|
||||
FrameState frameState;
|
||||
uint8_t currentFrame;
|
||||
|
||||
bool isIndicatorDrawen;
|
||||
|
||||
// Normal = 1, Inverse = -1;
|
||||
int8_t frameTransitionDirection;
|
||||
|
||||
bool manuelControll;
|
||||
|
||||
// Custom data that can be used by the user
|
||||
void* userData;
|
||||
};
|
||||
|
||||
struct LoadingStage {
|
||||
const char* process;
|
||||
void (*callback)();
|
||||
};
|
||||
|
||||
typedef void (*FrameCallback)(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
|
||||
typedef void (*OverlayCallback)(OLEDDisplay *display, OLEDDisplayUiState* state);
|
||||
typedef void (*LoadingDrawFunction)(OLEDDisplay *display, LoadingStage* stage, uint8_t progress);
|
||||
|
||||
class OLEDDisplayUi {
|
||||
private:
|
||||
OLEDDisplay *display;
|
||||
|
||||
// Symbols for the Indicator
|
||||
IndicatorPosition indicatorPosition;
|
||||
IndicatorDirection indicatorDirection;
|
||||
|
||||
const uint8_t* activeSymbol;
|
||||
const uint8_t* inactiveSymbol;
|
||||
|
||||
bool shouldDrawIndicators;
|
||||
|
||||
// Values for the Frames
|
||||
AnimationDirection frameAnimationDirection;
|
||||
|
||||
int8_t lastTransitionDirection;
|
||||
|
||||
uint16_t ticksPerFrame; // ~ 5000ms at 30 FPS
|
||||
uint16_t ticksPerTransition; // ~ 500ms at 30 FPS
|
||||
|
||||
bool autoTransition;
|
||||
|
||||
FrameCallback* frameFunctions;
|
||||
uint8_t frameCount;
|
||||
|
||||
// Internally used to transition to a specific frame
|
||||
int8_t nextFrameNumber;
|
||||
|
||||
// Values for Overlays
|
||||
OverlayCallback* overlayFunctions;
|
||||
uint8_t overlayCount;
|
||||
|
||||
// Will the Indicator be drawen
|
||||
// 3 Not drawn in both frames
|
||||
// 2 Drawn this frame but not next
|
||||
// 1 Not drown this frame but next
|
||||
// 0 Not known yet
|
||||
uint8_t indicatorDrawState;
|
||||
|
||||
// Loading screen
|
||||
LoadingDrawFunction loadingDrawFunction;
|
||||
|
||||
// UI State
|
||||
OLEDDisplayUiState state;
|
||||
|
||||
// Bookeeping for update
|
||||
uint16_t updateInterval = 33;
|
||||
|
||||
uint8_t getNextFrameNumber();
|
||||
void drawIndicator();
|
||||
void drawFrame();
|
||||
void drawOverlays();
|
||||
void tick();
|
||||
void resetState();
|
||||
|
||||
public:
|
||||
|
||||
OLEDDisplayUi(OLEDDisplay *display);
|
||||
|
||||
/**
|
||||
* Initialise the display
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* Configure the internal used target FPS
|
||||
*/
|
||||
void setTargetFPS(uint8_t fps);
|
||||
|
||||
// Automatic Controll
|
||||
/**
|
||||
* Enable automatic transition to next frame after the some time can be configured with `setTimePerFrame` and `setTimePerTransition`.
|
||||
*/
|
||||
void enableAutoTransition();
|
||||
|
||||
/**
|
||||
* Disable automatic transition to next frame.
|
||||
*/
|
||||
void disableAutoTransition();
|
||||
|
||||
/**
|
||||
* Set the direction if the automatic transitioning
|
||||
*/
|
||||
void setAutoTransitionForwards();
|
||||
void setAutoTransitionBackwards();
|
||||
|
||||
/**
|
||||
* Set the approx. time a frame is displayed
|
||||
*/
|
||||
void setTimePerFrame(uint16_t time);
|
||||
|
||||
/**
|
||||
* Set the approx. time a transition will take
|
||||
*/
|
||||
void setTimePerTransition(uint16_t time);
|
||||
|
||||
// Customize indicator position and style
|
||||
|
||||
/**
|
||||
* Draw the indicator.
|
||||
* This is the defaut state for all frames if
|
||||
* the indicator was hidden on the previous frame
|
||||
* it will be slided in.
|
||||
*/
|
||||
void enableIndicator();
|
||||
|
||||
/**
|
||||
* Don't draw the indicator.
|
||||
* This will slide out the indicator
|
||||
* when transitioning to the next frame.
|
||||
*/
|
||||
void disableIndicator();
|
||||
|
||||
/**
|
||||
* Enable drawing of indicators
|
||||
*/
|
||||
void enableAllIndicators();
|
||||
|
||||
/**
|
||||
* Disable draw of indicators.
|
||||
*/
|
||||
void disableAllIndicators();
|
||||
|
||||
/**
|
||||
* Set the position of the indicator bar.
|
||||
*/
|
||||
void setIndicatorPosition(IndicatorPosition pos);
|
||||
|
||||
/**
|
||||
* Set the direction of the indicator bar. Defining the order of frames ASCENDING / DESCENDING
|
||||
*/
|
||||
void setIndicatorDirection(IndicatorDirection dir);
|
||||
|
||||
/**
|
||||
* Set the symbol to indicate an active frame in the indicator bar.
|
||||
*/
|
||||
void setActiveSymbol(const uint8_t* symbol);
|
||||
|
||||
/**
|
||||
* Set the symbol to indicate an inactive frame in the indicator bar.
|
||||
*/
|
||||
void setInactiveSymbol(const uint8_t* symbol);
|
||||
|
||||
|
||||
// Frame settings
|
||||
|
||||
/**
|
||||
* Configure what animation is used to transition from one frame to another
|
||||
*/
|
||||
void setFrameAnimation(AnimationDirection dir);
|
||||
|
||||
/**
|
||||
* Add frame drawing functions
|
||||
*/
|
||||
void setFrames(FrameCallback* frameFunctions, uint8_t frameCount);
|
||||
|
||||
// Overlay
|
||||
|
||||
/**
|
||||
* Add overlays drawing functions that are draw independent of the Frames
|
||||
*/
|
||||
void setOverlays(OverlayCallback* overlayFunctions, uint8_t overlayCount);
|
||||
|
||||
|
||||
// Loading animation
|
||||
/**
|
||||
* Set the function that will draw each step
|
||||
* in the loading animation
|
||||
*/
|
||||
void setLoadingDrawFunction(LoadingDrawFunction loadingFunction);
|
||||
|
||||
|
||||
/**
|
||||
* Run the loading process
|
||||
*/
|
||||
void runLoadingProcess(LoadingStage* stages, uint8_t stagesCount);
|
||||
|
||||
|
||||
// Manual Control
|
||||
void nextFrame();
|
||||
void previousFrame();
|
||||
|
||||
/**
|
||||
* Switch without transition to frame `frame`.
|
||||
*/
|
||||
void switchToFrame(uint8_t frame);
|
||||
|
||||
/**
|
||||
* Transition to frame `frame`, when the `frame` number is bigger than the current
|
||||
* frame the forward animation will be used, otherwise the backwards animation is used.
|
||||
*/
|
||||
void transitionToFrame(uint8_t frame);
|
||||
|
||||
// State Info
|
||||
OLEDDisplayUiState* getUiState();
|
||||
|
||||
int16_t update();
|
||||
};
|
||||
#endif
|
||||
419
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/README.md
Normal file
419
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/README.md
Normal file
@@ -0,0 +1,419 @@
|
||||
[](https://travis-ci.org/ThingPulse/esp8266-oled-ssd1306)
|
||||
|
||||
# ThingPulse OLED SSD1306 (ESP8266/ESP32/Mbed-OS)
|
||||
|
||||
> We just released version 4.0.0. Please have a look at our [upgrade guide](UPGRADE-4.0.md)
|
||||
|
||||
This is a driver for SSD1306 128x64 and 128x32 OLED displays running on the Arduino/ESP8266 & ESP32 and mbed-os platforms.
|
||||
Can be used with either the I2C or SPI version of the display.
|
||||
|
||||
You can either download this library as a zip file and unpack it to your Arduino/libraries folder or find it in the Arduino library manager under "ESP8266 and ESP32 Oled Driver for SSD1306 display". For mbed-os a copy of the files are available as an mbed-os library.
|
||||
|
||||
It is also available as a platformio library. Just execute the following command:
|
||||
```
|
||||
platformio lib install 562
|
||||
```
|
||||
|
||||
## Service level promise
|
||||
|
||||
<table><tr><td><img src="https://thingpulse.com/assets/ThingPulse-open-source-prime.png" width="150">
|
||||
</td><td>This is a ThingPulse <em>prime</em> project. See our <a href="https://thingpulse.com/about/open-source-commitment/">open-source commitment declaration</a> for what this means.</td></tr></table>
|
||||
|
||||
## Credits
|
||||
|
||||
This library has initially been written by Daniel Eichhorn ([@squix78](https://github.com/squix78)). Many thanks go to Fabrice Weinberg ([@FWeinb](https://github.com/FWeinb)) for optimizing and refactoring many aspects of the library. Also many thanks to the many committers who helped to add new features and who fixed many bugs. Mbed-OS support and other improvements were contributed by Helmut Tschemernjak ([@helmut64](https://github.com/helmut64)).
|
||||
|
||||
The init sequence for the SSD1306 was inspired by Adafruit's library for the same display.
|
||||
|
||||
## mbed-os
|
||||
This library has been adopted to support the ARM mbed-os environment. A copy of this library is available in mbed-os under the name OLED_SSD1306 by Helmut Tschemernjak. An alternate installation option is to copy the following files into your mbed-os project: OLEDDisplay.cpp OLEDDisplay.h OLEDDisplayFonts.h OLEDDisplayUi.cpp OLEDDisplayUi.h SSD1306I2C.h
|
||||
|
||||
## Usage
|
||||
|
||||
Check out the examples folder for a few comprehensive demonstrations how to use the library. Also check out the [ESP8266 Weather Station](https://github.com/ThingPulse/esp8266-weather-station) library which uses the OLED library to display beautiful weather information.
|
||||
|
||||
## Upgrade
|
||||
|
||||
The API changed a lot with the 3.0 release. If you were using this library with older versions please have a look at the [Upgrade Guide](UPGRADE-3.0.md).
|
||||
|
||||
Going from 3.x version to 4.0 a lot of internals changed and compatibility for more displays was added. Please read the [Upgrade Guide](UPGRADE-4.0.md).
|
||||
|
||||
## Features
|
||||
|
||||
* Draw pixels at given coordinates
|
||||
* Draw lines from given coordinates to given coordinates
|
||||
* Draw or fill a rectangle with given dimensions
|
||||
* Draw Text at given coordinates:
|
||||
* Define Alignment: Left, Right and Center
|
||||
* Set the Fontface you want to use (see section Fonts below)
|
||||
* Limit the width of the text by an amount of pixels. Before this widths will be reached, the renderer will wrap the text to a new line if possible
|
||||
* Display content in automatically side scrolling carousel
|
||||
* Define transition cycles
|
||||
* Define how long one frame will be displayed
|
||||
* Draw the different frames in callback methods
|
||||
* One indicator per frame will be automatically displayed. The active frame will be displayed from inactive once
|
||||
|
||||
## Fonts
|
||||
|
||||
Fonts are defined in a proprietary but open format. You can create new font files by choosing from a given list
|
||||
of open sourced Fonts from this web app: http://oleddisplay.squix.ch
|
||||
Choose the font family, style and size, check the preview image and if you like what you see click the "Create" button. This will create the font array in a text area form where you can copy and paste it into a new or existing header file.
|
||||
|
||||
|
||||

|
||||
|
||||
## Hardware Abstraction
|
||||
|
||||
The library supports different protocols to access the OLED display. Currently there is support for I2C using the built in Wire.h library, I2C by using the much faster [BRZO I2C library](https://github.com/pasko-zh/brzo_i2c) written in assembler and it also supports displays which come with the SPI interface.
|
||||
|
||||
### I2C with Wire.h
|
||||
|
||||
```C++
|
||||
#include <Wire.h>
|
||||
#include "SSD1306Wire.h"
|
||||
|
||||
// for 128x64 displays:
|
||||
SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL
|
||||
// for 128x32 displays:
|
||||
// SSD1306Wire display(0x3c, SDA, SCL, GEOMETRY_128_32); // ADDRESS, SDA, SCL, GEOMETRY_128_32 (or 128_64)
|
||||
```
|
||||
|
||||
for a SH1106:
|
||||
```C++
|
||||
#include <Wire.h>
|
||||
#include "SH1106Wire.h"
|
||||
|
||||
SH1106Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL
|
||||
```
|
||||
|
||||
### I2C with brzo_i2c
|
||||
|
||||
```C++
|
||||
#include <brzo_i2c.h>
|
||||
#include "SSD1306Brzo.h"
|
||||
|
||||
SSD1306Brzo display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL
|
||||
```
|
||||
or for the SH1106:
|
||||
```C++
|
||||
#include <brzo_i2c.h>
|
||||
#include "SH1106Brzo.h"
|
||||
|
||||
SH1106Brzo display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL
|
||||
```
|
||||
|
||||
### SPI
|
||||
|
||||
```C++
|
||||
#include <SPI.h>
|
||||
#include "SSD1306Spi.h"
|
||||
|
||||
SSD1306Spi display(D0, D2, D8); // RES, DC, CS
|
||||
```
|
||||
or for the SH1106:
|
||||
```C++
|
||||
#include <SPI.h>
|
||||
#include "SH1106Spi.h"
|
||||
|
||||
SH1106Spi display(D0, D2); // RES, DC
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Display Control
|
||||
|
||||
```C++
|
||||
// Initialize the display
|
||||
void init();
|
||||
|
||||
// Free the memory used by the display
|
||||
void end();
|
||||
|
||||
// Cycle through the initialization
|
||||
void resetDisplay(void);
|
||||
|
||||
// Connect again to the display through I2C
|
||||
void reconnect(void);
|
||||
|
||||
// Turn the display on
|
||||
void displayOn(void);
|
||||
|
||||
// Turn the display offs
|
||||
void displayOff(void);
|
||||
|
||||
// Clear the local pixel buffer
|
||||
void clear(void);
|
||||
|
||||
// Write the buffer to the display memory
|
||||
void display(void);
|
||||
|
||||
// Inverted display mode
|
||||
void invertDisplay(void);
|
||||
|
||||
// Normal display mode
|
||||
void normalDisplay(void);
|
||||
|
||||
// Set display contrast
|
||||
// really low brightness & contrast: contrast = 10, precharge = 5, comdetect = 0
|
||||
// normal brightness & contrast: contrast = 100
|
||||
void setContrast(uint8_t contrast, uint8_t precharge = 241, uint8_t comdetect = 64);
|
||||
|
||||
// Convenience method to access
|
||||
void setBrightness(uint8_t);
|
||||
|
||||
// Turn the display upside down
|
||||
void flipScreenVertically();
|
||||
|
||||
// Draw the screen mirrored
|
||||
void mirrorScreen();
|
||||
```
|
||||
|
||||
## Pixel drawing
|
||||
|
||||
```C++
|
||||
|
||||
/* Drawing functions */
|
||||
// Sets the color of all pixel operations
|
||||
void setColor(OLEDDISPLAY_COLOR color);
|
||||
|
||||
// Draw a pixel at given position
|
||||
void setPixel(int16_t x, int16_t y);
|
||||
|
||||
// Draw a line from position 0 to position 1
|
||||
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1);
|
||||
|
||||
// Draw the border of a rectangle at the given location
|
||||
void drawRect(int16_t x, int16_t y, int16_t width, int16_t height);
|
||||
|
||||
// Fill the rectangle
|
||||
void fillRect(int16_t x, int16_t y, int16_t width, int16_t height);
|
||||
|
||||
// Draw the border of a circle
|
||||
void drawCircle(int16_t x, int16_t y, int16_t radius);
|
||||
|
||||
// Fill circle
|
||||
void fillCircle(int16_t x, int16_t y, int16_t radius);
|
||||
|
||||
// Draw a line horizontally
|
||||
void drawHorizontalLine(int16_t x, int16_t y, int16_t length);
|
||||
|
||||
// Draw a lin vertically
|
||||
void drawVerticalLine(int16_t x, int16_t y, int16_t length);
|
||||
|
||||
// Draws a rounded progress bar with the outer dimensions given by width and height. Progress is
|
||||
// a unsigned byte value between 0 and 100
|
||||
void drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress);
|
||||
|
||||
// Draw a bitmap in the internal image format
|
||||
void drawFastImage(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *image);
|
||||
|
||||
// Draw a XBM
|
||||
void drawXbm(int16_t x, int16_t y, int16_t width, int16_t height, const char* xbm);
|
||||
```
|
||||
|
||||
## Text operations
|
||||
|
||||
``` C++
|
||||
void drawString(int16_t x, int16_t y, String text);
|
||||
|
||||
// Draws a String with a maximum width at the given location.
|
||||
// If the given String is wider than the specified width
|
||||
// The text will be wrapped to the next line at a space or dash
|
||||
void drawStringMaxWidth(int16_t x, int16_t y, int16_t maxLineWidth, String text);
|
||||
|
||||
// Returns the width of the const char* with the current
|
||||
// font settings
|
||||
uint16_t getStringWidth(const char* text, uint16_t length);
|
||||
|
||||
// Convencience method for the const char version
|
||||
uint16_t getStringWidth(String text);
|
||||
|
||||
// Specifies relative to which anchor point
|
||||
// the text is rendered. Available constants:
|
||||
// TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER_BOTH
|
||||
void setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment);
|
||||
|
||||
// Sets the current font. Available default fonts
|
||||
// ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24
|
||||
// Or create one with the font tool at http://oleddisplay.squix.ch
|
||||
void setFont(const uint8_t* fontData);
|
||||
```
|
||||
|
||||
## Ui Library (OLEDDisplayUi)
|
||||
|
||||
The Ui Library is used to provide a basic set of Ui elements called, `Frames` and `Overlays`. A `Frame` is used to provide
|
||||
information the default behaviour is to display a `Frame` for a defined time and than move to the next. The library also provides an `Indicator` that will be updated accordingly. An `Overlay` on the other hand is a pieces of information (e.g. a clock) that is displayed always at the same position.
|
||||
|
||||
|
||||
```C++
|
||||
/**
|
||||
* Initialise the display
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* Configure the internal used target FPS
|
||||
*/
|
||||
void setTargetFPS(uint8_t fps);
|
||||
|
||||
/**
|
||||
* Enable automatic transition to next frame after the some time can be configured with
|
||||
* `setTimePerFrame` and `setTimePerTransition`.
|
||||
*/
|
||||
void enableAutoTransition();
|
||||
|
||||
/**
|
||||
* Disable automatic transition to next frame.
|
||||
*/
|
||||
void disableAutoTransition();
|
||||
|
||||
/**
|
||||
* Set the direction if the automatic transitioning
|
||||
*/
|
||||
void setAutoTransitionForwards();
|
||||
void setAutoTransitionBackwards();
|
||||
|
||||
/**
|
||||
* Set the approx. time a frame is displayed
|
||||
*/
|
||||
void setTimePerFrame(uint16_t time);
|
||||
|
||||
/**
|
||||
* Set the approx. time a transition will take
|
||||
*/
|
||||
void setTimePerTransition(uint16_t time);
|
||||
|
||||
/**
|
||||
* Draw the indicator.
|
||||
* This is the default state for all frames if
|
||||
* the indicator was hidden on the previous frame
|
||||
* it will be slided in.
|
||||
*/
|
||||
void enableIndicator();
|
||||
|
||||
/**
|
||||
* Don't draw the indicator.
|
||||
* This will slide out the indicator
|
||||
* when transitioning to the next frame.
|
||||
*/
|
||||
void disableIndicator();
|
||||
|
||||
/**
|
||||
* Enable drawing of all indicators.
|
||||
*/
|
||||
void enableAllIndicators();
|
||||
|
||||
/**
|
||||
* Disable drawing of all indicators.
|
||||
*/
|
||||
void disableAllIndicators();
|
||||
|
||||
/**
|
||||
* Set the position of the indicator bar.
|
||||
*/
|
||||
void setIndicatorPosition(IndicatorPosition pos);
|
||||
|
||||
/**
|
||||
* Set the direction of the indicator bar. Defining the order of frames ASCENDING / DESCENDING
|
||||
*/
|
||||
void setIndicatorDirection(IndicatorDirection dir);
|
||||
|
||||
/**
|
||||
* Set the symbol to indicate an active frame in the indicator bar.
|
||||
*/
|
||||
void setActiveSymbol(const char* symbol);
|
||||
|
||||
/**
|
||||
* Set the symbol to indicate an inactive frame in the indicator bar.
|
||||
*/
|
||||
void setInactiveSymbol(const char* symbol);
|
||||
|
||||
/**
|
||||
* Configure what animation is used to transition from one frame to another
|
||||
*/
|
||||
void setFrameAnimation(AnimationDirection dir);
|
||||
|
||||
/**
|
||||
* Add frame drawing functions
|
||||
*/
|
||||
void setFrames(FrameCallback* frameFunctions, uint8_t frameCount);
|
||||
|
||||
/**
|
||||
* Add overlays drawing functions that are draw independent of the Frames
|
||||
*/
|
||||
void setOverlays(OverlayCallback* overlayFunctions, uint8_t overlayCount);
|
||||
|
||||
/**
|
||||
* Set the function that will draw each step
|
||||
* in the loading animation
|
||||
*/
|
||||
void setLoadingDrawFunction(LoadingDrawFunction loadingDrawFunction);
|
||||
|
||||
/**
|
||||
* Run the loading process
|
||||
*/
|
||||
void runLoadingProcess(LoadingStage* stages, uint8_t stagesCount);
|
||||
|
||||
// Manuell Controll
|
||||
void nextFrame();
|
||||
void previousFrame();
|
||||
|
||||
/**
|
||||
* Switch without transition to frame `frame`.
|
||||
*/
|
||||
void switchToFrame(uint8_t frame);
|
||||
|
||||
/**
|
||||
* Transition to frame `frame`, when the `frame` number is bigger than the current
|
||||
* frame the forward animation will be used, otherwise the backwards animation is used.
|
||||
*/
|
||||
void transitionToFrame(uint8_t frame);
|
||||
|
||||
// State Info
|
||||
OLEDDisplayUiState* getUiState();
|
||||
|
||||
// This needs to be called in the main loop
|
||||
// the returned value is the remaining time (in ms)
|
||||
// you have to draw after drawing to keep the frame budget.
|
||||
int8_t update();
|
||||
```
|
||||
|
||||
## Example: SSD1306Demo
|
||||
|
||||
### Frame 1
|
||||

|
||||
|
||||
This frame shows three things:
|
||||
* How to draw an xbm image
|
||||
* How to draw a static text which is not moved by the frame transition
|
||||
* The active/inactive frame indicators
|
||||
|
||||
### Frame 2
|
||||

|
||||
|
||||
Currently there are one fontface with three sizes included in the library: Arial 10, 16 and 24. Once the converter is published you will be able to convert any ttf font into the used format.
|
||||
|
||||
### Frame 3
|
||||
|
||||

|
||||
|
||||
This frame demonstrates the text alignment. The coordinates in the frame show relative to which position the texts have been rendered.
|
||||
|
||||
### Frame 4
|
||||
|
||||

|
||||
|
||||
This shows how to use define a maximum width after which the driver automatically wraps a word to the next line. This comes in very handy if you have longer texts to display.
|
||||
|
||||
### SPI version
|
||||
|
||||

|
||||
|
||||
This shows the code working on the SPI version of the display. See demo code for ESP8266 pins used.
|
||||
|
||||
## Selection of projects using this library
|
||||
|
||||
* [QRCode ESP8266](https://github.com/anunpanya/ESP8266_QRcode) (by @anunpanya)
|
||||
* [Scan I2C](https://github.com/hallard/Scan-I2C-WiFi) (by @hallard)
|
||||
* [ThingPulse Weather Station](https://github.com/ThingPulse/esp8266-weather-station)
|
||||
* Yours?
|
||||
39
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SH1106.h
Normal file
39
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SH1106.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
* Copyright (c) 2018 by Fabrice Weinberg
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
* Please support us by buying our products (and not the clones) from
|
||||
* https://thingpulse.com
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SH1106_h
|
||||
#define SH1106_h
|
||||
#include "SH1106Wire.h"
|
||||
|
||||
// For make SH1106 an alias for SH1106Wire
|
||||
typedef SH1106Wire SH1106;
|
||||
|
||||
|
||||
#endif
|
||||
141
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SH1106Brzo.h
Normal file
141
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SH1106Brzo.h
Normal file
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
* Copyright (c) 2018 by Fabrice Weinberg
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
* Please support us by buying our products (and not the clones) from
|
||||
* https://thingpulse.com
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SH1106Brzo_h
|
||||
#define SH1106Brzo_h
|
||||
|
||||
#include "OLEDDisplay.h"
|
||||
#include <brzo_i2c.h>
|
||||
|
||||
#if F_CPU == 160000000L
|
||||
#define BRZO_I2C_SPEED 1000
|
||||
#else
|
||||
#define BRZO_I2C_SPEED 800
|
||||
#endif
|
||||
|
||||
class SH1106Brzo : public OLEDDisplay {
|
||||
private:
|
||||
uint8_t _address;
|
||||
uint8_t _sda;
|
||||
uint8_t _scl;
|
||||
|
||||
public:
|
||||
SH1106Brzo(uint8_t _address, uint8_t _sda, uint8_t _scl, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) {
|
||||
setGeometry(g);
|
||||
|
||||
this->_address = _address;
|
||||
this->_sda = _sda;
|
||||
this->_scl = _scl;
|
||||
}
|
||||
|
||||
bool connect(){
|
||||
brzo_i2c_setup(_sda, _scl, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void display(void) {
|
||||
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
|
||||
uint8_t minBoundY = UINT8_MAX;
|
||||
uint8_t maxBoundY = 0;
|
||||
|
||||
uint8_t minBoundX = UINT8_MAX;
|
||||
uint8_t maxBoundX = 0;
|
||||
uint8_t x, y;
|
||||
|
||||
// Calculate the Y bounding box of changes
|
||||
// and copy buffer[pos] to buffer_back[pos];
|
||||
for (y = 0; y < (displayHeight / 8); y++) {
|
||||
for (x = 0; x < displayWidth; x++) {
|
||||
uint16_t pos = x + y * displayWidth;
|
||||
if (buffer[pos] != buffer_back[pos]) {
|
||||
minBoundY = _min(minBoundY, y);
|
||||
maxBoundY = _max(maxBoundY, y);
|
||||
minBoundX = _min(minBoundX, x);
|
||||
maxBoundX = _max(maxBoundX, x);
|
||||
}
|
||||
buffer_back[pos] = buffer[pos];
|
||||
}
|
||||
yield();
|
||||
}
|
||||
|
||||
// If the minBoundY wasn't updated
|
||||
// we can savely assume that buffer_back[pos] == buffer[pos]
|
||||
// holdes true for all values of pos
|
||||
if (minBoundY == UINT8_MAX) return;
|
||||
|
||||
byte k = 0;
|
||||
uint8_t sendBuffer[17];
|
||||
sendBuffer[0] = 0x40;
|
||||
|
||||
// Calculate the colum offset
|
||||
uint8_t minBoundXp2H = (minBoundX + 2) & 0x0F;
|
||||
uint8_t minBoundXp2L = 0x10 | ((minBoundX + 2) >> 4 );
|
||||
|
||||
brzo_i2c_start_transaction(this->_address, BRZO_I2C_SPEED);
|
||||
|
||||
for (y = minBoundY; y <= maxBoundY; y++) {
|
||||
sendCommand(0xB0 + y);
|
||||
sendCommand(minBoundXp2H);
|
||||
sendCommand(minBoundXp2L);
|
||||
for (x = minBoundX; x <= maxBoundX; x++) {
|
||||
k++;
|
||||
sendBuffer[k] = buffer[x + y * displayWidth];
|
||||
if (k == 16) {
|
||||
brzo_i2c_write(sendBuffer, 17, true);
|
||||
k = 0;
|
||||
}
|
||||
}
|
||||
if (k != 0) {
|
||||
brzo_i2c_write(sendBuffer, k + 1, true);
|
||||
k = 0;
|
||||
}
|
||||
yield();
|
||||
}
|
||||
if (k != 0) {
|
||||
brzo_i2c_write(sendBuffer, k + 1, true);
|
||||
}
|
||||
brzo_i2c_end_transaction();
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
int getBufferOffset(void) {
|
||||
return 0;
|
||||
}
|
||||
inline void sendCommand(uint8_t com) __attribute__((always_inline)){
|
||||
uint8_t command[2] = {0x80 /* command mode */, com};
|
||||
brzo_i2c_start_transaction(_address, BRZO_I2C_SPEED);
|
||||
brzo_i2c_write(command, 2, true);
|
||||
brzo_i2c_end_transaction();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
135
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SH1106Spi.h
Normal file
135
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SH1106Spi.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
* Copyright (c) 2018 by Fabrice Weinberg
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
* Please support us by buying our products (and not the clones) from
|
||||
* https://thingpulse.com
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SH1106Spi_h
|
||||
#define SH1106Spi_h
|
||||
|
||||
#include "OLEDDisplay.h"
|
||||
#include <SPI.h>
|
||||
|
||||
class SH1106Spi : public OLEDDisplay {
|
||||
private:
|
||||
uint8_t _rst;
|
||||
uint8_t _dc;
|
||||
|
||||
public:
|
||||
SH1106Spi(uint8_t _rst, uint8_t _dc, uint8_t _cs, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) {
|
||||
setGeometry(g);
|
||||
|
||||
this->_rst = _rst;
|
||||
this->_dc = _dc;
|
||||
}
|
||||
|
||||
bool connect(){
|
||||
pinMode(_dc, OUTPUT);
|
||||
pinMode(_rst, OUTPUT);
|
||||
|
||||
SPI.begin ();
|
||||
SPI.setClockDivider (SPI_CLOCK_DIV2);
|
||||
|
||||
// Pulse Reset low for 10ms
|
||||
digitalWrite(_rst, HIGH);
|
||||
delay(1);
|
||||
digitalWrite(_rst, LOW);
|
||||
delay(10);
|
||||
digitalWrite(_rst, HIGH);
|
||||
return true;
|
||||
}
|
||||
|
||||
void display(void) {
|
||||
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
|
||||
uint8_t minBoundY = UINT8_MAX;
|
||||
uint8_t maxBoundY = 0;
|
||||
|
||||
uint8_t minBoundX = UINT8_MAX;
|
||||
uint8_t maxBoundX = 0;
|
||||
|
||||
uint8_t x, y;
|
||||
|
||||
// Calculate the Y bounding box of changes
|
||||
// and copy buffer[pos] to buffer_back[pos];
|
||||
for (y = 0; y < (displayHeight / 8); y++) {
|
||||
for (x = 0; x < displayWidth; x++) {
|
||||
uint16_t pos = x + y * displayWidth;
|
||||
if (buffer[pos] != buffer_back[pos]) {
|
||||
minBoundY = _min(minBoundY, y);
|
||||
maxBoundY = _max(maxBoundY, y);
|
||||
minBoundX = _min(minBoundX, x);
|
||||
maxBoundX = _max(maxBoundX, x);
|
||||
}
|
||||
buffer_back[pos] = buffer[pos];
|
||||
}
|
||||
yield();
|
||||
}
|
||||
|
||||
// If the minBoundY wasn't updated
|
||||
// we can savely assume that buffer_back[pos] == buffer[pos]
|
||||
// holdes true for all values of pos
|
||||
if (minBoundY == UINT8_MAX) return;
|
||||
|
||||
// Calculate the colum offset
|
||||
uint8_t minBoundXp2H = (minBoundX + 2) & 0x0F;
|
||||
uint8_t minBoundXp2L = 0x10 | ((minBoundX + 2) >> 4 );
|
||||
|
||||
for (y = minBoundY; y <= maxBoundY; y++) {
|
||||
sendCommand(0xB0 + y);
|
||||
sendCommand(minBoundXp2H);
|
||||
sendCommand(minBoundXp2L);
|
||||
digitalWrite(_dc, HIGH); // data mode
|
||||
for (x = minBoundX; x <= maxBoundX; x++) {
|
||||
SPI.transfer(buffer[x + y * displayWidth]);
|
||||
}
|
||||
yield();
|
||||
}
|
||||
#else
|
||||
for (uint8_t y=0; y<displayHeight/8; y++) {
|
||||
sendCommand(0xB0 + y);
|
||||
sendCommand(0x02);
|
||||
sendCommand(0x10);
|
||||
digitalWrite(_dc, HIGH); // data mode
|
||||
for( uint8_t x=0; x < displayWidth; x++) {
|
||||
SPI.transfer(buffer[x + y * displayWidth]);
|
||||
}
|
||||
yield();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
int getBufferOffset(void) {
|
||||
return 0;
|
||||
}
|
||||
inline void sendCommand(uint8_t com) __attribute__((always_inline)){
|
||||
digitalWrite(_dc, LOW);
|
||||
SPI.transfer(com);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
160
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SH1106Wire.h
Normal file
160
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SH1106Wire.h
Normal file
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
* Copyright (c) 2018 by Fabrice Weinberg
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
* Please support us by buying our products (and not the clones) from
|
||||
* https://thingpulse.com
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SH1106Wire_h
|
||||
#define SH1106Wire_h
|
||||
|
||||
#include "OLEDDisplay.h"
|
||||
#include <Wire.h>
|
||||
|
||||
#define SH1106_SET_PUMP_VOLTAGE 0X30
|
||||
#define SH1106_SET_PUMP_MODE 0XAD
|
||||
#define SH1106_PUMP_ON 0X8B
|
||||
#define SH1106_PUMP_OFF 0X8A
|
||||
//--------------------------------------
|
||||
|
||||
class SH1106Wire : public OLEDDisplay {
|
||||
private:
|
||||
uint8_t _address;
|
||||
uint8_t _sda;
|
||||
uint8_t _scl;
|
||||
|
||||
public:
|
||||
SH1106Wire(uint8_t _address, uint8_t _sda, uint8_t _scl, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) {
|
||||
setGeometry(g);
|
||||
|
||||
this->_address = _address;
|
||||
this->_sda = _sda;
|
||||
this->_scl = _scl;
|
||||
}
|
||||
|
||||
bool connect() {
|
||||
Wire.begin(this->_sda, this->_scl);
|
||||
// Let's use ~700khz if ESP8266 is in 160Mhz mode
|
||||
// this will be limited to ~400khz if the ESP8266 in 80Mhz mode.
|
||||
Wire.setClock(700000);
|
||||
return true;
|
||||
}
|
||||
|
||||
void display(void) {
|
||||
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
|
||||
uint8_t minBoundY = UINT8_MAX;
|
||||
uint8_t maxBoundY = 0;
|
||||
|
||||
uint8_t minBoundX = UINT8_MAX;
|
||||
uint8_t maxBoundX = 0;
|
||||
|
||||
uint8_t x, y;
|
||||
|
||||
// Calculate the Y bounding box of changes
|
||||
// and copy buffer[pos] to buffer_back[pos];
|
||||
for (y = 0; y < (displayHeight / 8); y++) {
|
||||
for (x = 0; x < displayWidth; x++) {
|
||||
uint16_t pos = x + y * displayWidth;
|
||||
if (buffer[pos] != buffer_back[pos]) {
|
||||
minBoundY = _min(minBoundY, y);
|
||||
maxBoundY = _max(maxBoundY, y);
|
||||
minBoundX = _min(minBoundX, x);
|
||||
maxBoundX = _max(maxBoundX, x);
|
||||
}
|
||||
buffer_back[pos] = buffer[pos];
|
||||
}
|
||||
yield();
|
||||
}
|
||||
|
||||
// If the minBoundY wasn't updated
|
||||
// we can savely assume that buffer_back[pos] == buffer[pos]
|
||||
// holdes true for all values of pos
|
||||
if (minBoundY == UINT8_MAX) return;
|
||||
|
||||
// Calculate the colum offset
|
||||
uint8_t minBoundXp2H = (minBoundX + 2) & 0x0F;
|
||||
uint8_t minBoundXp2L = 0x10 | ((minBoundX + 2) >> 4 );
|
||||
|
||||
byte k = 0;
|
||||
for (y = minBoundY; y <= maxBoundY; y++) {
|
||||
sendCommand(0xB0 + y);
|
||||
sendCommand(minBoundXp2H);
|
||||
sendCommand(minBoundXp2L);
|
||||
for (x = minBoundX; x <= maxBoundX; x++) {
|
||||
if (k == 0) {
|
||||
Wire.beginTransmission(_address);
|
||||
Wire.write(0x40);
|
||||
}
|
||||
Wire.write(buffer[x + y * displayWidth]);
|
||||
k++;
|
||||
if (k == 16) {
|
||||
Wire.endTransmission();
|
||||
k = 0;
|
||||
}
|
||||
}
|
||||
if (k != 0) {
|
||||
Wire.endTransmission();
|
||||
k = 0;
|
||||
}
|
||||
yield();
|
||||
}
|
||||
|
||||
if (k != 0) {
|
||||
Wire.endTransmission();
|
||||
}
|
||||
#else
|
||||
uint8_t * p = &buffer[0];
|
||||
for (uint8_t y=0; y<8; y++) {
|
||||
sendCommand(0xB0+y);
|
||||
sendCommand(0x02);
|
||||
sendCommand(0x10);
|
||||
for( uint8_t x=0; x<8; x++) {
|
||||
Wire.beginTransmission(_address);
|
||||
Wire.write(0x40);
|
||||
for (uint8_t k = 0; k < 16; k++) {
|
||||
Wire.write(*p++);
|
||||
}
|
||||
Wire.endTransmission();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
int getBufferOffset(void) {
|
||||
return 0;
|
||||
}
|
||||
inline void sendCommand(uint8_t command) __attribute__((always_inline)){
|
||||
Wire.beginTransmission(_address);
|
||||
Wire.write(0x80);
|
||||
Wire.write(command);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
39
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SSD1306.h
Normal file
39
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SSD1306.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
* Copyright (c) 2018 by Fabrice Weinberg
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
* Please support us by buying our products (and not the clones) from
|
||||
* https://thingpulse.com
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SSD1306_h
|
||||
#define SSD1306_h
|
||||
#include "SSD1306Wire.h"
|
||||
|
||||
// For legacy support make SSD1306 an alias for SSD1306
|
||||
typedef SSD1306Wire SSD1306;
|
||||
|
||||
|
||||
#endif
|
||||
162
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SSD1306Brzo.h
Normal file
162
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SSD1306Brzo.h
Normal file
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
* Copyright (c) 2018 by Fabrice Weinberg
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
* Please support us by buying our products (and not the clones) from
|
||||
* https://thingpulse.com
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SSD1306Brzo_h
|
||||
#define SSD1306Brzo_h
|
||||
|
||||
#include "OLEDDisplay.h"
|
||||
#include <brzo_i2c.h>
|
||||
|
||||
#if F_CPU == 160000000L
|
||||
#define BRZO_I2C_SPEED 1000
|
||||
#else
|
||||
#define BRZO_I2C_SPEED 800
|
||||
#endif
|
||||
|
||||
class SSD1306Brzo : public OLEDDisplay {
|
||||
private:
|
||||
uint8_t _address;
|
||||
uint8_t _sda;
|
||||
uint8_t _scl;
|
||||
|
||||
public:
|
||||
SSD1306Brzo(uint8_t _address, uint8_t _sda, uint8_t _scl, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) {
|
||||
setGeometry(g);
|
||||
|
||||
this->_address = _address;
|
||||
this->_sda = _sda;
|
||||
this->_scl = _scl;
|
||||
}
|
||||
|
||||
bool connect(){
|
||||
brzo_i2c_setup(_sda, _scl, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void display(void) {
|
||||
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
|
||||
uint8_t minBoundY = UINT8_MAX;
|
||||
uint8_t maxBoundY = 0;
|
||||
|
||||
uint8_t minBoundX = UINT8_MAX;
|
||||
uint8_t maxBoundX = 0;
|
||||
|
||||
uint8_t x, y;
|
||||
|
||||
// Calculate the Y bounding box of changes
|
||||
// and copy buffer[pos] to buffer_back[pos];
|
||||
for (y = 0; y < (displayHeight / 8); y++) {
|
||||
for (x = 0; x < displayWidth; x++) {
|
||||
uint16_t pos = x + y * displayWidth;
|
||||
if (buffer[pos] != buffer_back[pos]) {
|
||||
minBoundY = _min(minBoundY, y);
|
||||
maxBoundY = _max(maxBoundY, y);
|
||||
minBoundX = _min(minBoundX, x);
|
||||
maxBoundX = _max(maxBoundX, x);
|
||||
}
|
||||
buffer_back[pos] = buffer[pos];
|
||||
}
|
||||
yield();
|
||||
}
|
||||
|
||||
// If the minBoundY wasn't updated
|
||||
// we can savely assume that buffer_back[pos] == buffer[pos]
|
||||
// holdes true for all values of pos
|
||||
if (minBoundY == UINT8_MAX) return;
|
||||
|
||||
sendCommand(COLUMNADDR);
|
||||
sendCommand(minBoundX);
|
||||
sendCommand(maxBoundX);
|
||||
|
||||
sendCommand(PAGEADDR);
|
||||
sendCommand(minBoundY);
|
||||
sendCommand(maxBoundY);
|
||||
|
||||
byte k = 0;
|
||||
uint8_t sendBuffer[17];
|
||||
sendBuffer[0] = 0x40;
|
||||
brzo_i2c_start_transaction(this->_address, BRZO_I2C_SPEED);
|
||||
for (y = minBoundY; y <= maxBoundY; y++) {
|
||||
for (x = minBoundX; x <= maxBoundX; x++) {
|
||||
k++;
|
||||
sendBuffer[k] = buffer[x + y * displayWidth];
|
||||
if (k == 16) {
|
||||
brzo_i2c_write(sendBuffer, 17, true);
|
||||
k = 0;
|
||||
}
|
||||
}
|
||||
yield();
|
||||
}
|
||||
brzo_i2c_write(sendBuffer, k + 1, true);
|
||||
brzo_i2c_end_transaction();
|
||||
#else
|
||||
// No double buffering
|
||||
sendCommand(COLUMNADDR);
|
||||
sendCommand(0x0);
|
||||
sendCommand(0x7F);
|
||||
|
||||
sendCommand(PAGEADDR);
|
||||
sendCommand(0x0);
|
||||
|
||||
if (geometry == GEOMETRY_128_64) {
|
||||
sendCommand(0x7);
|
||||
} else if (geometry == GEOMETRY_128_32) {
|
||||
sendCommand(0x3);
|
||||
}
|
||||
|
||||
uint8_t sendBuffer[17];
|
||||
sendBuffer[0] = 0x40;
|
||||
brzo_i2c_start_transaction(this->_address, BRZO_I2C_SPEED);
|
||||
for (uint16_t i=0; i<displayBufferSize; i++) {
|
||||
for (uint8_t x=1; x<17; x++) {
|
||||
sendBuffer[x] = buffer[i];
|
||||
i++;
|
||||
}
|
||||
i--;
|
||||
brzo_i2c_write(sendBuffer, 17, true);
|
||||
yield();
|
||||
}
|
||||
brzo_i2c_end_transaction();
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
int getBufferOffset(void) {
|
||||
return 0;
|
||||
}
|
||||
inline void sendCommand(uint8_t com) __attribute__((always_inline)){
|
||||
uint8_t command[2] = {0x80 /* command mode */, com};
|
||||
brzo_i2c_start_transaction(_address, BRZO_I2C_SPEED);
|
||||
brzo_i2c_write(command, 2, true);
|
||||
brzo_i2c_end_transaction();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
152
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SSD1306I2C.h
Normal file
152
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SSD1306I2C.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 by Helmut Tschemernjak - www.radioshuttle.de
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
* Please support us by buying our products (and not the clones) from
|
||||
* https://thingpulse.com
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SSD1306I2C_h
|
||||
#define SSD1306I2C_h
|
||||
|
||||
|
||||
#ifdef __MBED__
|
||||
|
||||
#include "OLEDDisplay.h"
|
||||
#include <mbed.h>
|
||||
|
||||
#ifndef UINT8_MAX
|
||||
#define UINT8_MAX 0xff
|
||||
#endif
|
||||
|
||||
class SSD1306I2C : public OLEDDisplay {
|
||||
public:
|
||||
SSD1306I2C(uint8_t _address, PinName _sda, PinName _scl, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) {
|
||||
setGeometry(g);
|
||||
|
||||
this->_address = _address << 1; // convert from 7 to 8 bit for mbed.
|
||||
this->_sda = _sda;
|
||||
this->_scl = _scl;
|
||||
_i2c = new I2C(_sda, _scl);
|
||||
}
|
||||
|
||||
bool connect() {
|
||||
// mbed supports 100k and 400k some device maybe 1000k
|
||||
#ifdef TARGET_STM32L4
|
||||
_i2c->frequency(1000000);
|
||||
#else
|
||||
_i2c->frequency(400000);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void display(void) {
|
||||
const int x_offset = (128 - this->width()) / 2;
|
||||
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
|
||||
uint8_t minBoundY = UINT8_MAX;
|
||||
uint8_t maxBoundY = 0;
|
||||
|
||||
uint8_t minBoundX = UINT8_MAX;
|
||||
uint8_t maxBoundX = 0;
|
||||
uint8_t x, y;
|
||||
|
||||
// Calculate the Y bounding box of changes
|
||||
// and copy buffer[pos] to buffer_back[pos];
|
||||
for (y = 0; y < (this->height() / 8); y++) {
|
||||
for (x = 0; x < this->width(); x++) {
|
||||
uint16_t pos = x + y * this->width();
|
||||
if (buffer[pos] != buffer_back[pos]) {
|
||||
minBoundY = std::min(minBoundY, y);
|
||||
maxBoundY = std::max(maxBoundY, y);
|
||||
minBoundX = std::min(minBoundX, x);
|
||||
maxBoundX = std::max(maxBoundX, x);
|
||||
}
|
||||
buffer_back[pos] = buffer[pos];
|
||||
}
|
||||
yield();
|
||||
}
|
||||
|
||||
// If the minBoundY wasn't updated
|
||||
// we can savely assume that buffer_back[pos] == buffer[pos]
|
||||
// holdes true for all values of pos
|
||||
|
||||
if (minBoundY == UINT8_MAX) return;
|
||||
|
||||
sendCommand(COLUMNADDR);
|
||||
sendCommand(x_offset + minBoundX); // column start address (0 = reset)
|
||||
sendCommand(x_offset + maxBoundX); // column end address (127 = reset)
|
||||
|
||||
sendCommand(PAGEADDR);
|
||||
sendCommand(minBoundY); // page start address
|
||||
sendCommand(maxBoundY); // page end address
|
||||
|
||||
for (y = minBoundY; y <= maxBoundY; y++) {
|
||||
uint8_t *start = &buffer[(minBoundX + y * this->width())-1];
|
||||
uint8_t save = *start;
|
||||
|
||||
*start = 0x40; // control
|
||||
_i2c->write(_address, (char *)start, (maxBoundX-minBoundX) + 1 + 1);
|
||||
*start = save;
|
||||
}
|
||||
#else
|
||||
|
||||
sendCommand(COLUMNADDR);
|
||||
sendCommand(x_offset); // column start address (0 = reset)
|
||||
sendCommand(x_offset + (this->width() - 1));// column end address (127 = reset)
|
||||
|
||||
sendCommand(PAGEADDR);
|
||||
sendCommand(0x0); // page start address (0 = reset)
|
||||
|
||||
if (geometry == GEOMETRY_128_64) {
|
||||
sendCommand(0x7);
|
||||
} else if (geometry == GEOMETRY_128_32) {
|
||||
sendCommand(0x3);
|
||||
}
|
||||
|
||||
buffer[-1] = 0x40; // control
|
||||
_i2c->write(_address, (char *)&buffer[-1], displayBufferSize + 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
int getBufferOffset(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void sendCommand(uint8_t command) __attribute__((always_inline)) {
|
||||
char _data[2];
|
||||
_data[0] = 0x80; // control
|
||||
_data[1] = command;
|
||||
_i2c->write(_address, _data, sizeof(_data));
|
||||
}
|
||||
|
||||
uint8_t _address;
|
||||
PinName _sda;
|
||||
PinName _scl;
|
||||
I2C *_i2c;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
163
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SSD1306Spi.h
Normal file
163
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SSD1306Spi.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
* Copyright (c) 2018 by Fabrice Weinberg
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
* Please support us by buying our products (and not the clones) from
|
||||
* https://thingpulse.com
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SSD1306Spi_h
|
||||
#define SSD1306Spi_h
|
||||
|
||||
#include "OLEDDisplay.h"
|
||||
#include <SPI.h>
|
||||
|
||||
#if F_CPU == 160000000L
|
||||
#define BRZO_I2C_SPEED 1000
|
||||
#else
|
||||
#define BRZO_I2C_SPEED 800
|
||||
#endif
|
||||
|
||||
class SSD1306Spi : public OLEDDisplay {
|
||||
private:
|
||||
uint8_t _rst;
|
||||
uint8_t _dc;
|
||||
uint8_t _cs;
|
||||
|
||||
public:
|
||||
SSD1306Spi(uint8_t _rst, uint8_t _dc, uint8_t _cs, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) {
|
||||
setGeometry(g);
|
||||
|
||||
this->_rst = _rst;
|
||||
this->_dc = _dc;
|
||||
this->_cs = _cs;
|
||||
}
|
||||
|
||||
bool connect(){
|
||||
pinMode(_dc, OUTPUT);
|
||||
pinMode(_cs, OUTPUT);
|
||||
pinMode(_rst, OUTPUT);
|
||||
|
||||
SPI.begin ();
|
||||
SPI.setClockDivider (SPI_CLOCK_DIV2);
|
||||
|
||||
// Pulse Reset low for 10ms
|
||||
digitalWrite(_rst, HIGH);
|
||||
delay(1);
|
||||
digitalWrite(_rst, LOW);
|
||||
delay(10);
|
||||
digitalWrite(_rst, HIGH);
|
||||
return true;
|
||||
}
|
||||
|
||||
void display(void) {
|
||||
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
|
||||
uint8_t minBoundY = UINT8_MAX;
|
||||
uint8_t maxBoundY = 0;
|
||||
|
||||
uint8_t minBoundX = UINT8_MAX;
|
||||
uint8_t maxBoundX = 0;
|
||||
|
||||
uint8_t x, y;
|
||||
|
||||
// Calculate the Y bounding box of changes
|
||||
// and copy buffer[pos] to buffer_back[pos];
|
||||
for (y = 0; y < (displayHeight / 8); y++) {
|
||||
for (x = 0; x < displayWidth; x++) {
|
||||
uint16_t pos = x + y * displayWidth;
|
||||
if (buffer[pos] != buffer_back[pos]) {
|
||||
minBoundY = _min(minBoundY, y);
|
||||
maxBoundY = _max(maxBoundY, y);
|
||||
minBoundX = _min(minBoundX, x);
|
||||
maxBoundX = _max(maxBoundX, x);
|
||||
}
|
||||
buffer_back[pos] = buffer[pos];
|
||||
}
|
||||
yield();
|
||||
}
|
||||
|
||||
// If the minBoundY wasn't updated
|
||||
// we can savely assume that buffer_back[pos] == buffer[pos]
|
||||
// holdes true for all values of pos
|
||||
if (minBoundY == UINT8_MAX) return;
|
||||
|
||||
sendCommand(COLUMNADDR);
|
||||
sendCommand(minBoundX);
|
||||
sendCommand(maxBoundX);
|
||||
|
||||
sendCommand(PAGEADDR);
|
||||
sendCommand(minBoundY);
|
||||
sendCommand(maxBoundY);
|
||||
|
||||
digitalWrite(_cs, HIGH);
|
||||
digitalWrite(_dc, HIGH); // data mode
|
||||
digitalWrite(_cs, LOW);
|
||||
for (y = minBoundY; y <= maxBoundY; y++) {
|
||||
for (x = minBoundX; x <= maxBoundX; x++) {
|
||||
SPI.transfer(buffer[x + y * displayWidth]);
|
||||
}
|
||||
yield();
|
||||
}
|
||||
digitalWrite(_cs, HIGH);
|
||||
#else
|
||||
// No double buffering
|
||||
sendCommand(COLUMNADDR);
|
||||
sendCommand(0x0);
|
||||
sendCommand(0x7F);
|
||||
|
||||
sendCommand(PAGEADDR);
|
||||
sendCommand(0x0);
|
||||
|
||||
if (geometry == GEOMETRY_128_64) {
|
||||
sendCommand(0x7);
|
||||
} else if (geometry == GEOMETRY_128_32) {
|
||||
sendCommand(0x3);
|
||||
}
|
||||
|
||||
digitalWrite(_cs, HIGH);
|
||||
digitalWrite(_dc, HIGH); // data mode
|
||||
digitalWrite(_cs, LOW);
|
||||
for (uint16_t i=0; i<displayBufferSize; i++) {
|
||||
SPI.transfer(buffer[i]);
|
||||
yield();
|
||||
}
|
||||
digitalWrite(_cs, HIGH);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
int getBufferOffset(void) {
|
||||
return 0;
|
||||
}
|
||||
inline void sendCommand(uint8_t com) __attribute__((always_inline)){
|
||||
digitalWrite(_cs, HIGH);
|
||||
digitalWrite(_dc, LOW);
|
||||
digitalWrite(_cs, LOW);
|
||||
SPI.transfer(com);
|
||||
digitalWrite(_cs, HIGH);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
188
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SSD1306Wire.h
Normal file
188
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/SSD1306Wire.h
Normal file
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
* Copyright (c) 2018 by Fabrice Weinberg
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
* Please support us by buying our products (and not the clones) from
|
||||
* https://thingpulse.com
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SSD1306Wire_h
|
||||
#define SSD1306Wire_h
|
||||
|
||||
#include "OLEDDisplay.h"
|
||||
#include <Wire.h>
|
||||
|
||||
#ifdef ARDUINO_ARCH_AVR
|
||||
#define _min min
|
||||
#define _max max
|
||||
#endif
|
||||
|
||||
class SSD1306Wire : public OLEDDisplay {
|
||||
private:
|
||||
uint8_t _address;
|
||||
uint8_t _sda;
|
||||
uint8_t _scl;
|
||||
bool _doI2cAutoInit = false;
|
||||
|
||||
public:
|
||||
SSD1306Wire(uint8_t _address, uint8_t _sda, uint8_t _scl, OLEDDISPLAY_GEOMETRY g = GEOMETRY_128_64) {
|
||||
setGeometry(g);
|
||||
|
||||
this->_address = _address;
|
||||
this->_sda = _sda;
|
||||
this->_scl = _scl;
|
||||
}
|
||||
|
||||
bool connect() {
|
||||
#ifdef ARDUINO_ARCH_AVR
|
||||
Wire.begin();
|
||||
#else
|
||||
Wire.begin(this->_sda, this->_scl);
|
||||
#endif
|
||||
// Let's use ~700khz if ESP8266 is in 160Mhz mode
|
||||
// this will be limited to ~400khz if the ESP8266 in 80Mhz mode.
|
||||
Wire.setClock(700000);
|
||||
return true;
|
||||
}
|
||||
|
||||
void display(void) {
|
||||
initI2cIfNeccesary();
|
||||
const int x_offset = (128 - this->width()) / 2;
|
||||
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
|
||||
uint8_t minBoundY = UINT8_MAX;
|
||||
uint8_t maxBoundY = 0;
|
||||
|
||||
uint8_t minBoundX = UINT8_MAX;
|
||||
uint8_t maxBoundX = 0;
|
||||
uint8_t x, y;
|
||||
|
||||
// Calculate the Y bounding box of changes
|
||||
// and copy buffer[pos] to buffer_back[pos];
|
||||
for (y = 0; y < (this->height() / 8); y++) {
|
||||
for (x = 0; x < this->width(); x++) {
|
||||
uint16_t pos = x + y * this->width();
|
||||
if (buffer[pos] != buffer_back[pos]) {
|
||||
minBoundY = _min(minBoundY, y);
|
||||
maxBoundY = _max(maxBoundY, y);
|
||||
minBoundX = _min(minBoundX, x);
|
||||
maxBoundX = _max(maxBoundX, x);
|
||||
}
|
||||
buffer_back[pos] = buffer[pos];
|
||||
}
|
||||
yield();
|
||||
}
|
||||
|
||||
// If the minBoundY wasn't updated
|
||||
// we can savely assume that buffer_back[pos] == buffer[pos]
|
||||
// holdes true for all values of pos
|
||||
|
||||
if (minBoundY == UINT8_MAX) return;
|
||||
|
||||
sendCommand(COLUMNADDR);
|
||||
sendCommand(x_offset + minBoundX);
|
||||
sendCommand(x_offset + maxBoundX);
|
||||
|
||||
sendCommand(PAGEADDR);
|
||||
sendCommand(minBoundY);
|
||||
sendCommand(maxBoundY);
|
||||
|
||||
byte k = 0;
|
||||
for (y = minBoundY; y <= maxBoundY; y++) {
|
||||
for (x = minBoundX; x <= maxBoundX; x++) {
|
||||
if (k == 0) {
|
||||
Wire.beginTransmission(_address);
|
||||
Wire.write(0x40);
|
||||
}
|
||||
|
||||
Wire.write(buffer[x + y * this->width()]);
|
||||
k++;
|
||||
if (k == 16) {
|
||||
Wire.endTransmission();
|
||||
k = 0;
|
||||
}
|
||||
}
|
||||
yield();
|
||||
}
|
||||
|
||||
if (k != 0) {
|
||||
Wire.endTransmission();
|
||||
}
|
||||
#else
|
||||
|
||||
sendCommand(COLUMNADDR);
|
||||
sendCommand(x_offset);
|
||||
sendCommand(x_offset + (this->width() - 1));
|
||||
|
||||
sendCommand(PAGEADDR);
|
||||
sendCommand(0x0);
|
||||
|
||||
if (geometry == GEOMETRY_128_64) {
|
||||
sendCommand(0x7);
|
||||
} else if (geometry == GEOMETRY_128_32) {
|
||||
sendCommand(0x3);
|
||||
}
|
||||
|
||||
for (uint16_t i=0; i < displayBufferSize; i++) {
|
||||
Wire.beginTransmission(this->_address);
|
||||
Wire.write(0x40);
|
||||
for (uint8_t x = 0; x < 16; x++) {
|
||||
Wire.write(buffer[i]);
|
||||
i++;
|
||||
}
|
||||
i--;
|
||||
Wire.endTransmission();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void setI2cAutoInit(bool doI2cAutoInit) {
|
||||
_doI2cAutoInit = doI2cAutoInit;
|
||||
}
|
||||
|
||||
private:
|
||||
int getBufferOffset(void) {
|
||||
return 0;
|
||||
}
|
||||
inline void sendCommand(uint8_t command) __attribute__((always_inline)){
|
||||
initI2cIfNeccesary();
|
||||
Wire.beginTransmission(_address);
|
||||
Wire.write(0x80);
|
||||
Wire.write(command);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
void initI2cIfNeccesary() {
|
||||
if (_doI2cAutoInit) {
|
||||
#ifdef ARDUINO_ARCH_AVR
|
||||
Wire.begin();
|
||||
#else
|
||||
Wire.begin(this->_sda, this->_scl);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
24
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/license
Normal file
24
esp8266_deauther/src/esp8266-oled-ssd1306-4.1.0/license
Normal file
@@ -0,0 +1,24 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 by Daniel Eichhorn
|
||||
Copyright (c) 2016 by Fabrice Weinberg
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
See more at http://blog.squix.ch
|
||||
675
esp8266_deauther/src/my92xx-3.0.3/LICENSE
Normal file
675
esp8266_deauther/src/my92xx-3.0.3/LICENSE
Normal file
@@ -0,0 +1,675 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it 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 program 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/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
|
||||
221
esp8266_deauther/src/my92xx-3.0.3/my92xx.cpp
Normal file
221
esp8266_deauther/src/my92xx-3.0.3/my92xx.cpp
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
|
||||
MY92XX LED Driver for Arduino
|
||||
Based on the C driver by MaiKe Labs
|
||||
|
||||
Copyright (c) 2016 - 2026 MaiKe Labs
|
||||
Copyright (C) 2017 - 2018 Xose Pérez for the Arduino compatible library
|
||||
|
||||
This program is free software: you can redistribute it 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 program 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 "my92xx.h"
|
||||
|
||||
#if ARDUINO_ARCH_ESP8266
|
||||
|
||||
extern "C" {
|
||||
void os_delay_us(unsigned int);
|
||||
}
|
||||
|
||||
#elif ARDUINO_ARCH_AVR
|
||||
|
||||
#define os_delay_us delayMicroseconds
|
||||
|
||||
#endif
|
||||
|
||||
void my92xx::_di_pulse(unsigned int times) {
|
||||
for (unsigned int i = 0; i < times; i++) {
|
||||
digitalWrite(_pin_di, HIGH);
|
||||
digitalWrite(_pin_di, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void my92xx::_dcki_pulse(unsigned int times) {
|
||||
for (unsigned int i = 0; i < times; i++) {
|
||||
digitalWrite(_pin_dcki, HIGH);
|
||||
digitalWrite(_pin_dcki, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void my92xx::_write(unsigned int data, unsigned char bit_length) {
|
||||
|
||||
unsigned int mask = (0x01 << (bit_length - 1));
|
||||
|
||||
for (unsigned int i = 0; i < bit_length / 2; i++) {
|
||||
digitalWrite(_pin_dcki, LOW);
|
||||
digitalWrite(_pin_di, (data & mask) ? HIGH : LOW);
|
||||
digitalWrite(_pin_dcki, HIGH);
|
||||
data = data << 1;
|
||||
digitalWrite(_pin_di, (data & mask) ? HIGH : LOW);
|
||||
digitalWrite(_pin_dcki, LOW);
|
||||
digitalWrite(_pin_di, LOW);
|
||||
data = data << 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void my92xx::_set_cmd(my92xx_cmd_t command) {
|
||||
|
||||
// ets_intr_lock();
|
||||
|
||||
// TStop > 12us.
|
||||
os_delay_us(12);
|
||||
|
||||
// Send 12 DI pulse, after 6 pulse's falling edge store duty data, and 12
|
||||
// pulse's rising edge convert to command mode.
|
||||
_di_pulse(12);
|
||||
|
||||
// Delay >12us, begin send CMD data
|
||||
os_delay_us(12);
|
||||
|
||||
// Send CMD data
|
||||
unsigned char command_data = *(unsigned char *) (&command);
|
||||
for (unsigned char i=0; i<_chips; i++) {
|
||||
_write(command_data, 8);
|
||||
}
|
||||
|
||||
// TStart > 12us. Delay 12 us.
|
||||
os_delay_us(12);
|
||||
|
||||
// Send 16 DI pulse,at 14 pulse's falling edge store CMD data, and
|
||||
// at 16 pulse's falling edge convert to duty mode.
|
||||
_di_pulse(16);
|
||||
|
||||
// TStop > 12us.
|
||||
os_delay_us(12);
|
||||
|
||||
// ets_intr_unlock();
|
||||
|
||||
}
|
||||
|
||||
void my92xx::_send() {
|
||||
|
||||
#ifdef DEBUG_MY92XX
|
||||
DEBUG_MSG_MY92XX("[MY92XX] Refresh: %s (", _state ? "ON" : "OFF");
|
||||
for (unsigned char channel = 0; channel < _channels; channel++) {
|
||||
DEBUG_MSG_MY92XX(" %d", _value[channel]);
|
||||
}
|
||||
DEBUG_MSG_MY92XX(" )\n");
|
||||
#endif
|
||||
|
||||
unsigned char bit_length = 8;
|
||||
switch (_command.bit_width) {
|
||||
case MY92XX_CMD_BIT_WIDTH_16:
|
||||
bit_length = 16;
|
||||
break;
|
||||
case MY92XX_CMD_BIT_WIDTH_14:
|
||||
bit_length = 14;
|
||||
break;
|
||||
case MY92XX_CMD_BIT_WIDTH_12:
|
||||
bit_length = 12;
|
||||
break;
|
||||
case MY92XX_CMD_BIT_WIDTH_8:
|
||||
bit_length = 8;
|
||||
break;
|
||||
default:
|
||||
bit_length = 8;
|
||||
break;
|
||||
}
|
||||
|
||||
// ets_intr_lock();
|
||||
|
||||
// TStop > 12us.
|
||||
os_delay_us(12);
|
||||
|
||||
// Send color data
|
||||
for (unsigned char channel = 0; channel < _channels; channel++) {
|
||||
_write(_state ? _value[channel] : 0, bit_length);
|
||||
}
|
||||
|
||||
// TStart > 12us. Ready for send DI pulse.
|
||||
os_delay_us(12);
|
||||
|
||||
// Send 8 DI pulse. After 8 pulse falling edge, store old data.
|
||||
_di_pulse(8);
|
||||
|
||||
// TStop > 12us.
|
||||
os_delay_us(12);
|
||||
|
||||
// ets_intr_unlock();
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
unsigned char my92xx::getChannels() {
|
||||
return _channels;
|
||||
}
|
||||
|
||||
void my92xx::setChannel(unsigned char channel, unsigned int value) {
|
||||
if (0 <= channel && channel < _channels) {
|
||||
_value[channel] = value;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int my92xx::getChannel(unsigned char channel) {
|
||||
if (0 <= channel && channel < _channels) {
|
||||
return _value[channel];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool my92xx::getState() {
|
||||
return _state;
|
||||
}
|
||||
|
||||
void my92xx::setState(bool state) {
|
||||
_state = state;
|
||||
}
|
||||
|
||||
void my92xx::update() {
|
||||
_send();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
my92xx::my92xx(my92xx_model_t model, unsigned char chips, unsigned char di, unsigned char dcki, my92xx_cmd_t command) {
|
||||
|
||||
_model = model;
|
||||
_chips = chips;
|
||||
_pin_di = di;
|
||||
_pin_dcki = dcki;
|
||||
_command = command;
|
||||
|
||||
// Init channels
|
||||
if (_model == MY92XX_MODEL_MY9291) {
|
||||
_channels = 4 * _chips;
|
||||
} else if (_model == MY92XX_MODEL_MY9231) {
|
||||
_channels = 3 * _chips;
|
||||
}
|
||||
_value = new uint16_t[_channels];
|
||||
for (unsigned char i=0; i<_channels; i++) {
|
||||
_value[i] = 0;
|
||||
}
|
||||
|
||||
// Init GPIO
|
||||
pinMode(_pin_di, OUTPUT);
|
||||
pinMode(_pin_dcki, OUTPUT);
|
||||
digitalWrite(_pin_di, LOW);
|
||||
digitalWrite(_pin_dcki, LOW);
|
||||
|
||||
// Clear all duty register
|
||||
_dcki_pulse(32 * _chips);
|
||||
|
||||
// Send init command
|
||||
_set_cmd(command);
|
||||
|
||||
DEBUG_MSG_MY92XX("[MY92XX] Initialized\n");
|
||||
|
||||
}
|
||||
123
esp8266_deauther/src/my92xx-3.0.3/my92xx.h
Normal file
123
esp8266_deauther/src/my92xx-3.0.3/my92xx.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
|
||||
MY92XX LED Driver for Arduino
|
||||
Based on the C driver by MaiKe Labs
|
||||
|
||||
Copyright (c) 2016 - 2026 MaiKe Labs
|
||||
Copyright (C) 2017 - 2018 Xose Pérez for the Arduino compatible library
|
||||
|
||||
This program is free software: you can redistribute it 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 program 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/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _my92xx_h
|
||||
#define _my92xx_h
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#ifdef DEBUG_MY92XX
|
||||
#if ARDUINO_ARCH_ESP8266
|
||||
#define DEBUG_MSG_MY92XX(...) DEBUG_MY92XX.printf( __VA_ARGS__ )
|
||||
#elif ARDUINO_ARCH_AVR
|
||||
#define DEBUG_MSG_MY92XX(...) { char buffer[80]; snprintf(buffer, sizeof(buffer), __VA_ARGS__ ); DEBUG_MY92XX.print(buffer); }
|
||||
#endif
|
||||
#else
|
||||
#define DEBUG_MSG_MY92XX(...)
|
||||
#endif
|
||||
|
||||
typedef enum my92xx_model_t {
|
||||
MY92XX_MODEL_MY9291 = 0X00,
|
||||
MY92XX_MODEL_MY9231 = 0X01,
|
||||
} my92xx_model_t;
|
||||
|
||||
typedef enum my92xx_cmd_one_shot_t {
|
||||
MY92XX_CMD_ONE_SHOT_DISABLE = 0X00,
|
||||
MY92XX_CMD_ONE_SHOT_ENFORCE = 0X01,
|
||||
} my92xx_cmd_one_shot_t;
|
||||
|
||||
typedef enum my92xx_cmd_reaction_t {
|
||||
MY92XX_CMD_REACTION_FAST = 0X00,
|
||||
MY92XX_CMD_REACTION_SLOW = 0X01,
|
||||
} my92xx_cmd_reaction_t;
|
||||
|
||||
typedef enum my92xx_cmd_bit_width_t {
|
||||
MY92XX_CMD_BIT_WIDTH_16 = 0X00,
|
||||
MY92XX_CMD_BIT_WIDTH_14 = 0X01,
|
||||
MY92XX_CMD_BIT_WIDTH_12 = 0X02,
|
||||
MY92XX_CMD_BIT_WIDTH_8 = 0X03,
|
||||
} my92xx_cmd_bit_width_t;
|
||||
|
||||
typedef enum my92xx_cmd_frequency_t {
|
||||
MY92XX_CMD_FREQUENCY_DIVIDE_1 = 0X00,
|
||||
MY92XX_CMD_FREQUENCY_DIVIDE_4 = 0X01,
|
||||
MY92XX_CMD_FREQUENCY_DIVIDE_16 = 0X02,
|
||||
MY92XX_CMD_FREQUENCY_DIVIDE_64 = 0X03,
|
||||
} my92xx_cmd_frequency_t;
|
||||
|
||||
typedef enum my92xx_cmd_scatter_t {
|
||||
MY92XX_CMD_SCATTER_APDM = 0X00,
|
||||
MY92XX_CMD_SCATTER_PWM = 0X01,
|
||||
} my92xx_cmd_scatter_t;
|
||||
|
||||
typedef struct {
|
||||
my92xx_cmd_scatter_t scatter:1;
|
||||
my92xx_cmd_frequency_t frequency:2;
|
||||
my92xx_cmd_bit_width_t bit_width:2;
|
||||
my92xx_cmd_reaction_t reaction:1;
|
||||
my92xx_cmd_one_shot_t one_shot:1;
|
||||
unsigned char resv:1;
|
||||
} __attribute__ ((aligned(1), packed)) my92xx_cmd_t;
|
||||
|
||||
#define MY92XX_COMMAND_DEFAULT { \
|
||||
.scatter = MY92XX_CMD_SCATTER_APDM, \
|
||||
.frequency = MY92XX_CMD_FREQUENCY_DIVIDE_1, \
|
||||
.bit_width = MY92XX_CMD_BIT_WIDTH_8, \
|
||||
.reaction = MY92XX_CMD_REACTION_FAST, \
|
||||
.one_shot = MY92XX_CMD_ONE_SHOT_DISABLE, \
|
||||
.resv = 0 \
|
||||
}
|
||||
|
||||
class my92xx {
|
||||
|
||||
public:
|
||||
|
||||
my92xx(my92xx_model_t model, unsigned char chips, unsigned char di, unsigned char dcki, my92xx_cmd_t command);
|
||||
unsigned char getChannels();
|
||||
void setChannel(unsigned char channel, unsigned int value);
|
||||
unsigned int getChannel(unsigned char channel);
|
||||
void setState(bool state);
|
||||
bool getState();
|
||||
void update();
|
||||
|
||||
private:
|
||||
|
||||
void _di_pulse(unsigned int times);
|
||||
void _dcki_pulse(unsigned int times);
|
||||
void _set_cmd(my92xx_cmd_t command);
|
||||
void _send();
|
||||
void _write(unsigned int data, unsigned char bit_length);
|
||||
|
||||
my92xx_cmd_t _command;
|
||||
my92xx_model_t _model = MY92XX_MODEL_MY9291;
|
||||
unsigned char _chips = 1;
|
||||
unsigned char _channels;
|
||||
uint16_t * _value;
|
||||
bool _state = false;
|
||||
unsigned char _pin_di;
|
||||
unsigned char _pin_dcki;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user