diff --git a/M5Stack.cpp b/M5Stack.cpp index b6d62c2..bb768eb 100644 --- a/M5Stack.cpp +++ b/M5Stack.cpp @@ -44,38 +44,32 @@ void M5Stack::update() { void M5Stack::startupLogo() { static uint8_t brightness, pre_brightness; uint32_t length = strlen((char*)m5stack_startup_music); - uint8_t _volume = 2; - uint16_t delay_interval = ((uint32_t)1000000/20000); Lcd.setBrightness(0); Lcd.drawBitmap(0, 0, 320, 240, (uint16_t *)gImage_logoM5); - if(_volume != 0) { - for(int i=0; i>2); - delayMicroseconds(40); - brightness = (i/157); - if(pre_brightness != brightness) { - pre_brightness = brightness; - Lcd.setBrightness(brightness); - } + for(int i=0; i>2); + delayMicroseconds(40); + brightness = (i/157); + if(pre_brightness != brightness) { + pre_brightness = brightness; + Lcd.setBrightness(brightness); } } - for(int i=32; i>0; i--) { - dacWrite(SPEAKER_PIN, i); - delay(2); - } - for(int i=255; i>=0; i--) { lcd.setBrightness(i); + if(i<=32) { + dacWrite(SPEAKER_PIN, i); + } delay(2); } + Lcd.fillScreen(BLACK); - delay(1000); + delay(800); for(int i=0; i>=100; i++) { Lcd.setBrightness(i); delay(2); } - Lcd.setBrightness(100); } M5Stack m5; diff --git a/examples/Advanced/AppStore/AppStore.ino b/examples/Advanced/AppStore/AppStore.ino deleted file mode 100644 index 9ed22f1..0000000 --- a/examples/Advanced/AppStore/AppStore.ino +++ /dev/null @@ -1,163 +0,0 @@ -#include -#include "clock.h" -#include "DHT.h" - -#define DHTPIN 22 // what digital pin we're connected to -#define DHTTYPE DHT11 // DHT 11 -DHT dht(DHTPIN, DHTTYPE); -uint8_t select_app_id; - -void setup() -{ - m5.begin(); - select_app_id = m5.bootSetup(); - - m5.lcd.fillScreen(WHITE); - m5.lcd.drawPicture(47, 38, 120, 96, gImage_logo); - - switch (select_app_id) { - case 0: - wifi_scan_setup(); - break; - - case 1: - DHT11_setup(); - break; - - case 2: - clock_setup(); - break; - } -} - -void loop() -{ - switch (select_app_id) { - case 0: - wifi_scan_loop(); - break; - - case 1: - DHT11_loop(); - break; - - case 2: - clock_loop(); - break; - } - - m5.loop(); -} - -//------------------------- -void DHT11_setup() -{ - dht.begin(); - m5.lcd.fillScreen(WHITE); - m5.lcd.drawTitle("Environment", 0x09F1); - #define X_OFFSET 40 - #define Y_POS 165 -} - -void DHT11_loop() -{ - static uint32_t sampling_tick; - static float pre_hif, pre_hic; - static bool f2c_flag=0; - - if(millis() > sampling_tick) { - sampling_tick = millis() + 1000; - // Reading temperature or humidity takes about 250 milliseconds! - // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) - float h = dht.readHumidity(); - // Read temperature as Celsius (the default) - float t = dht.readTemperature(); - // Read temperature as Fahrenheit (isFahrenheit = true) - float f = dht.readTemperature(true); - - // Check if any reads failed and exit early (to try again). - if (isnan(h) || isnan(t) || isnan(f)) { - Serial.println("Failed to read from DHT sensor!"); - return; - } - - // Compute heat index in Fahrenheit (the default) - float hif = dht.computeHeatIndex(f, h); - // Compute heat index in Celsius (isFahreheit = false) - float hic = dht.computeHeatIndex(t, h, false); - - Serial.print("Humidity: "); - Serial.print(h); - Serial.print(" %\t"); - Serial.print("Temperature: "); - Serial.print(t); - Serial.print(" *C "); - Serial.print(f); - Serial.print(" *F\t"); - Serial.print("Heat index: "); - Serial.print(hic); - Serial.print(" *C "); - Serial.print(hif); - Serial.println(" *F"); - - if((pre_hif!=hif) || (pre_hic!=hic)) { - pre_hif = hif; - pre_hic = hic; - - m5.lcd.setFont(&FreeMonoBoldOblique12pt7b); - // m5.lcd.setFont(&FreeMonoBoldOblique18pt7b); - m5.lcd.fillRect(19, 70, 190, 30, WHITE); - m5.lcd.setTextColor(GRAY); - m5.lcd.setTextSize(1); - m5.lcd.setCursor(25, 90); - if(f2c_flag) { - m5.lcd.printf("%2.1fF %2.1f%%", hif, h); - } else { - m5.lcd.printf("%2.1fC %2.1f%%", hic, h); - } - } - } - if(m5.pressed(BUTTON_B)) { - f2c_flag = !f2c_flag; - sampling_tick = 0; - pre_hif=0; - } -} - -void wifi_scan_setup() -{ - m5.lcd.setFont(); -} - -void wifi_scan_loop() -{ - m5.lcd.setCursor(0, 0); - // m5.lcd.println("scan start"); - // WiFi.scanNetworks will return the number of networks found - int n = WiFi.scanNetworks(); - m5.lcd.fillScreen(BLACK); - m5.lcd.println("wifi scan done"); - if (n == 0) - { - m5.lcd.println("no networks found"); - } - else - { - m5.lcd.print(n); - m5.lcd.println(" networks found"); - for (int i = 0; i < n; ++i) - { - // Print SSID and RSSI for each network found - m5.lcd.printf("%2d", i + 1); - m5.lcd.print(": "); - m5.lcd.print(WiFi.SSID(i)); - m5.lcd.print(" ("); - m5.lcd.print(WiFi.RSSI(i)); - m5.lcd.print(")"); - m5.lcd.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*"); - delay(10); - } - } - Serial.println(""); - delay(3000); -} diff --git a/examples/Advanced/AppStore/clock.cpp b/examples/Advanced/AppStore/clock.cpp deleted file mode 100644 index 260c1cb..0000000 --- a/examples/Advanced/AppStore/clock.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* - WiFi Web Server LED Blink - - A simple web server that lets you blink an LED via the web. - This sketch will print the IP address of your WiFi Shield (once connected) - to the Serial monitor. From there, you can open that address in a web browser - to turn on and off the LED on pin 5. - - If the IP address of your shield is yourAddress: - http://yourAddress/H turns the LED on - http://yourAddress/L turns it off - - This example is written for a network using WPA encryption. For - WEP or WPA, change the Wifi.begin() call accordingly. - - Circuit: - * WiFi shield attached - * LED attached to pin 5 - - created for arduino 25 Nov 2012 - by Tom Igoe - -ported for sparkfun esp32 -31.01.2017 by Jan Hendrik Berlin - - */ -#include "clock.h" - -WiFiUDP ntpUDP; -// NTPClient timeClient(ntpUDP); -NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000); - -TimerObject *timer1 = new TimerObject(1000); -TimerObject *timer_setting_select = new TimerObject(500); -TimerObject *timer_button_draw = new TimerObject(10); - -typedef void (*CallBackType)(); -#define X_POS_OFFSET 15 -#define Y_POS_OFFSET 45 - -// M5Stack_Button button[3]; -void upCursorBlink(); - -class AlarmClock { - -enum week {SUN, MON, TUE, WED, THU, FRI, SAT, EVERYDAY}; - -public: - AlarmClock() { - state = 0; - } - - AlarmClock(uint8_t h, uint8_t m) { - hours = h; - minutes = m; - // seconds = s; - repeat_week_mask = EVERYDAY; - state = 1; - } - - AlarmClock(uint8_t h, uint8_t m, uint8_t repeat_mask) { - AlarmClock(h, m); - repeat_week_mask = repeat_mask; - state = 1; - } - - void setAlarmTime(uint8_t h, uint8_t m) { - hours = h; - minutes = m; - // seconds = s; - } - - void setEnable() { - state = 1; - } - - void setDisable() { - state = 0; - } - - void setOnClock(CallBackType callback) { - on_alarm_clock = callback; - } - - void update(uint64_t epoch_time) { - if(state == 1) { - unsigned long rawTime = epoch_time; - unsigned long local_hours = (rawTime % 86400L) / 3600; - unsigned long local_minutes = (rawTime % 3600) / 60; - // unsigned long local_seconds = rawTime % 60; - - if((local_minutes==minutes)&&(local_hours==hours)) { - if(on_alarm_clock) { - on_alarm_clock(); - } - } - } - } - -// private: - bool state; - int8_t hours; - int8_t minutes; - int8_t seconds; - int8_t repeat_week_mask; - CallBackType on_alarm_clock; -}; - -AlarmClock alarm_clock(6, 30); - -// AlarmClock alarm_clock; //= new AlarmClock(7, 30, 00); -uint8_t alarm_state = 0; -uint8_t setting_state = 0; -#define ACLOCK_RUNING 0 -#define ACLOCK_SETTING 1 - -void upTimeDisplay() -{ - m5.lcd.setTextSize(4); - m5.lcd.setTextColor(BLACK, WHITE); - m5.lcd.setCursor(X_POS_OFFSET, 45); - m5.lcd.print(timeClient.getFormattedTime().c_str()); -} - -void upCursorBlink() -{ - static bool tg = 1; - - m5.lcd.setTextSize(4); - m5.lcd.setCursor(X_POS_OFFSET+35, 95); - - if((setting_state == 1) && (tg)) { - m5.lcd.setTextColor(WHITE, BLACK); - } else { - m5.lcd.setTextColor(BLACK, WHITE); - } - m5.lcd.printf("%2.2d", alarm_clock.hours); - - m5.lcd.setTextColor(BLACK, WHITE); - m5.lcd.printf(":"); - - if((setting_state == 2) && (tg)) { - m5.lcd.setTextColor(WHITE, BLACK); - } else { - m5.lcd.setTextColor(BLACK, WHITE); - } - m5.lcd.printf("%2.2d", alarm_clock.minutes); -} - -void clock_setup() -{ - -//--------------------------------------- - m5.lcd.setFont(); - m5.lcd.fillScreen(WHITE); - m5.lcd.fillRect(0, 0, 220, 22, 0x09F1); - m5.lcd.setCursor(4, 4); - m5.lcd.setTextColor(WHITE); - m5.lcd.setTextSize(2); - m5.lcd.printf("Alarm Clock"); - - #define X_OFFSET 40 - #define Y_POS 165 - - m5.lcd.buttonSet(BTN_A, "+"); - m5.lcd.buttonSet(BTN_B, "-"); - m5.lcd.buttonSet(BTN_C, "+SET"); - -//--------------------------------------------- - - m5.lcd.setTextSize(4); - m5.lcd.setCursor(X_POS_OFFSET, 45); - // m5.lcd.setTextColor(BLACK); - m5.lcd.setTextColor(BLACK, WHITE); - - // m5.lcd.setTextWrap(boolean w); - // m5.lcd.print("hello world!"); - // m5.lcd.print(timeClient.getFormattedTime().c_str()); - - // alarm_state = ACLOCK_SETTING; - // setting_state = 1; - - //--------timeClient------ - // wifi_connect(); - timeClient.begin(); - timeClient.setTimeOffset(28800); - - timer1->setOnTimer(&upTimeDisplay); - timer1->Start(); - timer_setting_select->setOnTimer(upCursorBlink); - upTimeDisplay(); - upCursorBlink(); -} - - -void clock_loop(){ - switch (alarm_state) { - case ACLOCK_RUNING: - if(m5.pressed(BTN_C)) { - setting_state = 1; - alarm_state = ACLOCK_SETTING; - timer_setting_select->Start(); - } - break; - - case ACLOCK_SETTING: - if(m5.pressed(BTN_C)) { - if(++setting_state == 3) { - setting_state = 0; - alarm_state = ACLOCK_RUNING; - // timer_setting_select->Stop(); - } - } - switch (setting_state) { - case 1: - if(m5.pressed(BTN_A)) {if(++alarm_clock.hours == 24) alarm_clock.hours = 0;} - if(m5.pressed(BTN_B)) {if(--alarm_clock.hours == -1) alarm_clock.hours = 23;} - break; - - case 2: - if(m5.pressed(BTN_A)) {if(++alarm_clock.minutes == 60) alarm_clock.minutes = 0;} - if(m5.pressed(BTN_B)) {if(--alarm_clock.minutes == -1) alarm_clock.minutes = 59;} - break; - } - break; - } - - timer1->Update(); - timer_setting_select->Update(); - // timer_button_draw->Update(); - timeClient.update(); -} diff --git a/examples/Advanced/AppStore/clock.h b/examples/Advanced/AppStore/clock.h deleted file mode 100644 index ac6526d..0000000 --- a/examples/Advanced/AppStore/clock.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _CLOCK_H_ -#define _CLOCK_H_ - -#include "M5Stack.h" -#include "NTPClient.h" -#include "TimerObject.h" - -void clock_setup(); -void clock_loop(); - -#endif diff --git a/examples/Advanced/Camera/Adafruit_ILI9341.cpp b/examples/Advanced/Camera/Adafruit_ILI9341.cpp deleted file mode 100644 index 79fd0b1..0000000 --- a/examples/Advanced/Camera/Adafruit_ILI9341.cpp +++ /dev/null @@ -1,669 +0,0 @@ -/*************************************************** - This is our library for the Adafruit ILI9341 Breakout and Shield - ----> http://www.adafruit.com/products/1651 - - Check out the links above for our tutorials and wiring diagrams - These displays use SPI to communicate, 4 or 5 pins are required to - interface (RST is optional) - Adafruit invests time and resources providing this open source code, - please support Adafruit and open-source hardware by purchasing - products from Adafruit! - - Written by Limor Fried/Ladyada for Adafruit Industries. - MIT license, all text above must be included in any redistribution - ****************************************************/ - -#include "Adafruit_ILI9341.h" -#ifndef ARDUINO_STM32_FEATHER - #include "pins_arduino.h" -#ifndef RASPI - #include "wiring_private.h" -#endif -#endif -#include - - -#define MADCTL_MY 0x80 -#define MADCTL_MX 0x40 -#define MADCTL_MV 0x20 -#define MADCTL_ML 0x10 -#define MADCTL_RGB 0x00 -#define MADCTL_BGR 0x08 -#define MADCTL_MH 0x04 - -/* - * Control Pins - * */ - -#ifdef USE_FAST_PINIO -#define SPI_DC_HIGH() *dcport |= dcpinmask -#define SPI_DC_LOW() *dcport &= ~dcpinmask -#define SPI_CS_HIGH() *csport |= cspinmask -#define SPI_CS_LOW() *csport &= ~cspinmask -#else -#define SPI_DC_HIGH() digitalWrite(_dc, HIGH) -#define SPI_DC_LOW() digitalWrite(_dc, LOW) -#define SPI_CS_HIGH() digitalWrite(_cs, HIGH) -#define SPI_CS_LOW() digitalWrite(_cs, LOW) -#endif - -/* - * Software SPI Macros - * */ - -#ifdef USE_FAST_PINIO -#define SSPI_MOSI_HIGH() *mosiport |= mosipinmask -#define SSPI_MOSI_LOW() *mosiport &= ~mosipinmask -#define SSPI_SCK_HIGH() *clkport |= clkpinmask -#define SSPI_SCK_LOW() *clkport &= ~clkpinmask -#define SSPI_MISO_READ() ((*misoport & misopinmask) != 0) -#else -#define SSPI_MOSI_HIGH() digitalWrite(_mosi, HIGH) -#define SSPI_MOSI_LOW() digitalWrite(_mosi, LOW) -#define SSPI_SCK_HIGH() digitalWrite(_sclk, HIGH) -#define SSPI_SCK_LOW() digitalWrite(_sclk, LOW) -#define SSPI_MISO_READ() digitalRead(_miso) -#endif - -#define SSPI_BEGIN_TRANSACTION() -#define SSPI_END_TRANSACTION() -#define SSPI_WRITE(v) spiWrite(v) -#define SSPI_WRITE16(s) SSPI_WRITE((s) >> 8); SSPI_WRITE(s) -#define SSPI_WRITE32(l) SSPI_WRITE((l) >> 24); SSPI_WRITE((l) >> 16); SSPI_WRITE((l) >> 8); SSPI_WRITE(l) -#define SSPI_WRITE_PIXELS(c,l) for(uint32_t i=0; i<(l); i+=2){ SSPI_WRITE(((uint8_t*)(c))[i+1]); SSPI_WRITE(((uint8_t*)(c))[i]); } - -/* - * Hardware SPI Macros - * */ - -#ifndef ESP32 - #define SPI_OBJECT SPI -#else - #define SPI_OBJECT _spi -#endif - -#if defined (__AVR__) || defined(TEENSYDUINO) || defined(ARDUINO_ARCH_STM32F1) - #define HSPI_SET_CLOCK() SPI_OBJECT.setClockDivider(SPI_CLOCK_DIV2); -#elif defined (__arm__) - #define HSPI_SET_CLOCK() SPI_OBJECT.setClockDivider(11); -#elif defined(ESP8266) || defined(ESP32) - #define HSPI_SET_CLOCK() SPI_OBJECT.setFrequency(_freq); -#elif defined(RASPI) - #define HSPI_SET_CLOCK() SPI_OBJECT.setClock(_freq); -#elif defined(ARDUINO_ARCH_STM32F1) - #define HSPI_SET_CLOCK() SPI_OBJECT.setClock(_freq); -#else - #define HSPI_SET_CLOCK() -#endif - -#ifdef SPI_HAS_TRANSACTION - #define HSPI_BEGIN_TRANSACTION() SPI_OBJECT.beginTransaction(SPISettings(_freq, MSBFIRST, SPI_MODE0)) - #define HSPI_END_TRANSACTION() SPI_OBJECT.endTransaction() -#else - #define HSPI_BEGIN_TRANSACTION() HSPI_SET_CLOCK(); SPI_OBJECT.setBitOrder(MSBFIRST); SPI_OBJECT.setDataMode(SPI_MODE0) - #define HSPI_END_TRANSACTION() -#endif - -#ifdef ESP32 - #define SPI_HAS_WRITE_PIXELS -#endif -#if defined(ESP8266) || defined(ESP32) - // Optimized SPI (ESP8266 and ESP32) - #define HSPI_READ() SPI_OBJECT.transfer(0) - #define HSPI_WRITE(b) SPI_OBJECT.write(b) - #define HSPI_WRITE16(s) SPI_OBJECT.write16(s) - #define HSPI_WRITE32(l) SPI_OBJECT.write32(l) - #ifdef SPI_HAS_WRITE_PIXELS - #define SPI_MAX_PIXELS_AT_ONCE 32 - #define HSPI_WRITE_PIXELS(c,l) SPI_OBJECT.writePixels(c,l) - #else - #define HSPI_WRITE_PIXELS(c,l) for(uint32_t i=0; i<((l)/2); i++){ SPI_WRITE16(((uint16_t*)(c))[i]); } - #endif -#else - // Standard Byte-by-Byte SPI - - #if defined (__AVR__) || defined(TEENSYDUINO) -static inline uint8_t _avr_spi_read(void) __attribute__((always_inline)); -static inline uint8_t _avr_spi_read(void) { - uint8_t r = 0; - SPDR = r; - while(!(SPSR & _BV(SPIF))); - r = SPDR; - return r; -} - #define HSPI_WRITE(b) {SPDR = (b); while(!(SPSR & _BV(SPIF)));} - #define HSPI_READ() _avr_spi_read() - #else - #define HSPI_WRITE(b) SPI_OBJECT.transfer((uint8_t)(b)) - #define HSPI_READ() HSPI_WRITE(0) - #endif - #define HSPI_WRITE16(s) HSPI_WRITE((s) >> 8); HSPI_WRITE(s) - #define HSPI_WRITE32(l) HSPI_WRITE((l) >> 24); HSPI_WRITE((l) >> 16); HSPI_WRITE((l) >> 8); HSPI_WRITE(l) - #define HSPI_WRITE_PIXELS(c,l) for(uint32_t i=0; i<(l); i+=2){ HSPI_WRITE(((uint8_t*)(c))[i+1]); HSPI_WRITE(((uint8_t*)(c))[i]); } -#endif - -/* - * Final SPI Macros - * */ -#if defined (ARDUINO_ARCH_ARC32) -#define SPI_DEFAULT_FREQ 16000000 -#elif defined (__AVR__) || defined(TEENSYDUINO) -#define SPI_DEFAULT_FREQ 8000000 -#elif defined(ESP8266) || defined(ESP32) -#define SPI_DEFAULT_FREQ 78000000 -#elif defined(RASPI) -#define SPI_DEFAULT_FREQ 80000000 -#elif defined(ARDUINO_ARCH_STM32F1) -#define SPI_DEFAULT_FREQ 36000000 -#else -#define SPI_DEFAULT_FREQ 24000000 -#endif - -#define SPI_BEGIN() if(_sclk < 0){SPI_OBJECT.begin();} -#define SPI_BEGIN_TRANSACTION() if(_sclk < 0){HSPI_BEGIN_TRANSACTION();} -#define SPI_END_TRANSACTION() if(_sclk < 0){HSPI_END_TRANSACTION();} -#define SPI_WRITE16(s) if(_sclk < 0){HSPI_WRITE16(s);}else{SSPI_WRITE16(s);} -#define SPI_WRITE32(l) if(_sclk < 0){HSPI_WRITE32(l);}else{SSPI_WRITE32(l);} -#define SPI_WRITE_PIXELS(c,l) if(_sclk < 0){HSPI_WRITE_PIXELS(c,l);}else{SSPI_WRITE_PIXELS(c,l);} - -// Pass 8-bit (each) R,G,B, get back 16-bit packed color -uint16_t Adafruit_ILI9341::color565(uint8_t r, uint8_t g, uint8_t b) { - return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3); -} - -Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t mosi, - int8_t sclk, int8_t rst, int8_t miso) : Adafruit_GFX(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT) { - _cs = cs; - _dc = dc; - _rst = rst; - _sclk = sclk; - _mosi = mosi; - _miso = miso; - _freq = 0; -#ifdef USE_FAST_PINIO - csport = portOutputRegister(digitalPinToPort(_cs)); - cspinmask = digitalPinToBitMask(_cs); - dcport = portOutputRegister(digitalPinToPort(_dc)); - dcpinmask = digitalPinToBitMask(_dc); - clkport = portOutputRegister(digitalPinToPort(_sclk)); - clkpinmask = digitalPinToBitMask(_sclk); - mosiport = portOutputRegister(digitalPinToPort(_mosi)); - mosipinmask = digitalPinToBitMask(_mosi); - if(miso >= 0){ - misoport = portInputRegister(digitalPinToPort(_miso)); - misopinmask = digitalPinToBitMask(_miso); - } else { - misoport = 0; - misopinmask = 0; - } -#endif -} - -Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t rst) : Adafruit_GFX(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT) { - _cs = cs; - _dc = dc; - _rst = rst; - _sclk = -1; - _mosi = -1; - _miso = -1; - _freq = 0; -#ifdef USE_FAST_PINIO - csport = portOutputRegister(digitalPinToPort(_cs)); - cspinmask = digitalPinToBitMask(_cs); - dcport = portOutputRegister(digitalPinToPort(_dc)); - dcpinmask = digitalPinToBitMask(_dc); - clkport = 0; - clkpinmask = 0; - mosiport = 0; - mosipinmask = 0; - misoport = 0; - misopinmask = 0; -#endif -} - - -#ifdef ESP32 -void Adafruit_ILI9341::begin(uint32_t freq, SPIClass &spi) -#else -void Adafruit_ILI9341::begin(uint32_t freq) -#endif -{ -#ifdef ESP32 - _spi = spi; -#endif - if(!freq){ - freq = SPI_DEFAULT_FREQ; - } - _freq = freq; - - // Control Pins - pinMode(_dc, OUTPUT); - digitalWrite(_dc, LOW); - pinMode(_cs, OUTPUT); - digitalWrite(_cs, HIGH); - - // Software SPI - if(_sclk >= 0){ - pinMode(_mosi, OUTPUT); - digitalWrite(_mosi, LOW); - pinMode(_sclk, OUTPUT); - digitalWrite(_sclk, HIGH); - if(_miso >= 0){ - pinMode(_miso, INPUT); - } - } - - // Hardware SPI - SPI_BEGIN(); - - // toggle RST low to reset - if (_rst >= 0) { - pinMode(_rst, OUTPUT); - digitalWrite(_rst, HIGH); - delay(100); - digitalWrite(_rst, LOW); - delay(100); - digitalWrite(_rst, HIGH); - delay(200); - } - - startWrite(); - - writeCommand(0xEF); - spiWrite(0x03); - spiWrite(0x80); - spiWrite(0x02); - - writeCommand(0xCF); - spiWrite(0x00); - spiWrite(0XC1); - spiWrite(0X30); - - writeCommand(0xED); - spiWrite(0x64); - spiWrite(0x03); - spiWrite(0X12); - spiWrite(0X81); - - writeCommand(0xE8); - spiWrite(0x85); - spiWrite(0x00); - spiWrite(0x78); - - writeCommand(0xCB); - spiWrite(0x39); - spiWrite(0x2C); - spiWrite(0x00); - spiWrite(0x34); - spiWrite(0x02); - - writeCommand(0xF7); - spiWrite(0x20); - - writeCommand(0xEA); - spiWrite(0x00); - spiWrite(0x00); - - writeCommand(ILI9341_PWCTR1); //Power control - spiWrite(0x23); //VRH[5:0] - - writeCommand(ILI9341_PWCTR2); //Power control - spiWrite(0x10); //SAP[2:0];BT[3:0] - - writeCommand(ILI9341_VMCTR1); //VCM control - spiWrite(0x3e); - spiWrite(0x28); - - writeCommand(ILI9341_VMCTR2); //VCM control2 - spiWrite(0x86); //-- - - writeCommand(ILI9341_MADCTL); // Memory Access Control - // spiWrite(0x48); - spiWrite(0x48); - - writeCommand(ILI9341_VSCRSADD); // Vertical scroll - SPI_WRITE16(0); // Zero - - writeCommand(ILI9341_PIXFMT); - spiWrite(0x55); - - writeCommand(ILI9341_FRMCTR1); - spiWrite(0x00); - spiWrite(0x18); - - writeCommand(ILI9341_DFUNCTR); // Display Function Control - spiWrite(0x08); - spiWrite(0x82); - spiWrite(0x27); - - writeCommand(0xF2); // 3Gamma Function Disable - spiWrite(0x00); - - writeCommand(ILI9341_GAMMASET); //Gamma curve selected - spiWrite(0x01); - - writeCommand(ILI9341_GMCTRP1); //Set Gamma - spiWrite(0x0F); - spiWrite(0x31); - spiWrite(0x2B); - spiWrite(0x0C); - spiWrite(0x0E); - spiWrite(0x08); - spiWrite(0x4E); - spiWrite(0xF1); - spiWrite(0x37); - spiWrite(0x07); - spiWrite(0x10); - spiWrite(0x03); - spiWrite(0x0E); - spiWrite(0x09); - spiWrite(0x00); - - writeCommand(ILI9341_GMCTRN1); //Set Gamma - spiWrite(0x00); - spiWrite(0x0E); - spiWrite(0x14); - spiWrite(0x03); - spiWrite(0x11); - spiWrite(0x07); - spiWrite(0x31); - spiWrite(0xC1); - spiWrite(0x48); - spiWrite(0x08); - spiWrite(0x0F); - spiWrite(0x0C); - spiWrite(0x31); - spiWrite(0x36); - spiWrite(0x0F); - - writeCommand(ILI9341_SLPOUT); //Exit Sleep - delay(120); - writeCommand(ILI9341_DISPON); //Display on - delay(120); - endWrite(); - - _width = ILI9341_TFTWIDTH; - _height = ILI9341_TFTHEIGHT; - setRotation(0); -} - -void Adafruit_ILI9341::setRotation(uint8_t m) { - rotation = m % 4; // can't be higher than 3 - switch (rotation) { - case 0: - // m = (MADCTL_MX | MADCTL_BGR); - m = ( MADCTL_BGR); - _width = ILI9341_TFTWIDTH; - _height = ILI9341_TFTHEIGHT; - break; - case 1: - m = (MADCTL_MX | MADCTL_MV | MADCTL_BGR); - _width = ILI9341_TFTHEIGHT; - _height = ILI9341_TFTWIDTH; - break; - case 2: - m = (MADCTL_MX | MADCTL_MY | MADCTL_BGR); - _width = ILI9341_TFTWIDTH; - _height = ILI9341_TFTHEIGHT; - break; - case 3: - // m = (MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR); - m = (MADCTL_MY | MADCTL_MV | MADCTL_BGR); - _width = ILI9341_TFTHEIGHT; - _height = ILI9341_TFTWIDTH; - break; - } - - startWrite(); - writeCommand(ILI9341_MADCTL); - spiWrite(m); - endWrite(); -} - -void Adafruit_ILI9341::invertDisplay(boolean i) { - startWrite(); - writeCommand(i ? ILI9341_INVON : ILI9341_INVOFF); - endWrite(); -} - -void Adafruit_ILI9341::scrollTo(uint16_t y) { - startWrite(); - writeCommand(ILI9341_VSCRSADD); - SPI_WRITE16(y); - endWrite(); -} - -uint8_t Adafruit_ILI9341::spiRead() { - if(_sclk < 0){ - return HSPI_READ(); - } - if(_miso < 0){ - return 0; - } - uint8_t r = 0; - for (uint8_t i=0; i<8; i++) { - SSPI_SCK_LOW(); - SSPI_SCK_HIGH(); - r <<= 1; - if (SSPI_MISO_READ()){ - r |= 0x1; - } - } - return r; -} - -void Adafruit_ILI9341::spiWrite(uint8_t b) { - if(_sclk < 0){ - HSPI_WRITE(b); - return; - } - for(uint8_t bit = 0x80; bit; bit >>= 1){ - if((b) & bit){ - SSPI_MOSI_HIGH(); - } else { - SSPI_MOSI_LOW(); - } - SSPI_SCK_LOW(); - SSPI_SCK_HIGH(); - } -} - - -/* - * Transaction API - * */ - -void Adafruit_ILI9341::startWrite(void){ - SPI_BEGIN_TRANSACTION(); - SPI_CS_LOW(); -} - -void Adafruit_ILI9341::endWrite(void){ - SPI_CS_HIGH(); - SPI_END_TRANSACTION(); -} - -void Adafruit_ILI9341::writeCommand(uint8_t cmd){ - SPI_DC_LOW(); - spiWrite(cmd); - SPI_DC_HIGH(); -} - -void Adafruit_ILI9341::setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) { - // x = ILI9341_TFTWIDTH - x; - uint32_t xa = ((uint32_t)x << 16) | (x+w-1); - uint32_t ya = ((uint32_t)y << 16) | (y+h-1); - writeCommand(ILI9341_CASET); // Column addr set - SPI_WRITE32(xa); - writeCommand(ILI9341_PASET); // Row addr set - SPI_WRITE32(ya); - writeCommand(ILI9341_RAMWR); // write to RAM -} - -void Adafruit_ILI9341::pushColor(uint16_t color) { - startWrite(); - SPI_WRITE16(color); - endWrite(); -} - - -void Adafruit_ILI9341::writePixel(uint16_t color){ - SPI_WRITE16(color); -} - -void Adafruit_ILI9341::writePixels(uint16_t * colors, uint32_t len){ - SPI_WRITE_PIXELS((uint8_t*)colors , len * 2); -} - -void Adafruit_ILI9341::writeColor(uint16_t color, uint32_t len){ -#ifdef SPI_HAS_WRITE_PIXELS - if(_sclk >= 0){ - for (uint32_t t=0; t SPI_MAX_PIXELS_AT_ONCE)?SPI_MAX_PIXELS_AT_ONCE:len; - uint16_t tlen = 0; - - for (uint32_t t=0; tblen)?blen:len; - writePixels(temp, tlen); - len -= tlen; - } -#else - uint8_t hi = color >> 8, lo = color; - if(_sclk < 0){ //AVR Optimization - for (uint32_t t=len; t; t--){ - HSPI_WRITE(hi); - HSPI_WRITE(lo); - } - return; - } - for (uint32_t t=len; t; t--){ - spiWrite(hi); - spiWrite(lo); - } -#endif -} - -void Adafruit_ILI9341::writePixel(int16_t x, int16_t y, uint16_t color) { - if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return; - setAddrWindow(x,y,1,1); - writePixel(color); -} - -void Adafruit_ILI9341::writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color){ - if((x >= _width) || (y >= _height)) return; - int16_t x2 = x + w - 1, y2 = y + h - 1; - if((x2 < 0) || (y2 < 0)) return; - - // Clip left/top - if(x < 0) { - x = 0; - w = x2 + 1; - } - if(y < 0) { - y = 0; - h = y2 + 1; - } - - // Clip right/bottom - if(x2 >= _width) w = _width - x; - if(y2 >= _height) h = _height - y; - - int32_t len = (int32_t)w * h; - setAddrWindow(x, y, w, h); - writeColor(color, len); -} - -void Adafruit_ILI9341::writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color){ - writeFillRect(x, y, 1, h, color); -} - -void Adafruit_ILI9341::writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color){ - writeFillRect(x, y, w, 1, color); -} - -uint8_t Adafruit_ILI9341::readcommand8(uint8_t c, uint8_t index) { - uint32_t freq = _freq; - if(_freq > 24000000){ - _freq = 24000000; - } - startWrite(); - writeCommand(0xD9); // woo sekret command? - spiWrite(0x10 + index); - writeCommand(c); - uint8_t r = spiRead(); - endWrite(); - _freq = freq; - return r; -} - -void Adafruit_ILI9341::drawPixel(int16_t x, int16_t y, uint16_t color){ - startWrite(); - writePixel(x, y, color); - endWrite(); -} - -void Adafruit_ILI9341::drawFastVLine(int16_t x, int16_t y, - int16_t h, uint16_t color) { - startWrite(); - writeFastVLine(x, y, h, color); - endWrite(); -} - -void Adafruit_ILI9341::drawFastHLine(int16_t x, int16_t y, - int16_t w, uint16_t color) { - startWrite(); - writeFastHLine(x, y, w, color); - endWrite(); -} - -void Adafruit_ILI9341::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, - uint16_t color) { - startWrite(); - writeFillRect(x,y,w,h,color); - endWrite(); -} - -// This code was ported/adapted from https://github.com/PaulStoffregen/ILI9341_t3 -// by Marc MERLIN. See examples/pictureEmbed to use this. -void Adafruit_ILI9341::drawBitmap(int16_t x, int16_t y, int16_t w, int16_t h, - const uint16_t *pcolors) { - - int16_t x2, y2; // Lower-right coord - if(( x >= _width ) || // Off-edge right - ( y >= _height) || // " top - ((x2 = (x+w-1)) < 0 ) || // " left - ((y2 = (y+h-1)) < 0) ) return; // " bottom - - int16_t bx1=0, by1=0, // Clipped top-left within bitmap - saveW=w; // Save original bitmap width value - if(x < 0) { // Clip left - w += x; - bx1 = -x; - x = 0; - } - if(y < 0) { // Clip top - h += y; - by1 = -y; - y = 0; - } - if(x2 >= _width ) w = _width - x; // Clip right - if(y2 >= _height) h = _height - y; // Clip bottom - - pcolors += by1 * saveW + bx1; // Offset bitmap ptr to clipped top-left - startWrite(); - setAddrWindow(x, y, w, h); // Clipped area - while(h--) { // For each (clipped) scanline... - writePixels((uint16_t*)pcolors, w); // Push one (clipped) row - pcolors += saveW; // Advance pointer by one full (unclipped) line - } - endWrite(); -} diff --git a/examples/Advanced/Camera/Adafruit_ILI9341.h b/examples/Advanced/Camera/Adafruit_ILI9341.h deleted file mode 100644 index b57d1e9..0000000 --- a/examples/Advanced/Camera/Adafruit_ILI9341.h +++ /dev/null @@ -1,214 +0,0 @@ -/****************************************************************** - This is our library for the Adafruit ILI9341 Breakout and Shield - ----> http://www.adafruit.com/products/1651 - - Check out the links above for our tutorials and wiring diagrams - These displays use SPI to communicate, 4 or 5 pins are required - to interface (RST is optional) - Adafruit invests time and resources providing this open source - code, please support Adafruit and open-source hardware by - purchasing products from Adafruit! - - Written by Limor Fried/Ladyada for Adafruit Industries. - MIT license, all text above must be included in any redistribution - *******************************************************************/ - -#ifndef _ADAFRUIT_ILI9341H_ -#define _ADAFRUIT_ILI9341H_ - -#if ARDUINO >= 100 - #include "Arduino.h" - #include "Print.h" -#else - #include "WProgram.h" -#endif -#include -#include "Adafruit_GFX.h" - -#if defined(ARDUINO_STM32_FEATHER) -typedef volatile uint32 RwReg; -#endif -#if defined(ARDUINO_FEATHER52) -typedef volatile uint32_t RwReg; -#endif - -#define ILI9341_TFTWIDTH 320 -#define ILI9341_TFTHEIGHT 240 - -#define ILI9341_NOP 0x00 -#define ILI9341_SWRESET 0x01 -#define ILI9341_RDDID 0x04 -#define ILI9341_RDDST 0x09 - -#define ILI9341_SLPIN 0x10 -#define ILI9341_SLPOUT 0x11 -#define ILI9341_PTLON 0x12 -#define ILI9341_NORON 0x13 - -#define ILI9341_RDMODE 0x0A -#define ILI9341_RDMADCTL 0x0B -#define ILI9341_RDPIXFMT 0x0C -#define ILI9341_RDIMGFMT 0x0D -#define ILI9341_RDSELFDIAG 0x0F - -#define ILI9341_INVOFF 0x20 -#define ILI9341_INVON 0x21 -#define ILI9341_GAMMASET 0x26 -#define ILI9341_DISPOFF 0x28 -#define ILI9341_DISPON 0x29 - -#define ILI9341_CASET 0x2A -#define ILI9341_PASET 0x2B -#define ILI9341_RAMWR 0x2C -#define ILI9341_RAMRD 0x2E - -#define ILI9341_PTLAR 0x30 -#define ILI9341_MADCTL 0x36 -#define ILI9341_VSCRSADD 0x37 -#define ILI9341_PIXFMT 0x3A - -#define ILI9341_FRMCTR1 0xB1 -#define ILI9341_FRMCTR2 0xB2 -#define ILI9341_FRMCTR3 0xB3 -#define ILI9341_INVCTR 0xB4 -#define ILI9341_DFUNCTR 0xB6 - -#define ILI9341_PWCTR1 0xC0 -#define ILI9341_PWCTR2 0xC1 -#define ILI9341_PWCTR3 0xC2 -#define ILI9341_PWCTR4 0xC3 -#define ILI9341_PWCTR5 0xC4 -#define ILI9341_VMCTR1 0xC5 -#define ILI9341_VMCTR2 0xC7 - -#define ILI9341_RDID1 0xDA -#define ILI9341_RDID2 0xDB -#define ILI9341_RDID3 0xDC -#define ILI9341_RDID4 0xDD - -#define ILI9341_GMCTRP1 0xE0 -#define ILI9341_GMCTRN1 0xE1 -/* -#define ILI9341_PWCTR6 0xFC - - */ - -// Color definitions -#define ILI9341_BLACK 0x0000 /* 0, 0, 0 */ -#define ILI9341_NAVY 0x000F /* 0, 0, 128 */ -#define ILI9341_DARKGREEN 0x03E0 /* 0, 128, 0 */ -#define ILI9341_DARKCYAN 0x03EF /* 0, 128, 128 */ -#define ILI9341_MAROON 0x7800 /* 128, 0, 0 */ -#define ILI9341_PURPLE 0x780F /* 128, 0, 128 */ -#define ILI9341_OLIVE 0x7BE0 /* 128, 128, 0 */ -#define ILI9341_LIGHTGREY 0xC618 /* 192, 192, 192 */ -#define ILI9341_DARKGREY 0x7BEF /* 128, 128, 128 */ -#define ILI9341_BLUE 0x001F /* 0, 0, 255 */ -#define ILI9341_GREEN 0x07E0 /* 0, 255, 0 */ -#define ILI9341_CYAN 0x07FF /* 0, 255, 255 */ -#define ILI9341_RED 0xF800 /* 255, 0, 0 */ -#define ILI9341_MAGENTA 0xF81F /* 255, 0, 255 */ -#define ILI9341_YELLOW 0xFFE0 /* 255, 255, 0 */ -#define ILI9341_WHITE 0xFFFF /* 255, 255, 255 */ -#define ILI9341_ORANGE 0xFD20 /* 255, 165, 0 */ -#define ILI9341_GREENYELLOW 0xAFE5 /* 173, 255, 47 */ -#define ILI9341_PINK 0xF81F - -#if defined (__AVR__) || defined(TEENSYDUINO) || defined(ESP8266) || defined (ESP32) || defined(__arm__) -#define USE_FAST_PINIO -#endif - -class Adafruit_ILI9341 : public Adafruit_GFX { - protected: - - public: - Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK, int8_t _RST = -1, int8_t _MISO = -1); - Adafruit_ILI9341(int8_t _CS, int8_t _DC, int8_t _RST = -1); - -#ifndef ESP32 - void begin(uint32_t freq = 0); -#else - void begin(uint32_t freq = 0, SPIClass &spi=SPI); -#endif - void setRotation(uint8_t r); - void invertDisplay(boolean i); - void scrollTo(uint16_t y); - - // Required Non-Transaction - void drawPixel(int16_t x, int16_t y, uint16_t color); - - // Transaction API - void startWrite(void); - void endWrite(void); - void writePixel(int16_t x, int16_t y, uint16_t color); - void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); - void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); - void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); - - // Transaction API not used by GFX - void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h); - void writePixel(uint16_t color); - void writePixels(uint16_t * colors, uint32_t len); - void writeColor(uint16_t color, uint32_t len); - void pushColor(uint16_t color); - - // Recommended Non-Transaction - void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); - void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); - void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); - void drawBitmap(int16_t x, int16_t y, int16_t w, int16_t h, const uint16_t *pcolors); - - uint8_t readcommand8(uint8_t reg, uint8_t index = 0); - - uint16_t color565(uint8_t r, uint8_t g, uint8_t b); - - // via Charles Bailey on stackoverflow: - // "Functions in derived classes which don't override functions in base - // classes but which have the same name will hide other functions of the - // same name in the base class. - // "It is generally considered bad practice to have have functions in - // derived classes which have the same name as functions in the base - // class which aren't intended to override the base class functions as - // what you are seeing is not usually desirable behaviour. It is usually - // preferable to give different functions different names." - // i.e. this function in ILI9341 should not have been called this; it's - // fundamentally different from GFX's drawBitmap(). But here we are, - // painted into the proverbial corner. C++11 has the 'using' keyword - // to allow access to base class functions. This'll band-aid the issue - // for now but might be inadequate for "vintage" complier variants that - // some board support packages might possibly be using, dunno. - using Adafruit_GFX::drawBitmap; - - private: -#ifdef ESP32 - SPIClass _spi; -#endif - uint32_t _freq; -#if defined (__AVR__) || defined(TEENSYDUINO) - int8_t _cs, _dc, _rst, _sclk, _mosi, _miso; -#ifdef USE_FAST_PINIO - volatile uint8_t *mosiport, *misoport, *clkport, *dcport, *csport; - uint8_t mosipinmask, misopinmask, clkpinmask, cspinmask, dcpinmask; -#endif -#elif defined (__arm__) - int32_t _cs, _dc, _rst, _sclk, _mosi, _miso; -#ifdef USE_FAST_PINIO - volatile RwReg *mosiport, *misoport, *clkport, *dcport, *csport; - uint32_t mosipinmask, misopinmask, clkpinmask, cspinmask, dcpinmask; -#endif -#elif defined (ESP8266) || defined (ESP32) - int8_t _cs, _dc, _rst, _sclk, _mosi, _miso; -#ifdef USE_FAST_PINIO - volatile uint32_t *mosiport, *misoport, *clkport, *dcport, *csport; - uint32_t mosipinmask, misopinmask, clkpinmask, cspinmask, dcpinmask; -#endif -#else - int8_t _cs, _dc, _rst, _sclk, _mosi, _miso; -#endif - - void writeCommand(uint8_t cmd); - void spiWrite(uint8_t v); - uint8_t spiRead(void); -}; - -#endif diff --git a/examples/Advanced/Camera/Camera.ino b/examples/Advanced/Camera/Camera.ino deleted file mode 100644 index f8f894a..0000000 --- a/examples/Advanced/Camera/Camera.ino +++ /dev/null @@ -1,337 +0,0 @@ -/* - This sketch is based on the sdFatTftBitmap example sketch from the ILI9341_due library. - - See: http://marekburiak.github.io/ILI9341_due/ - - Adapted by Bodmer 20th January 2017 to incorporate the JPEGDecoder library and draw - Jpeg images that have been stored on an SD card. - - It is compatible with the Mega and Due boards, modify the defined CS, DC pins - for the TFT and SD connections to suit your setup. - - You can generate your own Jpeg images from digital photographs by cropping and resizing - by using commonly available picture/image editors such as Paint or IrfanView. - The example image used by the sketch is in the extras folder in the JPEGDecoder library, - copy the "arduino.jpg" file to the SD card. - - See: https://github.com/Bodmer/JPEGDecoder - - The Arduino IDE's built in SD library is used: - - https://www.arduino.cc/en/reference/SD -*/ - -// IMPORTANT: Edit the ILI9341_due_config.h to select: -// #define ILI9341_SPI_MODE_NORMAL // uses SPI library -// this sketch will not work if the Due DMA or SPI extended mode is enabled. -// Use the hardware SPI lines MOSI, MISO and SCK to interface with both the TFT and -// the SD card. - -//==================================================================================== -// libraries -//==================================================================================== - -#include -#include // Use the Arduino IDE built-in SD library - -#include "Adafruit_ILI9341.h" -#include // JPEG decoder library -#include -#include - -#define USE_SERIAL Serial - -WiFiMulti wifiMulti; - -/////////////////// -#include -#include -#include -#include "tjpgd.h" - -//=====================PTC08======================= -HardwareSerial PTC08(2); - -// the setup routine runs once when M5Stack starts up -// 复位指令:56 00 26 00 返回:76 00 26 00 +DSP 版 信息 -const uint8_t ptc_reset[] = {0x56, 0x00, 0x26, 0x00}; - -// 拍照指令:56 00 36 01 00 返回:76 00 36 00 00 -const uint8_t ptc_kaca[] = {0x56, 0x00, 0x36, 0x01, 0x00}; - -// 清空图片缓存指令:56 00 36 01 02 返回:76 00 36 00 00 -const uint8_t ptc_clean_cache[] = {0x56, 0x00, 0x36, 0x01, 0x02}; - -// 读所拍图片长度指令:56 00 34 01 00 返回:76 00 34 00 04 00 00 XX YY -// XX YY -------图片数据长度,XX为高位字节,YY为低位字节 -const uint8_t ptc_read_length[] = {0x56, 0x00, 0x34, 0x01, 0x00}; - -// 读取所拍图片数据指令:56 00 32 0C 00 0A 00 00 XX(8) XX 00 00 YY(12) YY 00 FF -// 返回:7600320000 FFD8 。FFD9 7600320000 -uint8_t ptc_read_data[16] = {0x56, 0x00, 0x32, 0x0c, 0x00, 0x0a, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x11, 0x11, 0x00, 0xff}; - -// 设置拍照图片压缩率指令:56 00 31 05 01 01 12 04 XX(8) 返回:76 00 31 00 00 -// XX 一般选 36 (范围:00 ----FF) -uint8_t ptc_set_compress[] = {0x56, 0x00, 0x31, 0x05, 0x01, 0x01, 0x12, 0x04, 0x00}; - -// 修改串口初始波特率指令: 56 00 31 06 04 02 00 08 XX(8) YY -const uint8_t ptc_set_baud[] = {0x56, 0x00, 0x31, 0x06, 0x04, 0x02, 0x00, 0x08, 0x0d, 0xa6}; - -void camera_set_baud() { - PTC08.write(ptc_set_baud, 10); - delay(100); - while(PTC08.available()) { - Serial.printf("%2.2x ", PTC08.read()); - } - Serial.printf("\r\n"); -} - -void camera_reset() { - Serial.printf("PTC reset.\r\n"); - delay(1000); - PTC08.write(ptc_clean_cache, 5); - delay(100); - while(PTC08.available()) { - Serial.printf("%2.2x ", PTC08.read()); - } - Serial.printf("\r\n"); -} - -void camera_clean_cache() { - Serial.printf("PTC clean cache.\r\n"); - PTC08.write(ptc_clean_cache, 5); - delay(100); - while(PTC08.available()) { - Serial.printf("%2.2x ", PTC08.read()); - } - Serial.printf("\r\n"); -} - -void camera_shutter() { - Serial.printf("PTC shutter.\r\n"); - PTC08.write(ptc_kaca, 5); - delay(100); - while(PTC08.available()) { - Serial.printf("%2.2x ", PTC08.read()); - } - Serial.printf("\r\n"); -} - -uint16_t camera_get_length() { - uint8_t buffer[10]; - uint8_t idx = 0; - Serial.printf("PTC get length.\r\n"); - PTC08.write(ptc_read_length, 5); - delay(100); - while(PTC08.available()) { - buffer[idx] = PTC08.read(); - // Serial.write(buffer[idx]); - // Serial.printf("%2.2x ", buffer[idx]); - // Serial.write(PTC08.read()); - idx++; - } - return (buffer[7]<<8 | buffer[8]); -} - -void camera_read_data(uint16_t addr, uint16_t length, uint8_t* dest) { - int idx = 0; - ptc_read_data[9] = (uint8_t)(addr&0x00ff); - ptc_read_data[8] = (uint8_t)(addr>>8); - ptc_read_data[13] = (uint8_t)(length&0x00ff); - ptc_read_data[12] = (uint8_t)(length>>8); - - PTC08.write(ptc_read_data, 16); - delay(100); - while(PTC08.available()) { - int ch = PTC08.read(); - // Serial.printf("%2.2x ", ch); - if(++idx >= 6) { - dest[idx-6] = ch; - } - } -} - -void camera_set_compress(uint8_t val) { - Serial.printf("PTC set compress.\r\n"); - ptc_set_compress[8] = val; - PTC08.write(ptc_set_compress, 9); - delay(100); - while(PTC08.available()) { - int ch = PTC08.read(); - Serial.printf("%2.2x ", ch); - } -} -//------------------------------------------------------ - - -//==================================================================================== -// defines -//==================================================================================== -// For the Adafruit shield, these are the default. -#define TFT_DC 27 -#define TFT_CS 14 -#define TFT_MOSI 23 -#define TFT_CLK 18 -#define TFT_RST 2 -#define TFT_MISO 0 - -#define LED_PIN 12 -#define SD_CS 4 // Chip Select for SD card - -#define TFT_BLACK 0x0000 -#define TFT_WHITE 0xFFFF - - -const uint8_t bmp_header[] = { -0x42,0x4d,0x36,0x84,0x03,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x28, \ -0x00,0x00,0x00,0x40,0x01,0x00,0x00,0xf0,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x84, \ -0x03,0x00,0xc4,0x0e,0x00,0x00,0xc4,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - -void take_picture() { - camera_clean_cache(); - camera_shutter(); - - int pic_length = camera_get_length(); - Serial.printf("picture length:%d\r\n", pic_length); - delay(80); - - int count = 0; - uint8_t get_buf[512]; - File file = SD.open("/camera.jpg", FILE_WRITE); - Serial.printf("PTC read data.\r\n"); - for(int i=0; i 128) { - camera_read_data(i, 128, get_buf); - file.write(get_buf, 128); - } else { - camera_read_data(i, pic_length-i, get_buf); - file.write(get_buf, pic_length-i); - } - } - file.close(); -} - -void listDir(fs::FS &fs, const char * dirname, uint8_t levels){ - Serial.printf("Listing directory: %s\n", dirname); - - File root = fs.open(dirname); - if(!root){ - Serial.println("Failed to open directory"); - return; - } - if(!root.isDirectory()){ - Serial.println("Not a directory"); - return; - } - - File file = root.openNextFile(); - while(file){ - if(file.isDirectory()){ - Serial.print(" DIR : "); - Serial.println(file.name()); - if(levels){ - listDir(fs, file.name(), levels -1); - } - } else { - Serial.print(" FILE: "); - Serial.print(file.name()); - Serial.print(" SIZE: "); - Serial.println(file.size()); - } - file = root.openNextFile(); - } -} -//==================================================================================== -// setup -//==================================================================================== -// ILI9341_due tft = ILI9341_due(TFT_CS, TFT_DC, TFT_RST); -Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); - -void setup() { - Serial.begin(115200); - PTC08.begin(115200); - - // Make sure the SD card chip select is high before we initialise the TFT - pinMode(SD_CS, OUTPUT); - digitalWrite(SD_CS, HIGH); - pinMode(LED_PIN, OUTPUT); - digitalWrite(LED_PIN, HIGH); - - // Initialise the TFT - tft.begin(); - tft.fillScreen(TFT_BLACK); - // tft.drawRGBBitmap(0, 0, uint16_t *pcolors, int16_t w, int16_t h); - - Serial.print(F("Initialising SD card...")); - - if (!SD.begin(SD_CS)) { - Serial.println(F("failed!")); - return; - } - Serial.println(F("OK!")); - - listDir(SD, "/", 0); - -//------------------------ - wifiMulti.addAP("MasterHax_2.4G", "wittyercheese551"); - - // File fsFile = SD.open("/camera2.bmp", FILE_READ); - // uint8_t buffer[512]; - // fsFile.read(buffer, 54); - // Serial.printf("\r\n\r\n\r\n\r\n"); - // for(int i=0; i<54; i++) { - // Serial.printf("0x%2.2x,", buffer[i]); - // } - // Serial.printf("\r\n\r\n\r\n\r\n"); - - // for(int j=0; j<240; j++) { - // fsFile.read(buffer, 320); - // uint16_t *pt16 = (uint16_t*)buffer; - // for(int k=0; k<160; k++) { - // Serial.printf("%4.4x ", pt16[k]); - // } - // Serial.printf("\r\n"); - // } - - // tft.drawBitmap(0, 0, 320, 240, fsFile.flashRead()); - Serial.printf("reset.\r\n"); - camera_reset(); - delay(2500); - - while(PTC08.available()) { - Serial.printf("%2.2x ", PTC08.read()); - } - Serial.printf("\r\n"); -} - - -//==================================================================================== -// loop -//==================================================================================== - -void loop() { - // draw Arduino logo at a random position - // drawJpeg( "/arduino.jpg", random(tft.width() - 160), random(tft.height() - 128) ); - take_picture(); - drawJpeg("/camera.jpg", 0, 0); - - File jpegFile = SD.open("/camera.jpg", FILE_READ); - // // File jpegFile = SD.open("/pic.jpg"); - // // File jpegFile = SD.open("/EagleEye.jpg", FILE_READ); - - // wait for WiFi connection - if((wifiMulti.run() == WL_CONNECTED)) { - HTTPClient http; - USE_SERIAL.print("[HTTP] begin...\n"); - - // configure server and url - // http.begin("http://api.heclouds.com/bindata?device_id=5811741&datastream_id=pic"); - http.begin("http://api.yeelink.net/v1.0/device/18607/sensor/407330/photos"); - // http.addHeader("api-key", "3siYnijpqzOtLKaqdGFIvj5PcM4="); - http.addHeader("U-ApiKey", "e92dea44e2c4b29838fea13b9cf7ab59"); - http.sendRequest("POST", &jpegFile, jpegFile.size()); - USE_SERIAL.print("[HTTP] POST...\n"); - http.end(); - } -} - diff --git a/examples/Advanced/Camera/JPEG_functions.ino b/examples/Advanced/Camera/JPEG_functions.ino deleted file mode 100644 index 60ab2db..0000000 --- a/examples/Advanced/Camera/JPEG_functions.ino +++ /dev/null @@ -1,185 +0,0 @@ -/*==================================================================================== - This sketch contains support functions to render the Jpeg images. - - Created by Bodmer 15th Jan 2017 - ==================================================================================*/ - -// Return the minimum of two values a and b -#define minimum(a,b) (((a) < (b)) ? (a) : (b)) - -//==================================================================================== -// Opens the image file and prime the Jpeg decoder -//==================================================================================== -void drawJpeg(const char *filename, int xpos, int ypos) { - - // Open the named file (the Jpeg decoder library will close it) - File jpegFile = SD.open( filename, FILE_READ); // or, file handle reference for SD library - - if ( !jpegFile ) { - Serial.print("ERROR: File \""); Serial.print(filename); Serial.println ("\" not found!"); - return; - } - - Serial.println("==========================="); - Serial.print("Drawing file: "); Serial.println(filename); - Serial.println("==========================="); - - // Use one of the following methods to initialise the decoder: - boolean decoded = JpegDec.decodeSdFile(jpegFile); // Pass the SD file handle to the decoder, - // boolean decoded = JpegDec.decodeSdFile(filename); // or pass the filename (String or character array) - - if (decoded) { - // print information about the image to the serial port - jpegInfo(); - // render the image onto the screen at given coordinates - jpegRender(xpos, ypos); - } - else { - Serial.println("Jpeg file format not supported!"); - } -} - -//==================================================================================== -// Decode and render the Jpeg image onto the TFT screen -//==================================================================================== -void jpegRender(int xpos, int ypos) { - - // retrieve information about the image - uint16_t mcu_w = JpegDec.MCUWidth; - uint16_t mcu_h = JpegDec.MCUHeight; - uint32_t max_x = JpegDec.width; - uint32_t max_y = JpegDec.height; - - uint16_t *pImg; // Pointer for the returned image block - - // Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs) - // Typically these MCUs are 16x16 pixel blocks - // Determine the width and height of the right and bottom edge image blocks - uint32_t min_w = minimum(mcu_w, max_x % mcu_w); - uint32_t min_h = minimum(mcu_h, max_y % mcu_h); - - // save the current image block size - uint32_t win_w = mcu_w; - uint32_t win_h = mcu_h; - - // record the current time so we can measure how long it takes to draw an image - uint32_t drawTime = millis(); - - // save the coordinate of the right and bottom edges to assist image cropping - // to the screen size - max_x += xpos; - max_y += ypos; - - File fsFile = SD.open("/camera.bmp", FILE_WRITE); - fsFile.write(bmp_header, 54); - - // read each MCU block until there are no more - while ( JpegDec.read()) { - - // save a pointer to the image block - pImg = JpegDec.pImage; // Pointer to block - - // calculate where the image block should be drawn on the screen - int mcu_x = JpegDec.MCUx * mcu_w + xpos; - int mcu_y = JpegDec.MCUy * mcu_h + ypos; - - // check if the image block size needs to be changed for the right and bottom edges - if (mcu_x + mcu_w <= max_x) win_w = mcu_w; - else win_w = min_w; - if (mcu_y + mcu_h <= max_y) win_h = mcu_h; - else win_h = min_h; - - // calculate how many pixels must be drawn - uint32_t mcu_pixels = win_w * win_h; - fsFile.write((uint8_t*)pImg, mcu_pixels*2); - - // draw image MCU block only if it will fit on the screen - if ( ( mcu_x + win_w) <= tft.width() && ( mcu_y + win_h) <= tft.height()) - { - tft.drawRGBBitmap(mcu_x, mcu_y, pImg, win_w, win_h); - // Now set a MCU bounding window on the TFT to push pixels into (x, y, x + width - 1, y + height - 1) - // tft.setAddrWindow(mcu_x, mcu_y, mcu_x + win_w - 1, mcu_y + win_h - 1); - - // Write all MCU pixels to the TFT window - // while (mcu_pixels--) tft.pushColor(*pImg++); // Send to TFT 16 bits at a time - // tft.pushColors(pImg, 0, mcu_pixels); // Send the whole buffer, this is faster - // tft.writePixels(pImg, mcu_pixels); - } - - // Stop drawing blocks if the bottom of the screen has been reached, - // the abort function will close the file - else if ( ( mcu_y + win_h) >= tft.height()) JpegDec.abort(); - - } - fsFile.close(); - - // calculate how long it took to draw the image - drawTime = millis() - drawTime; - - // print the results to the serial port - Serial.print ("Total render time was : "); Serial.print(drawTime); Serial.println(" ms"); - Serial.println("====================================="); -} - -//==================================================================================== -// Print information decoded from the Jpeg image -//==================================================================================== -void jpegInfo() { - Serial.println(F("===============")); - Serial.println(F("JPEG image info")); - Serial.println(F("===============")); - Serial.print(F( "Width :")); Serial.println(JpegDec.width); - Serial.print(F( "Height :")); Serial.println(JpegDec.height); - Serial.print(F( "Components :")); Serial.println(JpegDec.comps); - Serial.print(F( "MCU / row :")); Serial.println(JpegDec.MCUSPerRow); - Serial.print(F( "MCU / col :")); Serial.println(JpegDec.MCUSPerCol); - Serial.print(F( "Scan type :")); Serial.println(JpegDec.scanType); - Serial.print(F( "MCU width :")); Serial.println(JpegDec.MCUWidth); - Serial.print(F( "MCU height :")); Serial.println(JpegDec.MCUHeight); - Serial.println(F("===============")); -} - -//==================================================================================== -// Open a Jpeg file and send it to the Serial port in a C array compatible format -//==================================================================================== -void createArray(const char *filename) { - - // Open the named file - //fs::File jpgFile = SPIFFS.open( filename, "r"); // File handle reference for SPIFFS - File jpgFile = SD.open( filename, FILE_READ); // or, file handle reference for SD library - - if ( !jpgFile ) { - Serial.print("ERROR: File \""); Serial.print(filename); Serial.println ("\" not found!"); - return; - } - - uint8_t data; - byte line_len = 0; - Serial.println(""); - Serial.println("// Generated by a JPEGDecoder library example sketch:"); - Serial.println("// https://github.com/Bodmer/JPEGDecoder"); - Serial.println(""); - Serial.println("#if defined(__AVR__)"); - Serial.println(" #include "); - Serial.println("#endif"); - Serial.println(""); - Serial.print ("const uint8_t "); - while (*filename != '.') Serial.print(*filename++); - Serial.println("[] PROGMEM = {"); // PROGMEM added for AVR processors, it is ignored by Due - - while ( jpgFile.available()) { - - data = jpgFile.read(); - Serial.print("0x"); if (abs(data) < 16) Serial.print("0"); - Serial.print(data, HEX); Serial.print(",");// Add value and comma - line_len++; - if ( line_len >= 32) { - line_len = 0; - Serial.println(); - } - } - - Serial.println("};\r\n"); - jpgFile.close(); -} -//==================================================================================== diff --git a/examples/Advanced/Camera/integer.h b/examples/Advanced/Camera/integer.h deleted file mode 100644 index 7dcaef4..0000000 --- a/examples/Advanced/Camera/integer.h +++ /dev/null @@ -1,37 +0,0 @@ -/*-------------------------------------------*/ -/* Integer type definitions for FatFs module */ -/*-------------------------------------------*/ - -#ifndef _INTEGER -#define _INTEGER - -#ifdef _WIN32 /* FatFs development platform */ - -// #include -// #include - -#else /* Embedded platform */ - -/* These types must be 16-bit, 32-bit or larger integer */ -typedef int INT; -typedef unsigned int UINT; - -/* These types must be 8-bit integer */ -typedef char CHAR; -typedef unsigned char UCHAR; -typedef unsigned char BYTE; - -/* These types must be 16-bit integer */ -typedef short SHORT; -typedef unsigned short USHORT; -typedef unsigned short WORD; -typedef unsigned short WCHAR; - -/* These types must be 32-bit integer */ -typedef long LONG; -typedef unsigned long ULONG; -typedef unsigned long DWORD; - -#endif - -#endif diff --git a/examples/Advanced/Camera/tjpgd.c b/examples/Advanced/Camera/tjpgd.c deleted file mode 100644 index cc8557e..0000000 --- a/examples/Advanced/Camera/tjpgd.c +++ /dev/null @@ -1,951 +0,0 @@ -/*----------------------------------------------------------------------------/ -/ TJpgDec - Tiny JPEG Decompressor R0.01a (C)ChaN, 2012 -/-----------------------------------------------------------------------------/ -/ The TJpgDec is a generic JPEG decompressor module for tiny embedded systems. -/ This is a free software that opened for education, research and commercial -/ developments under license policy of following terms. -/ -/ Copyright (C) 2012, ChaN, all right reserved. -/ -/ * The TJpgDec module is a free software and there is NO WARRANTY. -/ * No restriction on use. You can use, modify and redistribute it for -/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. -/ * Redistributions of source code must retain the above copyright notice. -/ -/-----------------------------------------------------------------------------/ -/ Oct 04,'11 R0.01 First release. -/ Feb 19,'12 R0.01a Fixed decompression fails when scan starts with an escape seq. -/----------------------------------------------------------------------------*/ - -#include "tjpgd.h" - - -/*-----------------------------------------------*/ -/* Zigzag-order to raster-order conversion table */ -/*-----------------------------------------------*/ - -#define ZIG(n) Zig[n] - -static -const BYTE Zig[64] = { /* Zigzag-order to raster-order conversion table */ - 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 -}; - - - -/*-------------------------------------------------*/ -/* Input scale factor of Arai algorithm */ -/* (scaled up 16 bits for fixed point operations) */ -/*-------------------------------------------------*/ - -#define IPSF(n) Ipsf[n] - -static -const WORD Ipsf[64] = { /* See also aa_idct.png */ - (WORD)(1.00000*8192), (WORD)(1.38704*8192), (WORD)(1.30656*8192), (WORD)(1.17588*8192), (WORD)(1.00000*8192), (WORD)(0.78570*8192), (WORD)(0.54120*8192), (WORD)(0.27590*8192), - (WORD)(1.38704*8192), (WORD)(1.92388*8192), (WORD)(1.81226*8192), (WORD)(1.63099*8192), (WORD)(1.38704*8192), (WORD)(1.08979*8192), (WORD)(0.75066*8192), (WORD)(0.38268*8192), - (WORD)(1.30656*8192), (WORD)(1.81226*8192), (WORD)(1.70711*8192), (WORD)(1.53636*8192), (WORD)(1.30656*8192), (WORD)(1.02656*8192), (WORD)(0.70711*8192), (WORD)(0.36048*8192), - (WORD)(1.17588*8192), (WORD)(1.63099*8192), (WORD)(1.53636*8192), (WORD)(1.38268*8192), (WORD)(1.17588*8192), (WORD)(0.92388*8192), (WORD)(0.63638*8192), (WORD)(0.32442*8192), - (WORD)(1.00000*8192), (WORD)(1.38704*8192), (WORD)(1.30656*8192), (WORD)(1.17588*8192), (WORD)(1.00000*8192), (WORD)(0.78570*8192), (WORD)(0.54120*8192), (WORD)(0.27590*8192), - (WORD)(0.78570*8192), (WORD)(1.08979*8192), (WORD)(1.02656*8192), (WORD)(0.92388*8192), (WORD)(0.78570*8192), (WORD)(0.61732*8192), (WORD)(0.42522*8192), (WORD)(0.21677*8192), - (WORD)(0.54120*8192), (WORD)(0.75066*8192), (WORD)(0.70711*8192), (WORD)(0.63638*8192), (WORD)(0.54120*8192), (WORD)(0.42522*8192), (WORD)(0.29290*8192), (WORD)(0.14932*8192), - (WORD)(0.27590*8192), (WORD)(0.38268*8192), (WORD)(0.36048*8192), (WORD)(0.32442*8192), (WORD)(0.27590*8192), (WORD)(0.21678*8192), (WORD)(0.14932*8192), (WORD)(0.07612*8192) -}; - - - -/*---------------------------------------------*/ -/* Conversion table for fast clipping process */ -/*---------------------------------------------*/ - -#define BYTECLIP(v) Clip8[(UINT)(v) & 0x3FF] - -static -const BYTE Clip8[1024] = { - /* 0..255 */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 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, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - /* 256..511 */ - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* -512..-257 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* -256..-1 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - - - - -/*-----------------------------------------------------------------------*/ -/* Allocate a memory block from memory pool */ -/*-----------------------------------------------------------------------*/ - -static -void* alloc_pool ( /* Pointer to allocated memory block (NULL:no memory available) */ - JDEC* jd, /* Pointer to the decompressor object */ - UINT nd /* Number of bytes to allocate */ -) -{ - char *rp = 0; - - - nd = (nd + 3) & ~3; /* Align block size to the word boundary */ - - if (jd->sz_pool >= nd) { - jd->sz_pool -= nd; - rp = (char*)jd->pool; /* Get start of available memory pool */ - jd->pool = (void*)(rp + nd); /* Allocate requierd bytes */ - } - - return (void*)rp; /* Return allocated memory block (NULL:no memory to allocate) */ -} - - - - -/*-----------------------------------------------------------------------*/ -/* Create de-quantization and prescaling tables with a DQT segment */ -/*-----------------------------------------------------------------------*/ - -static -UINT create_qt_tbl ( /* 0:OK, !0:Failed */ - JDEC* jd, /* Pointer to the decompressor object */ - const BYTE* data, /* Pointer to the quantizer tables */ - UINT ndata /* Size of input data */ -) -{ - UINT i; - BYTE d, z; - LONG *pb; - - - while (ndata) { /* Process all tables in the segment */ - if (ndata < 65) return JDR_FMT1; /* Err: table size is unaligned */ - ndata -= 65; - d = *data++; /* Get table property */ - if (d & 0xF0) return JDR_FMT1; /* Err: not 8-bit resolution */ - i = d & 3; /* Get table ID */ - pb = alloc_pool(jd, 64 * sizeof (LONG));/* Allocate a memory block for the table */ - if (!pb) return JDR_MEM1; /* Err: not enough memory */ - jd->qttbl[i] = pb; /* Register the table */ - for (i = 0; i < 64; i++) { /* Load the table */ - z = ZIG(i); /* Zigzag-order to raster-order conversion */ - pb[z] = (LONG)((DWORD)*data++ * IPSF(z)); /* Apply scale factor of Arai algorithm to the de-quantizers */ - } - } - - return JDR_OK; -} - - - - -/*-----------------------------------------------------------------------*/ -/* Create huffman code tables with a DHT segment */ -/*-----------------------------------------------------------------------*/ - -static -UINT create_huffman_tbl ( /* 0:OK, !0:Failed */ - JDEC* jd, /* Pointer to the decompressor object */ - const BYTE* data, /* Pointer to the packed huffman tables */ - UINT ndata /* Size of input data */ -) -{ - UINT i, j, b, np, cls, num; - BYTE d, *pb, *pd; - WORD hc, *ph; - - - while (ndata) { /* Process all tables in the segment */ - if (ndata < 17) return JDR_FMT1; /* Err: wrong data size */ - ndata -= 17; - d = *data++; /* Get table number and class */ - cls = (d >> 4); num = d & 0x0F; /* class = dc(0)/ac(1), table number = 0/1 */ - if (d & 0xEE) return JDR_FMT1; /* Err: invalid class/number */ - pb = alloc_pool(jd, 16); /* Allocate a memory block for the bit distribution table */ - if (!pb) return JDR_MEM1; /* Err: not enough memory */ - jd->huffbits[num][cls] = pb; - for (np = i = 0; i < 16; i++) { /* Load number of patterns for 1 to 16-bit code */ - pb[i] = b = *data++; - np += b; /* Get sum of code words for each code */ - } - - ph = alloc_pool(jd, np * sizeof (WORD));/* Allocate a memory block for the code word table */ - if (!ph) return JDR_MEM1; /* Err: not enough memory */ - jd->huffcode[num][cls] = ph; - hc = 0; - for (j = i = 0; i < 16; i++) { /* Re-build huffman code word table */ - b = pb[i]; - while (b--) ph[j++] = hc++; - hc <<= 1; - } - - if (ndata < np) return JDR_FMT1; /* Err: wrong data size */ - ndata -= np; - pd = alloc_pool(jd, np); /* Allocate a memory block for the decoded data */ - if (!pd) return JDR_MEM1; /* Err: not enough memory */ - jd->huffdata[num][cls] = pd; - for (i = 0; i < np; i++) { /* Load decoded data corresponds to each code ward */ - d = *data++; - if (!cls && d > 11) return JDR_FMT1; - *pd++ = d; - } - } - - return JDR_OK; -} - - - - -/*-----------------------------------------------------------------------*/ -/* Extract N bits from input stream */ -/*-----------------------------------------------------------------------*/ - -static -INT bitext ( /* >=0: extracted data, <0: error code */ - JDEC* jd, /* Pointer to the decompressor object */ - UINT nbit /* Number of bits to extract (1 to 11) */ -) -{ - BYTE msk, s, *dp; - UINT dc, v, f; - - - msk = jd->dmsk; dc = jd->dctr; dp = jd->dptr; /* Bit mask, number of data available, read ptr */ - s = *dp; v = f = 0; - do { - if (!msk) { /* Next byte? */ - if (!dc) { /* No input data is available, re-fill input buffer */ - dp = jd->inbuf; /* Top of input buffer */ - dc = jd->infunc(jd, dp, JD_SZBUF); - if (!dc) return 0 - JDR_INP; /* Err: read error or wrong stream termination */ - } else { - dp++; /* Next data ptr */ - } - dc--; /* Decrement number of available bytes */ - if (f) { /* In flag sequence? */ - f = 0; /* Exit flag sequence */ - if (*dp != 0) return 0 - JDR_FMT1; /* Err: unexpected flag is detected (may be collapted data) */ - *dp = s = 0xFF; /* The flag is a data 0xFF */ - } else { - s = *dp; /* Get next data byte */ - if (s == 0xFF) { /* Is start of flag sequence? */ - f = 1; continue; /* Enter flag sequence */ - } - } - msk = 0x80; /* Read from MSB */ - } - v <<= 1; /* Get a bit */ - if (s & msk) v++; - msk >>= 1; - nbit--; - } while (nbit); - jd->dmsk = msk; jd->dctr = dc; jd->dptr = dp; - - return (INT)v; -} - - - - -/*-----------------------------------------------------------------------*/ -/* Extract a huffman decoded data from input stream */ -/*-----------------------------------------------------------------------*/ - -static -INT huffext ( /* >=0: decoded data, <0: error code */ - JDEC* jd, /* Pointer to the decompressor object */ - const BYTE* hbits, /* Pointer to the bit distribution table */ - const WORD* hcode, /* Pointer to the code word table */ - const BYTE* hdata /* Pointer to the data table */ -) -{ - BYTE msk, s, *dp; - UINT dc, v, f, bl, nd; - - - msk = jd->dmsk; dc = jd->dctr; dp = jd->dptr; /* Bit mask, number of data available, read ptr */ - s = *dp; v = f = 0; - bl = 16; /* Max code length */ - do { - if (!msk) { /* Next byte? */ - if (!dc) { /* No input data is available, re-fill input buffer */ - dp = jd->inbuf; /* Top of input buffer */ - dc = jd->infunc(jd, dp, JD_SZBUF); - if (!dc) return 0 - JDR_INP; /* Err: read error or wrong stream termination */ - } else { - dp++; /* Next data ptr */ - } - dc--; /* Decrement number of available bytes */ - if (f) { /* In flag sequence? */ - f = 0; /* Exit flag sequence */ - if (*dp != 0) - return 0 - JDR_FMT1;/* Err: unexpected flag is detected (may be collapted data) */ - *dp = s = 0xFF; /* The flag is a data 0xFF */ - } else { - s = *dp; /* Get next data byte */ - if (s == 0xFF) { /* Is start of flag sequence? */ - f = 1; continue; /* Enter flag sequence, get trailing byte */ - } - } - msk = 0x80; /* Read from MSB */ - } - v <<= 1; /* Get a bit */ - if (s & msk) v++; - msk >>= 1; - - for (nd = *hbits++; nd; nd--) { /* Search the code word in this bit length */ - if (v == *hcode++) { /* Matched? */ - jd->dmsk = msk; jd->dctr = dc; jd->dptr = dp; - return *hdata; /* Return the decoded data */ - } - hdata++; - } - bl--; - } while (bl); - - return 0 - JDR_FMT1; /* Err: code not found (may be collapted data) */ -} - - - - -/*-----------------------------------------------------------------------*/ -/* Apply Inverse-DCT in Arai Algorithm (see also aa_idct.png) */ -/*-----------------------------------------------------------------------*/ - -static -void block_idct ( - LONG* src, /* Input block data (de-quantized and pre-scaled for Arai Algorithm) */ - BYTE* dst /* Pointer to the destination to store the block as byte array */ -) -{ - const LONG M13 = (LONG)(1.41421*4096), M2 = (LONG)(1.08239*4096), M4 = (LONG)(2.61313*4096), M5 = (LONG)(1.84776*4096); - LONG v0, v1, v2, v3, v4, v5, v6, v7; - LONG t10, t11, t12, t13; - UINT i; - - /* Process columns */ - for (i = 0; i < 8; i++) { - v0 = src[8 * 0]; /* Get even elements */ - v1 = src[8 * 2]; - v2 = src[8 * 4]; - v3 = src[8 * 6]; - - t10 = v0 + v2; /* Process the even elements */ - t12 = v0 - v2; - t11 = (v1 - v3) * M13 >> 12; - v3 += v1; - t11 -= v3; - v0 = t10 + v3; - v3 = t10 - v3; - v1 = t11 + t12; - v2 = t12 - t11; - - v4 = src[8 * 7]; /* Get odd elements */ - v5 = src[8 * 1]; - v6 = src[8 * 5]; - v7 = src[8 * 3]; - - t10 = v5 - v4; /* Process the odd elements */ - t11 = v5 + v4; - t12 = v6 - v7; - v7 += v6; - v5 = (t11 - v7) * M13 >> 12; - v7 += t11; - t13 = (t10 + t12) * M5 >> 12; - v4 = t13 - (t10 * M2 >> 12); - v6 = t13 - (t12 * M4 >> 12) - v7; - v5 -= v6; - v4 -= v5; - - src[8 * 0] = v0 + v7; /* Write-back transformed values */ - src[8 * 7] = v0 - v7; - src[8 * 1] = v1 + v6; - src[8 * 6] = v1 - v6; - src[8 * 2] = v2 + v5; - src[8 * 5] = v2 - v5; - src[8 * 3] = v3 + v4; - src[8 * 4] = v3 - v4; - - src++; /* Next column */ - } - - /* Process rows */ - src -= 8; - for (i = 0; i < 8; i++) { - v0 = src[0] + (128L << 8); /* Get even elements (remove DC offset (-128) here) */ - v1 = src[2]; - v2 = src[4]; - v3 = src[6]; - - t10 = v0 + v2; /* Process the even elements */ - t12 = v0 - v2; - t11 = (v1 - v3) * M13 >> 12; - v3 += v1; - t11 -= v3; - v0 = t10 + v3; - v3 = t10 - v3; - v1 = t11 + t12; - v2 = t12 - t11; - - v4 = src[7]; /* Get odd elements */ - v5 = src[1]; - v6 = src[5]; - v7 = src[3]; - - t10 = v5 - v4; /* Process the odd elements */ - t11 = v5 + v4; - t12 = v6 - v7; - v7 += v6; - v5 = (t11 - v7) * M13 >> 12; - v7 += t11; - t13 = (t10 + t12) * M5 >> 12; - v4 = t13 - (t10 * M2 >> 12); - v6 = t13 - (t12 * M4 >> 12) - v7; - v5 -= v6; - v4 -= v5; - - dst[0] = BYTECLIP((v0 + v7) >> 8); /* Descale the transformed values 8 bits and output */ - dst[7] = BYTECLIP((v0 - v7) >> 8); - dst[1] = BYTECLIP((v1 + v6) >> 8); - dst[6] = BYTECLIP((v1 - v6) >> 8); - dst[2] = BYTECLIP((v2 + v5) >> 8); - dst[5] = BYTECLIP((v2 - v5) >> 8); - dst[3] = BYTECLIP((v3 + v4) >> 8); - dst[4] = BYTECLIP((v3 - v4) >> 8); - dst += 8; - - src += 8; /* Next row */ - } -} - - - - -/*-----------------------------------------------------------------------*/ -/* Load all blocks in the MCU into working buffer */ -/*-----------------------------------------------------------------------*/ - -static -JRESULT mcu_load ( - JDEC* jd /* Pointer to the decompressor object */ -) -{ - LONG *tmp = (LONG*)jd->workbuf; /* Block working buffer for de-quantize and IDCT */ - UINT blk, nby, nbc, i, z, id, cmp; - INT b, d, e; - BYTE *bp; - const BYTE *hb, *hd; - const WORD *hc; - const LONG *dqf; - - - nby = jd->msx * jd->msy; /* Number of Y blocks (1, 2 or 4) */ - nbc = 2; /* Number of C blocks (2) */ - bp = jd->mcubuf; /* Pointer to the first block */ - - for (blk = 0; blk < nby + nbc; blk++) { - cmp = (blk < nby) ? 0 : blk - nby + 1; /* Component number 0:Y, 1:Cb, 2:Cr */ - id = cmp ? 1 : 0; /* Huffman table ID of the component */ - - /* Extract a DC element from input stream */ - hb = jd->huffbits[id][0]; /* Huffman table for the DC element */ - hc = jd->huffcode[id][0]; - hd = jd->huffdata[id][0]; - b = huffext(jd, hb, hc, hd); /* Extract a huffman coded data (bit length) */ - if (b < 0) return 0 - b; /* Err: invalid code or input */ - d = jd->dcv[cmp]; /* DC value of previous block */ - if (b) { /* If there is any difference from previous block */ - e = bitext(jd, b); /* Extract data bits */ - if (e < 0) return 0 - e; /* Err: input */ - b = 1 << (b - 1); /* MSB position */ - if (!(e & b)) e -= (b << 1) - 1; /* Restore sign if needed */ - d += e; /* Get current value */ - jd->dcv[cmp] = (SHORT)d; /* Save current DC value for next block */ - } - dqf = jd->qttbl[jd->qtid[cmp]]; /* De-quantizer table ID for this component */ - tmp[0] = d * dqf[0] >> 8; /* De-quantize, apply scale factor of Arai algorithm and descale 8 bits */ - - /* Extract following 63 AC elements from input stream */ - for (i = 1; i < 64; i++) tmp[i] = 0; /* Clear rest of elements */ - hb = jd->huffbits[id][1]; /* Huffman table for the AC elements */ - hc = jd->huffcode[id][1]; - hd = jd->huffdata[id][1]; - i = 1; /* Top of the AC elements */ - do { - b = huffext(jd, hb, hc, hd); /* Extract a huffman coded value (zero runs and bit length) */ - if (b == 0) break; /* EOB? */ - if (b < 0) return 0 - b; /* Err: invalid code or input error */ - z = (UINT)b >> 4; /* Number of leading zero elements */ - if (z) { - i += z; /* Skip zero elements */ - if (i >= 64) return JDR_FMT1; /* Too long zero run */ - } - if (b &= 0x0F) { /* Bit length */ - d = bitext(jd, b); /* Extract data bits */ - if (d < 0) return 0 - d; /* Err: input device */ - b = 1 << (b - 1); /* MSB position */ - if (!(d & b)) d -= (b << 1) - 1;/* Restore negative value if needed */ - z = ZIG(i); /* Zigzag-order to raster-order converted index */ - tmp[z] = d * dqf[z] >> 8; /* De-quantize, apply scale factor of Arai algorithm and descale 8 bits */ - } - } while (++i < 64); /* Next AC element */ - - if (JD_USE_SCALE && jd->scale == 3) - *bp = (*tmp / 256) + 128; /* If scale ratio is 1/8, IDCT can be ommited and only DC element is used */ - else - block_idct(tmp, bp); /* Apply IDCT and store the block to the MCU buffer */ - - bp += 64; /* Next block */ - } - - return JDR_OK; /* All blocks have been loaded successfully */ -} - - - - -/*-----------------------------------------------------------------------*/ -/* Output an MCU: Convert YCrCb to RGB and output it in RGB form */ -/*-----------------------------------------------------------------------*/ - -static -JRESULT mcu_output ( - JDEC* jd, /* Pointer to the decompressor object */ - UINT (*outfunc)(JDEC*, void*, JRECT*), /* RGB output function */ - UINT x, /* MCU position in the image (left of the MCU) */ - UINT y /* MCU position in the image (top of the MCU) */ -) -{ - const INT CVACC = (sizeof (INT) > 2) ? 1024 : 128; - UINT ix, iy, mx, my, rx, ry; - INT yy, cb, cr; - BYTE *py, *pc, *rgb24; - JRECT rect; - - - mx = jd->msx * 8; my = jd->msy * 8; /* MCU size (pixel) */ - rx = (x + mx <= jd->width) ? mx : jd->width - x; /* Output rectangular size (it may be clipped at right/bottom end) */ - ry = (y + my <= jd->height) ? my : jd->height - y; - if (JD_USE_SCALE) { - rx >>= jd->scale; ry >>= jd->scale; - if (!rx || !ry) return JDR_OK; /* Skip this MCU if all pixel is to be rounded off */ - x >>= jd->scale; y >>= jd->scale; - } - rect.left = x; rect.right = x + rx - 1; /* Rectangular area in the frame buffer */ - rect.top = y; rect.bottom = y + ry - 1; - - - if (!JD_USE_SCALE || jd->scale != 3) { /* Not for 1/8 scaling */ - - /* Build an RGB MCU from discrete comopnents */ - rgb24 = (BYTE*)jd->workbuf; - for (iy = 0; iy < my; iy++) { - pc = jd->mcubuf; - py = pc + iy * 8; - if (my == 16) { /* Double block height? */ - pc += 64 * 4 + (iy >> 1) * 8; - if (iy >= 8) py += 64; - } else { /* Single block height */ - pc += mx * 8 + iy * 8; - } - for (ix = 0; ix < mx; ix++) { - cb = pc[0] - 128; /* Get Cb/Cr component and restore right level */ - cr = pc[64] - 128; - if (mx == 16) { /* Double block width? */ - if (ix == 8) py += 64 - 8; /* Jump to next block if double block heigt */ - pc += ix & 1; /* Increase chroma pointer every two pixels */ - } else { /* Single block width */ - pc++; /* Increase chroma pointer every pixel */ - } - yy = *py++; /* Get Y component */ - - /* Convert YCbCr to RGB */ - *rgb24++ = /* R */ BYTECLIP(yy + ((INT)(1.402 * CVACC) * cr) / CVACC); - *rgb24++ = /* G */ BYTECLIP(yy - ((INT)(0.344 * CVACC) * cb + (INT)(0.714 * CVACC) * cr) / CVACC); - *rgb24++ = /* B */ BYTECLIP(yy + ((INT)(1.772 * CVACC) * cb) / CVACC); - } - } - - /* Descale the MCU rectangular if needed */ - if (JD_USE_SCALE && jd->scale) { - UINT x, y, r, g, b, s, w, a; - BYTE *op; - - /* Get averaged RGB value of each square correcponds to a pixel */ - s = jd->scale * 2; /* Bumber of shifts for averaging */ - w = 1 << jd->scale; /* Width of square */ - a = (mx - w) * 3; /* Bytes to skip for next line in the square */ - op = (BYTE*)jd->workbuf; - for (iy = 0; iy < my; iy += w) { - for (ix = 0; ix < mx; ix += w) { - rgb24 = (BYTE*)jd->workbuf + (iy * mx + ix) * 3; - r = g = b = 0; - for (y = 0; y < w; y++) { /* Accumulate RGB value in the square */ - for (x = 0; x < w; x++) { - r += *rgb24++; - g += *rgb24++; - b += *rgb24++; - } - rgb24 += a; - } /* Put the averaged RGB value as a pixel */ - *op++ = (BYTE)(r >> s); - *op++ = (BYTE)(g >> s); - *op++ = (BYTE)(b >> s); - } - } - } - - } else { /* For only 1/8 scaling (left-top pixel in each block are the DC value of the block) */ - - /* Build a 1/8 descaled RGB MCU from discrete comopnents */ - rgb24 = (BYTE*)jd->workbuf; - pc = jd->mcubuf + mx * my; - cb = pc[0] - 128; /* Get Cb/Cr component and restore right level */ - cr = pc[64] - 128; - for (iy = 0; iy < my; iy += 8) { - py = jd->mcubuf; - if (iy == 8) py += 64 * 2; - for (ix = 0; ix < mx; ix += 8) { - yy = *py; /* Get Y component */ - py += 64; - - /* Convert YCbCr to RGB */ - *rgb24++ = /* R */ BYTECLIP(yy + ((INT)(1.402 * CVACC) * cr / CVACC)); - *rgb24++ = /* G */ BYTECLIP(yy - ((INT)(0.344 * CVACC) * cb + (INT)(0.714 * CVACC) * cr) / CVACC); - *rgb24++ = /* B */ BYTECLIP(yy + ((INT)(1.772 * CVACC) * cb / CVACC)); - } - } - } - - /* Squeeze up pixel table if a part of MCU is to be truncated */ - mx >>= jd->scale; - if (rx < mx) { - BYTE *s, *d; - UINT x, y; - - s = d = (BYTE*)jd->workbuf; - for (y = 0; y < ry; y++) { - for (x = 0; x < rx; x++) { /* Copy effective pixels */ - *d++ = *s++; - *d++ = *s++; - *d++ = *s++; - } - s += (mx - rx) * 3; /* Skip truncated pixels */ - } - } - - /* Convert RGB888 to RGB565 if needed */ - if (JD_FORMAT == 1) { - BYTE *s = (BYTE*)jd->workbuf; - WORD w, *d = (WORD*)s; - UINT n = rx * ry; - - do { - w = (*s++ & 0xF8) << 8; /* RRRRR----------- */ - w |= (*s++ & 0xFC) << 3; /* -----GGGGGG----- */ - w |= *s++ >> 3; /* -----------BBBBB */ - *d++ = w; - } while (--n); - } - - /* Output the RGB rectangular */ - return outfunc(jd, jd->workbuf, &rect) ? JDR_OK : JDR_INTR; -} - - - - -/*-----------------------------------------------------------------------*/ -/* Process restart interval */ -/*-----------------------------------------------------------------------*/ - -static -JRESULT restart ( - JDEC* jd, /* Pointer to the decompressor object */ - WORD rstn /* Expected restert sequense number */ -) -{ - UINT i, dc; - WORD d; - BYTE *dp; - - - /* Discard padding bits and get two bytes from the input stream */ - dp = jd->dptr; dc = jd->dctr; - d = 0; - for (i = 0; i < 2; i++) { - if (!dc) { /* No input data is available, re-fill input buffer */ - dp = jd->inbuf; - dc = jd->infunc(jd, dp, JD_SZBUF); - if (!dc) return JDR_INP; - } else { - dp++; - } - dc--; - d = (d << 8) | *dp; /* Get a byte */ - } - jd->dptr = dp; jd->dctr = dc; jd->dmsk = 0; - - /* Check the marker */ - if ((d & 0xFFD8) != 0xFFD0 || (d & 7) != (rstn & 7)) - return JDR_FMT1; /* Err: expected RSTn marker is not detected (may be collapted data) */ - - /* Reset DC offset */ - jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0; - - return JDR_OK; -} - - - - -/*-----------------------------------------------------------------------*/ -/* Analyze the JPEG image and Initialize decompressor object */ -/*-----------------------------------------------------------------------*/ - -#define LDB_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr))<<8)|(WORD)*(BYTE*)((ptr)+1)) - - -JRESULT jd_prepare ( - JDEC* jd, /* Blank decompressor object */ - UINT (*infunc)(JDEC*, BYTE*, UINT), /* JPEG strem input function */ - void* pool, /* Working buffer for the decompression session */ - UINT sz_pool, /* Size of working buffer */ - void* dev /* I/O device identifier for the session */ -) -{ - BYTE *seg, b; - WORD marker; - DWORD ofs; - UINT n, i, j, len; - JRESULT rc; - - - if (!pool) return JDR_PAR; - - jd->pool = pool; /* Work memroy */ - jd->sz_pool = sz_pool; /* Size of given work memory */ - jd->infunc = infunc; /* Stream input function */ - jd->device = dev; /* I/O device identifier */ - jd->nrst = 0; /* No restart interval (default) */ - - for (i = 0; i < 2; i++) { /* Nulls pointers */ - for (j = 0; j < 2; j++) { - jd->huffbits[i][j] = 0; - jd->huffcode[i][j] = 0; - jd->huffdata[i][j] = 0; - } - } - for (i = 0; i < 4; i++) jd->qttbl[i] = 0; - - jd->inbuf = seg = alloc_pool(jd, JD_SZBUF); /* Allocate stream input buffer */ - if (!seg) return JDR_MEM1; - - if (jd->infunc(jd, seg, 2) != 2) return JDR_INP;/* Check SOI marker */ - if (LDB_WORD(seg) != 0xFFD8) return JDR_FMT1; /* Err: SOI is not detected */ - ofs = 2; - - for (;;) { - /* Get a JPEG marker */ - if (jd->infunc(jd, seg, 4) != 4) return JDR_INP; - marker = LDB_WORD(seg); /* Marker */ - len = LDB_WORD(seg + 2); /* Length field */ - if (len <= 2 || (marker >> 8) != 0xFF) return JDR_FMT1; - len -= 2; /* Content size excluding length field */ - ofs += 4 + len; /* Number of bytes loaded */ - - switch (marker & 0xFF) { - case 0xC0: /* SOF0 (baseline JPEG) */ - /* Load segment data */ - if (len > JD_SZBUF) return JDR_MEM2; - if (jd->infunc(jd, seg, len) != len) return JDR_INP; - - jd->width = LDB_WORD(seg+3); /* Image width in unit of pixel */ - jd->height = LDB_WORD(seg+1); /* Image height in unit of pixel */ - if (seg[5] != 3) return JDR_FMT3; /* Err: Supports only Y/Cb/Cr format */ - - /* Check three image components */ - for (i = 0; i < 3; i++) { - b = seg[7 + 3 * i]; /* Get sampling factor */ - if (!i) { /* Y component */ - if (b != 0x11 && b != 0x22 && b != 0x21)/* Check sampling factor */ - return JDR_FMT3; /* Err: Supports only 4:4:4, 4:2:0 or 4:2:2 */ - jd->msx = b >> 4; jd->msy = b & 15; /* Size of MCU [blocks] */ - } else { /* Cb/Cr component */ - if (b != 0x11) return JDR_FMT3; /* Err: Sampling factor of Cr/Cb must be 1 */ - } - b = seg[8 + 3 * i]; /* Get dequantizer table ID for this component */ - if (b > 3) return JDR_FMT3; /* Err: Invalid ID */ - jd->qtid[i] = b; - } - break; - - case 0xDD: /* DRI */ - /* Load segment data */ - if (len > JD_SZBUF) return JDR_MEM2; - if (jd->infunc(jd, seg, len) != len) return JDR_INP; - - /* Get restart interval (MCUs) */ - jd->nrst = LDB_WORD(seg); - break; - - case 0xC4: /* DHT */ - /* Load segment data */ - if (len > JD_SZBUF) return JDR_MEM2; - if (jd->infunc(jd, seg, len) != len) return JDR_INP; - - /* Create huffman tables */ - rc = create_huffman_tbl(jd, seg, len); - if (rc) return rc; - break; - - case 0xDB: /* DQT */ - /* Load segment data */ - if (len > JD_SZBUF) return JDR_MEM2; - if (jd->infunc(jd, seg, len) != len) return JDR_INP; - - /* Create de-quantizer tables */ - rc = create_qt_tbl(jd, seg, len); - if (rc) return rc; - break; - - case 0xDA: /* SOS */ - /* Load segment data */ - if (len > JD_SZBUF) return JDR_MEM2; - if (jd->infunc(jd, seg, len) != len) return JDR_INP; - - if (!jd->width || !jd->height) return JDR_FMT1; /* Err: Invalid image size */ - - if (seg[0] != 3) return JDR_FMT3; /* Err: Supports only three color components format */ - - /* Check if all tables corresponding to each components have been loaded */ - for (i = 0; i < 3; i++) { - b = seg[2 + 2 * i]; /* Get huffman table ID */ - if (b != 0x00 && b != 0x11) return JDR_FMT3; /* Err: Different table number for DC/AC element */ - b = i ? 1 : 0; - if (!jd->huffbits[b][0] || !jd->huffbits[b][1]) /* Check huffman table for this component */ - return JDR_FMT1; /* Err: Huffman table not loaded */ - if (!jd->qttbl[jd->qtid[i]]) return JDR_FMT1; /* Err: Dequantizer table not loaded */ - } - - /* Allocate working buffer for MCU and RGB */ - n = jd->msy * jd->msx; /* Number of Y blocks in the MCU */ - if (!n) return JDR_FMT1; /* Err: SOF0 has not been loaded */ - len = n * 64 * 2 + 64; /* Allocate buffer for IDCT and RGB output */ - if (len < 256) len = 256; /* but at least 256 byte is required for IDCT */ - jd->workbuf = alloc_pool(jd, len); /* and it may occupy a part of following MCU working buffer for RGB output */ - if (!jd->workbuf) return JDR_MEM1; /* Err: not enough memory */ - jd->mcubuf = alloc_pool(jd, (n + 2) * 64); /* Allocate MCU working buffer */ - if (!jd->mcubuf) return JDR_MEM1; /* Err: not enough memory */ - - /* Pre-load the JPEG data to extract it from the bit stream */ - jd->dptr = seg; jd->dctr = 0; jd->dmsk = 0; /* Prepare to read bit stream */ - if (ofs %= JD_SZBUF) { /* Align read offset to JD_SZBUF */ - jd->dctr = jd->infunc(jd, seg + ofs, JD_SZBUF - (UINT)ofs); - jd->dptr = seg + ofs - 1; - } - - return JDR_OK; /* Initialization succeeded. Ready to decompress the JPEG image. */ - - case 0xC1: /* SOF1 */ - case 0xC2: /* SOF2 */ - case 0xC3: /* SOF3 */ - case 0xC5: /* SOF5 */ - case 0xC6: /* SOF6 */ - case 0xC7: /* SOF7 */ - case 0xC9: /* SOF9 */ - case 0xCA: /* SOF10 */ - case 0xCB: /* SOF11 */ - case 0xCD: /* SOF13 */ - case 0xCE: /* SOF14 */ - case 0xCF: /* SOF15 */ - case 0xD9: /* EOI */ - return JDR_FMT3; /* Unsuppoted JPEG standard (may be progressive JPEG) */ - - default: /* Unknown segment (comment, exif or etc..) */ - /* Skip segment data */ - if (jd->infunc(jd, 0, len) != len) /* Null pointer specifies to skip bytes of stream */ - return JDR_INP; - } - } -} - - - - -/*-----------------------------------------------------------------------*/ -/* Start to decompress the JPEG picture */ -/*-----------------------------------------------------------------------*/ - -JRESULT jd_decomp ( - JDEC* jd, /* Initialized decompression object */ - UINT (*outfunc)(JDEC*, void*, JRECT*), /* RGB output function */ - BYTE scale /* Output de-scaling factor (0 to 3) */ -) -{ - UINT x, y, mx, my; - WORD rst, rsc; - JRESULT rc; - - - if (scale > (JD_USE_SCALE ? 3 : 0)) return JDR_PAR; - jd->scale = scale; - - mx = jd->msx * 8; my = jd->msy * 8; /* Size of the MCU (pixel) */ - - jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0; /* Initialize DC values */ - rst = rsc = 0; - - rc = JDR_OK; - for (y = 0; y < jd->height; y += my) { /* Vertical loop of MCUs */ - for (x = 0; x < jd->width; x += mx) { /* Horizontal loop of MCUs */ - if (jd->nrst && rst++ == jd->nrst) { /* Process restart interval if enabled */ - rc = restart(jd, rsc++); - if (rc != JDR_OK) return rc; - rst = 1; - } - rc = mcu_load(jd); /* Load an MCU (decompress huffman coded stream and IDCT) */ - if (rc != JDR_OK) return rc; - rc = mcu_output(jd, outfunc, x, y); /* Output the MCU (color space conversion, scaling and output) */ - if (rc != JDR_OK) return rc; - } - } - - return rc; -} - - - diff --git a/examples/Advanced/Camera/tjpgd.h b/examples/Advanced/Camera/tjpgd.h deleted file mode 100644 index 7965c64..0000000 --- a/examples/Advanced/Camera/tjpgd.h +++ /dev/null @@ -1,70 +0,0 @@ -/*----------------------------------------------------------------------------/ -/ TJpgDec - Tiny JPEG Decompressor include file (C)ChaN, 2011 -/----------------------------------------------------------------------------*/ - -/* System Configurations */ - -#define JD_SZBUF 512 /* Size of stream input buffer (should be multiple of 512) */ -#define JD_FORMAT 0 /* Output RGB format 0:RGB888 (3 BYTE/pix), 1:RGB565 (1 WORD/pix) */ -#define JD_USE_SCALE 1 /* Use descaling feature for output */ - - -/*---------------------------------------------------------------------------*/ - -#include "integer.h" - - -/* Error code */ -typedef enum { - JDR_OK = 0, /* 0: Succeeded */ - JDR_INTR, /* 1: Interrupted by output function */ - JDR_INP, /* 2: Device error or wrong termination of input stream */ - JDR_MEM1, /* 3: Insufficient memory pool for the image */ - JDR_MEM2, /* 4: Insufficient stream input buffer */ - JDR_PAR, /* 5: Parameter error */ - JDR_FMT1, /* 6: Data format error (may be damaged data) */ - JDR_FMT2, /* 7: Right format but not supported */ - JDR_FMT3 /* 8: Not supported JPEG standard */ -} JRESULT; - - -typedef struct { - WORD left, right, top, bottom; -} JRECT; - - -/* Decompressor object structure */ -typedef struct JDEC JDEC; -struct JDEC { - UINT dctr; /* Number of bytes available in the input buffer */ - BYTE* dptr; /* Current data read ptr */ - BYTE* inbuf; /* Bit stream input buffer */ - BYTE dmsk; /* Current bit in the current read byte */ - BYTE scale; /* Output scaling ratio */ - BYTE msx, msy; /* MCU size in unit of block (width, height) */ - BYTE qtid[3]; /* Quantization table ID of each component */ - SHORT dcv[3]; /* Previous DC element of each component */ - WORD nrst; /* Restart inverval */ - UINT width, height; /* Size of the input image (pixel) */ - BYTE* huffbits[2][2]; /* Huffman bit distribution tables [id][dcac] */ - WORD* huffcode[2][2]; /* Huffman code word tables [id][dcac] */ - BYTE* huffdata[2][2]; /* Huffman decoded data tables [id][dcac] */ - LONG* qttbl[4]; /* Dequaitizer tables [id] */ - void* workbuf; /* Working buffer for IDCT and RGB output */ - BYTE* mcubuf; /* Working buffer for the MCU */ - void* pool; /* Pointer to available memory pool */ - UINT sz_pool; /* Size of momory pool (bytes available) */ - UINT (*infunc)(JDEC*, BYTE*, UINT);/* Pointer to jpeg stream input function */ - UINT (*outfunc)(JDEC*, void*, JRECT*); /* Pointer to RGB output function */ - void* device; /* Pointer to I/O device identifiler for the session */ -}; - - -#define LDB_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr))<<8)|(WORD)*(BYTE*)((ptr)+1)) - - - -/* TJpgDec API functions */ -JRESULT jd_prepare (JDEC*, UINT(*)(JDEC*,BYTE*,UINT), void*, UINT, void*); -JRESULT jd_decomp (JDEC*, UINT(*)(JDEC*,void*,JRECT*), BYTE); - diff --git a/examples/Advanced/Changer/Changer.ino b/examples/Advanced/Changer/Changer.ino deleted file mode 100644 index 5ecf479..0000000 --- a/examples/Advanced/Changer/Changer.ino +++ /dev/null @@ -1,61 +0,0 @@ -/* - Blink - Turns on an LED on for one second, then off for one second, repeatedly. - - Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO - it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to - the correct LED pin independent of which board is used. - If you want to know what pin the on-board LED is connected to on your Arduino model, check - the Technical Specs of your board at https://www.arduino.cc/en/Main/Products - - This example code is in the public domain. - - modified 8 May 2014 - by Scott Fitzgerald - - modified 2 Sep 2016 - by Arturo Guadalupi - - modified 8 Sep 2016 - by Colby Newman -*/ - -#include - -// the setup function runs once when you press reset or power the board -void setup() { - // initialize the M5Stack object - // m5.begin(); - Wire.begin(); - Serial.begin(115200); - Serial.printf("start\r\n"); - - // initialize digital pin LED_BUILTIN as an output. - // pinMode(LED_PIN, OUTPUT); -} - -// the loop function runs over and over again forever -void loop() { - uint8_t data1, data2; - Wire.beginTransmission(0x75); - Wire.write(0xa3); - Wire.endTransmission(); - - Wire.requestFrom((int)0x75, 1); - - // while(Wire.available()) - { - data1 = Wire.read(); // receive a byte as character - // data2 = Wire.read(); // receive a byte as character - // Serial.printf("data: 0x%x, 0x%x\r\n", data1, data2); - Serial.printf("data: 0x%x\r\n", data1); - } - - // Wire.beginTransmission(0x75); - // Wire.write(2); - // Wire.write((uint8_t)0x78); - // // Wire.write((uint8_t)0x78); - // Wire.endTransmission(); - - delay(2000); -} diff --git a/examples/Advanced/ParamConfig/ParamConfig.ino b/examples/Advanced/ParamConfig/ParamConfig.ino deleted file mode 100644 index c93f7e6..0000000 --- a/examples/Advanced/ParamConfig/ParamConfig.ino +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include - -bool getParamFromTFCard(const char* filename, const char* keyword, char* strout) { - // fs file read - File fsFile; - uint8_t fsbuffer[255]; - // const char* filename = "/azure-config.json"; - if(SD.exists(filename)) { - fsFile = SD.open(filename, "r"); - if(fsFile) { - Serial.printf("Success open file:\r\n"); - fsFile.read(fsbuffer, fsFile.size()); - Serial.printf("\r\n"); - fsbuffer[fsFile.size()] = 0; - Serial.printf("%s", fsbuffer); - } else { - Serial.printf("Fail open file!\r\n"); - return false; - } - } - - // Memory pool for JSON object tree. - // - // Inside the brackets, 200 is the size of the pool in bytes, - // If the JSON object is more complex, you need to increase that value. - StaticJsonBuffer<200> jsonBuffer; - - // StaticJsonBuffer allocates memory on the stack, it can be - // replaced by DynamicJsonBuffer which allocates in the heap. - // It's simpler but less efficient. - // - // DynamicJsonBuffer jsonBuffer; - - // Root of the object tree. - // - // It's a reference to the JsonObject, the actual bytes are inside the - // JsonBuffer with all the other nodes of the object tree. - // Memory is freed when jsonBuffer goes out of scope. - JsonObject& root = jsonBuffer.parseObject(fsbuffer); - - // Test if parsing succeeds. - if (!root.success()) { - Serial.println("parseObject() failed"); - return false; - } - - // Fetch values. - // - // Most of the time, you can rely on the implicit casts. - // In other case, you can do root["time"].as(); - const char* value = root[keyword]; - - // Copy values. - strcpy((char*)strout, value); - Serial.printf("Keyword:%s\r\nValue:%s\r\n", keyword, strout); - return true; -} - -// the setup routine runs once when M5Stack starts up -void setup(){ - - // initialize the M5Stack object - m5.begin(); - - // lcd display - m5.lcd.printf("JSON test"); - - char ssid[30]; - if(getParamFromTFCard("/azure-config.json", "WiFi_SSID", ssid)) { - Serial.printf("Read Value:%s", ssid); - } - -} - -// the loop routine runs over and over again forever -void loop(){ - - m5.loop(); -} - diff --git a/examples/Advanced/ParamConfig/azure-config.json b/examples/Advanced/ParamConfig/azure-config.json deleted file mode 100644 index 07c5159..0000000 --- a/examples/Advanced/ParamConfig/azure-config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "WiFi_SSID":"MasterHax_2.4G", - "WiFi_PASSWORD":"wittyercheese551", - "AzureDeviceID":"test001", - "ConnectingString":"m5statck-abcde" -} \ No newline at end of file diff --git a/examples/Advanced/TFCardPicture/TFCardPicture.ino b/examples/Advanced/TFCardPicture/TFCardPicture.ino deleted file mode 100644 index 5aac1ba..0000000 --- a/examples/Advanced/TFCardPicture/TFCardPicture.ino +++ /dev/null @@ -1,18 +0,0 @@ -#include - -// the setup routine runs once when M5Stack starts up -void setup(){ - // initialize the M5Stack object - m5.begin(); -} - -// the loop routine runs over and over again forever -void loop(){ - - m5.lcd.drawPicture("/ROBOT2.bmp"); - m5.lcd.drawPicture("/ROBOT3.bmp"); - m5.lcd.drawPicture("/ROBOT4.bmp"); - m5.lcd.drawPicture("/ROBOT5.bmp"); - - m5.loop(); -} diff --git a/examples/Advanced/WavPlayer/WavPlayer.ino b/examples/Advanced/WavPlayer/WavPlayer.ino deleted file mode 100644 index f7c2a79..0000000 --- a/examples/Advanced/WavPlayer/WavPlayer.ino +++ /dev/null @@ -1,135 +0,0 @@ -/* -wavPlayer -Madnerd.org -Primitive wav file player -Only read : Wav Unsigned 8-bit PCM file -Track will stopped if saturation -If you want to make a real mp3 player , use a DFPlayer Mini instead -This is just a proof of concept. -Components -- Micro SD card adapter -- Headphone input -- 2 buttons -- Arduino mini pro 3v -* Open MP3 with Audacity -* File/Export Audio -* Save as type: Other uncompressed files -* Header: Wav (Microsoft) -* Encoding : Unsigned 8_bit PCM -* Save to 0.wav -Wiring: -SD card -1 --> X -2 --> 12 -3 --> GND -4 --> 13 -5 --> VCC -6 --> GND -7 --> 11 -8 --> 10 (Chip select) -Audio: 6 -Button Previous track: 7 -Button Next track:8 -Source: http://garagelab.com/profiles/blogs/tutorial-playing-music-with-garagino-or-arduino-wav-player -*/ -// #include -// #include -#include - -File myFile; -const int b_prev = 8; -const int b_next = 7; -int file = 1; -bool playing = true; -String string_filename; -char* filename; -int check_buttons = 0; - -void setup() { - // // Open serial communications and wait for port to open: - // Serial.begin(115200); - // // pinMode(6, OUTPUT); - // // TCCR0B = 0x01; // Sets the PWM frequency to 64KHz in pins 5 and 6. - // //while (!Serial) { - // // ; // wait for serial port to connect. Needed for native USB port only - // //} - - // Serial.print("Initializing SD card..."); - // while (!SD.begin(10)) { - // Serial.println("initialization failed!"); - // } - - // Serial.println("initialization done."); - - //Enable buttons - // pinMode(b_prev, INPUT_PULLUP); - // pinMode(b_next, INPUT_PULLUP); - m5.begin(); -} - -void loop() { - //Convert string to char - // string_filename = String(file) + ".wav"; - // string_filename = "/1.wav"; - // string_filename = "/500miles.wav"; - string_filename = "/8k8bitpcm.wav"; - unsigned int bufSize = string_filename.length() + 1; //String length + null terminator - filename = new char[bufSize]; - string_filename.toCharArray(filename, bufSize); - - if (SD.exists(filename)) { - Serial.println(string_filename); - myFile = SD.open(filename, FILE_READ); - } - else { - Serial.println(string_filename + "doesn't exists"); - file = 0; - } - - unsigned char data; - for (int count = 0; count < 128; count++) { - data = myFile.read(); - } - Serial.println("Start"); - playing = true; - check_buttons = 0; - while (data != 255) { - data = myFile.read(); - dacWrite(25, data); - // analogWrite(6, data); - // delayMicroseconds(10); - delayMicroseconds(125); - // checkButtons(); - - if (!playing) { - break; - } - } - - //Serial.println("Stop"); - myFile.close(); - Serial.println("Replay"); - // nothing happens after setup finishes. - delay(1000); -} - -// void checkButtons() { -// check_buttons++; -// //We reduce check because our arduino is really time sensitive when reading wav files. -// if (check_buttons == 1000) { -// check_buttons = 0; -// if (!digitalRead(b_prev)) { -// Serial.println("Button previous"); -// file--; -// playing = false; -// delay(1000); -// } - -// if (!digitalRead(b_next)) { -// Serial.println("Button next"); -// file++; -// playing = false; -// delay(1000); -// } -// } -// } diff --git a/examples/Advanced/httpUpdate/ESP8266HTTPClient.cpp b/examples/Advanced/httpUpdate/ESP8266HTTPClient.cpp deleted file mode 100644 index de1fde4..0000000 --- a/examples/Advanced/httpUpdate/ESP8266HTTPClient.cpp +++ /dev/null @@ -1,1119 +0,0 @@ -/** - * ESP8266HTTPClient.cpp - * - * Created on: 02.11.2015 - * - * Copyright (c) 2015 Markus Sattler. All rights reserved. - * This file is part of the ESP8266HTTPClient for Arduino. - * - * This library 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 2.1 of the License, or (at your option) any later version. - * - * This library 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 this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include -#include -#include -#include -#include - -#include "ESP8266HTTPClient.h" - -class TransportTraits -{ -public: - virtual ~TransportTraits() - { - } - - virtual std::unique_ptr create() - { - return std::unique_ptr(new WiFiClient()); - } - - virtual bool verify(WiFiClient& client, const char* host) - { - return true; - } -}; - -class TLSTraits : public TransportTraits -{ -public: - TLSTraits(const String& fingerprint) : - _fingerprint(fingerprint) - { - } - - std::unique_ptr create() override - { - // return std::unique_ptr(new WiFiClientSecure()); - } - - bool verify(WiFiClient& client, const char* host) override - { - // auto wcs = static_cast(client); - // return wcs.verify(_fingerprint.c_str(), host); - } - -protected: - String _fingerprint; -}; - -/** - * constructor - */ -HTTPClient::HTTPClient() -{ -} - -/** - * destructor - */ -HTTPClient::~HTTPClient() -{ - if(_tcp) { - _tcp->stop(); - } - if(_currentHeaders) { - delete[] _currentHeaders; - } -} - -void HTTPClient::clear() -{ - _returnCode = 0; - _size = -1; - _headers = ""; -} - - -bool HTTPClient::begin(String url, String httpsFingerprint) -{ - _transportTraits.reset(nullptr); - _port = 443; - if (httpsFingerprint.length() == 0) { - return false; - } - if (!beginInternal(url, "https")) { - return false; - } - _transportTraits = TransportTraitsPtr(new TLSTraits(httpsFingerprint)); - DEBUG_HTTPCLIENT("[HTTP-Client][begin] httpsFingerprint: %s\n", httpsFingerprint.c_str()); - return true; -} - -/** - * parsing the url for all needed parameters - * @param url String - */ -bool HTTPClient::begin(String url) -{ - _transportTraits.reset(nullptr); - _port = 80; - if (!beginInternal(url, "http")) { - return false; - } - _transportTraits = TransportTraitsPtr(new TransportTraits()); - return true; -} - -bool HTTPClient::beginInternal(String url, const char* expectedProtocol) -{ - DEBUG_HTTPCLIENT("[HTTP-Client][begin] url: %s\n", url.c_str()); - bool hasPort = false; - clear(); - - // check for : (http: or https: - int index = url.indexOf(':'); - if(index < 0) { - DEBUG_HTTPCLIENT("[HTTP-Client][begin] failed to parse protocol\n"); - return false; - } - - _protocol = url.substring(0, index); - url.remove(0, (index + 3)); // remove http:// or https:// - - index = url.indexOf('/'); - String host = url.substring(0, index); - url.remove(0, index); // remove host part - - // get Authorization - index = host.indexOf('@'); - if(index >= 0) { - // auth info - String auth = host.substring(0, index); - host.remove(0, index + 1); // remove auth part including @ - _base64Authorization = base64::encode(auth); - } - - // get port - index = host.indexOf(':'); - if(index >= 0) { - _host = host.substring(0, index); // hostname - host.remove(0, (index + 1)); // remove hostname + : - _port = host.toInt(); // get port - } else { - _host = host; - } - _uri = url; - if (_protocol != expectedProtocol) { - DEBUG_HTTPCLIENT("[HTTP-Client][begin] unexpected protocol: %s, expected %s\n", _protocol.c_str(), expectedProtocol); - return false; - } - DEBUG_HTTPCLIENT("[HTTP-Client][begin] host: %s port: %d url: %s\n", _host.c_str(), _port, _uri.c_str()); - return true; -} - -bool HTTPClient::begin(String host, uint16_t port, String uri) -{ - clear(); - _host = host; - _port = port; - _uri = uri; - _transportTraits = TransportTraitsPtr(new TransportTraits()); - DEBUG_HTTPCLIENT("[HTTP-Client][begin] host: %s port: %d uri: %s\n", host.c_str(), port, uri.c_str()); - return true; -} - -bool HTTPClient::begin(String host, uint16_t port, String uri, bool https, String httpsFingerprint) -{ - if (https) { - return begin(host, port, uri, httpsFingerprint); - } else { - return begin(host, port, uri); - } -} - -bool HTTPClient::begin(String host, uint16_t port, String uri, String httpsFingerprint) -{ - clear(); - _host = host; - _port = port; - _uri = uri; - - if (httpsFingerprint.length() == 0) { - return false; - } - _transportTraits = TransportTraitsPtr(new TLSTraits(httpsFingerprint)); - DEBUG_HTTPCLIENT("[HTTP-Client][begin] host: %s port: %d url: %s httpsFingerprint: %s\n", host.c_str(), port, uri.c_str(), httpsFingerprint.c_str()); - return true; -} - -/** - * end - * called after the payload is handled - */ -void HTTPClient::end(void) -{ - if(connected()) { - if(_tcp->available() > 0) { - DEBUG_HTTPCLIENT("[HTTP-Client][end] still data in buffer (%d), clean up.\n", _tcp->available()); - while(_tcp->available() > 0) { - _tcp->read(); - } - } - if(_reuse && _canReuse) { - DEBUG_HTTPCLIENT("[HTTP-Client][end] tcp keep open for reuse\n"); - } else { - DEBUG_HTTPCLIENT("[HTTP-Client][end] tcp stop\n"); - _tcp->stop(); - } - } else { - DEBUG_HTTPCLIENT("[HTTP-Client][end] tcp is closed\n"); - } -} - -/** - * connected - * @return connected status - */ -bool HTTPClient::connected() -{ - if(_tcp) { - return (_tcp->connected() || (_tcp->available() > 0)); - } - return false; -} - -/** - * try to reuse the connection to the server - * keep-alive - * @param reuse bool - */ -void HTTPClient::setReuse(bool reuse) -{ - _reuse = reuse; -} - -/** - * set User Agent - * @param userAgent const char * - */ -void HTTPClient::setUserAgent(const String& userAgent) -{ - _userAgent = userAgent; -} - -/** - * set the Authorizatio for the http request - * @param user const char * - * @param password const char * - */ -void HTTPClient::setAuthorization(const char * user, const char * password) -{ - if(user && password) { - String auth = user; - auth += ":"; - auth += password; - _base64Authorization = base64::encode(auth); - } -} - -/** - * set the Authorizatio for the http request - * @param auth const char * base64 - */ -void HTTPClient::setAuthorization(const char * auth) -{ - if(auth) { - _base64Authorization = auth; - } -} - -/** - * set the timeout for the TCP connection - * @param timeout unsigned int - */ -void HTTPClient::setTimeout(uint16_t timeout) -{ - _tcpTimeout = timeout; - if(connected()) { - _tcp->setTimeout(timeout); - } -} - -/** - * use HTTP1.0 - * @param timeout - */ -void HTTPClient::useHTTP10(bool useHTTP10) -{ - _useHTTP10 = useHTTP10; -} - -/** - * send a GET request - * @return http code - */ -int HTTPClient::GET() -{ - return sendRequest("GET"); -} - -/** - * sends a post request to the server - * @param payload uint8_t * - * @param size size_t - * @return http code - */ -int HTTPClient::POST(uint8_t * payload, size_t size) -{ - return sendRequest("POST", payload, size); -} - -int HTTPClient::POST(String payload) -{ - return POST((uint8_t *) payload.c_str(), payload.length()); -} - -/** - * sends a put request to the server - * @param payload uint8_t * - * @param size size_t - * @return http code - */ -int HTTPClient::PUT(uint8_t * payload, size_t size) { - return sendRequest("PUT", payload, size); -} - -int HTTPClient::PUT(String payload) { - return PUT((uint8_t *) payload.c_str(), payload.length()); -} - -/** - * sendRequest - * @param type const char * "GET", "POST", .... - * @param payload String data for the message body - * @return - */ -int HTTPClient::sendRequest(const char * type, String payload) -{ - return sendRequest(type, (uint8_t *) payload.c_str(), payload.length()); -} - -/** - * sendRequest - * @param type const char * "GET", "POST", .... - * @param payload uint8_t * data for the message body if null not send - * @param size size_t size for the message body if 0 not send - * @return -1 if no info or > 0 when Content-Length is set by server - */ -int HTTPClient::sendRequest(const char * type, uint8_t * payload, size_t size) -{ - // connect to server - if(!connect()) { - return returnError(HTTPC_ERROR_CONNECTION_REFUSED); - } - - if(payload && size > 0) { - addHeader(F("Content-Length"), String(size)); - } - - // send Header - if(!sendHeader(type)) { - return returnError(HTTPC_ERROR_SEND_HEADER_FAILED); - } - - // send Payload if needed - if(payload && size > 0) { - if(_tcp->write(&payload[0], size) != size) { - return returnError(HTTPC_ERROR_SEND_PAYLOAD_FAILED); - } - } - - // handle Server Response (Header) - return returnError(handleHeaderResponse()); -} - -/** - * sendRequest - * @param type const char * "GET", "POST", .... - * @param stream Stream * data stream for the message body - * @param size size_t size for the message body if 0 not Content-Length is send - * @return -1 if no info or > 0 when Content-Length is set by server - */ -int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size) -{ - - if(!stream) { - return returnError(HTTPC_ERROR_NO_STREAM); - } - - // connect to server - if(!connect()) { - return returnError(HTTPC_ERROR_CONNECTION_REFUSED); - } - - if(size > 0) { - addHeader("Content-Length", String(size)); - } - - // send Header - if(!sendHeader(type)) { - return returnError(HTTPC_ERROR_SEND_HEADER_FAILED); - } - - int buff_size = HTTP_TCP_BUFFER_SIZE; - - int len = size; - int bytesWritten = 0; - - if(len == 0) { - len = -1; - } - - // if possible create smaller buffer then HTTP_TCP_BUFFER_SIZE - if((len > 0) && (len < HTTP_TCP_BUFFER_SIZE)) { - buff_size = len; - } - - // create buffer for read - uint8_t * buff = (uint8_t *) malloc(buff_size); - - if(buff) { - // read all data from stream and send it to server - while(connected() && (stream->available() > -1) && (len > 0 || len == -1)) { - - // get available data size - int sizeAvailable = stream->available(); - - if(sizeAvailable) { - - int readBytes = sizeAvailable; - - // read only the asked bytes - if(len > 0 && readBytes > len) { - readBytes = len; - } - - // not read more the buffer can handle - if(readBytes > buff_size) { - readBytes = buff_size; - } - - // read data - int bytesRead = stream->readBytes(buff, readBytes); - - // write it to Stream - int bytesWrite = _tcp->write((const uint8_t *) buff, bytesRead); - bytesWritten += bytesWrite; - - // are all Bytes a writen to stream ? - if(bytesWrite != bytesRead) { - DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] short write, asked for %d but got %d retry...\n", bytesRead, bytesWrite); - - // check for write error - if(_tcp->getWriteError()) { - DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] stream write error %d\n", _tcp->getWriteError()); - - //reset write error for retry - _tcp->clearWriteError(); - } - - // some time for the stream - delay(1); - - int leftBytes = (readBytes - bytesWrite); - - // retry to send the missed bytes - bytesWrite = _tcp->write((const uint8_t *) (buff + bytesWrite), leftBytes); - bytesWritten += bytesWrite; - - if(bytesWrite != leftBytes) { - // failed again - DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] short write, asked for %d but got %d failed.\n", leftBytes, bytesWrite); - free(buff); - return returnError(HTTPC_ERROR_SEND_PAYLOAD_FAILED); - } - } - - // check for write error - if(_tcp->getWriteError()) { - DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] stream write error %d\n", _tcp->getWriteError()); - free(buff); - return returnError(HTTPC_ERROR_SEND_PAYLOAD_FAILED); - } - - // count bytes to read left - if(len > 0) { - len -= readBytes; - } - - delay(0); - } else { - delay(1); - } - } - - free(buff); - - if(size && (int) size != bytesWritten) { - DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] Stream payload bytesWritten %d and size %d mismatch!.\n", bytesWritten, size); - DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] ERROR SEND PAYLOAD FAILED!"); - return returnError(HTTPC_ERROR_SEND_PAYLOAD_FAILED); - } else { - DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] Stream payload written: %d\n", bytesWritten); - } - - } else { - DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] too less ram! need %d\n", HTTP_TCP_BUFFER_SIZE); - return returnError(HTTPC_ERROR_TOO_LESS_RAM); - } - - // handle Server Response (Header) - return returnError(handleHeaderResponse()); -} - -/** - * size of message body / payload - * @return -1 if no info or > 0 when Content-Length is set by server - */ -int HTTPClient::getSize(void) -{ - return _size; -} - -/** - * returns the stream of the tcp connection - * @return WiFiClient - */ -WiFiClient& HTTPClient::getStream(void) -{ - if(connected()) { - return *_tcp; - } - - DEBUG_HTTPCLIENT("[HTTP-Client] getStream: not connected\n"); - static WiFiClient empty; - return empty; -} - -/** - * returns the stream of the tcp connection - * @return WiFiClient * - */ -WiFiClient* HTTPClient::getStreamPtr(void) -{ - if(connected()) { - return _tcp.get(); - } - - DEBUG_HTTPCLIENT("[HTTP-Client] getStreamPtr: not connected\n"); - return nullptr; -} - -/** - * write all message body / payload to Stream - * @param stream Stream * - * @return bytes written ( negative values are error codes ) - */ -int HTTPClient::writeToStream(Stream * stream) -{ - - if(!stream) { - return returnError(HTTPC_ERROR_NO_STREAM); - } - - if(!connected()) { - return returnError(HTTPC_ERROR_NOT_CONNECTED); - } - - // get length of document (is -1 when Server sends no Content-Length header) - int len = _size; - int ret = 0; - - if(_transferEncoding == HTTPC_TE_IDENTITY) { - ret = writeToStreamDataBlock(stream, len); - - // have we an error? - if(ret < 0) { - return returnError(ret); - } - } else if(_transferEncoding == HTTPC_TE_CHUNKED) { - int size = 0; - while(1) { - if(!connected()) { - return returnError(HTTPC_ERROR_CONNECTION_LOST); - } - String chunkHeader = _tcp->readStringUntil('\n'); - - if(chunkHeader.length() <= 0) { - return returnError(HTTPC_ERROR_READ_TIMEOUT); - } - - chunkHeader.trim(); // remove \r - - // read size of chunk - len = (uint32_t) strtol((const char *) chunkHeader.c_str(), NULL, 16); - size += len; - DEBUG_HTTPCLIENT("[HTTP-Client] read chunk len: %d\n", len); - - // data left? - if(len > 0) { - int r = writeToStreamDataBlock(stream, len); - if(r < 0) { - // error in writeToStreamDataBlock - return returnError(r); - } - ret += r; - } else { - - // if no length Header use global chunk size - if(_size <= 0) { - _size = size; - } - - // check if we have write all data out - if(ret != _size) { - return returnError(HTTPC_ERROR_STREAM_WRITE); - } - break; - } - - // read trailing \r\n at the end of the chunk - char buf[2]; - auto trailing_seq_len = _tcp->readBytes((uint8_t*)buf, 2); - if (trailing_seq_len != 2 || buf[0] != '\r' || buf[1] != '\n') { - return returnError(HTTPC_ERROR_READ_TIMEOUT); - } - - delay(0); - } - } else { - return returnError(HTTPC_ERROR_ENCODING); - } - - end(); - return ret; -} - -/** - * return all payload as String (may need lot of ram or trigger out of memory!) - * @return String - */ -String HTTPClient::getString(void) -{ - StreamString sstring; - - if(_size) { - // try to reserve needed memmory - if(!sstring.reserve((_size + 1))) { - DEBUG_HTTPCLIENT("[HTTP-Client][getString] not enough memory to reserve a string! need: %d\n", (_size + 1)); - return ""; - } - } - - writeToStream(&sstring); - return sstring; -} - -/** - * converts error code to String - * @param error int - * @return String - */ -String HTTPClient::errorToString(int error) -{ - switch(error) { - case HTTPC_ERROR_CONNECTION_REFUSED: - return F("connection refused"); - case HTTPC_ERROR_SEND_HEADER_FAILED: - return F("send header failed"); - case HTTPC_ERROR_SEND_PAYLOAD_FAILED: - return F("send payload failed"); - case HTTPC_ERROR_NOT_CONNECTED: - return F("not connected"); - case HTTPC_ERROR_CONNECTION_LOST: - return F("connection lost"); - case HTTPC_ERROR_NO_STREAM: - return F("no stream"); - case HTTPC_ERROR_NO_HTTP_SERVER: - return F("no HTTP server"); - case HTTPC_ERROR_TOO_LESS_RAM: - return F("too less ram"); - case HTTPC_ERROR_ENCODING: - return F("Transfer-Encoding not supported"); - case HTTPC_ERROR_STREAM_WRITE: - return F("Stream write error"); - case HTTPC_ERROR_READ_TIMEOUT: - return F("read Timeout"); - default: - return String(); - } -} - -/** - * adds Header to the request - * @param name - * @param value - * @param first - */ -void HTTPClient::addHeader(const String& name, const String& value, bool first, bool replace) -{ - // not allow set of Header handled by code - if(!name.equalsIgnoreCase(F("Connection")) && - !name.equalsIgnoreCase(F("User-Agent")) && - !name.equalsIgnoreCase(F("Host")) && - !(name.equalsIgnoreCase(F("Authorization")) && _base64Authorization.length())){ - - String headerLine = name; - headerLine += ": "; - - if (replace) { - int headerStart = _headers.indexOf(headerLine); - if (headerStart != -1) { - int headerEnd = _headers.indexOf('\n', headerStart); - _headers = _headers.substring(0, headerStart) + _headers.substring(headerEnd + 1); - } - } - - headerLine += value; - headerLine += "\r\n"; - if(first) { - _headers = headerLine + _headers; - } else { - _headers += headerLine; - } - } - -} - -void HTTPClient::collectHeaders(const char* headerKeys[], const size_t headerKeysCount) -{ - _headerKeysCount = headerKeysCount; - if(_currentHeaders) { - delete[] _currentHeaders; - } - _currentHeaders = new RequestArgument[_headerKeysCount]; - for(size_t i = 0; i < _headerKeysCount; i++) { - _currentHeaders[i].key = headerKeys[i]; - } -} - -String HTTPClient::header(const char* name) -{ - for(size_t i = 0; i < _headerKeysCount; ++i) { - if(_currentHeaders[i].key == name) { - return _currentHeaders[i].value; - } - } - return String(); -} - -String HTTPClient::header(size_t i) -{ - if(i < _headerKeysCount) { - return _currentHeaders[i].value; - } - return String(); -} - -String HTTPClient::headerName(size_t i) -{ - if(i < _headerKeysCount) { - return _currentHeaders[i].key; - } - return String(); -} - -int HTTPClient::headers() -{ - return _headerKeysCount; -} - -bool HTTPClient::hasHeader(const char* name) -{ - for(size_t i = 0; i < _headerKeysCount; ++i) { - if((_currentHeaders[i].key == name) && (_currentHeaders[i].value.length() > 0)) { - return true; - } - } - return false; -} - -/** - * init TCP connection and handle ssl verify if needed - * @return true if connection is ok - */ -bool HTTPClient::connect(void) -{ - - if(connected()) { - DEBUG_HTTPCLIENT("[HTTP-Client] connect. already connected, try reuse!\n"); - while(_tcp->available() > 0) { - _tcp->read(); - } - return true; - } - - if (!_transportTraits) { - DEBUG_HTTPCLIENT("[HTTP-Client] connect: HTTPClient::begin was not called or returned error\n"); - return false; - } - - _tcp = _transportTraits->create(); - - if(!_tcp->connect(_host.c_str(), _port)) { - DEBUG_HTTPCLIENT("[HTTP-Client] failed connect to %s:%u\n", _host.c_str(), _port); - return false; - } - - DEBUG_HTTPCLIENT("[HTTP-Client] connected to %s:%u\n", _host.c_str(), _port); - - if (!_transportTraits->verify(*_tcp, _host.c_str())) { - DEBUG_HTTPCLIENT("[HTTP-Client] transport level verify failed\n"); - _tcp->stop(); - return false; - } - - // set Timeout for readBytesUntil and readStringUntil - _tcp->setTimeout(_tcpTimeout); - -#ifdef ESP8266 - _tcp->setNoDelay(true); -#endif - return connected(); -} - -/** - * sends HTTP request header - * @param type (GET, POST, ...) - * @return status - */ -bool HTTPClient::sendHeader(const char * type) -{ - if(!connected()) { - return false; - } - - String header = String(type) + " " + _uri + F(" HTTP/1."); - - if(_useHTTP10) { - header += "0"; - } else { - header += "1"; - } - - header += String(F("\r\nHost: ")) + _host; - if (_port != 80 && _port != 443) - { - header += ':'; - header += String(_port); - } - header += String(F("\r\nUser-Agent: ")) + _userAgent + - F("\r\nConnection: "); - - if(_reuse) { - header += F("keep-alive"); - } else { - header += F("close"); - } - header += "\r\n"; - - if(!_useHTTP10) { - header += F("Accept-Encoding: identity;q=1,chunked;q=0.1,*;q=0\r\n"); - } - - if(_base64Authorization.length()) { - _base64Authorization.replace("\n", ""); - header += F("Authorization: Basic "); - header += _base64Authorization; - header += "\r\n"; - } - - header += _headers + "\r\n"; - - return (_tcp->write((const uint8_t *) header.c_str(), header.length()) == header.length()); -} - -/** - * reads the response from the server - * @return int http code - */ -int HTTPClient::handleHeaderResponse() -{ - - if(!connected()) { - return HTTPC_ERROR_NOT_CONNECTED; - } - - String transferEncoding; - _returnCode = -1; - _size = -1; - _transferEncoding = HTTPC_TE_IDENTITY; - unsigned long lastDataTime = millis(); - - while(connected()) { - size_t len = _tcp->available(); - if(len > 0) { - String headerLine = _tcp->readStringUntil('\n'); - headerLine.trim(); // remove \r - - lastDataTime = millis(); - - DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] RX: '%s'\n", headerLine.c_str()); - - if(headerLine.startsWith("HTTP/1.")) { - _returnCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt(); - } else if(headerLine.indexOf(':')) { - String headerName = headerLine.substring(0, headerLine.indexOf(':')); - String headerValue = headerLine.substring(headerLine.indexOf(':') + 1); - headerValue.trim(); - - if(headerName.equalsIgnoreCase("Content-Length")) { - _size = headerValue.toInt(); - } - - if(headerName.equalsIgnoreCase("Connection")) { - _canReuse = headerValue.equalsIgnoreCase("keep-alive"); - } - - if(headerName.equalsIgnoreCase("Transfer-Encoding")) { - transferEncoding = headerValue; - } - - for(size_t i = 0; i < _headerKeysCount; i++) { - if(_currentHeaders[i].key.equalsIgnoreCase(headerName)) { - _currentHeaders[i].value = headerValue; - break; - } - } - } - - if(headerLine == "") { - DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] code: %d\n", _returnCode); - - if(_size > 0) { - DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] size: %d\n", _size); - } - - if(transferEncoding.length() > 0) { - DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] Transfer-Encoding: %s\n", transferEncoding.c_str()); - if(transferEncoding.equalsIgnoreCase("chunked")) { - _transferEncoding = HTTPC_TE_CHUNKED; - } else { - return HTTPC_ERROR_ENCODING; - } - } else { - _transferEncoding = HTTPC_TE_IDENTITY; - } - - if(_returnCode) { - return _returnCode; - } else { - DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] Remote host is not an HTTP Server!"); - return HTTPC_ERROR_NO_HTTP_SERVER; - } - } - - } else { - if((millis() - lastDataTime) > _tcpTimeout) { - return HTTPC_ERROR_READ_TIMEOUT; - } - delay(0); - } - } - - return HTTPC_ERROR_CONNECTION_LOST; -} - -/** - * write one Data Block to Stream - * @param stream Stream * - * @param size int - * @return < 0 = error >= 0 = size written - */ -int HTTPClient::writeToStreamDataBlock(Stream * stream, int size) -{ - int buff_size = HTTP_TCP_BUFFER_SIZE; - int len = size; - int bytesWritten = 0; - - // if possible create smaller buffer then HTTP_TCP_BUFFER_SIZE - if((len > 0) && (len < HTTP_TCP_BUFFER_SIZE)) { - buff_size = len; - } - - // create buffer for read - uint8_t * buff = (uint8_t *) malloc(buff_size); - - if(buff) { - // read all data from server - while(connected() && (len > 0 || len == -1)) { - - // get available data size - size_t sizeAvailable = _tcp->available(); - - if(sizeAvailable) { - - int readBytes = sizeAvailable; - - // read only the asked bytes - if(len > 0 && readBytes > len) { - readBytes = len; - } - - // not read more the buffer can handle - if(readBytes > buff_size) { - readBytes = buff_size; - } - - // read data - int bytesRead = _tcp->readBytes(buff, readBytes); - - // write it to Stream - int bytesWrite = stream->write(buff, bytesRead); - bytesWritten += bytesWrite; - - // are all Bytes a writen to stream ? - if(bytesWrite != bytesRead) { - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] short write asked for %d but got %d retry...\n", bytesRead, bytesWrite); - - // check for write error - if(stream->getWriteError()) { - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] stream write error %d\n", stream->getWriteError()); - - //reset write error for retry - stream->clearWriteError(); - } - - // some time for the stream - delay(1); - - int leftBytes = (readBytes - bytesWrite); - - // retry to send the missed bytes - bytesWrite = stream->write((buff + bytesWrite), leftBytes); - bytesWritten += bytesWrite; - - if(bytesWrite != leftBytes) { - // failed again - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStream] short write asked for %d but got %d failed.\n", leftBytes, bytesWrite); - free(buff); - return HTTPC_ERROR_STREAM_WRITE; - } - } - - // check for write error - if(stream->getWriteError()) { - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] stream write error %d\n", stream->getWriteError()); - free(buff); - return HTTPC_ERROR_STREAM_WRITE; - } - - // count bytes to read left - if(len > 0) { - len -= readBytes; - } - - delay(0); - } else { - delay(1); - } - } - - free(buff); - - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] connection closed or file end (written: %d).\n", bytesWritten); - - if((size > 0) && (size != bytesWritten)) { - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] bytesWritten %d and size %d mismatch!.\n", bytesWritten, size); - return HTTPC_ERROR_STREAM_WRITE; - } - - } else { - DEBUG_HTTPCLIENT("[HTTP-Client][writeToStreamDataBlock] too less ram! need %d\n", HTTP_TCP_BUFFER_SIZE); - return HTTPC_ERROR_TOO_LESS_RAM; - } - - return bytesWritten; -} - -/** - * called to handle error return, may disconnect the connection if still exists - * @param error - * @return error - */ -int HTTPClient::returnError(int error) -{ - if(error < 0) { - DEBUG_HTTPCLIENT("[HTTP-Client][returnError] error(%d): %s\n", error, errorToString(error).c_str()); - if(connected()) { - DEBUG_HTTPCLIENT("[HTTP-Client][returnError] tcp stop\n"); - _tcp->stop(); - } - } - return error; -} diff --git a/examples/Advanced/httpUpdate/ESP8266HTTPClient.h b/examples/Advanced/httpUpdate/ESP8266HTTPClient.h deleted file mode 100644 index f0ecab3..0000000 --- a/examples/Advanced/httpUpdate/ESP8266HTTPClient.h +++ /dev/null @@ -1,228 +0,0 @@ -/** - * ESP8266HTTPClient.h - * - * Created on: 02.11.2015 - * - * Copyright (c) 2015 Markus Sattler. All rights reserved. - * This file is part of the ESP8266HTTPClient for Arduino. - * - * This library 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 2.1 of the License, or (at your option) any later version. - * - * This library 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 this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef ESP8266HTTPClient_H_ -#define ESP8266HTTPClient_H_ - -#include -#include -#include - -#ifdef DEBUG_ESP_HTTP_CLIENT -#ifdef DEBUG_ESP_PORT -#define DEBUG_HTTPCLIENT(...) DEBUG_ESP_PORT.printf( __VA_ARGS__ ) -#endif -#endif - -#ifndef DEBUG_HTTPCLIENT -#define DEBUG_HTTPCLIENT(...) -#endif - -#define HTTPCLIENT_DEFAULT_TCP_TIMEOUT (5000) - -/// HTTP client errors -#define HTTPC_ERROR_CONNECTION_REFUSED (-1) -#define HTTPC_ERROR_SEND_HEADER_FAILED (-2) -#define HTTPC_ERROR_SEND_PAYLOAD_FAILED (-3) -#define HTTPC_ERROR_NOT_CONNECTED (-4) -#define HTTPC_ERROR_CONNECTION_LOST (-5) -#define HTTPC_ERROR_NO_STREAM (-6) -#define HTTPC_ERROR_NO_HTTP_SERVER (-7) -#define HTTPC_ERROR_TOO_LESS_RAM (-8) -#define HTTPC_ERROR_ENCODING (-9) -#define HTTPC_ERROR_STREAM_WRITE (-10) -#define HTTPC_ERROR_READ_TIMEOUT (-11) - -/// size for the stream handling -#define HTTP_TCP_BUFFER_SIZE (1460) - -/// HTTP codes see RFC7231 -typedef enum { - HTTP_CODE_CONTINUE = 100, - HTTP_CODE_SWITCHING_PROTOCOLS = 101, - HTTP_CODE_PROCESSING = 102, - HTTP_CODE_OK = 200, - HTTP_CODE_CREATED = 201, - HTTP_CODE_ACCEPTED = 202, - HTTP_CODE_NON_AUTHORITATIVE_INFORMATION = 203, - HTTP_CODE_NO_CONTENT = 204, - HTTP_CODE_RESET_CONTENT = 205, - HTTP_CODE_PARTIAL_CONTENT = 206, - HTTP_CODE_MULTI_STATUS = 207, - HTTP_CODE_ALREADY_REPORTED = 208, - HTTP_CODE_IM_USED = 226, - HTTP_CODE_MULTIPLE_CHOICES = 300, - HTTP_CODE_MOVED_PERMANENTLY = 301, - HTTP_CODE_FOUND = 302, - HTTP_CODE_SEE_OTHER = 303, - HTTP_CODE_NOT_MODIFIED = 304, - HTTP_CODE_USE_PROXY = 305, - HTTP_CODE_TEMPORARY_REDIRECT = 307, - HTTP_CODE_PERMANENT_REDIRECT = 308, - HTTP_CODE_BAD_REQUEST = 400, - HTTP_CODE_UNAUTHORIZED = 401, - HTTP_CODE_PAYMENT_REQUIRED = 402, - HTTP_CODE_FORBIDDEN = 403, - HTTP_CODE_NOT_FOUND = 404, - HTTP_CODE_METHOD_NOT_ALLOWED = 405, - HTTP_CODE_NOT_ACCEPTABLE = 406, - HTTP_CODE_PROXY_AUTHENTICATION_REQUIRED = 407, - HTTP_CODE_REQUEST_TIMEOUT = 408, - HTTP_CODE_CONFLICT = 409, - HTTP_CODE_GONE = 410, - HTTP_CODE_LENGTH_REQUIRED = 411, - HTTP_CODE_PRECONDITION_FAILED = 412, - HTTP_CODE_PAYLOAD_TOO_LARGE = 413, - HTTP_CODE_URI_TOO_LONG = 414, - HTTP_CODE_UNSUPPORTED_MEDIA_TYPE = 415, - HTTP_CODE_RANGE_NOT_SATISFIABLE = 416, - HTTP_CODE_EXPECTATION_FAILED = 417, - HTTP_CODE_MISDIRECTED_REQUEST = 421, - HTTP_CODE_UNPROCESSABLE_ENTITY = 422, - HTTP_CODE_LOCKED = 423, - HTTP_CODE_FAILED_DEPENDENCY = 424, - HTTP_CODE_UPGRADE_REQUIRED = 426, - HTTP_CODE_PRECONDITION_REQUIRED = 428, - HTTP_CODE_TOO_MANY_REQUESTS = 429, - HTTP_CODE_REQUEST_HEADER_FIELDS_TOO_LARGE = 431, - HTTP_CODE_INTERNAL_SERVER_ERROR = 500, - HTTP_CODE_NOT_IMPLEMENTED = 501, - HTTP_CODE_BAD_GATEWAY = 502, - HTTP_CODE_SERVICE_UNAVAILABLE = 503, - HTTP_CODE_GATEWAY_TIMEOUT = 504, - HTTP_CODE_HTTP_VERSION_NOT_SUPPORTED = 505, - HTTP_CODE_VARIANT_ALSO_NEGOTIATES = 506, - HTTP_CODE_INSUFFICIENT_STORAGE = 507, - HTTP_CODE_LOOP_DETECTED = 508, - HTTP_CODE_NOT_EXTENDED = 510, - HTTP_CODE_NETWORK_AUTHENTICATION_REQUIRED = 511 -} t_http_codes; - -typedef enum { - HTTPC_TE_IDENTITY, - HTTPC_TE_CHUNKED -} transferEncoding_t; - -class TransportTraits; -typedef std::unique_ptr TransportTraitsPtr; - -class HTTPClient -{ -public: - HTTPClient(); - ~HTTPClient(); - - bool begin(String url); - bool begin(String url, String httpsFingerprint); - bool begin(String host, uint16_t port, String uri = "/"); - bool begin(String host, uint16_t port, String uri, String httpsFingerprint); - // deprecated, use the overload above instead - bool begin(String host, uint16_t port, String uri, bool https, String httpsFingerprint) __attribute__ ((deprecated)); - - void end(void); - - bool connected(void); - - void setReuse(bool reuse); /// keep-alive - void setUserAgent(const String& userAgent); - void setAuthorization(const char * user, const char * password); - void setAuthorization(const char * auth); - void setTimeout(uint16_t timeout); - - void useHTTP10(bool usehttp10 = true); - - /// request handling - int GET(); - int POST(uint8_t * payload, size_t size); - int POST(String payload); - int PUT(uint8_t * payload, size_t size); - int PUT(String payload); - int sendRequest(const char * type, String payload); - int sendRequest(const char * type, uint8_t * payload = NULL, size_t size = 0); - int sendRequest(const char * type, Stream * stream, size_t size = 0); - - void addHeader(const String& name, const String& value, bool first = false, bool replace = true); - - /// Response handling - void collectHeaders(const char* headerKeys[], const size_t headerKeysCount); - String header(const char* name); // get request header value by name - String header(size_t i); // get request header value by number - String headerName(size_t i); // get request header name by number - int headers(); // get header count - bool hasHeader(const char* name); // check if header exists - - - int getSize(void); - - WiFiClient& getStream(void); - WiFiClient* getStreamPtr(void); - int writeToStream(Stream* stream); - String getString(void); - - static String errorToString(int error); - -protected: - struct RequestArgument { - String key; - String value; - }; - - bool beginInternal(String url, const char* expectedProtocol); - void clear(); - int returnError(int error); - bool connect(void); - bool sendHeader(const char * type); - int handleHeaderResponse(); - int writeToStreamDataBlock(Stream * stream, int len); - - - TransportTraitsPtr _transportTraits; - std::unique_ptr _tcp; - - /// request handling - String _host; - uint16_t _port = 0; - bool _reuse = false; - uint16_t _tcpTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT; - bool _useHTTP10 = false; - - String _uri; - String _protocol; - String _headers; - String _userAgent = "ESP8266HTTPClient"; - String _base64Authorization; - - /// Response handling - RequestArgument* _currentHeaders = nullptr; - size_t _headerKeysCount = 0; - - int _returnCode = 0; - int _size = -1; - bool _canReuse = false; - transferEncoding_t _transferEncoding = HTTPC_TE_IDENTITY; -}; - - - -#endif /* ESP8266HTTPClient_H_ */ diff --git a/examples/Advanced/httpUpdate/ESP8266httpUpdate.cpp b/examples/Advanced/httpUpdate/ESP8266httpUpdate.cpp deleted file mode 100644 index a7a83af..0000000 --- a/examples/Advanced/httpUpdate/ESP8266httpUpdate.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/** - * - * @file ESP8266HTTPUpdate.cpp - * @date 21.06.2015 - * @author Markus Sattler - * - * Copyright (c) 2015 Markus Sattler. All rights reserved. - * This file is part of the ESP8266 Http Updater. - * - * This library 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 2.1 of the License, or (at your option) any later version. - * - * This library 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 this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "ESP8266httpUpdate.h" -#include - -// extern "C" uint32_t _SPIFFS_start; -// extern "C" uint32_t _SPIFFS_end; - -ESP8266HTTPUpdate::ESP8266HTTPUpdate(void) -{ -} - -ESP8266HTTPUpdate::~ESP8266HTTPUpdate(void) -{ -} - -HTTPUpdateResult ESP8266HTTPUpdate::update(const String& url, const String& currentVersion, - const String& httpsFingerprint, bool reboot) -{ - rebootOnUpdate(reboot); - return update(url, currentVersion, httpsFingerprint); -} - -HTTPUpdateResult ESP8266HTTPUpdate::update(const String& url, const String& currentVersion) -{ - HTTPClient http; - http.begin(url); - return handleUpdate(http, currentVersion, false); -} - -HTTPUpdateResult ESP8266HTTPUpdate::update(const String& url, const String& currentVersion, - const String& httpsFingerprint) -{ - HTTPClient http; - http.begin(url, httpsFingerprint); - return handleUpdate(http, currentVersion, false); -} - -HTTPUpdateResult ESP8266HTTPUpdate::updateSpiffs(const String& url, const String& currentVersion, const String& httpsFingerprint) -{ - HTTPClient http; - http.begin(url, httpsFingerprint); - return handleUpdate(http, currentVersion, true); -} - -HTTPUpdateResult ESP8266HTTPUpdate::updateSpiffs(const String& url, const String& currentVersion) -{ - HTTPClient http; - http.begin(url); - return handleUpdate(http, currentVersion, true); -} - -HTTPUpdateResult ESP8266HTTPUpdate::update(const String& host, uint16_t port, const String& uri, const String& currentVersion, - bool https, const String& httpsFingerprint, bool reboot) -{ - rebootOnUpdate(reboot); - if (httpsFingerprint.length() == 0) { - return update(host, port, uri, currentVersion); - } else { - return update(host, port, uri, currentVersion, httpsFingerprint); - } -} - -HTTPUpdateResult ESP8266HTTPUpdate::update(const String& host, uint16_t port, const String& uri, - const String& currentVersion) -{ - HTTPClient http; - http.begin(host, port, uri); - return handleUpdate(http, currentVersion, false); -} -HTTPUpdateResult ESP8266HTTPUpdate::update(const String& host, uint16_t port, const String& url, - const String& currentVersion, const String& httpsFingerprint) -{ - HTTPClient http; - http.begin(host, port, url, httpsFingerprint); - return handleUpdate(http, currentVersion, false); - -} - -/** - * return error code as int - * @return int error code - */ -int ESP8266HTTPUpdate::getLastError(void) -{ - return _lastError; -} - -/** - * return error code as String - * @return String error - */ -String ESP8266HTTPUpdate::getLastErrorString(void) -{ - - if(_lastError == 0) { - return String(); // no error - } - - // error from Update class - if(_lastError > 0) { - StreamString error; - Update.printError(error); - error.trim(); // remove line ending - return String(F("Update error: ")) + error; - } - - // error from http client - if(_lastError > -100) { - return String(F("HTTP error: ")) + HTTPClient::errorToString(_lastError); - } - - switch(_lastError) { - case HTTP_UE_TOO_LESS_SPACE: - return F("To less space"); - case HTTP_UE_SERVER_NOT_REPORT_SIZE: - return F("Server not Report Size"); - case HTTP_UE_SERVER_FILE_NOT_FOUND: - return F("File not Found (404)"); - case HTTP_UE_SERVER_FORBIDDEN: - return F("Forbidden (403)"); - case HTTP_UE_SERVER_WRONG_HTTP_CODE: - return F("Wrong HTTP code"); - case HTTP_UE_SERVER_FAULTY_MD5: - return F("Faulty MD5"); - case HTTP_UE_BIN_VERIFY_HEADER_FAILED: - return F("Verify bin header failed"); - case HTTP_UE_BIN_FOR_WRONG_FLASH: - return F("bin for wrong flash size"); - } - - return String(); -} - - -/** - * - * @param http HTTPClient * - * @param currentVersion const char * - * @return HTTPUpdateResult - */ -HTTPUpdateResult ESP8266HTTPUpdate::handleUpdate(HTTPClient& http, const String& currentVersion, bool spiffs) -{ - - HTTPUpdateResult ret = HTTP_UPDATE_FAILED; - - // use HTTP/1.0 for update since the update handler not support any transfer Encoding - http.useHTTP10(true); - http.setTimeout(8000); - http.setUserAgent(F("ESP8266-http-Update")); - // http.addHeader(F("x-ESP8266-STA-MAC"), WiFi.macAddress()); - // http.addHeader(F("x-ESP8266-AP-MAC"), WiFi.softAPmacAddress()); - // http.addHeader(F("x-ESP8266-free-space"), String(ESP.getFreeSketchSpace())); - // http.addHeader(F("x-ESP8266-sketch-size"), String(ESP.getSketchSize())); - // http.addHeader(F("x-ESP8266-sketch-md5"), String(ESP.getSketchMD5())); - // http.addHeader(F("x-ESP8266-chip-size"), String(ESP.getFlashChipRealSize())); - // http.addHeader(F("x-ESP8266-sdk-version"), ESP.getSdkVersion()); - - if(spiffs) { - http.addHeader(F("x-ESP8266-mode"), F("spiffs")); - } else { - http.addHeader(F("x-ESP8266-mode"), F("sketch")); - } - - if(currentVersion && currentVersion[0] != 0x00) { - http.addHeader(F("x-ESP8266-version"), currentVersion); - } - - const char * headerkeys[] = { "x-MD5" }; - size_t headerkeyssize = sizeof(headerkeys) / sizeof(char*); - - // track these headers - http.collectHeaders(headerkeys, headerkeyssize); - - int code = http.GET(); - int len = http.getSize(); - - if(code <= 0) { - DEBUG_HTTP_UPDATE("[httpUpdate] HTTP error: %s\n", http.errorToString(code).c_str()); - _lastError = code; - http.end(); - return HTTP_UPDATE_FAILED; - } - - DEBUG_HTTP_UPDATE("[httpUpdate] Header read fin.\n"); - DEBUG_HTTP_UPDATE("[httpUpdate] Server header:\n"); - DEBUG_HTTP_UPDATE("[httpUpdate] - code: %d\n", code); - DEBUG_HTTP_UPDATE("[httpUpdate] - len: %d\n", len); - - if(http.hasHeader("x-MD5")) { - DEBUG_HTTP_UPDATE("[httpUpdate] - MD5: %s\n", http.header("x-MD5").c_str()); - } - - DEBUG_HTTP_UPDATE("[httpUpdate] ESP8266 info:\n"); - DEBUG_HTTP_UPDATE("[httpUpdate] - free Space: %d\n", ESP.getFreeSketchSpace()); - DEBUG_HTTP_UPDATE("[httpUpdate] - current Sketch Size: %d\n", ESP.getSketchSize()); - - if(currentVersion && currentVersion[0] != 0x00) { - DEBUG_HTTP_UPDATE("[httpUpdate] - current version: %s\n", currentVersion.c_str() ); - } - - switch(code) { - case HTTP_CODE_OK: ///< OK (Start Update) - if(len > 0) { - bool startUpdate = true; - // if(spiffs) { - // size_t spiffsSize = ((size_t) &_SPIFFS_end - (size_t) &_SPIFFS_start); - // if(len > (int) spiffsSize) { - // DEBUG_HTTP_UPDATE("[httpUpdate] spiffsSize to low (%d) needed: %d\n", spiffsSize, len); - // startUpdate = false; - // } - // } else { - // if(0/*len > (int) ESP.getFreeSketchSpace()*/) { - // // DEBUG_HTTP_UPDATE("[httpUpdate] FreeSketchSpace to low (%d) needed: %d\n", ESP.getFreeSketchSpace(), len); - // startUpdate = false; - // } - // } - - if(!startUpdate) { - _lastError = HTTP_UE_TOO_LESS_SPACE; - ret = HTTP_UPDATE_FAILED; - } else { - - WiFiClient * tcp = http.getStreamPtr(); - - // WiFiUDP::stop(); - // WiFiClient::stopAllExcept(tcp); - - delay(100); - - int command; - - if(spiffs) { - command = U_SPIFFS; - DEBUG_HTTP_UPDATE("[httpUpdate] runUpdate spiffs...\n"); - } else { - command = U_FLASH; - DEBUG_HTTP_UPDATE("[httpUpdate] runUpdate flash...\n"); - Serial.print("[httpUpdate] runUpdate flash...\n"); - } - - // if(!spiffs) { - // uint8_t buf[4]; - // if(tcp->peekBytes(&buf[0], 4) != 4) { - // DEBUG_HTTP_UPDATE("[httpUpdate] peekBytes magic header failed\n"); - // _lastError = HTTP_UE_BIN_VERIFY_HEADER_FAILED; - // http.end(); - // return HTTP_UPDATE_FAILED; - // } - - // check for valid first magic byte - // if(buf[0] != 0xE9) { - // DEBUG_HTTP_UPDATE("[httpUpdate] magic header not starts with 0xE9\n"); - // _lastError = HTTP_UE_BIN_VERIFY_HEADER_FAILED; - // http.end(); - // return HTTP_UPDATE_FAILED; - // } - - // uint32_t bin_flash_size = ESP.magicFlashChipSize((buf[3] & 0xf0) >> 4); - - // check if new bin fits to SPI flash - // if(bin_flash_size > ESP.getFlashChipRealSize()) { - // DEBUG_HTTP_UPDATE("[httpUpdate] magic header, new bin not fits SPI Flash\n"); - // _lastError = HTTP_UE_BIN_FOR_WRONG_FLASH; - // http.end(); - // return HTTP_UPDATE_FAILED; - // } - // } - - if(runUpdate(*tcp, len, http.header("x-MD5"), command)) { - ret = HTTP_UPDATE_OK; - DEBUG_HTTP_UPDATE("[httpUpdate] Update ok\n"); - Serial.print("[httpUpdate] Update ok\n"); - http.end(); - - if(_rebootOnUpdate && !spiffs) { - ESP.restart(); - } - - } else { - ret = HTTP_UPDATE_FAILED; - DEBUG_HTTP_UPDATE("[httpUpdate] Update failed\n"); - } - } - } else { - _lastError = HTTP_UE_SERVER_NOT_REPORT_SIZE; - ret = HTTP_UPDATE_FAILED; - DEBUG_HTTP_UPDATE("[httpUpdate] Content-Length is 0 or not set by Server?!\n"); - } - break; - case HTTP_CODE_NOT_MODIFIED: - ///< Not Modified (No updates) - ret = HTTP_UPDATE_NO_UPDATES; - break; - case HTTP_CODE_NOT_FOUND: - _lastError = HTTP_UE_SERVER_FILE_NOT_FOUND; - ret = HTTP_UPDATE_FAILED; - break; - case HTTP_CODE_FORBIDDEN: - _lastError = HTTP_UE_SERVER_FORBIDDEN; - ret = HTTP_UPDATE_FAILED; - break; - default: - _lastError = HTTP_UE_SERVER_WRONG_HTTP_CODE; - ret = HTTP_UPDATE_FAILED; - DEBUG_HTTP_UPDATE("[httpUpdate] HTTP Code is (%d)\n", code); - //http.writeToStream(&Serial1); - break; - } - - http.end(); - return ret; -} - -/** - * write Update to flash - * @param in Stream& - * @param size uint32_t - * @param md5 String - * @return true if Update ok - */ -bool ESP8266HTTPUpdate::runUpdate(Stream& in, uint32_t size, String md5, int command) -{ - - StreamString error; - - if(!Update.begin(size, command)) { - _lastError = Update.getError(); - Update.printError(error); - error.trim(); // remove line ending - DEBUG_HTTP_UPDATE("[httpUpdate] Update.begin failed! (%s)\n", error.c_str()); - Serial.printf("[httpUpdate] Update.begin failed! (%s)\n", error.c_str()); - return false; - } - - if(md5.length()) { - if(!Update.setMD5(md5.c_str())) { - _lastError = HTTP_UE_SERVER_FAULTY_MD5; - DEBUG_HTTP_UPDATE("[httpUpdate] Update.setMD5 failed! (%s)\n", md5.c_str()); - Serial.printf("[httpUpdate] Update.setMD5 failed! (%s)\n", md5.c_str()); - return false; - } - } - - if(Update.writeStream(in) != size) { - _lastError = Update.getError(); - Update.printError(error); - error.trim(); // remove line ending - DEBUG_HTTP_UPDATE("[httpUpdate] Update.writeStream failed! (%s)\n", error.c_str()); - Serial.printf("[httpUpdate] Update.writeStream failed! (%s)\n", error.c_str()); - return false; - } - - if(!Update.end()) { - _lastError = Update.getError(); - Update.printError(error); - error.trim(); // remove line ending - DEBUG_HTTP_UPDATE("[httpUpdate] Update.end failed! (%s)\n", error.c_str()); - Serial.printf("[httpUpdate] Update.end failed! (%s)\n", error.c_str()); - return false; - } - - return true; -} - -#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_HTTPUPDATE) -ESP8266HTTPUpdate ESPhttpUpdate; -#endif diff --git a/examples/Advanced/httpUpdate/ESP8266httpUpdate.h b/examples/Advanced/httpUpdate/ESP8266httpUpdate.h deleted file mode 100644 index 0f9b1f8..0000000 --- a/examples/Advanced/httpUpdate/ESP8266httpUpdate.h +++ /dev/null @@ -1,116 +0,0 @@ -/** - * - * @file ESP8266HTTPUpdate.h - * @date 21.06.2015 - * @author Markus Sattler - * - * Copyright (c) 2015 Markus Sattler. All rights reserved. - * This file is part of the ESP8266 Http Updater. - * - * This library 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 2.1 of the License, or (at your option) any later version. - * - * This library 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 this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifndef ESP8266HTTPUPDATE_H_ -#define ESP8266HTTPUPDATE_H_ - -#include -#include -#include -#include "ESP8266HTTPClient.h" -#include "Update.h" -#include "WiFiUdp.h" - - -#define DEBUG_ESP_HTTP_UPDATE - -#ifdef DEBUG_ESP_HTTP_UPDATE -#ifdef DEBUG_ESP_PORT -#define DEBUG_HTTP_UPDATE(...) DEBUG_ESP_PORT.printf( __VA_ARGS__ ) -#endif -#endif - -#ifndef DEBUG_HTTP_UPDATE -#define DEBUG_HTTP_UPDATE(...) -#endif - -/// note we use HTTP client errors too so we start at 100 -#define HTTP_UE_TOO_LESS_SPACE (-100) -#define HTTP_UE_SERVER_NOT_REPORT_SIZE (-101) -#define HTTP_UE_SERVER_FILE_NOT_FOUND (-102) -#define HTTP_UE_SERVER_FORBIDDEN (-103) -#define HTTP_UE_SERVER_WRONG_HTTP_CODE (-104) -#define HTTP_UE_SERVER_FAULTY_MD5 (-105) -#define HTTP_UE_BIN_VERIFY_HEADER_FAILED (-106) -#define HTTP_UE_BIN_FOR_WRONG_FLASH (-107) - -enum HTTPUpdateResult { - HTTP_UPDATE_FAILED, - HTTP_UPDATE_NO_UPDATES, - HTTP_UPDATE_OK -}; - -typedef HTTPUpdateResult t_httpUpdate_return; // backward compatibility - -class ESP8266HTTPUpdate -{ -public: - ESP8266HTTPUpdate(void); - ~ESP8266HTTPUpdate(void); - - void rebootOnUpdate(bool reboot) - { - _rebootOnUpdate = reboot; - } - - // This function is deprecated, use rebootOnUpdate and the next one instead - t_httpUpdate_return update(const String& url, const String& currentVersion, - const String& httpsFingerprint, bool reboot) __attribute__((deprecated)); - t_httpUpdate_return update(const String& url, const String& currentVersion = ""); - t_httpUpdate_return update(const String& url, const String& currentVersion, - const String& httpsFingerprint); - - // This function is deprecated, use one of the overloads below along with rebootOnUpdate - t_httpUpdate_return update(const String& host, uint16_t port, const String& uri, const String& currentVersion, - bool https, const String& httpsFingerprint, bool reboot) __attribute__((deprecated)); - - t_httpUpdate_return update(const String& host, uint16_t port, const String& uri = "/", - const String& currentVersion = ""); - t_httpUpdate_return update(const String& host, uint16_t port, const String& url, - const String& currentVersion, const String& httpsFingerprint); - - // This function is deprecated, use rebootOnUpdate and the next one instead - t_httpUpdate_return updateSpiffs(const String& url, const String& currentVersion, - const String& httpsFingerprint, bool reboot) __attribute__((deprecated)); - t_httpUpdate_return updateSpiffs(const String& url, const String& currentVersion = ""); - t_httpUpdate_return updateSpiffs(const String& url, const String& currentVersion, const String& httpsFingerprint); - - - int getLastError(void); - String getLastErrorString(void); - -protected: - t_httpUpdate_return handleUpdate(HTTPClient& http, const String& currentVersion, bool spiffs = false); - bool runUpdate(Stream& in, uint32_t size, String md5, int command = U_FLASH); - - int _lastError; - bool _rebootOnUpdate = true; -}; - -#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_HTTPUPDATE) -extern ESP8266HTTPUpdate ESPhttpUpdate; -#endif - -#endif /* ESP8266HTTPUPDATE_H_ */ diff --git a/examples/Advanced/httpUpdate/Update.h b/examples/Advanced/httpUpdate/Update.h deleted file mode 100644 index 6f733d4..0000000 --- a/examples/Advanced/httpUpdate/Update.h +++ /dev/null @@ -1,161 +0,0 @@ -#ifndef ESP8266UPDATER_H -#define ESP8266UPDATER_H - -#include -#include -#include "esp_partition.h" - -#define UPDATE_ERROR_OK (0) -#define UPDATE_ERROR_WRITE (1) -#define UPDATE_ERROR_ERASE (2) -#define UPDATE_ERROR_READ (3) -#define UPDATE_ERROR_SPACE (4) -#define UPDATE_ERROR_SIZE (5) -#define UPDATE_ERROR_STREAM (6) -#define UPDATE_ERROR_MD5 (7) -#define UPDATE_ERROR_MAGIC_BYTE (8) -#define UPDATE_ERROR_ACTIVATE (9) -#define UPDATE_ERROR_NO_PARTITION (10) -#define UPDATE_ERROR_BAD_ARGUMENT (11) -#define UPDATE_ERROR_ABORT (12) - -#define UPDATE_SIZE_UNKNOWN 0xFFFFFFFF - -#define U_FLASH 0 -#define U_SPIFFS 100 -#define U_AUTH 200 - -class UpdateClass { - public: - UpdateClass(); - /* - Call this to check the space needed for the update - Will return false if there is not enough space - */ - bool begin(size_t size=UPDATE_SIZE_UNKNOWN, int command = U_FLASH); - - /* - Writes a buffer to the flash and increments the address - Returns the amount written - */ - size_t write(uint8_t *data, size_t len); - - /* - Writes the remaining bytes from the Stream to the flash - Uses readBytes() and sets UPDATE_ERROR_STREAM on timeout - Returns the bytes written - Should be equal to the remaining bytes when called - Usable for slow streams like Serial - */ - size_t writeStream(Stream &data); - - /* - If all bytes are written - this call will write the config to eboot - and return true - If there is already an update running but is not finished and !evenIfRemainanig - or there is an error - this will clear everything and return false - the last error is available through getError() - evenIfRemaining is helpfull when you update without knowing the final size first - */ - bool end(bool evenIfRemaining = false); - - /* - Aborts the running update - */ - void abort(); - - /* - Prints the last error to an output stream - */ - void printError(Stream &out); - - /* - sets the expected MD5 for the firmware (hexString) - */ - bool setMD5(const char * expected_md5); - - /* - returns the MD5 String of the sucessfully ended firmware - */ - String md5String(void){ return _md5.toString(); } - - /* - populated the result with the md5 bytes of the sucessfully ended firmware - */ - void md5(uint8_t * result){ return _md5.getBytes(result); } - - //Helpers - uint8_t getError(){ return _error; } - void clearError(){ _error = UPDATE_ERROR_OK; } - bool hasError(){ return _error != UPDATE_ERROR_OK; } - bool isRunning(){ return _size > 0; } - bool isFinished(){ return _progress == _size; } - size_t size(){ return _size; } - size_t progress(){ return _progress; } - size_t remaining(){ return _size - _progress; } - - /* - Template to write from objects that expose - available() and read(uint8_t*, size_t) methods - faster than the writeStream method - writes only what is available - */ - template - size_t write(T &data){ - size_t written = 0; - if (hasError() || !isRunning()) - return 0; - - size_t available = data.available(); - while(available) { - if(_bufferLen + available > remaining()){ - available = remaining() - _bufferLen; - } - if(_bufferLen + available > 4096) { - size_t toBuff = 4096 - _bufferLen; - data.read(_buffer + _bufferLen, toBuff); - _bufferLen += toBuff; - if(!_writeBuffer()) - return written; - written += toBuff; - } else { - data.read(_buffer + _bufferLen, available); - _bufferLen += available; - written += available; - if(_bufferLen == remaining()) { - if(!_writeBuffer()) { - return written; - } - } - } - if(remaining() == 0) - return written; - available = data.available(); - } - return written; - } - - private: - void _reset(); - void _abort(uint8_t err); - bool _writeBuffer(); - bool _verifyHeader(uint8_t data); - bool _verifyEnd(); - - uint8_t _error; - uint8_t *_buffer; - size_t _bufferLen; - size_t _size; - uint32_t _progress; - uint32_t _command; - const esp_partition_t* _partition; - - String _target_md5; - MD5Builder _md5; -}; - -extern UpdateClass Update; - -#endif diff --git a/examples/Advanced/httpUpdate/Updater.cpp b/examples/Advanced/httpUpdate/Updater.cpp deleted file mode 100644 index 1ff4b26..0000000 --- a/examples/Advanced/httpUpdate/Updater.cpp +++ /dev/null @@ -1,279 +0,0 @@ -#include "Update.h" -#include "Arduino.h" -#include "esp_spi_flash.h" -#include "esp_ota_ops.h" -#include "esp_image_format.h" - -static const char * _err2str(uint8_t _error){ - if(_error == UPDATE_ERROR_OK){ - return ("No Error"); - } else if(_error == UPDATE_ERROR_WRITE){ - return ("Flash Write Failed"); - } else if(_error == UPDATE_ERROR_ERASE){ - return ("Flash Erase Failed"); - } else if(_error == UPDATE_ERROR_READ){ - return ("Flash Read Failed"); - } else if(_error == UPDATE_ERROR_SPACE){ - return ("Not Enough Space"); - } else if(_error == UPDATE_ERROR_SIZE){ - return ("Bad Size Given"); - } else if(_error == UPDATE_ERROR_STREAM){ - return ("Stream Read Timeout"); - } else if(_error == UPDATE_ERROR_MD5){ - return ("MD5 Check Failed"); - } else if(_error == UPDATE_ERROR_MAGIC_BYTE){ - return ("Wrong Magic Byte"); - } else if(_error == UPDATE_ERROR_ACTIVATE){ - return ("Could Not Activate The Firmware"); - } else if(_error == UPDATE_ERROR_NO_PARTITION){ - return ("Partition Could Not be Found"); - } else if(_error == UPDATE_ERROR_BAD_ARGUMENT){ - return ("Bad Argument"); - } else if(_error == UPDATE_ERROR_ABORT){ - return ("Aborted"); - } - return ("UNKNOWN"); -} - -UpdateClass::UpdateClass() -: _error(0) -, _buffer(0) -, _bufferLen(0) -, _size(0) -, _progress(0) -, _command(U_FLASH) -, _partition(NULL) -{ -} - -void UpdateClass::_reset() { - if (_buffer) - delete[] _buffer; - _buffer = 0; - _bufferLen = 0; - _progress = 0; - _size = 0; - _command = U_FLASH; -} - -bool UpdateClass::begin(size_t size, int command) { - if(_size > 0){ - log_w("already running"); - return false; - } - - _reset(); - _error = 0; - - if(size == 0) { - _error = UPDATE_ERROR_SIZE; - return false; - } - - if (command == U_FLASH) { - _partition = esp_ota_get_next_update_partition(NULL); - if(!_partition){ - _error = UPDATE_ERROR_NO_PARTITION; - return false; - } - log_d("OTA Partition: %s", _partition->label); - } - else if (command == U_SPIFFS) { - _partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, NULL); - if(!_partition){ - _error = UPDATE_ERROR_NO_PARTITION; - return false; - } - } - else { - _error = UPDATE_ERROR_BAD_ARGUMENT; - log_e("bad command %u", command); - return false; - } - - if(size == UPDATE_SIZE_UNKNOWN){ - size = _partition->size; - } else if(size > _partition->size){ - _error = UPDATE_ERROR_SIZE; - log_e("too large %u > %u", size, _partition->size); - return false; - } - - //initialize - _buffer = (uint8_t*)malloc(SPI_FLASH_SEC_SIZE); - if(!_buffer){ - log_e("malloc failed"); - return false; - } - _size = size; - _command = command; - _md5.begin(); - return true; -} - -void UpdateClass::_abort(uint8_t err){ - _reset(); - _error = err; -} - -void UpdateClass::abort(){ - _abort(UPDATE_ERROR_ABORT); -} - -bool UpdateClass::_writeBuffer(){ - if(!ESP.flashEraseSector((_partition->address + _progress)/SPI_FLASH_SEC_SIZE)){ - _abort(UPDATE_ERROR_ERASE); - return false; - } - if (!ESP.flashWrite(_partition->address + _progress, (uint32_t*)_buffer, _bufferLen)) { - _abort(UPDATE_ERROR_WRITE); - return false; - } - _md5.add(_buffer, _bufferLen); - _progress += _bufferLen; - _bufferLen = 0; - return true; -} - -bool UpdateClass::_verifyHeader(uint8_t data) { - if(_command == U_FLASH) { - if(data != ESP_IMAGE_HEADER_MAGIC) { - _abort(UPDATE_ERROR_MAGIC_BYTE); - return false; - } - return true; - } else if(_command == U_SPIFFS) { - return true; - } - return false; -} - -bool UpdateClass::_verifyEnd() { - if(_command == U_FLASH) { - uint8_t buf[4]; - if(!ESP.flashRead(_partition->address, (uint32_t*)buf, 4)) { - _abort(UPDATE_ERROR_READ); - return false; - } - - if(buf[0] != ESP_IMAGE_HEADER_MAGIC) { - _abort(UPDATE_ERROR_MAGIC_BYTE); - return false; - } - - if(esp_ota_set_boot_partition(_partition)){ - _abort(UPDATE_ERROR_ACTIVATE); - return false; - } - _reset(); - return true; - } else if(_command == U_SPIFFS) { - return true; - } - return false; -} - -bool UpdateClass::setMD5(const char * expected_md5){ - if(strlen(expected_md5) != 32) - { - return false; - } - _target_md5 = expected_md5; - return true; -} - -bool UpdateClass::end(bool evenIfRemaining){ - if(hasError() || _size == 0){ - return false; - } - - if(!isFinished() && !evenIfRemaining){ - log_e("premature end: res:%u, pos:%u/%u\n", getError(), progress(), _size); - _abort(UPDATE_ERROR_ABORT); - return false; - } - - if(evenIfRemaining) { - if(_bufferLen > 0) { - _writeBuffer(); - } - _size = progress(); - } - - _md5.calculate(); - if(_target_md5.length()) { - if(_target_md5 != _md5.toString()){ - _abort(UPDATE_ERROR_MD5); - return false; - } - } - - return _verifyEnd(); -} - -size_t UpdateClass::write(uint8_t *data, size_t len) { - if(hasError() || !isRunning()){ - return 0; - } - - if(len > remaining()){ - _abort(UPDATE_ERROR_SPACE); - return 0; - } - - size_t left = len; - - while((_bufferLen + left) > SPI_FLASH_SEC_SIZE) { - size_t toBuff = SPI_FLASH_SEC_SIZE - _bufferLen; - memcpy(_buffer + _bufferLen, data + (len - left), toBuff); - _bufferLen += toBuff; - if(!_writeBuffer()){ - return len - left; - } - left -= toBuff; - } - memcpy(_buffer + _bufferLen, data + (len - left), left); - _bufferLen += left; - if(_bufferLen == remaining()){ - if(!_writeBuffer()){ - return len - left; - } - } - return len; -} - -size_t UpdateClass::writeStream(Stream &data) { - size_t written = 0; - size_t toRead = 0; - if(hasError() || !isRunning()) - return 0; - - // if(!_verifyHeader(data.peek())) { - // Serial.print("_reset\r\n"); - // _reset(); - // return 0; - // } - - while(remaining()) { - toRead = data.readBytes(_buffer + _bufferLen, (SPI_FLASH_SEC_SIZE - _bufferLen)); - if(toRead == 0) { //Timeout - delay(100); - toRead = data.readBytes(_buffer + _bufferLen, (SPI_FLASH_SEC_SIZE - _bufferLen)); - if(toRead == 0) { //Timeout - _abort(UPDATE_ERROR_STREAM); - return written; - } - } - _bufferLen += toRead; - if((_bufferLen == remaining() || _bufferLen == SPI_FLASH_SEC_SIZE) && !_writeBuffer()) - return written; - written += toRead; - } - return written; -} - -void UpdateClass::printError(Stream &out){ - out.println(_err2str(_error)); -} - -UpdateClass Update; diff --git a/examples/Advanced/httpUpdate/httpUpdate.ino b/examples/Advanced/httpUpdate/httpUpdate.ino deleted file mode 100644 index f636121..0000000 --- a/examples/Advanced/httpUpdate/httpUpdate.ino +++ /dev/null @@ -1,80 +0,0 @@ -/** - * httpUpdate.ino - * - * Created on: 27.11.2015 - * - */ - -#include - -#include -#include - -#include "ESP8266HTTPClient.h" -#include "ESP8266httpUpdate.h" -#include - -#define USE_SERIAL Serial - -WiFiMulti wifiMulti; - -void setup() { - - USE_SERIAL.begin(115200); - // USE_SERIAL.setDebugOutput(true); - - USE_SERIAL.println(); - USE_SERIAL.println(); - USE_SERIAL.println(); - // Serial.print("update success!\r\n"); - - for(uint8_t t = 4; t > 0; t--) { - USE_SERIAL.printf("[SETUP] WAIT %d...\n", t); - USE_SERIAL.flush(); - delay(100); - } - - WiFi.begin("MasterHax_2.4G", "wittyercheese551"); - while (WiFi.status() != WL_CONNECTED) { - delay(500); - Serial.print("."); - } - - Serial.println(""); - Serial.println("WiFi connected"); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - - // wifiMulti.addAP("MasterHax_2.4G", "wittyercheese551"); - // Serial.println("Connecting Wifi..."); - // if(wifiMulti.run() == WL_CONNECTED) { - // Serial.println(""); - // Serial.println("WiFi connected"); - // Serial.println("IP address: "); - // Serial.println(WiFi.localIP()); - // } -} - -void loop() { - // wait for WiFi connection - // if((wifiMulti.run() == WL_CONNECTED)) { - if(1) { - Serial.printf("connect...\n"); - t_httpUpdate_return ret = ESPhttpUpdate.update("http://olcunuug8.bkt.clouddn.com/httpUpdate.ino.esp32.bin"); - //t_httpUpdate_return ret = ESPhttpUpdate.update("https://server/file.bin"); - - switch(ret) { - case HTTP_UPDATE_FAILED: - USE_SERIAL.printf("HTTP_UPDATE_FAILD Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); - break; - - case HTTP_UPDATE_NO_UPDATES: - USE_SERIAL.println("HTTP_UPDATE_NO_UPDATES"); - break; - - case HTTP_UPDATE_OK: - USE_SERIAL.println("HTTP_UPDATE_OK"); - break; - } - } -} diff --git a/examples/Advanced/httpUpdate/httpUpdate.ino.esp32.bin b/examples/Advanced/httpUpdate/httpUpdate.ino.esp32.bin deleted file mode 100644 index a3f6ed1..0000000 Binary files a/examples/Advanced/httpUpdate/httpUpdate.ino.esp32.bin and /dev/null differ diff --git a/examples/Advanced/matrix-serial-draw/matrix-serial-draw.ino b/examples/Advanced/matrix-serial-draw/matrix-serial-draw.ino deleted file mode 100644 index 8980418..0000000 --- a/examples/Advanced/matrix-serial-draw/matrix-serial-draw.ino +++ /dev/null @@ -1,305 +0,0 @@ -#include -#include "matrix_rgb.h" -#include -#include //The DHT12 uses I2C comunication. - -HardwareSerial Serial2(2); -MATRIX_RGB matrix; -DHT12 dht12; //Preset scale CELSIUS and ID 0x5c. - - -/*************************************************** - This is our GFX example for the Adafruit ILI9341 Breakout and Shield - ----> http://www.adafruit.com/products/1651 - - Check out the links above for our tutorials and wiring diagrams - These displays use SPI to communicate, 4 or 5 pins are required to - interface (RST is optional) - Adafruit invests time and resources providing this open source code, - please support Adafruit and open-source hardware by purchasing - products from Adafruit! - - Written by Limor Fried/Ladyada for Adafruit Industries. - MIT license, all text above must be included in any redistribution - ****************************************************/ - -// void updateEnvLCD(float tmp, float humidty, float pressure, float light) { - void updateEnvLCD(float tmp, float humidty) { - - // m5.lcd.setFont(&FreeMonoBoldOblique12pt7b); - // m5.lcd.fillScreen(WHITE); - m5.lcd.setFont(&FreeSansOblique9pt7b); - m5.lcd.setTextSize(1); - m5.lcd.setTextColor(BLACK); - - //tmp - m5.lcd.fillRect(10, 51, 38, 28, WHITE); - m5.lcd.setCursor(18, 72); - m5.lcd.printf("%0.0f", tmp); - - //humidty - m5.lcd.fillRect(83, 51, 38, 28, WHITE); - m5.lcd.setCursor(88, 72); - m5.lcd.printf("%0.0f", humidty); - - // //pressure - // m5.lcd.fillRect(152, 51, 38, 28, WHITE); - // m5.lcd.setCursor(153, 72); - // m5.lcd.printf("%0.0f", pressure); - - // //light - // m5.lcd.fillRect(10, 110, 42, 28, WHITE); - // m5.lcd.setCursor(13, 130); - // m5.lcd.printf("%3.0f", light); -} - -void setup() { - // Serial2.begin(9600); - // Serial2.println("ILI9341 Test!"); - Serial.begin(74880); - // Serial.begin(250000); - Serial2.begin(115200); - m5.begin(); - Wire.begin(); - matrix.begin(); - // tft.begin(); - - // testFillScreen(); - // tft.fillScreen(ILI9341_GREEN); - matrix.fillScreen(ILI9341_BLACK); - // testText(); - - - - // testCircles(5, ILI9341_GREEN); - // draw a pixel in solid white - matrix.drawPixel(0, 0, matrix.Color333(7, 7, 7)); - delay(500); - - // fix the screen with green - matrix.fillRect(0, 0, matrix.width(), matrix.height(), matrix.Color333(0, 7, 0)); - delay(500); - - // draw a box in yellow - matrix.drawRect(0, 0, matrix.width(), matrix.height(), matrix.Color333(7, 7, 0)); - delay(500); - - // draw an 'X' in red - matrix.drawLine(0, 0, matrix.width()-1, matrix.height()-1, matrix.Color333(7, 0, 0)); - matrix.drawLine(matrix.width()-1, 0, 0, matrix.height()-1, matrix.Color333(7, 0, 0)); - delay(500); - - // draw a blue circle - matrix.drawCircle(10, 10, 10, matrix.Color333(0, 0, 7)); - delay(500); - - // fill a violet circle - matrix.fillCircle(40, 21, 10, matrix.Color333(7, 0, 7)); - delay(500); - - // fill the screen with 'black' - matrix.fillScreen(matrix.Color333(0, 0, 0)); - - // draw some text! - matrix.setTextSize(1); // size 1 == 8 pixels high - matrix.setTextWrap(false); // Don't wrap at end of line - will do ourselves - - matrix.setCursor(8, 0); // start at top left, with 8 pixel of spacing - uint8_t w = 0; - char *str = "AdafruitIndustries"; - for (w=0; w<8; w++) { - matrix.setTextColor(Wheel(w)); - matrix.print(str[w]); - } - matrix.setCursor(2, 8); // next line - for (w=8; w<18; w++) { - matrix.setTextColor(Wheel(w)); - matrix.print(str[w]); - } - matrix.println(); - //matrix.setTextColor(matrix.Color333(4,4,4)); - //matrix.println("Industries"); - matrix.setTextColor(matrix.Color333(7,7,7)); - matrix.println("LED MATRIX!"); - - // print each letter with a rainbow color - matrix.setTextColor(matrix.Color333(7,0,0)); - matrix.print('3'); - matrix.setTextColor(matrix.Color333(7,4,0)); - matrix.print('2'); - matrix.setTextColor(matrix.Color333(7,7,0)); - matrix.print('x'); - matrix.setTextColor(matrix.Color333(4,7,0)); - matrix.print('6'); - matrix.setTextColor(matrix.Color333(0,7,0)); - matrix.print('4'); - matrix.setCursor(34, 24); - matrix.setTextColor(matrix.Color333(0,7,7)); - matrix.print("*"); - matrix.setTextColor(matrix.Color333(0,4,7)); - matrix.print('R'); - matrix.setTextColor(matrix.Color333(0,0,7)); - matrix.print('G'); - matrix.setTextColor(matrix.Color333(4,0,7)); - matrix.print("B"); - matrix.setTextColor(matrix.Color333(7,0,4)); - matrix.println("*"); - -} - -// Input a value 0 to 24 to get a color value. -// The colours are a transition r - g - b - back to r. -uint16_t Wheel(byte WheelPos) { - if(WheelPos < 8) { - return matrix.Color333(7 - WheelPos, WheelPos, 0); - } else if(WheelPos < 16) { - WheelPos -= 8; - return matrix.Color333(0, 7-WheelPos, WheelPos); - } else { - WheelPos -= 16; - return matrix.Color333(0, WheelPos, 7 - WheelPos); - } -} - - -void loop(void) { - updateEnvLCD(dht12.readTemperature(), dht12.readHumidity()); -} - -// static const int8_t PROGMEM sinetab[256] = { -// 0, 2, 5, 8, 11, 15, 18, 21, -// 24, 27, 30, 33, 36, 39, 42, 45, -// 48, 51, 54, 56, 59, 62, 65, 67, -// 70, 72, 75, 77, 80, 82, 85, 87, -// 89, 91, 93, 96, 98, 100, 101, 103, -// 105, 107, 108, 110, 111, 113, 114, 116, -// 117, 118, 119, 120, 121, 122, 123, 123, -// 124, 125, 125, 126, 126, 126, 126, 126, -// 127, 126, 126, 126, 126, 126, 125, 125, -// 124, 123, 123, 122, 121, 120, 119, 118, -// 117, 116, 114, 113, 111, 110, 108, 107, -// 105, 103, 101, 100, 98, 96, 93, 91, -// 89, 87, 85, 82, 80, 77, 75, 72, -// 70, 67, 65, 62, 59, 56, 54, 51, -// 48, 45, 42, 39, 36, 33, 30, 27, -// 24, 21, 18, 15, 11, 8, 5, 2, -// 0, -3, -6, -9, -12, -16, -19, -22, -// -25, -28, -31, -34, -37, -40, -43, -46, -// -49, -52, -55, -57, -60, -63, -66, -68, -// -71, -73, -76, -78, -81, -83, -86, -88, -// -90, -92, -94, -97, -99,-101,-102,-104, -// -106,-108,-109,-111,-112,-114,-115,-117, -// -118,-119,-120,-121,-122,-123,-124,-124, -// -125,-126,-126,-127,-127,-127,-127,-127, -// -128,-127,-127,-127,-127,-127,-126,-126, -// -125,-124,-124,-123,-122,-121,-120,-119, -// -118,-117,-115,-114,-112,-111,-109,-108, -// -106,-104,-102,-101, -99, -97, -94, -92, -// -90, -88, -86, -83, -81, -78, -76, -73, -// -71, -68, -66, -63, -60, -57, -55, -52, -// -49, -46, -43, -40, -37, -34, -31, -28, -// -25, -22, -19, -16, -12, -9, -6, -3 -// }; - -// const float radius1 = 16.3, radius2 = 23.0, radius3 = 40.8, radius4 = 44.2, -// centerx1 = 16.1, centerx2 = 11.6, centerx3 = 23.4, centerx4 = 4.1, -// centery1 = 8.7, centery2 = 6.5, centery3 = 14.0, centery4 = -2.9; -// float angle1 = 0.0, angle2 = 0.0, angle3 = 0.0, angle4 = 0.0; -// long hueShift = 0; - -// void loop() { -// int x1, x2, x3, x4, y1, y2, y3, y4, sx1, sx2, sx3, sx4; -// unsigned char x, y; -// long value; - -// sx1 = (int)(cos(angle1) * radius1 + centerx1); -// sx2 = (int)(cos(angle2) * radius2 + centerx2); -// sx3 = (int)(cos(angle3) * radius3 + centerx3); -// sx4 = (int)(cos(angle4) * radius4 + centerx4); -// y1 = (int)(sin(angle1) * radius1 + centery1); -// y2 = (int)(sin(angle2) * radius2 + centery2); -// y3 = (int)(sin(angle3) * radius3 + centery3); -// y4 = (int)(sin(angle4) * radius4 + centery4); - -// for(y=0; y> 2)) -// + (int8_t)pgm_read_byte(sinetab + (uint8_t)((x2 * x2 + y2 * y2) >> 2)) -// + (int8_t)pgm_read_byte(sinetab + (uint8_t)((x3 * x3 + y3 * y3) >> 3)) -// + (int8_t)pgm_read_byte(sinetab + (uint8_t)((x4 * x4 + y4 * y4) >> 3)); -// matrix.drawPixel(x, y, matrix.ColorHSV(value * 3, 255, 255, true)); -// x1--; x2--; x3--; x4--; -// } -// y1--; y2--; y3--; y4--; -// } - -// angle1 += 0.03; -// angle2 -= 0.07; -// angle3 += 0.13; -// angle4 -= 0.15; -// hueShift += 2; -// } - - -// unsigned long testFillScreen() { -// unsigned long start = micros(); -// tft.fillScreen(ILI9341_BLACK); -// yield(); -// tft.fillScreen(ILI9341_RED); -// yield(); -// tft.fillScreen(ILI9341_GREEN); -// yield(); -// tft.fillScreen(ILI9341_BLUE); -// yield(); -// tft.fillScreen(ILI9341_BLACK); -// yield(); -// return micros() - start; -// } - -// unsigned long testCircles(uint8_t radius, uint16_t color) { -// unsigned long start; -// int x, y, r2 = radius * 2, -// w = tft.width() + radius, -// h = tft.height() + radius; - -// // Screen is not cleared for this one -- this is -// // intentional and does not affect the reported time. -// start = micros(); -// for(x=0; x>8)); -} - -// Promote 3/3/3 RGB to Adafruit_GFX 5/6/5 -uint16_t MATRIX_RGB::Color333(uint8_t r, uint8_t g, uint8_t b) { - // RRRrrGGGgggBBBbb - return ((r & 0x7) << 13) | ((r & 0x6) << 10) | - ((g & 0x7) << 8) | ((g & 0x7) << 5) | - ((b & 0x7) << 2) | ((b & 0x6) >> 1); -} - -// Promote 4/4/4 RGB to Adafruit_GFX 5/6/5 -uint16_t MATRIX_RGB::Color444(uint8_t r, uint8_t g, uint8_t b) { - // RRRRrGGGGggBBBBb - return ((r & 0xF) << 12) | ((r & 0x8) << 8) | - ((g & 0xF) << 7) | ((g & 0xC) << 3) | - ((b & 0xF) << 1) | ((b & 0x8) >> 3); -} - -// Demote 8/8/8 to Adafruit_GFX 5/6/5 -// If no gamma flag passed, assume linear color -uint16_t MATRIX_RGB::Color888(uint8_t r, uint8_t g, uint8_t b) { - return ((uint16_t)(r & 0xF8) << 8) | ((uint16_t)(g & 0xFC) << 3) | (b >> 3); -} - -// 8/8/8 -> gamma -> 5/6/5 -uint16_t MATRIX_RGB::Color888( - uint8_t r, uint8_t g, uint8_t b, boolean gflag) { - if(gflag) { // Gamma-corrected color? - r = pgm_read_byte(&gamma[r]); // Gamma correction table maps - g = pgm_read_byte(&gamma[g]); // 8-bit input to 4-bit output - b = pgm_read_byte(&gamma[b]); - return ((uint16_t)r << 12) | ((uint16_t)(r & 0x8) << 8) | // 4/4/4->5/6/5 - ((uint16_t)g << 7) | ((uint16_t)(g & 0xC) << 3) | - ( b << 1) | ( b >> 3); - } // else linear (uncorrected) color - return ((uint16_t)(r & 0xF8) << 8) | ((uint16_t)(g & 0xFC) << 3) | (b >> 3); -} - -uint16_t MATRIX_RGB::ColorHSV( - long hue, uint8_t sat, uint8_t val, boolean gflag) { - - uint8_t r, g, b, lo; - uint16_t s1, v1; - - // Hue - hue %= 1536; // -1535 to +1535 - if(hue < 0) hue += 1536; // 0 to +1535 - lo = hue & 255; // Low byte = primary/secondary color mix - switch(hue >> 8) { // High byte = sextant of colorwheel - case 0 : r = 255 ; g = lo ; b = 0 ; break; // R to Y - case 1 : r = 255 - lo; g = 255 ; b = 0 ; break; // Y to G - case 2 : r = 0 ; g = 255 ; b = lo ; break; // G to C - case 3 : r = 0 ; g = 255 - lo; b = 255 ; break; // C to B - case 4 : r = lo ; g = 0 ; b = 255 ; break; // B to M - default: r = 255 ; g = 0 ; b = 255 - lo; break; // M to R - } - - // Saturation: add 1 so range is 1 to 256, allowig a quick shift operation - // on the result rather than a costly divide, while the type upgrade to int - // avoids repeated type conversions in both directions. - s1 = sat + 1; - r = 255 - (((255 - r) * s1) >> 8); - g = 255 - (((255 - g) * s1) >> 8); - b = 255 - (((255 - b) * s1) >> 8); - - // Value (brightness) & 16-bit color reduction: similar to above, add 1 - // to allow shifts, and upgrade to int makes other conversions implicit. - v1 = val + 1; - if(gflag) { // Gamma-corrected color? - r = pgm_read_byte(&gamma[(r * v1) >> 8]); // Gamma correction table maps - g = pgm_read_byte(&gamma[(g * v1) >> 8]); // 8-bit input to 4-bit output - b = pgm_read_byte(&gamma[(b * v1) >> 8]); - } else { // linear (uncorrected) color - r = (r * v1) >> 12; // 4-bit results - g = (g * v1) >> 12; - b = (b * v1) >> 12; - } - return (r << 12) | ((r & 0x8) << 8) | // 4/4/4 -> 5/6/5 - (g << 7) | ((g & 0xC) << 3) | - (b << 1) | ( b >> 3); -} diff --git a/examples/Advanced/matrix-serial-draw/matrix_rgb.h b/examples/Advanced/matrix-serial-draw/matrix_rgb.h deleted file mode 100644 index e765f9f..0000000 --- a/examples/Advanced/matrix-serial-draw/matrix_rgb.h +++ /dev/null @@ -1,135 +0,0 @@ -#ifndef MATRIX_RGB_H -#define MATRIX_RGB_H - -#include -#include -#include "Adafruit_GFX.h" -#include "utility/config.h" -#include "FS.h" -#include "SD.h" - -#define ILI9341_TFTWIDTH 240 -#define ILI9341_TFTHEIGHT 320 - -#define ILI9341_NOP 0x00 -#define ILI9341_SWRESET 0x01 -#define ILI9341_RDDID 0x04 -#define ILI9341_RDDST 0x09 - -#define ILI9341_SLPIN 0x10 -#define ILI9341_SLPOUT 0x11 -#define ILI9341_PTLON 0x12 -#define ILI9341_NORON 0x13 - -#define ILI9341_RDMODE 0x0A -#define ILI9341_RDMADCTL 0x0B -#define ILI9341_RDPIXFMT 0x0C -#define ILI9341_RDIMGFMT 0x0D -#define ILI9341_RDSELFDIAG 0x0F - -#define ILI9341_INVOFF 0x20 -#define ILI9341_INVON 0x21 -#define ILI9341_GAMMASET 0x26 -#define ILI9341_DISPOFF 0x28 -#define ILI9341_DISPON 0x29 - -#define ILI9341_CASET 0x2A -#define ILI9341_PASET 0x2B -#define ILI9341_RAMWR 0x2C -#define ILI9341_RAMRD 0x2E - -#define ILI9341_PTLAR 0x30 -#define ILI9341_MADCTL 0x36 -#define ILI9341_VSCRSADD 0x37 -#define ILI9341_PIXFMT 0x3A - -#define ILI9341_FRMCTR1 0xB1 -#define ILI9341_FRMCTR2 0xB2 -#define ILI9341_FRMCTR3 0xB3 -#define ILI9341_INVCTR 0xB4 -#define ILI9341_DFUNCTR 0xB6 - -#define ILI9341_PWCTR1 0xC0 -#define ILI9341_PWCTR2 0xC1 -#define ILI9341_PWCTR3 0xC2 -#define ILI9341_PWCTR4 0xC3 -#define ILI9341_PWCTR5 0xC4 -#define ILI9341_VMCTR1 0xC5 -#define ILI9341_VMCTR2 0xC7 - -#define ILI9341_RDID1 0xDA -#define ILI9341_RDID2 0xDB -#define ILI9341_RDID3 0xDC -#define ILI9341_RDID4 0xDD - -#define ILI9341_GMCTRP1 0xE0 -#define ILI9341_GMCTRN1 0xE1 -/* -#define ILI9341_PWCTR6 0xFC - - */ - -// Color definitions -#define ILI9341_BLACK 0x0000 /* 0, 0, 0 */ -#define ILI9341_NAVY 0x000F /* 0, 0, 128 */ -#define ILI9341_DARKGREEN 0x03E0 /* 0, 128, 0 */ -#define ILI9341_DARKCYAN 0x03EF /* 0, 128, 128 */ -#define ILI9341_MAROON 0x7800 /* 128, 0, 0 */ -#define ILI9341_PURPLE 0x780F /* 128, 0, 128 */ -#define ILI9341_OLIVE 0x7BE0 /* 128, 128, 0 */ -#define ILI9341_LIGHTGREY 0xC618 /* 192, 192, 192 */ -#define ILI9341_DARKGREY 0x7BEF /* 128, 128, 128 */ -#define ILI9341_BLUE 0x001F /* 0, 0, 255 */ -#define ILI9341_GREEN 0x07E0 /* 0, 255, 0 */ -#define ILI9341_CYAN 0x07FF /* 0, 255, 255 */ -#define ILI9341_RED 0xF800 /* 255, 0, 0 */ -#define ILI9341_MAGENTA 0xF81F /* 255, 0, 255 */ -#define ILI9341_YELLOW 0xFFE0 /* 255, 255, 0 */ -#define ILI9341_WHITE 0xFFFF /* 255, 255, 255 */ -#define ILI9341_ORANGE 0xFD20 /* 255, 165, 0 */ -#define ILI9341_GREENYELLOW 0xAFE5 /* 173, 255, 47 */ -#define ILI9341_PINK 0xF81F - -#define WHITE 0xFFFF -#define BLACK 0x0000 -#define BLUE 0x001F -#define BRED 0XF81F -#define GRED 0XFFE0 -#define GBLUE 0X07FF -#define RED 0xF800 -#define MAGENTA 0xF81F -#define GREEN 0x07E0 -#define CYAN 0x7FFF -#define YELLOW 0xFFE0 -#define BROWN 0XBC40 -#define BRRED 0XFC07 -#define GRAY 0X8430 - -#ifndef _swap_int16_t -#define _swap_int16_t(a, b) { int16_t t = a; a = b; b = t; } -#endif - -class MATRIX_RGB : public Adafruit_GFX { - - public: -// M5STACK_TFTLCD(int8_t _CS = SPI_CS_PIN, int8_t _DC = LCD_RS_PIN, int8_t _RST = LCD_RST_PIN); - MATRIX_RGB(); - - void begin(void); - void drawPixel(int16_t x, int16_t y, uint16_t color); -// void writePixel(int16_t x, int16_t y, uint16_t color); - - uint16_t - Color333(uint8_t r, uint8_t g, uint8_t b), - Color444(uint8_t r, uint8_t g, uint8_t b), - Color888(uint8_t r, uint8_t g, uint8_t b), - Color888(uint8_t r, uint8_t g, uint8_t b, boolean gflag), - ColorHSV(long hue, uint8_t sat, uint8_t val, boolean gflag); - - private: - -}; - - - -#endif diff --git a/examples/Basics/FactoryTest/FactoryTest.ino b/examples/Basics/FactoryTest/FactoryTest.ino index 64a15ac..c73d84b 100644 --- a/examples/Basics/FactoryTest/FactoryTest.ino +++ b/examples/Basics/FactoryTest/FactoryTest.ino @@ -56,7 +56,7 @@ void listDir(fs::FS &fs, const char * dirname, uint8_t levels){ } } -void readFile(fs::FS &fs, const char * path){ +void readFile(fs::FS &fs, const char * path) { Serial.printf("Reading file: %s\n", path); m5.Lcd.printf("Reading file: %s\n", path); @@ -95,34 +95,6 @@ void writeFile(fs::FS &fs, const char * path, const char * message){ } } -// void startup_logo() { -// m5.lcd.setBrightness(0); -// m5.lcd.drawBitmap(0, 0, 320, 240, (uint16_t *)gImage_logoM5); -// static uint8_t brightness, pre_b; -// uint32_t length = strlen((char*)m5stack_startup_music); -// uint8_t _volume = 2; -// uint16_t delay_interval = ((uint32_t)1000000/20000); -// if(_volume != 0) { -// for(int i=0; i>2); -// delayMicroseconds(40); -// brightness = (i/157); -// if(pre_b != brightness) { -// pre_b = brightness; -// m5.lcd.setBrightness(brightness); -// } -// } -// } - -// for(int i=255; i>=0; i--) { -// m5.lcd.setBrightness(i); -// // delayMicroseconds(1500); -// delay(2); -// } -// m5.Lcd.fillScreen(BLACK); -// delay(1000); -// } - void buttons_test() { if(M5.BtnA.wasPressed()) { M5.Lcd.printf("A"); @@ -171,9 +143,7 @@ void wifi_test() { // the setup routine runs once when M5Stack starts up void setup() { // initialize the M5Stack object - // GPIO_test(); m5.begin(); - // startup_logo(); m5.startupLogo(); // Lcd display diff --git a/examples/Basics/Speaker/Speaker.ino b/examples/Basics/Speaker/Speaker.ino index 533b15c..60df9eb 100644 --- a/examples/Basics/Speaker/Speaker.ino +++ b/examples/Basics/Speaker/Speaker.ino @@ -30,7 +30,7 @@ void setup() { // Initialize the M5Stack object M5.begin(); - + M5.Speaker.setVolume(8); M5.Speaker.playMusic(m5stack_startup_music, 25000); } diff --git a/examples/Basics/bitmap/bitmap.ino b/examples/Basics/bitmap/bitmap.ino deleted file mode 100644 index a8c129f..0000000 --- a/examples/Basics/bitmap/bitmap.ino +++ /dev/null @@ -1,316 +0,0 @@ -/*************************************************** - This is our Bitmap drawing example for the Adafruit ILI9341 Breakout and Shield - ----> http://www.adafruit.com/products/1651 - - Check out the links above for our tutorials and wiring diagrams - These displays use SPI to communicate, 4 or 5 pins are required to - interface (RST is optional) - Adafruit invests time and resources providing this open source code, - please support Adafruit and open-source hardware by purchasing - products from Adafruit! - - Written by Limor Fried/Ladyada for Adafruit Industries. - MIT license, all text above must be included in any redistribution - ****************************************************/ - - -// #include // Hardware-specific library -// #include -// #include -#include - -// TFT display and SD card will share the hardware SPI interface. -// Hardware SPI pins are specific to the Arduino board type and -// cannot be remapped to alternate pins. For Arduino Uno, -// Duemilanove, etc., pin 11 = MOSI, pin 12 = MISO, pin 13 = SCK. - -// #define TFT_DC 9 -// #define TFT_CS 10 -// ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC); -// #define SD_CS 4 - -void setup(void) { - delay(2000); - Serial.begin(115200); - - // M5.Lcd.begin(); - M5.begin(); - M5.Lcd.fillScreen(ILI9341_BLUE); - - Serial.print("Initializing SD card..."); - if (!SD.begin(TFCARD_CS_PIN)) { - Serial.println("failed!"); - } - Serial.println("OK!"); - // bmpDraw("/WechatIMG128.bmp", 0, 0); -} - -void loop() { - delay(2000); - Serial.println("Try using writeRect"); - M5.Lcd.fillScreen(ILI9341_BLACK); - M5.Lcd.bmpDraw("/camera2.bmp", 0, 0); - // bmpDrawWriteRect("/WechatIMG410.bmp", 64, 64); - // bmpDrawWriteRect("/WechatIMG128.bmp", 0, 0); - // M5.Lcd.bmp("/WechatIMG128.bmp", 0, 0); - - // delay(2000); - // Serial.println("Using pushCOlor"); - // M5.Lcd.fillScreen(ILI9341_BLUE); - // bmpDraw("/WechatIMG410.bmp", 0, 0); -} - -// This function opens a Windows Bitmap (BMP) file and -// displays it at the given coordinates. It's sped up -// by reading many pixels worth of data at a time -// (rather than pixel by pixel). Increasing the buffer -// size takes more of the Arduino's precious RAM but -// makes loading a little faster. 20 pixels seems a -// good balance. - -// #define BUFFPIXEL 20 - -// void bmpDraw(char *filename, uint8_t x, uint16_t y) { - -// File bmpFile; -// int bmpWidth, bmpHeight; // W+H in pixels -// uint8_t bmpDepth; // Bit depth (currently must be 24) -// uint32_t bmpImageoffset; // Start of image data in file -// uint32_t rowSize; // Not always = bmpWidth; may have padding -// uint8_t sdbuffer[3*BUFFPIXEL]; // pixel buffer (R+G+B per pixel) -// uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer -// boolean goodBmp = false; // Set to true on valid header parse -// boolean flip = true; // BMP is stored bottom-to-top -// int w, h, row, col; -// uint8_t r, g, b; -// uint32_t pos = 0, startTime = millis(); - -// if((x >= M5.Lcd.width()) || (y >= M5.Lcd.height())) return; - -// Serial.println(); -// Serial.print(F("Loading image '")); -// Serial.print(filename); -// Serial.println('\''); - -// // Open requested file on SD card -// if ((bmpFile = SD.open(filename)) == NULL) { -// Serial.print(F("File not found")); -// return; -// } - -// // Parse BMP header -// if(read16(bmpFile) == 0x4D42) { // BMP signature -// Serial.print(F("File size: ")); Serial.println(read32(bmpFile)); -// (void)read32(bmpFile); // Read & ignore creator bytes -// bmpImageoffset = read32(bmpFile); // Start of image data -// Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC); -// // Read DIB header -// Serial.print(F("Header size: ")); Serial.println(read32(bmpFile)); -// bmpWidth = read32(bmpFile); -// bmpHeight = read32(bmpFile); -// if(read16(bmpFile) == 1) { // # planes -- must be '1' -// bmpDepth = read16(bmpFile); // bits per pixel -// Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth); -// if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed - -// goodBmp = true; // Supported BMP format -- proceed! -// Serial.print(F("Image size: ")); -// Serial.print(bmpWidth); -// Serial.print('x'); -// Serial.println(bmpHeight); - -// // BMP rows are padded (if needed) to 4-byte boundary -// rowSize = (bmpWidth * 3 + 3) & ~3; - -// // If bmpHeight is negative, image is in top-down order. -// // This is not canon but has been observed in the wild. -// if(bmpHeight < 0) { -// bmpHeight = -bmpHeight; -// flip = false; -// } - -// // Crop area to be loaded -// w = bmpWidth; -// h = bmpHeight; -// if((x+w-1) >= M5.Lcd.width()) w = M5.Lcd.width() - x; -// if((y+h-1) >= M5.Lcd.height()) h = M5.Lcd.height() - y; - -// // Set TFT address window to clipped image bounds -// M5.Lcd.setAddrWindow(x, y, x+w-1, y+h-1); - -// for (row=0; row= sizeof(sdbuffer)) { // Indeed -// bmpFile.read(sdbuffer, sizeof(sdbuffer)); -// buffidx = 0; // Set index to beginning -// } - -// // Convert pixel from BMP to TFT format, push to display -// b = sdbuffer[buffidx++]; -// g = sdbuffer[buffidx++]; -// r = sdbuffer[buffidx++]; -// M5.Lcd.pushColor(M5.Lcd.color565(r,g,b)); -// } // end pixel -// } // end scanline -// Serial.print(F("Loaded in ")); -// Serial.print(millis() - startTime); -// Serial.println(" ms"); -// } // end goodBmp -// } -// } - -// bmpFile.close(); -// if(!goodBmp) Serial.println(F("BMP format not recognized.")); -// } - - -// //=========================================================== -// // Try Draw using writeRect -// void bmpDrawWriteRect(char *filename, uint8_t x, uint16_t y) { - -// File bmpFile; -// int bmpWidth, bmpHeight; // W+H in pixels -// uint8_t bmpDepth; // Bit depth (currently must be 24) -// uint32_t bmpImageoffset; // Start of image data in file -// uint32_t rowSize; // Not always = bmpWidth; may have padding -// uint8_t sdbuffer[3*BUFFPIXEL]; // pixel buffer (R+G+B per pixel) -// uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer -// boolean goodBmp = false; // Set to true on valid header parse -// boolean flip = true; // BMP is stored bottom-to-top -// int w, h, row, col; -// uint8_t r, g, b; -// uint32_t pos = 0, startTime = millis(); - -// uint16_t awColors[320]; // hold colors for one row at a time... - -// if((x >= M5.Lcd.width()) || (y >= M5.Lcd.height())) return; - -// Serial.println(); -// Serial.print(F("Loading image '")); -// Serial.print(filename); -// Serial.println('\''); - -// // Open requested file on SD card -// if ((bmpFile = SD.open(filename)) == NULL) { -// Serial.print(F("File not found")); -// return; -// } - -// // Parse BMP header -// if(read16(bmpFile) == 0x4D42) { // BMP signature -// Serial.print(F("File size: ")); Serial.println(read32(bmpFile)); -// (void)read32(bmpFile); // Read & ignore creator bytes -// bmpImageoffset = read32(bmpFile); // Start of image data -// Serial.print(F("Image Offset: ")); Serial.println(bmpImageoffset, DEC); -// // Read DIB header -// Serial.print(F("Header size: ")); Serial.println(read32(bmpFile)); -// bmpWidth = read32(bmpFile); -// bmpHeight = read32(bmpFile); -// if(read16(bmpFile) == 1) { // # planes -- must be '1' -// bmpDepth = read16(bmpFile); // bits per pixel -// Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth); -// if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed - -// goodBmp = true; // Supported BMP format -- proceed! -// Serial.print(F("Image size: ")); -// Serial.print(bmpWidth); -// Serial.print('x'); -// Serial.println(bmpHeight); - -// // BMP rows are padded (if needed) to 4-byte boundary -// rowSize = (bmpWidth * 3 + 3) & ~3; - -// // If bmpHeight is negative, image is in top-down order. -// // This is not canon but has been observed in the wild. -// if(bmpHeight < 0) { -// bmpHeight = -bmpHeight; -// flip = false; -// } - -// // Crop area to be loaded -// w = bmpWidth; -// h = bmpHeight; -// if((x+w-1) >= M5.Lcd.width()) w = M5.Lcd.width() - x; -// if((y+h-1) >= M5.Lcd.height()) h = M5.Lcd.height() - y; - -// for (row=0; row= sizeof(sdbuffer)) { // Indeed -// bmpFile.read(sdbuffer, sizeof(sdbuffer)); -// buffidx = 0; // Set index to beginning -// } - -// // Convert pixel from BMP to TFT format, push to display -// b = sdbuffer[buffidx++]; -// g = sdbuffer[buffidx++]; -// r = sdbuffer[buffidx++]; -// awColors[col] = M5.Lcd.color565(r,g,b); -// } // end pixel -// // M5.Lcd.writeRect(0, row, w, 1, awColors); -// // M5.Lcd.drawBitmap(0, row, w, 1, awColors); -// M5.Lcd.drawBitmap(x, row+y, w, 1, awColors); -// } // end scanline -// Serial.print(F("Loaded in ")); -// Serial.print(millis() - startTime); -// Serial.println(" ms"); -// } // end goodBmp -// } -// } - -// bmpFile.close(); -// if(!goodBmp) Serial.println(F("BMP format not recognized.")); -// } - -// These read 16- and 32-bit types from the SD card file. -// BMP data is stored little-endian, Arduino is little-endian too. -// May need to reverse subscript order if porting elsewhere. - -// uint16_t read16(File &f) { -// uint16_t result; -// ((uint8_t *)&result)[0] = f.read(); // LSB -// ((uint8_t *)&result)[1] = f.read(); // MSB -// return result; -// } - -// uint32_t read32(File &f) { -// uint32_t result; -// ((uint8_t *)&result)[0] = f.read(); // LSB -// ((uint8_t *)&result)[1] = f.read(); -// ((uint8_t *)&result)[2] = f.read(); -// ((uint8_t *)&result)[3] = f.read(); // MSB -// return result; -// } diff --git a/keywords.txt b/keywords.txt index 6827607..6079cb8 100644 --- a/keywords.txt +++ b/keywords.txt @@ -18,6 +18,8 @@ */ M5Stack KEYWORD3 +M5 KEYWORD3 +m5 KEYWORD3 display KEYWORD1 buttons KEYWORD1 @@ -25,6 +27,7 @@ buttons KEYWORD1 begin KEYWORD1 update KEYWORD1 startupLogo KEYWORD1 +Speaker KEYWORD1 ////////////////////////buttons pressed KEYWORD1 diff --git a/utility/Display.h b/utility/Display.h index 3e32eab..cdec863 100644 --- a/utility/Display.h +++ b/utility/Display.h @@ -42,9 +42,6 @@ typedef struct { // Data stored for FONT AS A WHOLE: #include -// #include -// #include "utility/GFX_Library/dafruit_GFX.h" -// #include "gfxfont.h" #include #define ILI9341_TFTWIDTH 320 diff --git a/utility/Speaker.cpp b/utility/Speaker.cpp index 1545a7a..d3be562 100644 --- a/utility/Speaker.cpp +++ b/utility/Speaker.cpp @@ -66,6 +66,4 @@ void SPEAKER::playMusic(const uint8_t* music_data, uint16_t sample_rate) { delay(2); } } - pinMode(25, OUTPUT); - digitalWrite(25, 0); }