Close

submitted first set of request changes to adafruit.com st77xx library

A project log for spi write up to 64 colors at a time on Arduino!

amg8833 equivilent sensor thermal cam is a perfect example of how to write faster with spi lcd displays. 128x128 sample fast on Arduino.

jamesdanielvjamesdanielv 08/23/2018 at 19:161 Comment

just suggested update to adafruit libray for st77xx display. 

this is for 4 writes at a time feature. 16x writes feature will be submitted later on.

in order to do so i added in safety checks to ensure spi data had competed for different spi data rates. i ensured that most if not all the time the loop back function of while(!(SPSR & (1<<SPIF) )); or equivalent would jus pass thru when spi is at full speed, if spi speed is slower it will wait and loop back for spi data to complete. it reduces performance by 5%, but makes it easier for new users to manage, and it reduces troubleshooting issues. it still is about 4x-8x faster than normal, as spi data is burst twice as fast as normal, and pixel location and window size overhead is reduced by 4x.

here my submission to them below:

would you add a method that allows for up to 4 writes at a time together? #52

 Open jamesdanielv opened this issue 6 minutes ago · 0 comments

it is unrolled a bit so some unconventional steps are used to make it more manageable, such as '#define' used to create complex commands. this code takes a large rectangle area, and subdivides it into 4 areas that can have different color values. while(!(SPSR & (1<<SPIF) )) is used as a safety check but should normally run thru without loop back or jmp performance tax, unless spi is at a lower speed. within this function spi is burst at about 80-100% increase speed from normal at max spi data rate, and overhead of pixel location and window size is reduced by 4x!

void Adafruit_ST77xx::fillRectFast4colors(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color0,uint16_t color1,uint16_t color2,uint16_t color3) { //this is needed for text but not fills with solid color! // rudimentary clipping (drawChar w/big text requires this) // if((x >= _width) || (y >= _height)) return; // if((x + w - 1) >= _width) w = _width - x; // if((y + h - 1) >= _height) h = _height - y;

setAddrWindow(x, y, x+w-1, y+h-1);

SPI_BEGIN_TRANSACTION(); //created complex commands in #define so code can be a lot cleaner //this is a complex command that complexspi= hi[0] value #define complexspi SPCRbackup = SPCR; SPCR = mySPCR; SPDR //this is small delay #define shortSpiDelay asm("nop\n\t");// asm("nop\n\t");// asm("nop\n\t"); //last comment out ';' not needed here, but can be added in commands later #define longSpiDelay asm("nop\n\t"); asm("nop\n\t");asm("nop\n\t"); asm("nop\n\t"); asm("nop\n\t"); asm("nop\n\t"); asm("nop\n\t"); asm("nop\n\t"); asm("nop\n\t"); asm("nop\n\t"); asm("nop\n\t");// asm("nop\n\t");// asm("nop\n\t");// asm("nop\n\t");// asm("nop\n\t")

digitalWriteFast(TFT_DC,HIGH);// old DC_HIGH(); digitalWriteFast(TFT_CS,LOW);// old CS_LOW();

// y=h; uint16_t countx;//we use these to understand what to draw! uint16_t county;

SPCR = SPCRbackup; //we place at top for next loop iteration county=h/2;

while (county !=0 ){countx=w/2;while (countx !=0) {while(!(SPSR & (1<<SPIF) ));;complexspi = highByte(color0);longSpiDelay;while(!(SPSR & (1<<SPIF) )); complexspi =lowByte(color0) ;shortSpiDelay;countx--;} while(!(SPSR & (1<<SPIF) ));

countx=w/2; while (countx !=0) {while(!(SPSR & (1<<SPIF) ));;complexspi =highByte(color1);longSpiDelay;while(!(SPSR & (1<<SPIF) )); complexspi=lowByte(color1);shortSpiDelay;countx--;} while(!(SPSR & (1<<SPIF) ));

county--; }//end of first half of rectange [0][1] drawn! county=h/2; while (county !=0){countx=w/2;while (countx !=0) {while(!(SPSR & (1<<SPIF) ));;complexspi = highByte(color2);longSpiDelay;while(!(SPSR & (1<<SPIF) )); complexspi =lowByte(color2);shortSpiDelay;countx--;} while(!(SPSR & (1<<SPIF) ));

countx=w/2;while (countx !=0) {while(!(SPSR & (1<<SPIF) ));;complexspi = highByte(color3);longSpiDelay;while(!(SPSR & (1<<SPIF) )); complexspi =lowByte(color3);shortSpiDelay; countx--;} county--; }//end of first half of rectange [2][3] drawn! while(!(SPSR & (1<<SPIF) )); digitalWriteFast(TFT_DC,HIGH);// old DC_HIGH(); digitalWriteFast(TFT_CS,HIGH);//old CS_HIGH(); SPI_END_TRANSACTION(); }

Discussions

jamesdanielv wrote 08/24/2018 at 00:44 point

submitted second request after finding that fill rectangle commands are now in Adafruit_GFX's SPITFT library . there are a lot of changes going on in the adafruit lcd st77xx librarys. I'm excited to see how much the drivers improve.

there is so much unneeded overhead in spi lcd displays currently. so much work is going on into optimizing spi speed and buffering (only part of picture but has increased performance). i bet the person writing the drivers is overworked, or has her plate full. just learned that  ladyada of adafruit manages changes to the main libraries. ill keep tweaking my drivers for performance, and offer changes when and where i can for them to the main branch. now i understand why it takes a lot of time. i only need to focus on Arduino and one a few functions. adafruit has the whole bag. still i will post updates soon that again double performance this time by running spi write s while main code is executing. at 64x64 the main loop has about 600-700 microseconds in processing of pixel subsampling. it will only cost about 16 microseconds to write data out during this time and double frame rate. sort of like a push and pop stack to get data sent faster and keep spi not only bursting, but updating display 100% of time

  Are you sure? yes | no