diff --git a/README.md b/README.md index 23e3d21..e4ea33f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,33 @@ # gratis + +## Notes for mrwastl/gratis-branch + +This branch adds basic support for Teensy 3.1/3.2 and ESP32. + +### Teensy 3.1/3.2 +Default IO layout is defined in EPD_PINOUT/EPD_PINOUT_Teensy.h. + +Pin numbers can be assigned individually when calling the constructor. + +### ESP32 +Default IO layout is defined in EPD_PINOUT/EPD_PINOUT_ESP32.h. + +Pin numbers and PWM channel ID (EPD_V110_G1 only) can be assigned individually when calling the constructor. + +SPI channel ID and SPI pin numbers can only be changed in EPD_PINOUT_ESP32.h, a more flexible handling would require +some API changes. + + +### Tests + +As I just own an EPD_V110_G1 module (2.7") I can only test this one. All other combinations are tested if compilation is successful. + + + + + +## Original README of repaper/gratis-branch below + ## Fast Update notes, July 2017 The update rate for Partial Update is determined by the temperature dependent stage time. diff --git a/Sketches/libraries/EPD_FLASH/EPD_FLASH.cpp b/Sketches/libraries/EPD_FLASH/EPD_FLASH.cpp index 14255f3..b2aacf6 100644 --- a/Sketches/libraries/EPD_FLASH/EPD_FLASH.cpp +++ b/Sketches/libraries/EPD_FLASH/EPD_FLASH.cpp @@ -31,6 +31,14 @@ #define Delay_us(us) delayMicroseconds(us) +#ifndef ESP32 + #define SPI_OBJECT SPI +#else + #include "EPD_PINOUT_ESP32.h" + #define SPI_OBJECT esp32_spi +#endif + + // FLASH MX25V8005 8Mbit flash chip command set (50MHz max clock) enum { EPD_FLASH_WREN = 0x06, @@ -84,18 +92,22 @@ void EPD_FLASH_Class::end(void) { // configure the SPI for EPD_FLASH access void EPD_FLASH_Class::spi_setup(void) { - SPI.begin(); +#ifndef ESP32 + SPI_OBJECT.begin(); +#else + SPI_OBJECT.begin(Pin_SPI_SCK, Pin_SPI_MISO, Pin_SPI_MOSI); +#endif digitalWrite(this->EPD_FLASH_CS, HIGH); - SPI.setBitOrder(MSBFIRST); - SPI.setDataMode(SPI_MODE3); - SPI.setClockDivider(SPI_CLOCK_DIV4); + SPI_OBJECT.setBitOrder(MSBFIRST); + SPI_OBJECT.setDataMode(SPI_MODE3); + SPI_OBJECT.setClockDivider(SPI_CLOCK_DIV4); Delay_us(10); - SPI.transfer(EPD_FLASH_NOP); // flush the SPI buffer - SPI.transfer(EPD_FLASH_NOP); // .. - SPI.transfer(EPD_FLASH_NOP); // .. + SPI_OBJECT.transfer(EPD_FLASH_NOP); // flush the SPI buffer + SPI_OBJECT.transfer(EPD_FLASH_NOP); // .. + SPI_OBJECT.transfer(EPD_FLASH_NOP); // .. Delay_us(10); } @@ -103,8 +115,8 @@ void EPD_FLASH_Class::spi_setup(void) { void EPD_FLASH_Class::spi_teardown(void) { Delay_us(10); digitalWrite(this->EPD_FLASH_CS, HIGH); - SPI.transfer(EPD_FLASH_NOP); // flush the SPI buffer - SPI.end(); + SPI_OBJECT.transfer(EPD_FLASH_NOP); // flush the SPI buffer + SPI_OBJECT.end(); } // return true if the chip is supported @@ -127,10 +139,10 @@ void EPD_FLASH_Class::info(uint8_t *maufacturer, uint16_t *device) { Delay_us(50); digitalWrite(this->EPD_FLASH_CS, LOW); Delay_us(10); - SPI.transfer(EPD_FLASH_RDID); - *maufacturer = SPI.transfer(EPD_FLASH_NOP); - uint8_t id_high = SPI.transfer(EPD_FLASH_NOP); - uint8_t id_low = SPI.transfer(EPD_FLASH_NOP); + SPI_OBJECT.transfer(EPD_FLASH_RDID); + *maufacturer = SPI_OBJECT.transfer(EPD_FLASH_NOP); + uint8_t id_high = SPI_OBJECT.transfer(EPD_FLASH_NOP); + uint8_t id_low = SPI_OBJECT.transfer(EPD_FLASH_NOP); *device = (id_high << 8) | id_low; this->spi_teardown(); } @@ -141,13 +153,13 @@ void EPD_FLASH_Class::read(void *buffer, uint32_t address, uint16_t length) { digitalWrite(this->EPD_FLASH_CS, LOW); Delay_us(10); - SPI.transfer(EPD_FLASH_FAST_READ); - SPI.transfer(address >> 16); - SPI.transfer(address >> 8); - SPI.transfer(address); - SPI.transfer(EPD_FLASH_NOP); // read dummy byte + SPI_OBJECT.transfer(EPD_FLASH_FAST_READ); + SPI_OBJECT.transfer(address >> 16); + SPI_OBJECT.transfer(address >> 8); + SPI_OBJECT.transfer(address); + SPI_OBJECT.transfer(EPD_FLASH_NOP); // read dummy byte for (uint8_t *p = (uint8_t *)buffer; length != 0; --length) { - *p++ = SPI.transfer(EPD_FLASH_NOP); + *p++ = SPI_OBJECT.transfer(EPD_FLASH_NOP); } this->spi_teardown(); } @@ -162,10 +174,10 @@ void EPD_FLASH_Class::wait_for_ready(void) { bool EPD_FLASH_Class::is_busy(void) { digitalWrite(this->EPD_FLASH_CS, LOW); Delay_us(10); - SPI.transfer(EPD_FLASH_RDSR); - bool busy = 0 != (EPD_FLASH_WIP & SPI.transfer(EPD_FLASH_NOP)); + SPI_OBJECT.transfer(EPD_FLASH_RDSR); + bool busy = 0 != (EPD_FLASH_WIP & SPI_OBJECT.transfer(EPD_FLASH_NOP)); digitalWrite(this->EPD_FLASH_CS, HIGH); - SPI.transfer(EPD_FLASH_NOP); + SPI_OBJECT.transfer(EPD_FLASH_NOP); Delay_us(10); return busy; } @@ -176,7 +188,7 @@ void EPD_FLASH_Class::write_enable(void) { digitalWrite(this->EPD_FLASH_CS, LOW); Delay_us(10); - SPI.transfer(EPD_FLASH_WREN); + SPI_OBJECT.transfer(EPD_FLASH_WREN); this->spi_teardown(); } @@ -187,7 +199,7 @@ void EPD_FLASH_Class::write_disable(void) { digitalWrite(this->EPD_FLASH_CS, LOW); Delay_us(10); - SPI.transfer(EPD_FLASH_WRDI); + SPI_OBJECT.transfer(EPD_FLASH_WRDI); this->spi_teardown(); } @@ -197,12 +209,12 @@ void EPD_FLASH_Class::write(uint32_t address, const void *buffer, uint16_t lengt digitalWrite(this->EPD_FLASH_CS, LOW); Delay_us(10); - SPI.transfer(EPD_FLASH_PP); - SPI.transfer(address >> 16); - SPI.transfer(address >> 8); - SPI.transfer(address); + SPI_OBJECT.transfer(EPD_FLASH_PP); + SPI_OBJECT.transfer(address >> 16); + SPI_OBJECT.transfer(address >> 8); + SPI_OBJECT.transfer(address); for (const uint8_t *p = (const uint8_t *)buffer; length != 0; --length) { - SPI.transfer(*p++); + SPI_OBJECT.transfer(*p++); } this->spi_teardown(); } @@ -214,13 +226,13 @@ void EPD_FLASH_Class::write_from_progmem(uint32_t address, PROGMEM const void *b digitalWrite(this->EPD_FLASH_CS, LOW); Delay_us(10); - SPI.transfer(EPD_FLASH_PP); - SPI.transfer(address >> 16); - SPI.transfer(address >> 8); - SPI.transfer(address); + SPI_OBJECT.transfer(EPD_FLASH_PP); + SPI_OBJECT.transfer(address >> 16); + SPI_OBJECT.transfer(address >> 8); + SPI_OBJECT.transfer(address); for (PROGMEM const uint8_t *p = (PROGMEM const uint8_t *)buffer; length != 0; ++p, --length) { uint8_t the_byte = pgm_read_byte_near(p); - SPI.transfer(the_byte); + SPI_OBJECT.transfer(the_byte); } this->spi_teardown(); } @@ -232,9 +244,9 @@ void EPD_FLASH_Class::sector_erase(uint32_t address) { digitalWrite(this->EPD_FLASH_CS, LOW); Delay_us(10); - SPI.transfer(EPD_FLASH_SE); - SPI.transfer(address >> 16); - SPI.transfer(address >> 8); - SPI.transfer(address); + SPI_OBJECT.transfer(EPD_FLASH_SE); + SPI_OBJECT.transfer(address >> 16); + SPI_OBJECT.transfer(address >> 8); + SPI_OBJECT.transfer(address); this->spi_teardown(); } diff --git a/Sketches/libraries/EPD_PINOUT/EPD_PINOUT.h b/Sketches/libraries/EPD_PINOUT/EPD_PINOUT.h index 7d62cbb..6e07481 100644 --- a/Sketches/libraries/EPD_PINOUT/EPD_PINOUT.h +++ b/Sketches/libraries/EPD_PINOUT/EPD_PINOUT.h @@ -1,4 +1,5 @@ // Copyright 2013-2015 Pervasive Displays, Inc. +// Copyright 2016-2017 Wolfgang Astleitner (mrwastl@users.sourceforge.net) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,7 +18,11 @@ #include -#if defined(ENERGIA) +#if defined(CORE_TEENSY) +#include +#elif defined(ESP32) +#include +#elif defined(ENERGIA) #include #else #include diff --git a/Sketches/libraries/EPD_PINOUT/EPD_PINOUT_ESP32.h b/Sketches/libraries/EPD_PINOUT/EPD_PINOUT_ESP32.h new file mode 100644 index 0000000..dfbde98 --- /dev/null +++ b/Sketches/libraries/EPD_PINOUT/EPD_PINOUT_ESP32.h @@ -0,0 +1,51 @@ +// Copyright 2013-2015 Pervasive Displays, Inc. +// Copyright 2017 Wolfgang Astleitner (mrwastl@users.sourceforge.net) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language +// governing permissions and limitations under the License. + +#if !defined(EPD_PINOUT_ESP32_H) +#define EPD_PINOUT_ESP32_H 1 + +// ESP32 IO layout +const int Pin_TEMPERATURE = A6 /* A6 == 34 */; +const int Pin_PANEL_ON = 21; +const int Pin_BORDER = 27; +const int Pin_DISCHARGE = 22; +const int Pin_RESET = 25; +const int Pin_BUSY = 33; +const int Pin_EPD_CS = 32; +const int Pin_EPD_FLASH_CS = 17; + +// PWM: for V110 only +const int Pin_PWM = 26; +const int Pin_PWM_Channel = 0; + +// customisable SPI +const int Pin_SPI_MISO = 12; +const int Pin_SPI_MOSI = 13; +const int Pin_SPI_SCK = 14; +const int Pin_SPI_Channel = 2; +// set SPI frequency to 40 MHz (max. freq. for COG driver) +// will be reduced to 20 MHz because of SPI_CLOCK_DIV2 (see SPI_on()) +const uint32_t ESP32_SPI_Frequency = 40000000; + + +// the following are defined for completeness but not used or required +// for driving the display +const int Pin_SW2 = 2; +const int Pin_RED_LED = 4; + +// SPI object for both EPD_FLASH and EPD_V???_G?-classes +static SPIClass esp32_spi(Pin_SPI_Channel); + +#endif diff --git a/Sketches/libraries/EPD_PINOUT/EPD_PINOUT_Teensy.h b/Sketches/libraries/EPD_PINOUT/EPD_PINOUT_Teensy.h new file mode 100644 index 0000000..efc36bd --- /dev/null +++ b/Sketches/libraries/EPD_PINOUT/EPD_PINOUT_Teensy.h @@ -0,0 +1,38 @@ +// Copyright 2013-2015 Pervasive Displays, Inc. +// Copyright 2016-2017 Wolfgang Astleitner (mrwastl@users.sourceforge.net) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language +// governing permissions and limitations under the License. + +#if !defined(EPD_PINOUT_TEENSY_H) +#define EPD_PINOUT_TEENSY_H 1 + +// pinout is taken from: +// https://forum.pjrc.com/threads/25793-2-7-inch-ePaper-on-Teensy-does-not-compile-Adafruit_GFX#post53636 + +// Teensy 3.1/3.2 IO layout +const int Pin_TEMPERATURE = A0; +const int Pin_PANEL_ON = 2; +const int Pin_BORDER = 3; +const int Pin_DISCHARGE = 4; +const int Pin_PWM = 5; +const int Pin_RESET = 6; +const int Pin_BUSY = 7; +const int Pin_EPD_CS = 8; +const int Pin_EPD_FLASH_CS = 9; + +// the following are defined for completeness but not used or required +// for driving the display +const int Pin_SW2 = 0; +const int Pin_RED_LED = 1; + +#endif diff --git a/Sketches/libraries/EPD_V110_G1/EPD_V110_G1.cpp b/Sketches/libraries/EPD_V110_G1/EPD_V110_G1.cpp index 2a6ce45..6b52867 100644 --- a/Sketches/libraries/EPD_V110_G1/EPD_V110_G1.cpp +++ b/Sketches/libraries/EPD_V110_G1/EPD_V110_G1.cpp @@ -1,5 +1,8 @@ // Copyright 2013-2015 Pervasive Displays, Inc. // +// Teensy 3.1/3.2 and ESP32 adaptions: +// Copyright 2016-2017 Wolfgang Astleitner (mrwastl@serdisplib.sf.net) +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: @@ -28,9 +31,15 @@ #define ARRAY(type, ...) ((type[]){__VA_ARGS__}) #define CU8(...) (ARRAY(const uint8_t, __VA_ARGS__)) +#ifndef ESP32 + #define SPI_OBJECT SPI +#else + #include "EPD_PINOUT_ESP32.h" + #define SPI_OBJECT esp32_spi +#endif -static void PWM_start(int pin); -static void PWM_stop(int pin); +static void PWM_start(int pin_chan); +static void PWM_stop(int pin_chan); static void SPI_on(void); static void SPI_off(void); @@ -47,7 +56,11 @@ EPD_Class::EPD_Class(EPD_size _size, uint8_t pwm_pin, uint8_t reset_pin, uint8_t busy_pin, - uint8_t chip_select_pin) : + uint8_t chip_select_pin +#ifdef ESP32 + ,uint8_t pwm_channel +#endif + ) : EPD_Pin_PANEL_ON(panel_on_pin), EPD_Pin_BORDER(border_pin), EPD_Pin_DISCHARGE(discharge_pin), @@ -55,6 +68,9 @@ EPD_Class::EPD_Class(EPD_size _size, EPD_Pin_RESET(reset_pin), EPD_Pin_BUSY(busy_pin), EPD_Pin_EPD_CS(chip_select_pin), +#ifdef ESP32 + EPD_Channel_PWM(pwm_channel), +#endif size(_size) { this->base_stage_time = 480; // milliseconds @@ -111,6 +127,15 @@ EPD_Class::EPD_Class(EPD_size _size, } this->factored_stage_time = this->base_stage_time; + +#if defined (ESP32) + // inialise ledcWrite() + pinMode(pwm_pin, OUTPUT); + ledcAttachPin(pwm_pin, pwm_channel); + ledcSetup(pwm_channel, /*10000*/ 488.28, 8); + // set SPI frequency (defined in EPD_PINOUT_ESP32.h) + SPI_OBJECT.setFrequency(ESP32_SPI_Frequency); +#endif } @@ -125,7 +150,11 @@ void EPD_Class::begin(void) { SPI_on(); +#ifndef ESP32 PWM_start(this->EPD_Pin_PWM); +#else + PWM_start(this->EPD_Channel_PWM); +#endif Delay_ms(25); // Allow time for PWM to start digitalWrite(this->EPD_Pin_PANEL_ON, HIGH); Delay_ms(10); @@ -206,7 +235,11 @@ void EPD_Class::begin(void) { // final delay before PWM off Delay_ms(30); +#ifndef ESP32 PWM_stop(this->EPD_Pin_PWM); +#else + PWM_stop(this->EPD_Channel_PWM); +#endif // charge pump negative voltage on Delay_us(10); @@ -590,11 +623,15 @@ void EPD_Class::line(uint16_t line, const uint8_t *data, uint8_t fixed_value, bo static void SPI_on(void) { - SPI.end(); - SPI.begin(); - SPI.setBitOrder(MSBFIRST); - SPI.setDataMode(SPI_MODE2); - SPI.setClockDivider(SPI_CLOCK_DIV2); + SPI_OBJECT.end(); +#ifndef ESP32 + SPI_OBJECT.begin(); +#else + SPI_OBJECT.begin(Pin_SPI_SCK, Pin_SPI_MISO, Pin_SPI_MOSI); +#endif + SPI_OBJECT.setBitOrder(MSBFIRST); + SPI_OBJECT.setDataMode(SPI_MODE2); + SPI_OBJECT.setClockDivider(SPI_CLOCK_DIV2); SPI_put(0x00); SPI_put(0x00); Delay_us(10); @@ -604,17 +641,17 @@ static void SPI_on(void) { static void SPI_off(void) { // SPI.begin(); // SPI.setBitOrder(MSBFIRST); - SPI.setDataMode(SPI_MODE0); + SPI_OBJECT.setDataMode(SPI_MODE0); // SPI.setClockDivider(SPI_CLOCK_DIV2); SPI_put(0x00); SPI_put(0x00); Delay_us(10); - SPI.end(); + SPI_OBJECT.end(); } static void SPI_put(uint8_t c) { - SPI.transfer(c); + SPI_OBJECT.transfer(c); } @@ -642,11 +679,19 @@ static void SPI_send(uint8_t cs_pin, const uint8_t *buffer, uint16_t length) { } -static void PWM_start(int pin) { - analogWrite(pin, 128); // 50% duty cycle +static void PWM_start(int pin_chan) { +#if defined (ESP32) + ledcWrite(pin_chan, 128); // 50% duty cycle +#else + analogWrite(pin_chan, 128); // 50% duty cycle +#endif } -static void PWM_stop(int pin) { - analogWrite(pin, 0); +static void PWM_stop(int pin_chan) { +#if defined (ESP32) + ledcWrite(pin_chan, 0); +#else + analogWrite(pin_chan, 0); +#endif } diff --git a/Sketches/libraries/EPD_V110_G1/EPD_V110_G1.h b/Sketches/libraries/EPD_V110_G1/EPD_V110_G1.h index 7f79ade..1ed6f97 100644 --- a/Sketches/libraries/EPD_V110_G1/EPD_V110_G1.h +++ b/Sketches/libraries/EPD_V110_G1/EPD_V110_G1.h @@ -43,7 +43,7 @@ // if more SRAM available (8 kBytes) -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(CORE_TEENSY) || defined (ESP32) #define EPD_ENABLE_EXTRA_SRAM 1 #endif @@ -95,6 +95,10 @@ class EPD_Class { EPD_Class(const EPD_Class &f); // prevent copy +#ifdef ESP32 + const uint8_t EPD_Channel_PWM; +#endif + public: // power up and power down the EPD panel void begin(void); @@ -174,7 +178,6 @@ class EPD_Class { // single line display - very low-level // also has to handle AVR progmem void line(uint16_t line, const uint8_t *data, uint8_t fixed_value, bool read_progmem, EPD_stage stage); - // inline static void attachInterrupt(); // inline static void detachInterrupt(); @@ -185,7 +188,11 @@ class EPD_Class { uint8_t pwm_pin, uint8_t reset_pin, uint8_t busy_pin, - uint8_t chip_select_pin); + uint8_t chip_select_pin +#ifdef ESP32 + ,uint8_t pwm_channel = 0 +#endif + ); }; diff --git a/Sketches/libraries/EPD_V230_G2/EPD_V230_G2.cpp b/Sketches/libraries/EPD_V230_G2/EPD_V230_G2.cpp index a365b6b..2c81a55 100644 --- a/Sketches/libraries/EPD_V230_G2/EPD_V230_G2.cpp +++ b/Sketches/libraries/EPD_V230_G2/EPD_V230_G2.cpp @@ -1,5 +1,8 @@ // Copyright 2013-2015 Pervasive Displays, Inc. // +// Teensy 3.1/3.2 and ESP32 adaptions: +// Copyright 2016-2017 Wolfgang Astleitner (mrwastl@serdisplib.sf.net) +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: @@ -33,6 +36,13 @@ #define BORDER_BYTE_WHITE 0xaa #define BORDER_BYTE_NULL 0x00 +#ifndef ESP32 + #define SPI_OBJECT SPI +#else + #include "EPD_PINOUT_ESP32.h" + #define SPI_OBJECT esp32_spi +#endif + static void SPI_on(void); static void SPI_off(void); static void SPI_put(uint8_t c); @@ -101,6 +111,10 @@ EPD_Class::EPD_Class(EPD_size _size, } } +#if defined (ESP32) + // set SPI frequency (defined in EPD_PINOUT_ESP32.h) + SPI_OBJECT.setFrequency(ESP32_SPI_Frequency); +#endif } @@ -683,11 +697,15 @@ void EPD_Class::line(uint16_t line, const uint8_t *data, uint8_t fixed_value, static void SPI_on(void) { - SPI.end(); - SPI.begin(); - SPI.setBitOrder(MSBFIRST); - SPI.setDataMode(SPI_MODE0); - SPI.setClockDivider(SPI_CLOCK_DIV2); + SPI_OBJECT.end(); +#ifndef ESP32 + SPI_OBJECT.begin(); +#else + SPI_OBJECT.begin(Pin_SPI_SCK, Pin_SPI_MISO, Pin_SPI_MOSI); +#endif + SPI_OBJECT.setBitOrder(MSBFIRST); + SPI_OBJECT.setDataMode(SPI_MODE0); + SPI_OBJECT.setClockDivider(SPI_CLOCK_DIV2); SPI_put(0x00); SPI_put(0x00); Delay_us(10); @@ -697,17 +715,17 @@ static void SPI_on(void) { static void SPI_off(void) { // SPI.begin(); // SPI.setBitOrder(MSBFIRST); - SPI.setDataMode(SPI_MODE0); + SPI_OBJECT.setDataMode(SPI_MODE0); // SPI.setClockDivider(SPI_CLOCK_DIV2); SPI_put(0x00); SPI_put(0x00); Delay_us(10); - SPI.end(); + SPI_OBJECT.end(); } static void SPI_put(uint8_t c) { - SPI.transfer(c); + SPI_OBJECT.transfer(c); } @@ -734,7 +752,7 @@ static uint8_t SPI_read(uint8_t cs_pin, const uint8_t *buffer, uint16_t length) // send all data for (uint16_t i = 0; i < length; ++i) { - result = SPI.transfer(*buffer++); + result = SPI_OBJECT.transfer(*buffer++); if (i < 4) { rbuffer[i] = result; } diff --git a/Sketches/libraries/EPD_V230_G2/EPD_V230_G2.h b/Sketches/libraries/EPD_V230_G2/EPD_V230_G2.h index bacab52..e1f6043 100644 --- a/Sketches/libraries/EPD_V230_G2/EPD_V230_G2.h +++ b/Sketches/libraries/EPD_V230_G2/EPD_V230_G2.h @@ -43,7 +43,7 @@ // if more SRAM available (8 kBytes) -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(CORE_TEENSY) || defined (ESP32) #define EPD_ENABLE_EXTRA_SRAM 1 #endif diff --git a/Sketches/libraries/EPD_V231_G2/EPD_V231_G2.cpp b/Sketches/libraries/EPD_V231_G2/EPD_V231_G2.cpp index cf3962a..2d9ee2b 100644 --- a/Sketches/libraries/EPD_V231_G2/EPD_V231_G2.cpp +++ b/Sketches/libraries/EPD_V231_G2/EPD_V231_G2.cpp @@ -1,5 +1,8 @@ // Copyright 2013-2015 Pervasive Displays, Inc. // +// Teensy 3.1/3.2 and ESP32 adaptions: +// Copyright 2016-2017 Wolfgang Astleitner (mrwastl@serdisplib.sf.net) +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: @@ -37,6 +40,13 @@ #define BORDER_BYTE_WHITE 0xaa #define BORDER_BYTE_NULL 0x00 +#ifndef ESP32 + #define SPI_OBJECT SPI +#else + #include "EPD_PINOUT_ESP32.h" + #define SPI_OBJECT esp32_spi +#endif + static void SPI_on(void); static void SPI_off(void); static void SPI_put(uint8_t c); @@ -141,6 +151,10 @@ EPD_Class::EPD_Class(EPD_size _size, this->factored_stage_time = this->base_stage_time; // milliseconds this->setFactor(); // ensure default temperature +#if defined (ESP32) + // set SPI frequency (defined in EPD_PINOUT_ESP32.h) + SPI_OBJECT.setFrequency(ESP32_SPI_Frequency); +#endif } @@ -710,15 +724,19 @@ void EPD_Class::line(uint16_t line, const uint8_t *data, uint8_t fixed_value, bo static void SPI_on(void) { - SPI.end(); - SPI.begin(); - SPI.setBitOrder(MSBFIRST); + SPI_OBJECT.end(); +#ifndef ESP32 + SPI_OBJECT.begin(); +#else + SPI_OBJECT.begin(Pin_SPI_SCK, Pin_SPI_MISO, Pin_SPI_MOSI); +#endif + SPI_OBJECT.setBitOrder(MSBFIRST); #if defined(__MSP432P401R__) - SPI.setDataMode(SPI_MODE3); - SPI.setClockDivider(SPI_CLOCK_DIV2); + SPI_OBJECT.setDataMode(SPI_MODE3); + SPI_OBJECT.setClockDivider(SPI_CLOCK_DIV2); #else - SPI.setDataMode(SPI_MODE0); - SPI.setClockDivider(SPI_CLOCK_DIV2); + SPI_OBJECT.setDataMode(SPI_MODE0); + SPI_OBJECT.setClockDivider(SPI_CLOCK_DIV2); #endif SPI_put(0x00); SPI_put(0x00); @@ -730,17 +748,17 @@ static void SPI_on(void) { static void SPI_off(void) { // SPI.begin(); // SPI.setBitOrder(MSBFIRST); - SPI.setDataMode(SPI_MODE0); + SPI_OBJECT.setDataMode(SPI_MODE0); // SPI.setClockDivider(SPI_CLOCK_DIV2); SPI_put(0x00); SPI_put(0x00); Delay_us(10); - SPI.end(); + SPI_OBJECT.end(); } static void SPI_put(uint8_t c) { - SPI.transfer(c); + SPI_OBJECT.transfer(c); } @@ -769,7 +787,7 @@ static uint8_t SPI_read(uint8_t cs_pin, const uint8_t *buffer, uint16_t length) // send all data for (uint16_t i = 0; i < length; ++i) { - result = SPI.transfer(*buffer++); + result = SPI_OBJECT.transfer(*buffer++); #if DEBUG_SPI_READ if (i < sizeof(rbuffer)) { rbuffer[i] = result; diff --git a/Sketches/libraries/EPD_V231_G2/EPD_V231_G2.h b/Sketches/libraries/EPD_V231_G2/EPD_V231_G2.h index 1cccd8a..644e452 100644 --- a/Sketches/libraries/EPD_V231_G2/EPD_V231_G2.h +++ b/Sketches/libraries/EPD_V231_G2/EPD_V231_G2.h @@ -51,7 +51,7 @@ // if more SRAM available (8 kBytes) -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(CORE_TEENSY) || defined (ESP32) #define EPD_ENABLE_EXTRA_SRAM 1 #endif diff --git a/Sketches/libraries/S5813A/S5813A.cpp b/Sketches/libraries/S5813A/S5813A.cpp index f79ab6e..d1da2bc 100644 --- a/Sketches/libraries/S5813A/S5813A.cpp +++ b/Sketches/libraries/S5813A/S5813A.cpp @@ -19,6 +19,11 @@ // Updated 18-04-2016 by Chiara Ruggeri (chiara@arduino.org) // . Added Arduino Due / Arduino M0 / Arduino Tian compatibility +// Updated 2016-2017 by Wolfgang Astleitner (mrwastl@users.sourceforge.net) +// . Added Teensy 3.1/3.2 and ESP32 compatibility +// . Removal of uV defines (not used anywhere) +// . Added optional parameter for fine tuning maximum ADC voltage in begin() + #if defined(ENERGIA) #include #else @@ -42,7 +47,6 @@ #define ANALOG_REFERENCE INTERNAL2V5 // ADC maximum voltage at counts -#define ADC_MAXIMUM_uV 2500000L #define ADC_MAXIMUM_mV 2500L #define ADC_COUNTS 1024L @@ -52,7 +56,6 @@ #define PIN_TEMPERATURE 6 // ADC maximum voltage at counts -#define ADC_MAXIMUM_uV 3300000L #define ADC_MAXIMUM_mV 3300L #define ADC_COUNTS 1024L @@ -62,7 +65,6 @@ #define PIN_TEMPERATURE 6 // ADC maximum voltage at counts -#define ADC_MAXIMUM_uV 3300000L #define ADC_MAXIMUM_mV 3300L #define ADC_COUNTS 4096L @@ -72,7 +74,6 @@ #define PIN_TEMPERATURE 6 // ADC maximum voltage at counts -#define ADC_MAXIMUM_uV 3300000L #define ADC_MAXIMUM_mV 3300L #define ADC_COUNTS 4096L @@ -84,7 +85,6 @@ // ADC maximum voltage at counts // See SWAS032E –JULY 2013–REVISED JUNE 2014 // § 3.2 Drive Strength and Reset States for Analog-Digital Multiplexed Pins -#define ADC_MAXIMUM_uV 1460000L #define ADC_MAXIMUM_mV 1460L #define ADC_COUNTS 4096L @@ -99,21 +99,34 @@ #define ANALOG_REFERENCE DEFAULT // ADC maximum voltage at counts -#define ADC_MAXIMUM_uV 3300000L #define ADC_MAXIMUM_mV 3300L #define ADC_COUNTS 1024L -#elif defined(ARDUINO_ARCH_SAM) -// Arduino Due runs at 3.3V +#elif defined(ARDUINO_ARCH_SAM) || defined(CORE_TEENSY) +// Arduino Due and Teensy run at 3.3V #define PIN_TEMPERATURE A0 #define ANALOG_REFERENCE DEFAULT // ADC maximum voltage at counts -#define ADC_MAXIMUM_uV 3300000L #define ADC_MAXIMUM_mV 3300L #define ADC_COUNTS 1024L +#elif defined(ESP32) +// ESP32 run at 3.3V, but measures from 0 to 3.6/3.9V (when using ADC_11db) +#define PIN_TEMPERATURE A6 + +#define ANALOG_REFERENCE DEFAULT + +// ADC maximum voltage at counts +// NOTA BENE: 4.1V-4.2V is to be determined empirically! +// it is unclear, why this doesn't match the voltage range that would be expected when using ADC_11db +// this can be fine tuned when calling begin(): 2nd parameter: tune_adc_mv +// ESP32 DevKitC : recommended: -100 +// DOIT Devkit ESP32 V.1: should be fine with default 0 +#define ADC_MAXIMUM_mV 4200L +#define ADC_COUNTS 4096L + #else // Arduino Leonardo / Atmel MEGA32U4 runs at 5V #define PIN_TEMPERATURE A0 @@ -122,7 +135,6 @@ #define ANALOG_REFERENCE DEFAULT // ADC maximum voltage at counts -#define ADC_MAXIMUM_uV 5000000L #define ADC_MAXIMUM_mV 5000L #define ADC_COUNTS 1024L @@ -132,9 +144,7 @@ // temperature chip parameters // these may need adjustment for a particular chip // (typical values taken from data sheet) -#define Vstart_uV 1145000L #define Tstart_C 100 -#define Vslope_uV -11040L #define Vstart_mV 1145L #define Vslope_mV -11 @@ -155,17 +165,24 @@ S5813A_Class S5813A(PIN_TEMPERATURE); S5813A_Class::S5813A_Class(uint8_t input_pin) : temperature_pin(input_pin) { + this->adc_maximum_mv = ADC_MAXIMUM_mV; } // initialise the analog system -void S5813A_Class::begin(uint8_t input_pin) +void S5813A_Class::begin(uint8_t input_pin, long tune_adc_mv) { pinMode(input_pin, INPUT); #if defined(__MSP430G2553__) analogReference(ANALOG_REFERENCE); +#endif +#if defined(ESP32) + analogSetPinAttenuation(input_pin, ADC_11db); /* 0 - 3.9V */ + analogReadResolution(12); // matches ADC_COUNTS #endif this->temperature_pin = input_pin; + + this->adc_maximum_mv = ADC_MAXIMUM_mV + tune_adc_mv; } @@ -177,14 +194,39 @@ void S5813A_Class::end(void) { // not the ADC value, but the value that should be measured on the // sensor output pin long S5813A_Class::readVoltage(void) { +#ifndef ESP32 long vADC = analogRead(this->temperature_pin); +#else + // ESP32: analog reads are not very reliable: take 3 samples, determine 2 with shortest distance and average these + long vADC = 0.0; + long vADCser[3]; + long vdiff01, vdiff02, vdiff12; + vADCser[0] = analogRead(this->temperature_pin); + vADCser[1] = analogRead(this->temperature_pin); + vADCser[2] = analogRead(this->temperature_pin); + // calculate absolute distances between all samples + vdiff01 = vADCser[0] - vADCser[1]; if (vdiff01 < 0.0) vdiff01 *= -1.0; + vdiff02 = vADCser[0] - vADCser[2]; if (vdiff02 < 0.0) vdiff02 *= -1.0; + vdiff12 = vADCser[1] - vADCser[2]; if (vdiff12 < 0.0) vdiff12 *= -1.0; + // find two samples with shortest distance and average these + if (vdiff01 < vdiff02) { // 0-1 < 0-2 + vADC = (vdiff12 < vdiff01) // 1-2 < 0-1 ? + ? (vADCser[1] + vADCser[2]) // shortest: 1-2 + : (vADCser[0] + vADCser[1]); // shortest: 0-1 + } else { // 0-2 < 0-1 + vADC = (vdiff12 < vdiff02) // 1-2 < 0-2 ? + ? (vADCser[1] + vADCser[2]) // shortest: 1-2 + : (vADCser[0] + vADCser[2]); // shortest: 0-2 + } + vADC /= 2.0; // two values added together: calculate average +#endif /* Serial.print("analogRead="); Serial.print(vADC); Serial.print("\treadVoltage="); Serial.println(REV_PD((vADC * ADC_MAXIMUM_mV) / ADC_COUNTS)); */ - return REV_PD((vADC * ADC_MAXIMUM_mV) / ADC_COUNTS); + return REV_PD((vADC * this->adc_maximum_mv) / ADC_COUNTS); } diff --git a/Sketches/libraries/S5813A/S5813A.h b/Sketches/libraries/S5813A/S5813A.h index a9547ac..b25d805 100644 --- a/Sketches/libraries/S5813A/S5813A.h +++ b/Sketches/libraries/S5813A/S5813A.h @@ -16,6 +16,11 @@ // . Added #include Energia // . Changed uV to mV to avoid overflows +// Updated 2016-2017 by Wolfgang Astleitner (mrwastl@users.sourceforge.net) +// . Added Teensy 3.1/3.2 and ESP32 compatibility +// . Removal of uV defines (not used anywhere) +// . Added optional parameter for fine tuning maximum ADC voltage in begin() + #if !defined(EPD_S5813A_H) #define EPD_S5813A_H 1 @@ -29,6 +34,7 @@ class S5813A_Class { private: uint8_t temperature_pin; + long adc_maximum_mv; S5813A_Class(const S5813A_Class &f); // prevent copy @@ -40,7 +46,16 @@ class S5813A_Class { // inline static void detachInterrupt(); // allow external program to configure actual analog pin to use - void begin(uint8_t input_pin); + // tune_adc_mv: fine tune max reference voltage (in mV) + // tested values: + // Teensy: -50 + // + // ESP32 DevKitC: -100 + // DOIT Devkit ESP32 V.1: 0 + // + // Seeeduino Mega, switched to 5V: 0 + // Seeeduino Mega, switched to 3.3V: -1600 (5.0V - 1.6V would give 3.4V but seems to be more accurate) + void begin(uint8_t input_pin, long tune_adc_mv = 0); void end(void); S5813A_Class(uint8_t input_pin);