Updating SPIN to work with ESP.

Status
Not open for further replies.

Duhjoker

Well-known member
Hi guys

I'm trying to add ESP compatibility with my gaming library. I've gotten pretty far as well as I can see but I'm having trouble with the SPIN library. I can see that there is support for the teensy boards and something called kinetisk.

Is there any way to add support for the ESP board? I think I'm gonna need it if I want to use KurtE's screen buffer.

The gaming library is made from paulS, KurtE and SumoToys III9341 libraries with Gamebuino functions for games added.

these are the errors

Code:
Arduino: 1.8.0 (Windows 7), TD: 1.34, Board: "ESP32 Dev Module, 80MHz, 921600, None"

In file included from C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:90:0,

                 from C:\Users\duhjoker\Desktop\basicSetup\basicSetup.ino:2:

C:\Users\duhjoker\Documents\Arduino\libraries\SPIN-master/SPIN.h:29:33: error: 'IRQ_NUMBER_t' has not been declared

     virtual void usingInterrupt(IRQ_NUMBER_t interruptName) = 0;

                                 ^

C:\Users\duhjoker\Documents\Arduino\libraries\SPIN-master/SPIN.h:30:36: error: 'IRQ_NUMBER_t' has not been declared

     virtual void notUsingInterrupt(IRQ_NUMBER_t interruptName) = 0;

                                    ^

C:\Users\duhjoker\Documents\Arduino\libraries\SPIN-master/SPIN.h:67:13: error: 'KINETISK_SPI_t' does not name a type

     virtual KINETISK_SPI_t *kinetisk_spi (void) = 0;

             ^

C:\Users\duhjoker\Documents\Arduino\libraries\SPIN-master/SPIN.h:85:30: error: 'IRQ_NUMBER_t' has not been declared

  virtual void usingInterrupt(IRQ_NUMBER_t interruptName);

                              ^

C:\Users\duhjoker\Documents\Arduino\libraries\SPIN-master/SPIN.h:86:33: error: 'IRQ_NUMBER_t' has not been declared

  virtual void notUsingInterrupt(IRQ_NUMBER_t interruptName);

                                 ^

C:\Users\duhjoker\Documents\Arduino\libraries\SPIN-master/SPIN.h:121:13: error: 'KINETISK_SPI_t' does not name a type

     virtual KINETISK_SPI_t *kinetisk_spi (void);

             ^

C:\Users\duhjoker\Documents\Arduino\libraries\SPIN-master/SPIN.h:142:33: error: 'IRQ_NUMBER_t' has not been declared

     virtual void usingInterrupt(IRQ_NUMBER_t interruptName);

                                 ^

C:\Users\duhjoker\Documents\Arduino\libraries\SPIN-master/SPIN.h:143:36: error: 'IRQ_NUMBER_t' has not been declared

     virtual void notUsingInterrupt(IRQ_NUMBER_t interruptName);

                                    ^

C:\Users\duhjoker\Documents\Arduino\libraries\SPIN-master/SPIN.h:178:13: error: 'KINETISK_SPI_t' does not name a type

     virtual KINETISK_SPI_t *kinetisk_spi (void);

             ^

exit status 1
Error compiling for board ESP32 Dev Module.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
 
Last edited:
I am not sure how much SPIN will help you on non Teensy boards. That is each SPIN object is a simple wrapper around the Teensy SPI methods. So if Teensy has additional non-standard methods like usingInterrupt, then if ESP... does not have, it won't compile.

In addition SPIN has some of the code very specific to T3.x for managing the fifo queues (borrowed from ili9341_t3 library), that if the other board has a different processor, plain won't work... I have some support in for T-LC, where it does not have the queue stuff... ) And as such the T-LC won't work with my ili9341_t3n library which uses the fifo queues.

As for screen buffer, I know very little about the ESP32, for example how much ram memory does it have? To have a buffer requires: 320*24*2 =153600 bytes just for the screen memory, which only the T3.5 and T3.6 have enough for.

Currently I am trying to see if I can make most/all of SPIN be replaced by an updated SPI library. But it is hard to say if anyone will accept a new API and if so when any of the other platforms support it.
 
From what I can see the ili9341 libraries already have ESP8266 compatibility so updating the else if and if defines should work but I could be wrong.

Ok so from the Espressif page it says the board comes with 520kb of ram which is double.

https://espressif.com/en/products/hardware/esp32/overview

Can your screen buffer work with out spin? Do I even need it if the ESP's are so fast?
 
Last edited:
I mainly did SPIN as a way to allow me to use some different libraries on the different SPI busses.

Working on different approach now. Where SPIClass is used for all the buses and as such you can pass a pointer or reference to which one to use... But that is a different subject.

Some of the different platforms already allow this, not sure about ESP...

With the ILI9341 display code it is not the processor speed or the like that makes the difference. It has more to do with how well you can utilize the SPI buss. And with DMA support also maybe how much processor time it takes to update the screen...

Now back to playing SPI
 
Ok so I found the ESP32 drivers for the ili9341 here........

https://github.com/MartyMacGyver/ESP32_Adafruit_ILI9341

That gives me two options. Update my current working library or build a new library using the new ESP32 ili9341 drivers. You never answered me on on wether or not your screen buffer will work with out the spin stuff.

Also your project sounds awesome please link me to the thread if there is one.

And thank you for your time and help
 
Ok there has got to be some kind of work around. I can getframebuffer() and useframebuffer() to compile but have no idea how to get it working. Can some one please point me in the right direction.
 
Again I am not sure really what you are expecting here? Sounds like you want to do stuff specific to ESP32? Maybe better to try to get support on website where people have experience using them and can give you more complete answers.

Are you attempting to use my ili9341_t3n with SPIN here? Or are you using Marty... driver you mention in #5? If so not sure about this as it looks more like demos and not libraries?

In either case I am not sure what to say, that I have not already said.

That is if you wish to use a frame buffer and the like. you could probably strip down my library such that you only have the code that writes stuff into the frame buffer and code that takes frame buffer and draws that to screen.

In here the frame buffer is simply memory that is allocated (malloc), so that should not be a problem.

Now drawing to the screen. You need to study their SPI library to get the rudimentary working. However my guess is using the SPI.transfer functions will not get you anywhere near the performance of the ili9341_t3 libraries on the Teensy. To maybe be able to get any where near that level of performance, you would probably need to study their hardware and see how much support they have for things like: Can I encode Chip select pin information with each output? and/or can I setup DMA access and will that help or not...

But then again I see things in their SPI header file, like: void writePixels(const void * data, uint32_t size);//ili9341 compatible,
But it looks like these apis, are wrappers to the HAL layer, which then uses their RTOS layers to do the work.

So if it were me, I would try out some simple SPI tests on the board to get an idea of how well SPI works on this board.
For example have you tried running from #5 the graphic test demo? https://github.com/MartyMacGyver/ES...o-esp32/graphicstest_mod/graphicstest_mod.ino How will does the screen update? What performance numbers do you see? How do these compare to Teensy? Compare it to standard Adafruit_ili... library and demo as well as the Teensy specific ones.

Note: Just because a processor may be faster and the like does not necessarily imply that things like SPI will be fast. For example it really su.. on the Intel Edison.
 
Lol. I've been asking questions over there for a week and can't get any answers. About anything. So that's why I'm here asking the smartest people I know. I'm not really wanting to switch to esp32 yet but I would still like to have the compatibility. Oh no I'm not trying to use Marty but I was able to find the adafruit drivers so I could start adding graphics. But having a frame buffer and update commands dramatically improve the graphics. Like with no flashing and all that.

I have tried to break your t3n library down but it gets stuck on the IRQ_T stuff and it's kinetis counter part. I have found the esp32 versions of kinetis but they don't have the IRQ stuff.

I've have extensively sought out and studied the spi libraries for both the esp32 and the esp8266 and they are the same. There are only two differences. 1st the spi for the esp32 is split into two spi files. 2nd the .cpp file has the function definitions written differently but have all the same values as each other and integer in the functions ().

Now I was looking around and found a frame buffer for the esp32 but it's used in the IDF. I was thinking maybe I could compile my ili9341 library in the IDF where I could include those files but I can't get an answer on site whether it's possible.

But also the frame buffer has been written in C++ and has both the .h and .cpp but I can't figure out if that can be included in my library like I would any other library files that come in C++ and header.
 
yes yes would you mind helping me do an if defined ESP32 draw buffer to screen on all the parts that would use the SPIN library. But how can I draw the buffer to the screen using the get and use functions.

Please!!!!

Oh yea im pretty sure the SPI is the same I just looked at the spi stuff for the esp32 on the latest adafruit ili9341 drivers and it lists the esp8266 and 32 together on the spi stuff.
 
Last edited:
As I have mentioned, I am not really sure how appropriate SPIN is for your needs.

That is the main things that I developed SPIN for the Teensy as part of the T3.6-5 betas is:
a) To allow other libraries to be able to be developed that can run on any of the SPI busses that the Teensy has. Hopefully in the next Teensyduino release or two, this part won't be needed and can do it with SPI library (different thread). This probably does not apply.

b) Add in some helper functions, to ask if specific pins are valid for that SPI buss like Miso, Mosi, SCLK - Again probably not appropriate to ESP... Also maybe again part of SPI later...

c) For T3.x - helper functions to help manage the SPI FIFO queues - Again does not apply here...

So it is not SPIN you need here but a modified ILI9341 library. Assuming you wish for similar functionality as my ili9341_t3n library, here is what I would do: Make a copy of the library, give it a new name (rename files, and class and then edit all Class name references to new name...)

Note In the list below, many of the steps are all parts of one step. As the first several steps is to remove stuff, and in order to remove them you will need to rework the functions...
  1. Remove SPIN - As mentioned probably not appropriate here. So remove all references to SPIN. Note recent version where I added support for TLC - More appropriate starting point for functions like readCommand8...
  2. Remove DMA functions - My more recent stuff not in master yet - so maybe you can avoid
  3. Remove Kinetisk references - Again these SPI registers are not appropriate for your board.
  4. Remove Fifo Queue functions - Again not appropriate.
  5. Rework the writedata/writeCommand functions - Here is where you mostly do all of the above - Probably start with the KINETISL code, Maybe rework the functions that toggle CS/DC pins to not use MASK and like but instead call digitalWrite.
    Then change the output functions, like outputToSPI(c) to simply be SPI.write(char), like wise change outputToSPI16() to SPI.write16(char). And remove or neuter wait functions as these will wait for completion... - Again this will be SLOWER than our T3.x register based code, but...
  6. Rework the main output screen functions (UpdateScreen - maybe fillRect...) - Make use of the SPI.transferBytes (writeBytes) function as part of their SPI
Assuming you can do most of the above, I would try to get everything up to the last step done and try to run graphictests to see that stuff is working... It should work, but initially will be quite a bit slower. But then if you are mainly using the frame buffer code, and you rewrite the updateScreen function to be something like:
Code:
void ILI9341_t3n::updateScreen(void)					// call to say update the screen now.
{
	if (_use_fbtft) {
		beginSPITransaction();
		if (_standard) {
			// Doing full window. 
			setAddr(0, 0, _width-1, _height-1);
			writecommand_cont(ILI9341_RAMWR);

			setDataMode(); 
			SPI.writeBytes(_pfbtft, ILI9341_TFTHEIGHT*ILI9341_TFTWIDTH*2);
		} else {
			// setup just to output the clip rectangle area. 
			setAddr(_displayclipx1, _displayclipy1, _displayclipx2-1, _displayclipy2-1);
			writecommand_cont(ILI9341_RAMWR);
			setDataMode(); 
			uint16_t * pfbPixel_row = &_pfbtft[ _displayclipy1*_width + _displayclipx1];
			uint16_t count_bytes_output_per_row = (_displayclipx2 - _displayclipx1) * 2; // Need to verify count
			for (uint16_t y = _displayclipy1; y < _displayclipy2; y++) {
				SPI.writeBytes(pbfPixel_row, count_bytes_output_per_row);
				pfbPixel_row += _width;	// setup for the next row. 
			}
		}
		endSPITransaction();
	}
}

Again I did this on the fly in the editor so probably needs work. But my guess is that something like this should work and give pretty good speed results as...

I mentioned in another thread, I am trying to update our SPI library and add a multi-byte transfer like the above that does not overwrite your buffer with the read data... So looking at different Arduino platforms to see what any have done and try to propose a standard... So yesterday I updated my test app to work with the ESP-WROOM-32 chip I have. The code emulates writing the data for a TeensyView display... In this case I run two versions to see the speed diferences.

One that simply outputs one byte at a time...
Code:
void display_transfer_byte(void)
{
  uint8_t i;
  uint8_t * pscreen_data = screenmemory;
  uint8_t count_pages = (_height / 8);
  SPI.beginTransaction(SPISettings(clockRateSetting, MSBFIRST, SPI_MODE0));
  ASSERT(PIN_CS);
  for (i = 0; i < count_pages; i++)
  {
    // Output the header
    ASSERT(PIN_DC); // assert DC
    SPI.transfer(0xb0 + i);
    SPI.transfer(0x21);
    SPI.transfer(0);
    SPI.transfer(0x7f);
    // Now go into data mode
    RELEASE(PIN_DC);
    for (uint8_t j = 0; j < LCDWIDTH; j++)
    {
      SPI.transfer(* pscreen_data++);
    }
  }
  RELEASE(PIN_CS);
  SPI.endTransaction();
}
On this board, this function is taking about: 1040us to complete, which is not great.

I then made a version that uses the multi-byte transfer, that looks like:
Code:
void display_transfer_buf(void)
{
  uint8_t set_page_column_address[] =
  {
    0xb0, 0x21, 0, 0x7f
  }; // set to page 0 column 0
  uint8_t i;
  uint8_t * pscreen_data = screenmemory;
  uint8_t count_pages = (_height / 8);
  SPI.beginTransaction(SPISettings(clockRateSetting, MSBFIRST, SPI_MODE0));
  ASSERT(PIN_CS);
  for (i = 0; i < count_pages; i++)
  {
    // Output the header
    ASSERT(PIN_DC); // assert DC
    set_page_column_address[0] = 0xb0 + i;
    SPI.transferBytes(set_page_column_address, NULL, sizeof(set_page_column_address));
    // Now go into data mode
    RELEASE(PIN_DC);
    SPI.transferBytes(pscreen_data, NULL, LCDWIDTH);
    pscreen_data += LCDWIDTH;
  }
  RELEASE(PIN_CS);
  SPI.endTransaction();
}
And this version of the function takes about: 555us
Which is pretty good. As comparted to T3.2 running at default speed. My times were:
One byte: 677, My new Transfer(output buf, input buf, cnt): 554 and using FIFO 539

Hope that helps
 
still trying to process your post but I thought it best to mention a couple things about my library.......

Ok it started out as SumoToys "super-optimized" library as the base and then I added my game stuff. It worked with my T3.6 but was flashy. So I started looking at your library and PaulS' and found some cool stuff. Mainly your much needed frame buffer commands. So I took every thing connected to he buffer in your library and transplanted it into now my own version of the library. It worked like a charm but yes it used spin.

Fortunately I have nothing in either the .cpp and .h that has kinetis.

I changed my library to the Grafx and changed its class and all that both the cpp .h and sketch file. The problems I'm having is that the stuff under your Class spin in your ili9341 library. No matter where I put these items after marking out the first line but the compiler tells me that they haven't been declared.

Code:
	// added support to use optional Frame buffer KurtE
	uint8_t     useFrameBuffer(boolean b);		// use the frame buffer?  First call will allocate
	void	    freeFrameBuffer(void);			// explicit call to release the buffer  
	void	    update(void);			        // call to say update the screen now.    

	uint16_t    frameDurationMicros;                   ////DUHJOKER GAMEBUINO
	uint32_t    frameStartMicros, frameEndMicros;      ////DUHJOKER GAMEBUINO
	uint32_t    frameCount;                            ////DUHJOKER GAMEBUINO

	void        setFrameRate(uint8_t fps);                 ////DUHJOKER GAMEBUINO

	inline void drawPixel(int16_t x, int16_t y, uint16_t color);

	uint8_t startMenuTimer;


I marked the stuff in the spin class that I can't incorporate to get the buffer going.
Code:
#ifdef ENABLE_ILI9341_FRAMEBUFFER
	 // Add support for optional frame buffer
	 uint16_t	*_pfbtft;						// Optional Frame buffer 
	 uint8_t		_use_fbtft;						// Are we in frame buffer mode?
#endif

void setAddr(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
		 __attribute__((always_inline)) {
		 writecommand_cont(ILI9341_CASET); // Column addr set
		 writedata16_cont(x0);   // XSTART
		 writedata16_cont(x1);   // XEND
		 writecommand_cont(ILI9341_PASET); // Row addr set
		 writedata16_cont(y0);   // YSTART
		 writedata16_cont(y1);   // YEND
	 }

/////////////////look here
	 void beginSPITransaction(uint32_t clock = ILI9341_SPICLOCK) __attribute__((always_inline)) {
		 _pspin->beginTransaction(SPISettings(clock, MSBFIRST, SPI_MODE0));
		 if (_csport)
			 *_csport &= ~_cspinmask;
	 }
	 void endSPITransaction() __attribute__((always_inline)) {
		 if (_csport)
			 *_csport |= _cspinmask;
		 _pspin->endTransaction();
	 }

///////look here 
	 SPINClass *_pspin //////////this stuff Duhjoker 
	 int16_t  _clipx1, _clipy1, _clipx2, _clipy2;
	 int16_t  _originx, _originy;
	 int16_t  _displayclipx1, _displayclipy1, _displayclipx2, _displayclipy2;
	 bool _invisible = false;
	 bool _standard = true; // no bounding rectangle or origin set. 
	 uint8_t _cspinmask;
	 volatile uint8_t *_csport;


	 inline void updateDisplayClip() {
		 _displayclipx1 = max(0, min(_clipx1 + _originx, width()));
		 _displayclipx2 = max(0, min(_clipx2 + _originx, width()));

		 _displayclipy1 = max(0, min(_clipy1 + _originy, height()));
		 _displayclipy2 = max(0, min(_clipy2 + _originy, height()));
		 _invisible = (_displayclipx1 == _displayclipx2 || _displayclipy1 == _displayclipy2);
		 _standard = (_displayclipx1 == 0) && (_displayclipx2 == _width) && (_displayclipy1 == 0) && (_displayclipy2 == _height);
		 if (Serial) {
			 //Serial.printf("UDC (%d %d)-(%d %d) %d %d\n", _displayclipx1, _displayclipy1, _displayclipx2, 
			 //	_displayclipy2, _invisible, _standard);

		 }
	 }


	int16_t					_width, _height;
	volatile int16_t		_cursorX, _cursorY;

There's also a get freeRam() function

.cpp

Code:
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
////-------------------------------FRAME BUFFER-------------------------------------////
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////


//=======================================================================
// Add optinal support for using frame buffer to speed up complex outputs
//=======================================================================
uint8_t Grafx::useFrameBuffer(boolean b)		// use the frame buffer?  First call will allocate
{
#ifdef ENABLE_ILI9341_FRAMEBUFFER
	if (b) {
		// First see if we need to allocate buffer
		if (_pfbtft == NULL) {
			_pfbtft = (uint16_t *)malloc(TFT_ILI93XX_TFTHEIGHT* TFT_ILI93XX_TFTWIDTH * 2);
			if (_pfbtft == NULL)
				return 0;	// failed 
			memset(_pfbtft, 0, TFT_ILI93XX_TFTHEIGHT* TFT_ILI93XX_TFTWIDTH * 2);
		}
		_use_fbtft = 1;
	}
	else
		_use_fbtft = 0;

	return _use_fbtft;
#else
	return 0;
#endif
}

void Grafx::freeFrameBuffer(void)						// explicit call to release the buffer
{
#ifdef ENABLE_ILI9341_FRAMEBUFFER
	if (_pfbtft != NULL) {
		free(_pfbtft);
		_pfbtft = NULL;
		_use_fbtft = 0;	// make sure the use is turned off
	}
#endif
}
void Grafx::update(void)					// call to say update the screen now.
{
	// Not sure if better here to check flag or check existence of buffer.
	// Will go by buffer as maybe can do interesting things?

	buttons.update();

#ifdef ENABLE_ILI9341_FRAMEBUFFER
	if (_use_fbtft) {
		beginSPITransaction();
		if (_standard) {
			// Doing full window. 
			setAddr(0, 0, _width - 1, _height - 1);
			writecommand_cont(ILI9341_RAMWR);

			// BUGBUG doing as one shot.  Not sure if should or not or do like
			// main code and break up into transactions...
			uint16_t *pfbtft_end = &_pfbtft[(TFT_ILI93XX_TFTWIDTH* TFT_ILI93XX_TFTHEIGHT) - 1];	// setup 
			uint16_t *pftbft = _pfbtft;

			// Quick write out the data;
			while (pftbft < pfbtft_end) {
				writedata16_cont(*pftbft++);
			}
			writedata16_last(*pftbft);
		}
		else {
			// setup just to output the clip rectangle area. 
			setAddr(_displayclipx1, _displayclipy1, _displayclipx2 - 1, _displayclipy2 - 1);
			writecommand_cont(ILI9341_RAMWR);

			// BUGBUG doing as one shot.  Not sure if should or not or do like
			// main code and break up into transactions...
			uint16_t * pfbPixel_row = &_pfbtft[_displayclipy1*_width + _displayclipx1];
			for (uint16_t y = _displayclipy1; y < _displayclipy2; y++) {
				uint16_t * pfbPixel = pfbPixel_row;
				for (uint16_t x = _displayclipx1; x < (_displayclipx2 - 1); x++) {
					writedata16_cont(*pfbPixel++);
				}
				if (y < (_displayclipy2 - 1))
					writedata16_cont(*pfbPixel);
				else
					writedata16_last(*pfbPixel);
				pfbPixel_row += _width;	// setup for the next row. 
			}
		}
		endSPITransaction();
	}
#endif
}

boolean Grafx::updateAll() {
	if (((nextFrameMillis - millis()) > timePerFrame) && frameEndMicros) { //if time to render a new frame is reached and the frame end has ran once
		nextFrameMillis = millis() + timePerFrame;
		frameCount++;

		frameEndMicros = 0;
		frameStartMicros = micros();

//		backlight.update();
		sound.updateTrack();
		sound.updatePattern();
		sound.updateNote();
		buttons.update();
		battery.update();
		return true;

	}
	else {
		if (!frameEndMicros) { //runs once at the end of the frame
			sound.updateTrack();
			sound.updatePattern();
			sound.updateNote();
//			updatePopup();
//			displayBattery();

			update(); //send the buffer to the screen
			if (!persistence)
				freeFrameBuffer(); //clear the buffer

			frameEndMicros = micros(); //measure the frame's end time
			frameDurationMicros = frameEndMicros - frameStartMicros;

			//            display.setTextColor(BLACK);
			//            display.setCursor(0, 40);
			//            display.print(frameDurationMicros / timePerFrame);
			//            display.print(" ");
			//            display.print(2048 - freeRam());

			//            display.setCursor(0, 32);
			//            display.print("CPU:");
			//            display.print(frameDurationMicros / timePerFrame);
			//            display.println("/1000");
			//            display.print("RAM:");
			//            display.print(2048 - freeRam());
			//            display.println("/2048");
		}
		return false;
	}
}

void Grafx::setFrameRate(uint8_t fps) {
	timePerFrame = 1000 / fps;
	sound.prescaler = fps / 20;
	sound.prescaler = max(1, sound.prescaler);
}

View attachment Grafx.zip

Here are the errors with all the corrections made. Also it's giving me errors beginspitransaction() and endspitransaction() due to the _pspin

Code:
Arduino: 1.8.0 (Windows 7), TD: 1.34, Board: "ESP32 Dev Module, 80MHz, 921600, None"

In file included from C:\Users\duhjoker\Desktop\basicSetup\basicSetup.ino:2:0:

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h: In function 'void setOrigin(int16_t, int16_t)':

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1106:2: error: '_originx' was not declared in this scope

  _originx = x; _originy = y;

  ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1106:16: error: '_originy' was not declared in this scope

  _originx = x; _originy = y;

                ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1108:20: error: 'updateDisplayClip' was not declared in this scope

  updateDisplayClip();

                    ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h: In function 'void getOrigin(int16_t*, int16_t*)':

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1110:47: error: '_originx' was not declared in this scope

 void getOrigin(int16_t* x, int16_t* y) { *x = _originx; *y = _originy; }

                                               ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1110:62: error: '_originy' was not declared in this scope

 void getOrigin(int16_t* x, int16_t* y) { *x = _originx; *y = _originy; }

                                                              ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h: In function 'void setClipRect(int16_t, int16_t, int16_t, int16_t)':

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1117:2: error: '_clipx1' was not declared in this scope

  _clipx1 = x1; _clipy1 = y1; _clipx2 = x1 + w; _clipy2 = y1 + h;

  ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1117:16: error: '_clipy1' was not declared in this scope

  _clipx1 = x1; _clipy1 = y1; _clipx2 = x1 + w; _clipy2 = y1 + h;

                ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1117:30: error: '_clipx2' was not declared in this scope

  _clipx1 = x1; _clipy1 = y1; _clipx2 = x1 + w; _clipy2 = y1 + h;

                              ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1117:48: error: '_clipy2' was not declared in this scope

  _clipx1 = x1; _clipy1 = y1; _clipx2 = x1 + w; _clipy2 = y1 + h;

                                                ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1119:20: error: 'updateDisplayClip' was not declared in this scope

  updateDisplayClip();

                    ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h: In function 'void setClipRect()':

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1122:2: error: '_clipx1' was not declared in this scope

  _clipx1 = 0; _clipy1 = 0; _clipx2 = _width; _clipy2 = _height;

  ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1122:15: error: '_clipy1' was not declared in this scope

  _clipx1 = 0; _clipy1 = 0; _clipx2 = _width; _clipy2 = _height;

               ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1122:28: error: '_clipx2' was not declared in this scope

  _clipx1 = 0; _clipy1 = 0; _clipx2 = _width; _clipy2 = _height;

                            ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1122:38: error: '_width' was not declared in this scope

  _clipx1 = 0; _clipy1 = 0; _clipx2 = _width; _clipy2 = _height;

                                      ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1122:46: error: '_clipy2' was not declared in this scope

  _clipx1 = 0; _clipy1 = 0; _clipx2 = _width; _clipy2 = _height;

                                              ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1122:56: error: '_height' was not declared in this scope

  _clipx1 = 0; _clipy1 = 0; _clipx2 = _width; _clipy2 = _height;

                                                        ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1124:20: error: 'updateDisplayClip' was not declared in this scope

  updateDisplayClip();

                    ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h: In function 'void updateDisplayClip()':

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1128:2: error: '_displayclipx1' was not declared in this scope

  _displayclipx1 = max(0, min(_clipx1 + _originx, width()));

  ^

In file included from sketch\basicSetup.ino.cpp:1:0:

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1128:30: error: '_clipx1' was not declared in this scope

  _displayclipx1 = max(0, min(_clipx1 + _originx, width()));

                              ^

C:\Users\duhjoker\Documents\Arduino\hardware\espressif\esp32\cores\esp32/Arduino.h:179:24: note: in definition of macro 'max'

 #define max(a,b) ((a)>(b)?(a):(b))

                        ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1128:26: note: in expansion of macro 'min'

  _displayclipx1 = max(0, min(_clipx1 + _originx, width()));

                          ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1128:40: error: '_originx' was not declared in this scope

  _displayclipx1 = max(0, min(_clipx1 + _originx, width()));

                                        ^

C:\Users\duhjoker\Documents\Arduino\hardware\espressif\esp32\cores\esp32/Arduino.h:179:24: note: in definition of macro 'max'

 #define max(a,b) ((a)>(b)?(a):(b))

                        ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1128:26: note: in expansion of macro 'min'

  _displayclipx1 = max(0, min(_clipx1 + _originx, width()));

                          ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1128:56: error: 'width' was not declared in this scope

  _displayclipx1 = max(0, min(_clipx1 + _originx, width()));

                                                        ^

C:\Users\duhjoker\Documents\Arduino\hardware\espressif\esp32\cores\esp32/Arduino.h:179:24: note: in definition of macro 'max'

 #define max(a,b) ((a)>(b)?(a):(b))

                        ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1128:26: note: in expansion of macro 'min'

  _displayclipx1 = max(0, min(_clipx1 + _originx, width()));

                          ^

In file included from C:\Users\duhjoker\Desktop\basicSetup\basicSetup.ino:2:0:

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1129:2: error: '_displayclipx2' was not declared in this scope

  _displayclipx2 = max(0, min(_clipx2 + _originx, width()));

  ^

In file included from sketch\basicSetup.ino.cpp:1:0:

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1129:30: error: '_clipx2' was not declared in this scope

  _displayclipx2 = max(0, min(_clipx2 + _originx, width()));

                              ^

C:\Users\duhjoker\Documents\Arduino\hardware\espressif\esp32\cores\esp32/Arduino.h:179:24: note: in definition of macro 'max'

 #define max(a,b) ((a)>(b)?(a):(b))

                        ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1129:26: note: in expansion of macro 'min'

  _displayclipx2 = max(0, min(_clipx2 + _originx, width()));

                          ^

In file included from C:\Users\duhjoker\Desktop\basicSetup\basicSetup.ino:2:0:

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1131:2: error: '_displayclipy1' was not declared in this scope

  _displayclipy1 = max(0, min(_clipy1 + _originy, height()));

  ^

In file included from sketch\basicSetup.ino.cpp:1:0:

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1131:30: error: '_clipy1' was not declared in this scope

  _displayclipy1 = max(0, min(_clipy1 + _originy, height()));

                              ^

C:\Users\duhjoker\Documents\Arduino\hardware\espressif\esp32\cores\esp32/Arduino.h:179:24: note: in definition of macro 'max'

 #define max(a,b) ((a)>(b)?(a):(b))

                        ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1131:26: note: in expansion of macro 'min'

  _displayclipy1 = max(0, min(_clipy1 + _originy, height()));

                          ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1131:40: error: '_originy' was not declared in this scope

  _displayclipy1 = max(0, min(_clipy1 + _originy, height()));

                                        ^

C:\Users\duhjoker\Documents\Arduino\hardware\espressif\esp32\cores\esp32/Arduino.h:179:24: note: in definition of macro 'max'

 #define max(a,b) ((a)>(b)?(a):(b))

                        ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1131:26: note: in expansion of macro 'min'

  _displayclipy1 = max(0, min(_clipy1 + _originy, height()));

                          ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1131:57: error: 'height' was not declared in this scope

  _displayclipy1 = max(0, min(_clipy1 + _originy, height()));

                                                         ^

C:\Users\duhjoker\Documents\Arduino\hardware\espressif\esp32\cores\esp32/Arduino.h:179:24: note: in definition of macro 'max'

 #define max(a,b) ((a)>(b)?(a):(b))

                        ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1131:26: note: in expansion of macro 'min'

  _displayclipy1 = max(0, min(_clipy1 + _originy, height()));

                          ^

In file included from C:\Users\duhjoker\Desktop\basicSetup\basicSetup.ino:2:0:

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1132:2: error: '_displayclipy2' was not declared in this scope

  _displayclipy2 = max(0, min(_clipy2 + _originy, height()));

  ^

In file included from sketch\basicSetup.ino.cpp:1:0:

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1132:30: error: '_clipy2' was not declared in this scope

  _displayclipy2 = max(0, min(_clipy2 + _originy, height()));

                              ^

C:\Users\duhjoker\Documents\Arduino\hardware\espressif\esp32\cores\esp32/Arduino.h:179:24: note: in definition of macro 'max'

 #define max(a,b) ((a)>(b)?(a):(b))

                        ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1132:26: note: in expansion of macro 'min'

  _displayclipy2 = max(0, min(_clipy2 + _originy, height()));

                          ^

In file included from C:\Users\duhjoker\Desktop\basicSetup\basicSetup.ino:2:0:

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1133:2: error: '_invisible' was not declared in this scope

  _invisible = (_displayclipx1 == _displayclipx2 || _displayclipy1 == _displayclipy2);

  ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1134:2: error: '_standard' was not declared in this scope

  _standard = (_displayclipx1 == 0) && (_displayclipx2 == _width) && (_displayclipy1 == 0) && (_displayclipy2 == _height);

  ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1134:58: error: '_width' was not declared in this scope

  _standard = (_displayclipx1 == 0) && (_displayclipx2 == _width) && (_displayclipy1 == 0) && (_displayclipy2 == _height);

                                                          ^

C:\Users\duhjoker\Documents\Arduino\libraries\TFT_ILI93XX-master2.0/TFT_ILI93XX.h:1134:113: error: '_height' was not declared in this scope

  _standard = (_displayclipx1 == 0) && (_displayclipx2 == _width) && (_displayclipy1 == 0) && (_displayclipy2 == _height);

                                                                                                                 ^

exit status 1
Error compiling for board ESP32 Dev Module.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

The enclosed library is the working version but with out any modifications for esp32. It's super easy to read with super defined labeling of each section and most of the function definitions are the same order in the .cpp with labeling.

And thank you for helping me with this I really do appreciate it.
 
Last edited:
Sorry, I don't understand what you are wanting here. does your zip file have the code that does not compile?

For example in your zip file _originx is only in the header file and only used to calculate rectangle.... So don't think this is integrated.
 
OK the origin stuff might not be needed but since I have to // comment out the SPINClass *_pspin in the header file I, I cant use the clip or display clip stuff either. like I said ive tried moving the stuff around but I still get the errors.......

Code:
//	 SPINClass *_pspin;
	 int16_t  _clipx1, _clipy1, _clipx2, _clipy2; /// not working
	 int16_t  _originx, _originy;                      
	 int16_t  _displayclipx1, _displayclipy1, _displayclipx2, _displayclipy2; /// not working
	 bool _invisible = false;
	 bool _standard = true; // no bounding rectangle or origin set. 
	 uint8_t _cspinmask;
	 volatile uint8_t *_csport;



	 inline void updateDisplayClip() {     ///not working
		 _displayclipx1 = max(0, min(_clipx1 + _originx, width()));
		 _displayclipx2 = max(0, min(_clipx2 + _originx, width()));

		 _displayclipy1 = max(0, min(_clipy1 + _originy, height()));
		 _displayclipy2 = max(0, min(_clipy2 + _originy, height()));
		 _invisible = (_displayclipx1 == _displayclipx2 || _displayclipy1 == _displayclipy2);
		 _standard = (_displayclipx1 == 0) && (_displayclipx2 == _width) && (_displayclipy1 == 0) && (_displayclipy2 == _height);
		 if (Serial) {
			 //Serial.printf("UDC (%d %d)-(%d %d) %d %d\n", _displayclipx1, _displayclipy1, _displayclipx2, 
			 //	_displayclipy2, _invisible, _standard);

		 }
	 }

here is the file edited for esp32

View attachment Grafx_2.zip

wait origin is needed by the update display clip
 
FYI - I have a version of my ili9341_t3n library working on my ESP32. However having issues getting frame buffer to work.

In particular if I call malloc(320*240*2) to allocate the frame buffer, the malloc call fails.

If I try to define a fixed buffer uint16_t screenbuffer[320*240] and point to it. The program halts the processor.

That is the compiler tells me:
Code:
Sketch uses 162126 bytes (15%) of program storage space. Maximum is 1044464 bytes.
Global variables use 168804 bytes (57%) of dynamic memory, leaving 126108 bytes for local variables. Maximum is 294912 bytes.

But the debug terminal says:
Code:
ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0x00
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0008,len:8
load:0x3fff0010,len:2036
load:0x40078000,len:9988
load:0x40080000,len:252
entry 0x40080034
Guru Meditation Error: Core  0 panic'ed (Unhandled debug exception)
Debug exception reason: BREAK instr 
Register dump:
PC      : 0x000008ef  PS      : 0x00000002  A0      : 0x00000000  A1      : 0x80078a4f  
A2      : 0x3ffe3cd0  A3      : 0x40081110  A4      : 0x00000008  A5      : 0x3fff0008  
A6      : 0xe0000000  A7      : 0x00000000  A8      : 0x80078a4f  A9      : 0x000008ef  
A10     : 0x00040000  A11     : 0x400d0000  A12     : 0x00000002  A13     : 0x00016540  
A14     : 0x400d0018  A15     : 0x00000010  SAR     : 0x00000010  EXCCAUSE: 0x00000001  
EXCVADDR: 0xffffffe0  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0xffffffff  

Backtrace: 0x000008ef:0x80078a4f

CPU halted.
 
Something you might want to try on your ESP...

Here is a quick and dirty program:
Code:
void setup() {
  while (!Serial && (millis() < 3000)) ;

  Serial.begin(115200);
  Serial.println("Quick and dirty test to see if malloc works");
  }

#define FB_SIZE (320*240*2)

void loop() {
  uint32_t alloc_size = FB_SIZE;
  void * buffer_pointer;
  while (alloc_size) {
     buffer_pointer = malloc(alloc_size);
     Serial.print("Try to malloc ");
     Serial.print(alloc_size, DEC);
     Serial.print(" pointer returned=");
     Serial.println((uint32_t)buffer_pointer, HEX);

     if (buffer_pointer) {
      free(buffer_pointer);
       break;
     }  
     alloc_size = alloc_size / 2; 
  }
  delay(10000);

}

Output from the program:
Code:
Quick and dirty test to see if malloc works
Try to malloc 153600 pointer returned=0
Try to malloc 76800 pointer returned=3FFC77F4
Try to malloc 153600 pointer returned=0
Try to malloc 76800 pointer returned=3FFC77F4

So can not allocate whole buffer, but can do half.

Now try this Version:
Code:
uint16_t screenbuffer[320*240];
void setup() {
  while (!Serial && (millis() < 3000)) ;

  Serial.begin(115200);
  Serial.println("Quick and dirty test to see if malloc works");
  }

#define FB_SIZE (320*240*2)

void loop() {
  Serial.print("Hard coded frame buffer: ");
  Serial.println((uint32_t)screenbuffer, HEX);
  
  delay(10000);

}

Again this faults my board.
 
ok so maybe it needs the register descriptions for the esp32? if so I was told where to find them.

ok so I fixed all of the above but the beginspitransaction and endspitransaction. They use the _pspin and are used in the .cpp files enable frame buffer as seen here....

Code:
void Grafx::update(void)					// call to say update the screen now.
{
	// Not sure if better here to check flag or check existence of buffer.
	// Will go by buffer as maybe can do interesting things?

	buttons.update();

#ifdef ENABLE_ILI9341_FRAMEBUFFER
	if (_use_fbtft) {
		beginSPITransaction();
		if (_standard) {
			// Doing full window. 
			setAddr(0, 0, _width - 1, _height - 1);
			writecommand_cont(ILI9341_RAMWR);

			// BUGBUG doing as one shot.  Not sure if should or not or do like
			// main code and break up into transactions...
			uint16_t *pfbtft_end = &_pfbtft[(TFT_ILI93XX_TFTWIDTH* TFT_ILI93XX_TFTHEIGHT) - 1];	// setup 
			uint16_t *pftbft = _pfbtft;

			// Quick write out the data;
			while (pftbft < pfbtft_end) {
				writedata16_cont(*pftbft++);
			}
			writedata16_last(*pftbft);
		}
		else {
			// setup just to output the clip rectangle area. 
			setAddr(_displayclipx1, _displayclipy1, _displayclipx2 - 1, _displayclipy2 - 1);
			writecommand_cont(ILI9341_RAMWR);

			// BUGBUG doing as one shot.  Not sure if should or not or do like
			// main code and break up into transactions...
			uint16_t * pfbPixel_row = &_pfbtft[_displayclipy1*_width + _displayclipx1];
			for (uint16_t y = _displayclipy1; y < _displayclipy2; y++) {
				uint16_t * pfbPixel = pfbPixel_row;
				for (uint16_t x = _displayclipx1; x < (_displayclipx2 - 1); x++) {
					writedata16_cont(*pfbPixel++);
				}
				if (y < (_displayclipy2 - 1))
					writedata16_cont(*pfbPixel);
				else
					writedata16_last(*pfbPixel);
				pfbPixel_row += _width;	// setup for the next row. 
			}
		}
		endSPITransaction();
	}
#endif
}

or maybe this is where I replace the update with the one you drew up earlier?
 
From my ILI9341_esp.h file
Code:
	void beginSPITransaction(uint32_t clock = ILI9341_SPICLOCK) __attribute__((always_inline)) {
		SPI.beginTransaction(SPISettings(clock, MSBFIRST, SPI_MODE0));
		if (_csport)
			*_csport  &= ~_cspinmask;
	}
	void endSPITransaction() __attribute__((always_inline)) {
		if (_csport)
			*_csport |= _cspinmask;
		SPI.endTransaction();
	}
 
All right awesome. Almost there!!!!!! Thank you!!!!

ok in my grafx .cpp file I have this.....

Code:
void Grafx::begin(bool avoidSPIinit) 
{
//initialize Vars
	uint8_t i;
	_currentMode = 0b00000000;
	_backlight = 1;
	_portrait = false;
	_initError = 0b00000000;
	_cursorY  = _cursorX = 0;
	_textScaleX = _textScaleY = 1;
	_centerText = false;
	_scrollTop = 0;
	_scrollBottom = 0;
	_fontInterline = 0;
	_charSpacing = 0;
	battery.begin();
	battery.update();
	buttons.begin();
	buttons.update();
	sound.begin();
    _defaultBgColor = _ILI93XX_BACKGROUND;
	_defaultFgColor = _ILI93XX_FOREGROUND;
	_textForeground = _textBackground = _defaultFgColor;//text transparent
	_textWrap      = true;
	_arcAngleMax = 360;
	_arcAngleOffset = -90;
	_bklPin = 255;

	//_Mactrl_Data = 0b00000000;
	#if defined(SPI_HAS_TRANSACTION)
		TFT_ILI93XXSPI = SPISettings(TFT_ILI93XX_SPI_SPEED, MSBFIRST, SPI_MODE0);
	#endif
#if defined(__AVR__)//(avr) Any 8Bit AVR
	pinMode(_dc, OUTPUT);
	pinMode(_cs, OUTPUT);
	csport    = portOutputRegister(digitalPinToPort(_cs));
	rsport    = portOutputRegister(digitalPinToPort(_dc));
	cspinmask = digitalPinToBitMask(_cs);
	dcpinmask = digitalPinToBitMask(_dc);
    if (!avoidSPIinit) SPI.begin();
	#if !defined(SPI_HAS_TRANSACTION)
		if (!avoidSPIinit){
			SPI.setClockDivider(SPI_CLOCK_DIV2); // 8 MHz
			SPI.setBitOrder(MSBFIRST);
			SPI.setDataMode(SPI_MODE0);
		}
	#endif
	*csport |= cspinmask;//hi
	enableDataStream();
#elif defined(__SAM3X8E__)//(arm) DUE
	pinMode(_dc, OUTPUT);
	pinMode(_cs, OUTPUT);
	csport    = digitalPinToPort(_cs);
	rsport    = digitalPinToPort(_dc);
	cspinmask = digitalPinToBitMask(_cs);
	dcpinmask = digitalPinToBitMask(_dc);
    if (!avoidSPIinit) SPI.begin();
	#if !defined(SPI_HAS_TRANSACTION)
		if (!avoidSPIinit){
			SPI.setClockDivider(5); // 8 MHz
			SPI.setBitOrder(MSBFIRST);
			SPI.setDataMode(SPI_MODE0);
		}
	#endif
	csport->PIO_SODR  |=  cspinmask;//HI
	enableDataStream();
#elif defined(__MKL26Z64__)//(arm) Teensy LC (preliminary)
	pinMode(_dc, OUTPUT);
	pinMode(_cs, OUTPUT);
	if (_useSPI1){
		if ((_mosi == 0 || _mosi == 21) && (_sclk == 20)) {//identify alternate SPI channel 1 (24Mhz)
			SPI1.setMOSI(_mosi);
			SPI1.setSCK(_sclk);
			if (!avoidSPIinit) SPI1.begin();
			_useSPI1 = true; //confirm
		} else {
			bitSet(_initError,0);
			return;
		}
		if (!SPI.pinIsChipSelect(_cs)) {//ERROR
			bitSet(_initError,1);
			return;
		}
	} else {
		if ((_mosi == 11 || _mosi == 7) && (_sclk == 13 || _sclk == 14)) {//valid SPI pins?
			SPI.setMOSI(_mosi);
			SPI.setSCK(_sclk);
			if (!avoidSPIinit) SPI.begin();
			_useSPI1 = false; //confirm
		} else {
			bitSet(_initError,0);
			return;
		}
		if (!SPI.pinIsChipSelect(_cs)) {//ERROR
			bitSet(_initError,1);
			return;
		}
	}
	#if defined(_TEENSYLC_FASTPORT)
		csportSet    	= portSetRegister(digitalPinToPort(_cs));
		csportClear     = portClearRegister(digitalPinToPort(_cs));
		cspinmask 		= digitalPinToBitMask(_cs);
		dcportSet       = portSetRegister(digitalPinToPort(_dc));
		dcportClear     = portClearRegister(digitalPinToPort(_dc));
		dcpinmask	    = digitalPinToBitMask(_dc);
		*csportSet = cspinmask;
	#else
		digitalWriteFast(_cs,HIGH);
	#endif
		enableDataStream();
#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
	if ((_mosi == 11 || _mosi == 7) && (_sclk == 13 || _sclk == 14)) {
        SPI.setMOSI(_mosi);
        SPI.setSCK(_sclk);
	} else {
		bitSet(_initError,0);
		return;
	}
	if (!avoidSPIinit) SPI.begin();
	if (SPI.pinIsChipSelect(_cs, _dc)) {
		pcs_data = SPI.setCS(_cs);
		pcs_command = pcs_data | SPI.setCS(_dc);
	} else {
		pcs_data = 0;
		pcs_command = 0;
		bitSet(_initError,1);
		return;
	}
#elif defined(ESP8266) || defined(ESP32) //(arm) XTENSA ESP8266 //////////////////////
	pinMode(_dc, OUTPUT);
	pinMode(_cs, OUTPUT);
	if (!avoidSPIinit) SPI.begin();
	#if !defined(SPI_HAS_TRANSACTION)
		if (!avoidSPIinit){
			SPI.setClockDivider(4);
			SPI.setBitOrder(MSBFIRST);
			SPI.setDataMode(SPI_MODE0);
		}
	#endif
	#if defined(ESP8266) && defined(_ESP8266_STANDARDMODE) && defined(ESP32) //////////////////////////
		digitalWrite(_cs,HIGH);
	#else
		GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, _pinRegister(_cs));//H ///////////////////////////////
	#endif
	enableDataStream();
#else//(xxx) Rest of CPU
	pinMode(_dc, OUTPUT);
	pinMode(_cs, OUTPUT);
	if (!avoidSPIinit) SPI.begin();
	#if !defined(SPI_HAS_TRANSACTION)
		if (!avoidSPIinit){
			SPI.setClockDivider(4);
			SPI.setBitOrder(MSBFIRST);
			SPI.setDataMode(SPI_MODE0);
		}
	#endif
	digitalWrite(_cs,HIGH);
	enableDataStream();
#endif
	if (_rst != 255) {
		pinMode(_rst, OUTPUT);
		digitalWrite(_rst, HIGH);
		delay(10);
		digitalWrite(_rst, LOW);
		delay(10);
		digitalWrite(_rst, HIGH);
		delay(10);
	}

/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
///-----------------------------------------------------------///
///------------------- Chip Initialization -------------------///
///-----------------------------------------------------------///
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
	
	startTransaction();
	//Software reset -------------------------
	writecommand_cont(CMD_SWRESET); delay(122);//500
	//Exit sleep -----------------------------
	writecommand_cont(CMD_SLPOUT);  delay(5);
	//Exit idle mode
	writecommand_cont(CMD_IDLEOF); 
	_sendInitData(CMD_EXTREG_1,TFT_ILI93XX_EXTREG_1);
	_sendInitData(CMD_EXTREG_2,TFT_ILI93XX_EXTREG_2);
	_sendInitData(CMD_EXTREG_3,TFT_ILI93XX_EXTREG_3);
	_sendInitData(CMD_EXTREG_4,TFT_ILI93XX_EXTREG_4);
	_sendInitData(CMD_EXTREG_5,TFT_ILI93XX_EXTREG_5);
	_sendInitData(CMD_EXTREG_6,TFT_ILI93XX_EXTREG_6);
	_sendInitData(CMD_EXTREG_7,TFT_ILI93XX_EXTREG_7);
	//Power Control 1 ------------------------
	_sendInitData(CMD_PWCTR1,TFT_ILI93XX_PWCTR1);
	//Power Control 3 ------------------------
	_sendInitData(CMD_PWCTR2,TFT_ILI93XX_PWCTR2);
	//VCOM control 1 -------------------------
	_sendInitData(CMD_VCOMCTR1,TFT_ILI93XX_VCOMCTR1);
	//VCOM control 2 -------------------------
	_sendInitData(CMD_VCOMCTR2,TFT_ILI93XX_VCOMCTR2);
	//How many bits per pixel are used?
	_sendInitData(CMD_PIXFMT,TFT_ILI93XX_PIXFMT);
	//Frame Rate Control (In normal mode/Full colors)
	_sendInitData(CMD_FRMCTR1,TFT_ILI93XX_FRMCTR1);
	//Display Fuction set 5
	_sendInitData(CMD_DFUNCTR,TFT_ILI93XX_DFUNCTR);
	//writecommand_cont(0xF2);  writedata8_cont(0x00); 
	//Default gamma curve?
	//writecommand_cont(CMD_GAMMASET); writedata8_cont(0x01);
	//compensate gamma
	#if defined(TFT_ILI93XX_GAMMASET)
		//Positive Gamma Correction Setting
		writecommand_cont(CMD_PGAMMAC); for (i=0;i<15;i++){writedata8_cont(TFT_ILI93XX_GAMMASPOS[i]);}
		//Negative Gamma Correction Setting
		writecommand_cont(CMD_NGAMMAC); for (i=0;i<15;i++){writedata8_cont(TFT_ILI93XX_GAMMASNEG[i]);}
	#endif
	//Normal Display ON
	writecommand_cont(CMD_NORML);    writecommand_last(CMD_DISPON); delay(1);
	endTransaction();
	delay(1);
	//default screen rotation
	setRotation(_ILI93XX_ROTATION);
	clearMemory();
	//scroll area (all screen)
	defineScrollArea(0,0);
	setScrollDirection(0);//default
	//Fill background with default color
	fillScreen(_defaultBgColor);
	//Backlight ON
	backlight(1);
	//Now set Font
	#if defined(_ILI93XX_DEF_FONT_PATH)
		setFont(&_ILI93XX_DEF_FONT_NAME);
	#else
		setFont(&nullfont);
	#endif
	delay(30);
	
}

void Grafx::_sendInitData(const uint8_t cmd,const uint8_t data[])
{
	uint8_t i;
	if (data[0] > 0){
		writecommand_cont(cmd);
		for (i=1;i<=data[0];i++) writedata8_cont(data[i]);
	}
}

I get these errors with the esp32 stuff since I included this esp32 to this.....

Code:
#if defined(ESP8266) && !defined(_ESP8266_STANDARDMODE) && !defined(esp32)  ///duhjoker
	#include <eagle_soc.h>
#endif

errors
Code:
Arduino: 1.8.0 (Windows 7), TD: 1.34, Board: "ESP32 Dev Module, 80MHz, 921600, None"

In file included from C:\Users\duhjoker\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/esp32/rom/ets_sys.h:21:0,

                 from C:\Users\duhjoker\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/freertos/freertos/FreeRTOSConfig.h:108,

                 from C:\Users\duhjoker\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/freertos/freertos/FreeRTOS.h:99,

                 from C:\Users\duhjoker\Documents\Arduino\hardware\espressif\esp32\cores\esp32/Arduino.h:32,

                 from C:\Users\duhjoker\Documents\Arduino\libraries\Grafx_2\Grafx.h:77,

                 from C:\Users\duhjoker\Documents\Arduino\libraries\Grafx_2\Grafx.cpp:1:

C:\Users\duhjoker\Documents\Arduino\libraries\Grafx_2\Grafx.cpp: In member function 'void Grafx::begin(bool)':

C:\Users\duhjoker\Documents\Arduino\libraries\Grafx_2\Grafx.cpp:623:18: error: 'GPIO_OUT_W1TS_ADDRESS' was not declared in this scope

   GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, _pinRegister(_cs));//H

                  ^

C:\Users\duhjoker\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/esp32/soc/soc.h:61:34: note: in definition of macro 'ETS_UNCACHED_ADDR'

 #define ETS_UNCACHED_ADDR(addr) (addr)

                                  ^

C:\Users\duhjoker\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/esp32/rom/gpio.h:37:41: note: in expansion of macro 'WRITE_PERI_REG'

 #define GPIO_REG_WRITE(reg, val)        WRITE_PERI_REG(reg, val)

                                         ^

C:\Users\duhjoker\Documents\Arduino\libraries\Grafx_2\Grafx.cpp:623:3: note: in expansion of macro 'GPIO_REG_WRITE'

   GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, _pinRegister(_cs));//H

   ^

C:\Users\duhjoker\Documents\Arduino\libraries\Grafx_2\Grafx.cpp:623:57: error: '_pinRegister' was not declared in this scope

   GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, _pinRegister(_cs));//H

                                                         ^

C:\Users\duhjoker\Documents\Arduino\hardware\espressif\esp32/tools/sdk/include/esp32/soc/soc.h:116:98: note: in definition of macro 'WRITE_PERI_REG'

 #define WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) = (uint32_t)(val)   

                                                                                                  ^

C:\Users\duhjoker\Documents\Arduino\libraries\Grafx_2\Grafx.cpp:623:3: note: in expansion of macro 'GPIO_REG_WRITE'

   GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, _pinRegister(_cs));//H

   ^

exit status 1
Error compiling for board ESP32 Dev Module.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Edit:::::

Just got the library to fully compile for esp32. The error above I fixed by removing the else gpio stuff so it just

#if defined(ESP8266) && defined(_ESP8266_) && defined(ESP32)
digitalWrite(_sc,High);
#endif
 
Last edited:
Another update: Looking at ESP manual... Why??? Other than curiosity?
https://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf

Look at sections on SRAM and you will see there are three sections of memory... SRAM0, SRAM1 and SRAM2...
If I modify the example to allocate memory, that can allocate half the size, I see the address:
Try to malloc 76800 pointer returned=3FFC764C, this is in the SRAM2 area. (200K)
If I try to allocate a 2nd buffer same size I get: Allocated 2nd buffer: 3FFE4358, which is in SRAM1 area (128k Max)

So doing frame buffer may be slightly more complicated unless you some how rig it to be able to allocate this size object...

EDIT: So again before you go too far, you might want to see how your memory works.
I may continue to hack mine up to see if it will work.
 
Last edited:
found it... Reading now

Also please check this out it might help

https://github.com/Ebiroll/qemu-xtensa-esp32/blob/master/hw/display/framebuffer.c

Edit:::::

Also might need to change any spi stuff to lsbfirst instead of msbfirst for the esp32. Since the 32 uses lsb first for its spi functions in spi.h for the 32

Wouldn't happen to know the pin out wiring for the esp32 to the TFT would you?

In SumoToys library he has optimized ESP8266 start and end SPI transactions. Seems I've got lots of options to try.

I really appreciate your help! One step closer to complete compatibility!!!'
 
Last edited:
That is a lot of topic areas in 324 pages for a 'unique' twin core CPU. SRAM 0,1,2 details are in the index ?
1.3.2.3 Internal SRAM 0 17
1.3.2.4 Internal SRAM 1 17
1.3.2.5 Internal SRAM 2 18
 
Here is an output on mine, FB not working yet in this one, I have the FB allocated in two buffers and now going through code to have it check to see if the Y is in the first allocation or 2nd allocation...

ESP32-ILI9341.jpg

The pin numbers I am using are:
#define TFT_SCK 18
#define TFT_MISO 19
#define TFT_MOSI 23
#define TFT_DC 5
#define TFT_CS 22
#define TFT_RST 17

May depend on different board variants.
To figure it out, I had the following code in a test program
Code:
  DBGSerial.println("Start");
  DBGSerial.println(SCK, DEC);
  DBGSerial.println(MISO, DEC);
  DBGSerial.println(MOSI, DEC);
  DBGSerial.println(SS, DEC);
DBGSerial is defined as Serial. In this test program I am testing some different things out in SPI on different platforms and for example one of the Sparkfun SAMD boards the USB serial is not Serial, but SerialUSB...
 
Looks great!!!! Is it solid? I may not need the buffer but when I was using my t3.6 and t3.2, I was having trouble with flashing especially with binary bitmaps being stacked (but not overlapped) to create multicolor bitmaps. Perhaps I can use one of the new drawBitMap functions that use pushcolor and try? Any one have an example on how to use the pushcolor drawBitMap versions? Can they be stored on SD instead of flash? Is it quick?
 
Last edited:
heres an example sketch.......

Code:
#include <SPI.h>
#include <Grafx.h>

/*
Teensy3.x and Arduino's
You are using 4 wire SPI here, so:
 MOSI:  11//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site)
 MISO:  12//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site)
 SCK:   13//Teensy3.x/Arduino UNO (for MEGA/DUE refere to arduino site)
ESP8266-----------------------------------
Use:
#define __CS  16  //(D0)
#define __DC  5   //(D1)
#define __RST 4   //(D2)

 SCLK:D5
 MOSI:D7
 */
#define __CS1 	10
#define __DC 	9
/*
Teensy 3.x can use: 2,6,10,15,20,21,22,23
Arduino's 8 bit: any
DUE: check arduino site
If you do not use reset, tie it to +3V3
*/

uint8_t errorCode = 0;

Grafx tft = Grafx(__CS1, __DC);

//////Paul Atreides
const byte paul_front_black[] PROGMEM = {16,16,
0x07,0xe0,0x08,0x10,0x10,0x08,0x20,0x04,0x20,0x04,0x20,0x04,0x62,0x46,0x40,0x02,0x30,0x0c,0x39,0x9c,0x40,0x02,0x4f,0xf2,0x39,0x9c,0x16,0x68,0x11,0x88,0x0e,0x70};

const byte paul_front_blue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x40,0x00,0x00,0x00,0x00,0x0c,0x30,0x00,0x00,0x06,0x00,0x09,0x90,0x0e,0x70,0x00,0x00};

const byte paul_front_brown[] PROGMEM = {16,16,
0x00,0x00,0x06,0x60,0x0d,0xb0,0x17,0xe8,0x1d,0xb8,0x08,0x10,0x10,0x08,0x20,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_front_pink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x20,0x2f,0xf4,0x39,0x9c,0x0d,0xb0,0x07,0xe0,0x36,0x6c,0x31,0x8c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_front_yellow[] PROGMEM = {16,16,
0x00,0x00,0x01,0x80,0x02,0x40,0x08,0x10,0x00,0x00,0x10,0x08,0x00,0x00,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00};

//front walk
const byte paul_front_walk_1_black[] PROGMEM = {16,16,
0x07,0xe0,0x08,0x10,0x10,0x08,0x20,0x04,0x20,0x04,0x20,0x04,0x62,0x46,0x40,0x02,0x30,0x0c,0x39,0x9c,0x40,0x02,0x4f,0xf2,0x39,0x9c,0x16,0x68,0x11,0xf8,0x0e,0x00};

const byte paul_front_walk_1_blue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x40,0x00,0x00,0x00,0x00,0x0c,0x30,0x00,0x00,0x06,0x00,0x09,0x90,0x0e,0x00,0x00,0x00};

const byte paul_front_walk_1_brown[] PROGMEM = {16,16,
0x00,0x00,0x06,0x60,0x0d,0xb0,0x17,0xe8,0x1d,0xb8,0x0b,0xd0,0x1e,0x78,0x2d,0xb4,0x1b,0xd8,0x05,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_front_walk_1_pink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x40,0x07,0xe0,0x0d,0xb0,0x0d,0xb0,0x0f,0xf0,0x06,0x60,0x33,0xcc,0x30,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_front_walk_1_yellow[] PROGMEM = {16,16,
0x00,0x00,0x01,0x80,0x02,0x40,0x08,0x10,0x00,0x00,0x10,0x08,0x00,0x00,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

//front walk 2
const byte paul_front_walk_2_black[] PROGMEM = {16,16,
0x07,0xe0,0x08,0x10,0x10,0x08,0x20,0x04,0x20,0x04,0x20,0x04,0x62,0x46,0x40,0x02,0x30,0x0c,0x39,0x9c,0x40,0x02,0x4f,0xf2,0x39,0x9c,0x16,0x68,0x1f,0x88,0x00,0x70};

const byte paul_front_walk_2_blue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x40,0x00,0x00,0x00,0x00,0x0c,0x30,0x00,0x00,0x00,0x60,0x09,0x90,0x00,0x70,0x00,0x00};

const byte paul_front_walk_2_brown[] PROGMEM = {16,16,
0x00,0x00,0x06,0x60,0x0d,0xb0,0x17,0xe8,0x1d,0xb8,0x08,0x10,0x10,0x08,0x20,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_front_walk_2_pink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x40,0x07,0xe0,0x0d,0xb0,0x0d,0xb0,0x0f,0xf0,0x06,0x60,0x33,0xcc,0x30,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_front_walk_2_yellow[] PROGMEM = {16,16,
0x00,0x00,0x01,0x80,0x02,0x40,0x08,0x10,0x00,0x00,0x10,0x08,0x00,0x00,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

//left
const byte paul_left_black[] PROGMEM = {16,16,
0x00,0x00,0x03,0xe0,0x04,0x10,0x08,0x08,0x10,0x04,0x10,0x04,0x14,0x04,0x10,0x08,0x10,0x10,0x08,0x60,0x07,0xe0,0x02,0x20,0x03,0x20,0x04,0xe0,0x04,0x20,0x03,0xc0};

const byte paul_left_blue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x03,0xc0,0x00,0x00};

const byte paul_left_brown[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x01,0xa0,0x06,0xd0,0x01,0x68,0x00,0xb0,0x00,0x58,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_left_pink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0f,0x00,0x0b,0x00,0x0b,0x60,0x0f,0xe0,0x07,0x80,0x00,0x00,0x00,0xc0,0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_left_yellow[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x02,0x40,0x01,0x20,0x08,0x90,0x00,0x48,0x00,0xa0,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

//rear
const byte paul_rear_black[] PROGMEM = {16,16,
0x07,0xe0,0x08,0x10,0x10,0x08,0x20,0x04,0x20,0x04,0x20,0x04,0x60,0x06,0x40,0x02,0x20,0x04,0x3a,0x5c,0x49,0x92,0x4f,0xf2,0x39,0x9c,0x16,0x68,0x11,0x88,0x0e,0x70};

const byte paul_rear_blue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x60,0x00,0x00,0x06,0x60,0x09,0x90,0x0e,0x70,0x00,0x00};

const byte paul_rear_brown[] PROGMEM = {16,16,
0x00,0x00,0x06,0x60,0x0d,0xb0,0x17,0xe8,0x1d,0xb8,0x0b,0xd0,0x1e,0x78,0x2d,0xb4,0x1b,0xd8,0x05,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rear_pink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x0c,0x30,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rear_yellow[] PROGMEM = {16,16,
0x00,0x00,0x01,0x80,0x02,0x40,0x08,0x10,0x02,0x40,0x14,0x28,0x01,0x80,0x12,0x48,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

//rear walk 1
const byte paul_rear_walk_1_black[] PROGMEM = {16,16,
0x07,0xe0,0x08,0x10,0x10,0x08,0x20,0x04,0x20,0x04,0x20,0x04,0x60,0x06,0x40,0x02,0x20,0x04,0x3a,0x5c,0x49,0x92,0x4f,0xf2,0x39,0x9c,0x16,0x68,0x11,0xf8,0x0e,0x00};

const byte paul_rear_walk_1_blue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x60,0x00,0x00,0x06,0x60,0x09,0x90,0x0e,0x00,0x00,0x00};

const byte paul_rear_walk_1_brown[] PROGMEM = {16,16,
0x00,0x00,0x06,0x60,0x0d,0xb0,0x17,0xe8,0x1d,0xb8,0x0b,0xd0,0x1e,0x78,0x2d,0xb4,0x1b,0xd8,0x05,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rear_walk_1_pink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x40,0x07,0xe0,0x0d,0xb0,0x0d,0xb0,0x0f,0xf0,0x06,0x60,0x33,0xcc,0x30,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rear_walk_1_yellow[] PROGMEM = {16,16,
0x00,0x00,0x01,0x80,0x02,0x40,0x08,0x10,0x02,0x40,0x14,0x28,0x01,0x80,0x12,0x48,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

//rear walk 2
const byte paul_rear_walk_2_black[] PROGMEM = {16,16,
0x07,0xe0,0x08,0x10,0x10,0x08,0x20,0x04,0x20,0x04,0x20,0x04,0x60,0x06,0x40,0x02,0x20,0x04,0x3a,0x5c,0x49,0x92,0x4f,0xf2,0x39,0x9c,0x16,0x68,0x1f,0x88,0x00,0x70};

const byte paul_rear_walk_2_blue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x40,0x00,0x00,0x00,0x00,0x0c,0x30,0x00,0x00,0x00,0x60,0x09,0x90,0x00,0x70,0x00,0x00};

const byte paul_rear_walk_2_brown[] PROGMEM = {16,16,
0x00,0x00,0x06,0x60,0x0d,0xb0,0x17,0xe8,0x1d,0xb8,0x0b,0xd0,0x1e,0x78,0x2d,0xb4,0x1b,0xd8,0x05,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rear_walk_2_pink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x0c,0x30,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_rear_walk_2_yellow[] PROGMEM = {16,16,
0x00,0x00,0x01,0x80,0x02,0x40,0x08,0x10,0x02,0x40,0x14,0x28,0x01,0x80,0x12,0x48,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

//right
const byte paul_right_black[] PROGMEM = {16,16,
0x00,0x00,0x07,0xc0,0x08,0x20,0x10,0x10,0x20,0x08,0x20,0x08,0x20,0x28,0x10,0x08,0x08,0x08,0x06,0x10,0x07,0xe0,0x04,0x40,0x04,0xc0,0x07,0x20,0x04,0x20,0x03,0xc0};

const byte paul_right_blue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0xc0,0x03,0xc0,0x00,0x00};

const byte paul_right_brown[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x05,0x80,0x0b,0x60,0x16,0x80,0x0d,0x00,0x1a,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_right_pink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0xf0,0x00,0xd0,0x06,0xd0,0x07,0xf0,0x01,0xe0,0x00,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_right_yellow[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x02,0x40,0x04,0x80,0x09,0x10,0x12,0x00,0x05,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

//walk left
const byte paul_walk_left_black[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x03,0x80,0x0c,0x40,0x10,0x20,0x20,0x20,0x20,0x30,0x20,0x10,0x20,0x10,0x20,0x20,0x10,0xc0,0x0f,0xc0,0x3f,0x30,0x49,0x28,0x27,0xc8,0x1c,0x30};

const byte paul_walk_left_blue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x10,0x18,0x30,0x00,0x00};

const byte paul_walk_left_brown[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x0a,0x80,0x01,0x40,0x0c,0x80,0x01,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_walk_left_pink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x12,0x00,0x16,0x00,0x1e,0xc0,0x1f,0xc0,0x0f,0x00,0x00,0x00,0x00,0xc0,0x00,0xc0,0x00,0x00,0x00,0x00};

const byte paul_walk_left_yellow[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x80,0x05,0x40,0x10,0x80,0x01,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

//walk right
const byte paul_walk_right_black[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x01,0xc0,0x02,0x30,0x04,0x08,0x04,0x04,0x0c,0x04,0x08,0x04,0x08,0x04,0x04,0x04,0x03,0x08,0x03,0xf0,0x0c,0xfc,0x14,0x92,0x13,0xe4,0x0c,0x38};

const byte paul_walk_right_blue[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x6c,0x0c,0x18,0x00,0x00};

const byte paul_walk_right_brown[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x50,0x02,0x80,0x01,0x30,0x02,0x80,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte paul_walk_right_pink[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x48,0x00,0x68,0x03,0x78,0x03,0xf8,0x00,0xf0,0x00,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00};

const byte paul_walk_right_yellow[] PROGMEM = {16,16,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x40,0x02,0xa0,0x01,0x08,0x02,0x80,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const byte blank_square[] PROGMEM ={16,16,
 B00000000,B00000000,
 B00000000,B00000000,
 B00000000,B00000000,
 B00000000,B00000000,
 B00000000,B00000000,
 B00000000,B00000000,
 B00000000,B00000000,
 B00000000,B00000000,
 B00000000,B00000000,
 B00000000,B00000000,
 B00000000,B00000000,
 B00000000,B00000000,
 B00000000,B00000000,
 B00000000,B00000000,
 B00000000,B00000000,
 B00000000,B00000000,};

const byte red_square[] PROGMEM ={16,16,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,};

const byte green_square[] PROGMEM ={16,16,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,};

 const byte blue_square[] PROGMEM ={16,16,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,};



 const byte yellow_square[] PROGMEM ={16,16,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,
 B11111111,B11111111,};

const byte tilemap1[] PROGMEM = {22,17,
16,16,
1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,
0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,};

const byte tilemap2[] PROGMEM = {22,17,
16,16,
0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,
1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,
0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,};


const byte *spritesheet1[] = {blank_square,green_square};
const byte *spritesheet2[] = {blank_square,blue_square};
const byte *spritesheet3[] = {blank_square,red_square};
const byte *spritesheet4[] = {blank_square,yellow_square};

int  player_x = 160;
int  player_y = 110;
int   player_direction = 2;
int x=0,y=0;

void setup() {
	Serial.begin(38400);
	long unsigned debug_start = millis();
	while (!Serial && ((millis() - debug_start) <= 5000));
	Serial.println("serial ok, testing lib...");
  tft.begin();
//  tft.buttons.begin();
//  tft.buttons.update();
  tft.setFrameRate(62);
  tft.persistence = false;
  //the following it's mainly for Teensy
  //it will help you to understand if you have choosed the
  //wrong combination of pins!
  errorCode = tft.getErrorCode();
  if (errorCode != 0) {
	  Serial.print("Init error! ");
	  if (bitRead(errorCode, 0)) Serial.print("MOSI or SCLK pin mismach!\n");
	  if (bitRead(errorCode, 1)) Serial.print("CS or DC pin mismach!\n");
  }
  else {
	  Serial.println("Inited");
  }
}

void loop(void) {
     if(tft.updateAll()){
    if (tft.buttons.repeat(BTN_RIGHT,2));//{x--;}
    if (tft.buttons.repeat(BTN_LEFT,0));//{x++;}
    if (tft.buttons.repeat(BTN_DOWN,3));//{y--;}
    if (tft.buttons.repeat(BTN_UP,1));//{y++;} 

    if (tft.buttons.repeat(BTN_A,4));//{x--;}
    if (tft.buttons.repeat(BTN_Y,7));//{x++;}
    if (tft.buttons.repeat(BTN_B,5));//{y--;}
    if (tft.buttons.repeat(BTN_X,6));//{y++;} 

    if (tft.buttons.repeat(BTN_L,8));//{x--;}
    if (tft.buttons.repeat(BTN_R,9));//{x++;}

//     tft.drawTilemap(22,17,tilemap1,spritesheet1, GREEN);
//  tft.drawTilemap(22,17,tilemap2,spritesheet2, BLUE); 

 if(tft.buttons.repeat(BTN_L,8)){
tft.drawBitmap1(player_x, player_y,green_square,16,16,GREEN);}

 if(tft.buttons.repeat(BTN_R,9)){
tft.drawBitmap1(player_x, player_y,blue_square,16,16,BLUE);}

       if(tft.buttons.repeat(BTN_UP,1)){
 tft.drawBitmap1(player_x, player_y,paul_rear_black,16,16,BLACK);
    tft.drawBitmap1(player_x, player_y,paul_rear_blue,16,16,BLUE);
     tft.drawBitmap1(player_x, player_y,paul_rear_brown,16,16,BROWN);
      tft.drawBitmap1(player_x, player_y,paul_rear_pink,16,16,PINK);
       tft.drawBitmap1(player_x, player_y,paul_rear_yellow,16,16,YELLOW);

         player_direction = 1;}
//      player_y = player_y - 1;}
//    if(player_y <= 0){
//      player_y = 0;}
     
       if(tft.buttons.repeat(BTN_X,6)){
 tft.drawBitmap1(player_x, player_y,paul_rear_black,16,16,BLACK);
    tft.drawBitmap1(player_x, player_y,paul_rear_blue,16,16,BLUE);
     tft.drawBitmap1(player_x, player_y,paul_rear_brown,16,16,BROWN);
      tft.drawBitmap1(player_x, player_y,paul_rear_pink,16,16,PINK);
       tft.drawBitmap1(player_x, player_y,paul_rear_yellow,16,16,YELLOW);

         player_direction = 1;}
//      player_y = player_y - 1;}
//    if(player_y <= 0){
//      player_y = 0;}


////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
      
    if(tft.buttons.repeat(BTN_DOWN,3)){
   tft.drawBitmap1(player_x, player_y,paul_front_black,16,16,BLACK);
    tft.drawBitmap1(player_x, player_y,paul_front_blue,16,16,BLUE);
     tft.drawBitmap1(player_x, player_y,paul_front_brown,16,16,BROWN);
      tft.drawBitmap1(player_x, player_y,paul_front_pink,16,16,PINK);
       tft.drawBitmap1(player_x, player_y,paul_front_yellow,16,16,YELLOW);
       
  player_direction = 2;}
//      player_y = player_y + 1;}
//    if(player_y >= 40){
//      player_y = 40;}
  
  if(tft.buttons.repeat(BTN_B,5)){
   tft.drawBitmap1(player_x, player_y,paul_front_black,16,16,BLACK);
    tft.drawBitmap1(player_x, player_y,paul_front_blue,16,16,BLUE);
     tft.drawBitmap1(player_x, player_y,paul_front_brown,16,16,BROWN);
      tft.drawBitmap1(player_x, player_y,paul_front_pink,16,16,PINK);
       tft.drawBitmap1(player_x, player_y,paul_front_yellow,16,16,YELLOW);
       
  player_direction = 2;}
//      player_y = player_y + 1;}
//    if(player_y >= 40){
//      player_y = 40;}



///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////     
         if(tft.buttons.repeat(BTN_LEFT,0)){
   tft.drawBitmap1(player_x, player_y,paul_left_black,16,16,BLACK);
    tft.drawBitmap1(player_x, player_y,paul_left_blue,16,16,BLUE);
     tft.drawBitmap1(player_x, player_y,paul_left_brown,16,16,BROWN);
      tft.drawBitmap1(player_x, player_y,paul_left_pink,16,16,PINK);
       tft.drawBitmap1(player_x, player_y,paul_left_yellow,16,16,YELLOW);

      player_direction = 3;}
//      player_x = player_x + 1;}
//    if(player_x >= 77){
//      player_x = 77;} 

         if(tft.buttons.repeat(BTN_Y,7)){
   tft.drawBitmap1(player_x, player_y,paul_left_black,16,16,BLACK);
    tft.drawBitmap1(player_x, player_y,paul_left_blue,16,16,BLUE);
     tft.drawBitmap1(player_x, player_y,paul_left_brown,16,16,BROWN);
      tft.drawBitmap1(player_x, player_y,paul_left_pink,16,16,PINK);
       tft.drawBitmap1(player_x, player_y,paul_left_yellow,16,16,YELLOW);

      player_direction = 3;}
//      player_x = player_x + 1;}
//    if(player_x >= 77){
//      player_x = 77;} 

//////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

  if(tft.buttons.repeat(BTN_RIGHT,2)){
   tft.drawBitmap1(player_x, player_y,paul_right_black,16,16,BLACK);
    tft.drawBitmap1(player_x, player_y,paul_right_blue,16,16,BLUE);
     tft.drawBitmap1(player_x, player_y,paul_right_brown,16,16,BROWN);
      tft.drawBitmap1(player_x, player_y,paul_right_pink,16,16,PINK);
       tft.drawBitmap1(player_x, player_y,paul_right_yellow,16,16,YELLOW);

   player_direction = 4;}
//      player_x = player_x + 1;}
//    if(player_x >= 77){
//      player_x = 77;}

 if(tft.buttons.repeat(BTN_A,4)){
   tft.drawBitmap1(player_x, player_y,paul_right_black,16,16,BLACK);
    tft.drawBitmap1(player_x, player_y,paul_right_blue,16,16,BLUE);
     tft.drawBitmap1(player_x, player_y,paul_right_brown,16,16,BROWN);
      tft.drawBitmap1(player_x, player_y,paul_right_pink,16,16,PINK);
       tft.drawBitmap1(player_x, player_y,paul_right_yellow,16,16,YELLOW);

   player_direction = 4;}
//      player_x = player_x + 1;}
//    if(player_x >= 77){
//      player_x = 77;}

 
/////////////////////////////////////////////////////
     ////////////PLAYER DIRECTION/////////////
/////////////////////////////////////////////////////

if (player_direction == 1){
     tft.drawBitmap1(player_x, player_y,paul_rear_black,16,16,BLACK);
    tft.drawBitmap1(player_x, player_y,paul_rear_blue,16,16,BLUE);
     tft.drawBitmap1(player_x, player_y,paul_rear_brown,16,16,BROWN);
      tft.drawBitmap1(player_x, player_y,paul_rear_pink,16,16,PINK);
       tft.drawBitmap1(player_x, player_y,paul_rear_yellow,16,16,YELLOW);
        
  }
       
      
      else if (player_direction == 2){
      tft.drawBitmap1(player_x, player_y,paul_front_black,16,16,BLACK);
    tft.drawBitmap1(player_x, player_y,paul_front_blue,16,16,BLUE);
     tft.drawBitmap1(player_x, player_y,paul_front_brown,16,16,BROWN);
      tft.drawBitmap1(player_x, player_y,paul_front_pink,16,16,PINK);
       tft.drawBitmap1(player_x, player_y,paul_front_yellow,16,16,YELLOW);
      }

      
else if (player_direction == 3){
       tft.drawBitmap1(player_x, player_y,paul_left_black,16,16,BLACK);
    tft.drawBitmap1(player_x, player_y,paul_left_blue,16,16,BLUE);
     tft.drawBitmap1(player_x, player_y,paul_left_brown,16,16,BROWN);
      tft.drawBitmap1(player_x, player_y,paul_left_pink,16,16,PINK);
       tft.drawBitmap1(player_x, player_y,paul_left_yellow,16,16,YELLOW);
}


      else if (player_direction == 4){
        tft.drawBitmap1(player_x, player_y,paul_right_black,16,16,BLACK);
    tft.drawBitmap1(player_x, player_y,paul_right_blue,16,16,BLUE);
     tft.drawBitmap1(player_x, player_y,paul_right_brown,16,16,BROWN);
      tft.drawBitmap1(player_x, player_y,paul_right_pink,16,16,PINK);
       tft.drawBitmap1(player_x, player_y,paul_right_yellow,16,16,YELLOW); 
  

 
   }
 }
}

and here is my compiling library........

View attachment Grafx_esp32.zip
 
Last edited:
Status
Not open for further replies.
Back
Top